diff --git a/android/media/AmrInputStream.java b/android/media/AmrInputStream.java
new file mode 100644
index 0000000..3cb224d
--- /dev/null
+++ b/android/media/AmrInputStream.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2008 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.compat.annotation.UnsupportedAppUsage;
+import android.media.MediaCodec.BufferInfo;
+import android.util.Log;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.ByteBuffer;
+
+
+/**
+ * DO NOT USE
+ * @hide
+ */
+public final class AmrInputStream extends InputStream {
+    private final static String TAG = "AmrInputStream";
+
+    // frame is 20 msec at 8.000 khz
+    private final static int SAMPLES_PER_FRAME = 8000 * 20 / 1000;
+
+    MediaCodec mCodec;
+    BufferInfo mInfo;
+    boolean mSawOutputEOS;
+    boolean mSawInputEOS;
+
+    // pcm input stream
+    private InputStream mInputStream;
+
+    // result amr stream
+    private final byte[] mBuf = new byte[SAMPLES_PER_FRAME * 2];
+    private int mBufIn = 0;
+    private int mBufOut = 0;
+
+    // helper for bytewise read()
+    private byte[] mOneByte = new byte[1];
+
+    /**
+     * DO NOT USE - use MediaCodec instead
+     */
+    @UnsupportedAppUsage
+    public AmrInputStream(InputStream inputStream) {
+        Log.w(TAG, "@@@@ AmrInputStream is not a public API @@@@");
+        mInputStream = inputStream;
+
+        MediaFormat format  = new MediaFormat();
+        format.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_AUDIO_AMR_NB);
+        format.setInteger(MediaFormat.KEY_SAMPLE_RATE, 8000);
+        format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
+        format.setInteger(MediaFormat.KEY_BIT_RATE, 12200);
+
+        MediaCodecList mcl = new MediaCodecList(MediaCodecList.REGULAR_CODECS);
+        String name = mcl.findEncoderForFormat(format);
+        if (name != null) {
+            try {
+                mCodec = MediaCodec.createByCodecName(name);
+                mCodec.configure(format,
+                        null /* surface */,
+                        null /* crypto */,
+                        MediaCodec.CONFIGURE_FLAG_ENCODE);
+                mCodec.start();
+            } catch (IOException e) {
+                if (mCodec != null) {
+                    mCodec.release();
+                }
+                mCodec = null;
+            }
+        }
+        mInfo = new BufferInfo();
+    }
+
+    /**
+     * DO NOT USE
+     */
+    @Override
+    public int read() throws IOException {
+        int rtn = read(mOneByte, 0, 1);
+        return rtn == 1 ? (0xff & mOneByte[0]) : -1;
+    }
+
+    /**
+     * DO NOT USE
+     */
+    @Override
+    public int read(byte[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    /**
+     * DO NOT USE
+     */
+    @Override
+    public int read(byte[] b, int offset, int length) throws IOException {
+        if (mCodec == null) {
+            throw new IllegalStateException("not open");
+        }
+
+        if (mBufOut >= mBufIn && !mSawOutputEOS) {
+            // no data left in buffer, refill it
+            mBufOut = 0;
+            mBufIn = 0;
+
+            // first push as much data into the encoder as possible
+            while (!mSawInputEOS) {
+                int index = mCodec.dequeueInputBuffer(0);
+                if (index < 0) {
+                    // no input buffer currently available
+                    break;
+                } else {
+                    int numRead;
+                    for (numRead = 0; numRead < SAMPLES_PER_FRAME * 2; ) {
+                        int n = mInputStream.read(mBuf, numRead, SAMPLES_PER_FRAME * 2 - numRead);
+                        if (n == -1) {
+                            mSawInputEOS = true;
+                            break;
+                        }
+                        numRead += n;
+                    }
+                    ByteBuffer buf = mCodec.getInputBuffer(index);
+                    buf.put(mBuf, 0, numRead);
+                    mCodec.queueInputBuffer(index,
+                            0 /* offset */,
+                            numRead,
+                            0 /* presentationTimeUs */,
+                            mSawInputEOS ? MediaCodec.BUFFER_FLAG_END_OF_STREAM : 0 /* flags */);
+                }
+            }
+
+            // now read encoded data from the encoder
+            int index = mCodec.dequeueOutputBuffer(mInfo, 0);
+            if (index >= 0) {
+                mBufIn = mInfo.size;
+                ByteBuffer out = mCodec.getOutputBuffer(index);
+                out.get(mBuf, 0 /* offset */, mBufIn /* length */);
+                mCodec.releaseOutputBuffer(index,  false /* render */);
+                if ((mInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+                    mSawOutputEOS = true;
+                }
+            }
+        }
+
+        if (mBufOut < mBufIn) {
+            // there is data in the buffer
+            if (length > mBufIn - mBufOut) {
+                length = mBufIn - mBufOut;
+            }
+            System.arraycopy(mBuf, mBufOut, b, offset, length);
+            mBufOut += length;
+            return length;
+        }
+
+        if (mSawInputEOS && mSawOutputEOS) {
+            // no more data available in buffer, codec or input stream
+            return -1;
+        }
+
+        // caller should try again
+        return 0;
+    }
+
+    @Override
+    public void close() throws IOException {
+        try {
+            if (mInputStream != null) {
+                mInputStream.close();
+            }
+        } finally {
+            mInputStream = null;
+            try {
+                if (mCodec != null) {
+                    mCodec.release();
+                }
+            } finally {
+                mCodec = null;
+            }
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        if (mCodec != null) {
+            Log.w(TAG, "AmrInputStream wasn't closed");
+            mCodec.release();
+        }
+    }
+}
diff --git a/android/media/ApplicationMediaCapabilities.java b/android/media/ApplicationMediaCapabilities.java
new file mode 100644
index 0000000..97fa0ec
--- /dev/null
+++ b/android/media/ApplicationMediaCapabilities.java
@@ -0,0 +1,626 @@
+/*
+ * Copyright (C) 2020 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.annotation.NonNull;
+import android.content.ContentResolver;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import com.android.modules.annotation.MinSdk;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ ApplicationMediaCapabilities is an immutable class that encapsulates an application's capabilities
+ for handling newer video codec format and media features.
+
+ <p>
+ Android 12 introduces Compatible media transcoding feature.  See
+ <a href="https://developer.android.com/about/versions/12/features#compatible_media_transcoding">
+ Compatible media transcoding</a>. By default, Android assumes apps can support playback of all
+ media formats. Apps that would like to request that media be transcoded into a more compatible
+ format should declare their media capabilities in a media_capabilities.xml resource file and add it
+ as a property tag in the AndroidManifest.xml file. Here is a example:
+ <pre>
+ {@code
+ <media-capabilities xmlns:android="http://schemas.android.com/apk/res/android">
+     <format android:name="HEVC" supported="true"/>
+     <format android:name="HDR10" supported="false"/>
+     <format android:name="HDR10Plus" supported="false"/>
+ </media-capabilities>
+ }
+ </pre>
+ The ApplicationMediaCapabilities class is generated from this xml and used by the platform to
+ represent an application's media capabilities in order to determine whether modern media files need
+ to be transcoded for that application.
+ </p>
+
+ <p>
+ ApplicationMediaCapabilities objects can also be built by applications at runtime for use with
+ {@link ContentResolver#openTypedAssetFileDescriptor(Uri, String, Bundle)} to provide more
+ control over the transcoding that is built into the platform. ApplicationMediaCapabilities
+ provided by applications at runtime like this override the default manifest capabilities for that
+ media access.The object could be build either through {@link #createFromXml(XmlPullParser)} or
+ through the builder class {@link ApplicationMediaCapabilities.Builder}
+
+ <h3> Video Codec Support</h3>
+ <p>
+ Newer video codes include HEVC, VP9 and AV1. Application only needs to indicate their support
+ for newer format with this class as they are assumed to support older format like h.264.
+
+ <h3>Capability of handling HDR(high dynamic range) video</h3>
+ <p>
+ There are four types of HDR video(Dolby-Vision, HDR10, HDR10+, HLG) supported by the platform,
+ application will only need to specify individual types they supported.
+ */
+@MinSdk(Build.VERSION_CODES.S)
+public final class ApplicationMediaCapabilities implements Parcelable {
+    private static final String TAG = "ApplicationMediaCapabilities";
+
+    /** List of supported video codec mime types. */
+    private Set<String> mSupportedVideoMimeTypes = new HashSet<>();
+
+    /** List of unsupported video codec mime types. */
+    private Set<String> mUnsupportedVideoMimeTypes = new HashSet<>();
+
+    /** List of supported hdr types. */
+    private Set<String> mSupportedHdrTypes = new HashSet<>();
+
+    /** List of unsupported hdr types. */
+    private Set<String> mUnsupportedHdrTypes = new HashSet<>();
+
+    private boolean mIsSlowMotionSupported = false;
+
+    private ApplicationMediaCapabilities(Builder b) {
+        mSupportedVideoMimeTypes.addAll(b.getSupportedVideoMimeTypes());
+        mUnsupportedVideoMimeTypes.addAll(b.getUnsupportedVideoMimeTypes());
+        mSupportedHdrTypes.addAll(b.getSupportedHdrTypes());
+        mUnsupportedHdrTypes.addAll(b.getUnsupportedHdrTypes());
+        mIsSlowMotionSupported = b.mIsSlowMotionSupported;
+    }
+
+    /**
+     * Query if a video codec format is supported by the application.
+     * <p>
+     * If the application has not specified supporting the format or not, this will return false.
+     * Use {@link #isFormatSpecified(String)} to query if a format is specified or not.
+     *
+     * @param videoMime The mime type of the video codec format. Must be the one used in
+     * {@link MediaFormat#KEY_MIME}.
+     * @return true if application supports the video codec format, false otherwise.
+     */
+    public boolean isVideoMimeTypeSupported(
+            @NonNull String videoMime) {
+        if (mSupportedVideoMimeTypes.contains(videoMime.toLowerCase())) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Query if a HDR type is supported by the application.
+     * <p>
+     * If the application has not specified supporting the format or not, this will return false.
+     * Use {@link #isFormatSpecified(String)} to query if a format is specified or not.
+     *
+     * @param hdrType The type of the HDR format.
+     * @return true if application supports the HDR format, false otherwise.
+     */
+    public boolean isHdrTypeSupported(
+            @NonNull @MediaFeature.MediaHdrType String hdrType) {
+        if (mSupportedHdrTypes.contains(hdrType)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Query if a format is specified by the application.
+     * <p>
+     * The format could be either the video format or the hdr format.
+     *
+     * @param format The name of the format.
+     * @return true if application specifies the format, false otherwise.
+     */
+    public boolean isFormatSpecified(@NonNull String format) {
+        if (mSupportedVideoMimeTypes.contains(format) || mUnsupportedVideoMimeTypes.contains(format)
+                || mSupportedHdrTypes.contains(format) || mUnsupportedHdrTypes.contains(format)) {
+            return true;
+
+        }
+        return false;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        // Write out the supported video mime types.
+        dest.writeInt(mSupportedVideoMimeTypes.size());
+        for (String cap : mSupportedVideoMimeTypes) {
+            dest.writeString(cap);
+        }
+        // Write out the unsupported video mime types.
+        dest.writeInt(mUnsupportedVideoMimeTypes.size());
+        for (String cap : mUnsupportedVideoMimeTypes) {
+            dest.writeString(cap);
+        }
+        // Write out the supported hdr types.
+        dest.writeInt(mSupportedHdrTypes.size());
+        for (String cap : mSupportedHdrTypes) {
+            dest.writeString(cap);
+        }
+        // Write out the unsupported hdr types.
+        dest.writeInt(mUnsupportedHdrTypes.size());
+        for (String cap : mUnsupportedHdrTypes) {
+            dest.writeString(cap);
+        }
+        // Write out the supported slow motion.
+        dest.writeBoolean(mIsSlowMotionSupported);
+    }
+
+    @Override
+    public String toString() {
+        String caps = new String(
+                "Supported Video MimeTypes: " + mSupportedVideoMimeTypes.toString());
+        caps += "Unsupported Video MimeTypes: " + mUnsupportedVideoMimeTypes.toString();
+        caps += "Supported HDR types: " + mSupportedHdrTypes.toString();
+        caps += "Unsupported HDR types: " + mUnsupportedHdrTypes.toString();
+        caps += "Supported slow motion: " + mIsSlowMotionSupported;
+        return caps;
+    }
+
+    @NonNull
+    public static final Creator<ApplicationMediaCapabilities> CREATOR =
+            new Creator<ApplicationMediaCapabilities>() {
+                public ApplicationMediaCapabilities createFromParcel(Parcel in) {
+                    ApplicationMediaCapabilities.Builder builder =
+                            new ApplicationMediaCapabilities.Builder();
+
+                    // Parse supported video codec mime types.
+                    int count = in.readInt();
+                    for (int readCount = 0; readCount < count; ++readCount) {
+                        builder.addSupportedVideoMimeType(in.readString());
+                    }
+
+                    // Parse unsupported video codec mime types.
+                    count = in.readInt();
+                    for (int readCount = 0; readCount < count; ++readCount) {
+                        builder.addUnsupportedVideoMimeType(in.readString());
+                    }
+
+                    // Parse supported hdr types.
+                    count = in.readInt();
+                    for (int readCount = 0; readCount < count; ++readCount) {
+                        builder.addSupportedHdrType(in.readString());
+                    }
+
+                    // Parse unsupported hdr types.
+                    count = in.readInt();
+                    for (int readCount = 0; readCount < count; ++readCount) {
+                        builder.addUnsupportedHdrType(in.readString());
+                    }
+
+                    boolean supported = in.readBoolean();
+                    builder.setSlowMotionSupported(supported);
+
+                    return builder.build();
+                }
+
+                public ApplicationMediaCapabilities[] newArray(int size) {
+                    return new ApplicationMediaCapabilities[size];
+                }
+            };
+
+    /**
+     * Query the video codec mime types supported by the application.
+     * @return List of supported video codec mime types. The list will be empty if there are none.
+     */
+    @NonNull
+    public List<String> getSupportedVideoMimeTypes() {
+        return new ArrayList<>(mSupportedVideoMimeTypes);
+    }
+
+    /**
+     * Query the video codec mime types that are not supported by the application.
+     * @return List of unsupported video codec mime types. The list will be empty if there are none.
+     */
+    @NonNull
+    public List<String> getUnsupportedVideoMimeTypes() {
+        return new ArrayList<>(mUnsupportedVideoMimeTypes);
+    }
+
+    /**
+     * Query all hdr types that are supported by the application.
+     * @return List of supported hdr types. The list will be empty if there are none.
+     */
+    @NonNull
+    public List<String> getSupportedHdrTypes() {
+        return new ArrayList<>(mSupportedHdrTypes);
+    }
+
+    /**
+     * Query all hdr types that are not supported by the application.
+     * @return List of unsupported hdr types. The list will be empty if there are none.
+     */
+    @NonNull
+    public List<String> getUnsupportedHdrTypes()  {
+        return new ArrayList<>(mUnsupportedHdrTypes);
+    }
+
+    /**
+     * Whether handling of slow-motion video is supported
+     * @hide
+     */
+    public boolean isSlowMotionSupported() {
+        return mIsSlowMotionSupported;
+    }
+
+    /**
+     * Creates {@link ApplicationMediaCapabilities} from an xml.
+     *
+     * The xml's syntax is the same as the media_capabilities.xml used by the AndroidManifest.xml.
+     * <p> Here is an example:
+     *
+     * <pre>
+     * {@code
+     * <media-capabilities xmlns:android="http://schemas.android.com/apk/res/android">
+     *     <format android:name="HEVC" supported="true"/>
+     *     <format android:name="HDR10" supported="false"/>
+     *     <format android:name="HDR10Plus" supported="false"/>
+     * </media-capabilities>
+     * }
+     * </pre>
+     * <p>
+     *
+     * @param xmlParser The underlying {@link XmlPullParser} that will read the xml.
+     * @return An ApplicationMediaCapabilities object.
+     * @throws UnsupportedOperationException if the capabilities in xml config are invalid or
+     * incompatible.
+     */
+    // TODO: Add developer.android.com link for the format of the xml.
+    @NonNull
+    public static ApplicationMediaCapabilities createFromXml(@NonNull XmlPullParser xmlParser) {
+        ApplicationMediaCapabilities.Builder builder = new ApplicationMediaCapabilities.Builder();
+        builder.parseXml(xmlParser);
+        return builder.build();
+    }
+
+    /**
+     * Builder class for {@link ApplicationMediaCapabilities} objects.
+     * Use this class to configure and create an ApplicationMediaCapabilities instance. Builder
+     * could be created from an existing ApplicationMediaCapabilities object, from a xml file or
+     * MediaCodecList.
+     * //TODO(hkuang): Add xml parsing support to the builder.
+     */
+    public final static class Builder {
+        /** List of supported video codec mime types. */
+        private Set<String> mSupportedVideoMimeTypes = new HashSet<>();
+
+        /** List of supported hdr types. */
+        private Set<String> mSupportedHdrTypes = new HashSet<>();
+
+        /** List of unsupported video codec mime types. */
+        private Set<String> mUnsupportedVideoMimeTypes = new HashSet<>();
+
+        /** List of unsupported hdr types. */
+        private Set<String> mUnsupportedHdrTypes = new HashSet<>();
+
+        private boolean mIsSlowMotionSupported = false;
+
+        /* Map to save the format read from the xml. */
+        private Map<String, Boolean> mFormatSupportedMap =  new HashMap<String, Boolean>();
+
+        /**
+         * Constructs a new Builder with all the supports default to false.
+         */
+        public Builder() {
+        }
+
+        private void parseXml(@NonNull XmlPullParser xmlParser)
+                throws UnsupportedOperationException {
+            if (xmlParser == null) {
+                throw new IllegalArgumentException("XmlParser must not be null");
+            }
+
+            try {
+                while (xmlParser.next() != XmlPullParser.START_TAG) {
+                    continue;
+                }
+
+                // Validates the tag is "media-capabilities".
+                if (!xmlParser.getName().equals("media-capabilities")) {
+                    throw new UnsupportedOperationException("Invalid tag");
+                }
+
+                xmlParser.next();
+                while (xmlParser.getEventType() != XmlPullParser.END_TAG) {
+                    while (xmlParser.getEventType() != XmlPullParser.START_TAG) {
+                        if (xmlParser.getEventType() == XmlPullParser.END_DOCUMENT) {
+                            return;
+                        }
+                        xmlParser.next();
+                    }
+
+                    // Validates the tag is "format".
+                    if (xmlParser.getName().equals("format")) {
+                        parseFormatTag(xmlParser);
+                    } else {
+                        throw new UnsupportedOperationException("Invalid tag");
+                    }
+                    while (xmlParser.getEventType() != XmlPullParser.END_TAG) {
+                        xmlParser.next();
+                    }
+                    xmlParser.next();
+                }
+            } catch (XmlPullParserException xppe) {
+                throw new UnsupportedOperationException("Ill-formatted xml file");
+            } catch (java.io.IOException ioe) {
+                throw new UnsupportedOperationException("Unable to read xml file");
+            }
+        }
+
+        private void parseFormatTag(XmlPullParser xmlParser) {
+            String name = null;
+            String supported = null;
+            for (int i = 0; i < xmlParser.getAttributeCount(); i++) {
+                String attrName = xmlParser.getAttributeName(i);
+                if (attrName.equals("name")) {
+                    name = xmlParser.getAttributeValue(i);
+                } else if (attrName.equals("supported")) {
+                    supported = xmlParser.getAttributeValue(i);
+                } else {
+                    throw new UnsupportedOperationException("Invalid attribute name " + attrName);
+                }
+            }
+
+            if (name != null && supported != null) {
+                if (!supported.equals("true") && !supported.equals("false")) {
+                    throw new UnsupportedOperationException(
+                            ("Supported value must be either true or false"));
+                }
+                boolean isSupported = Boolean.parseBoolean(supported);
+
+                // Check if the format is already found before.
+                if (mFormatSupportedMap.get(name) != null && mFormatSupportedMap.get(name)
+                        != isSupported) {
+                    throw new UnsupportedOperationException(
+                            "Format: " + name + " has conflict supported value");
+                }
+
+                switch (name) {
+                    case "HEVC":
+                        if (isSupported) {
+                            mSupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_HEVC);
+                        } else {
+                            mUnsupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_HEVC);
+                        }
+                        break;
+                    case "VP9":
+                        if (isSupported) {
+                            mSupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_VP9);
+                        } else {
+                            mUnsupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_VP9);
+                        }
+                        break;
+                    case "AV1":
+                        if (isSupported) {
+                            mSupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_AV1);
+                        } else {
+                            mUnsupportedVideoMimeTypes.add(MediaFormat.MIMETYPE_VIDEO_AV1);
+                        }
+                        break;
+                    case "HDR10":
+                        if (isSupported) {
+                            mSupportedHdrTypes.add(MediaFeature.HdrType.HDR10);
+                        } else {
+                            mUnsupportedHdrTypes.add(MediaFeature.HdrType.HDR10);
+                        }
+                        break;
+                    case "HDR10Plus":
+                        if (isSupported) {
+                            mSupportedHdrTypes.add(MediaFeature.HdrType.HDR10_PLUS);
+                        } else {
+                            mUnsupportedHdrTypes.add(MediaFeature.HdrType.HDR10_PLUS);
+                        }
+                        break;
+                    case "Dolby-Vision":
+                        if (isSupported) {
+                            mSupportedHdrTypes.add(MediaFeature.HdrType.DOLBY_VISION);
+                        } else {
+                            mUnsupportedHdrTypes.add(MediaFeature.HdrType.DOLBY_VISION);
+                        }
+                        break;
+                    case "HLG":
+                        if (isSupported) {
+                            mSupportedHdrTypes.add(MediaFeature.HdrType.HLG);
+                        } else {
+                            mUnsupportedHdrTypes.add(MediaFeature.HdrType.HLG);
+                        }
+                        break;
+                    case "SlowMotion":
+                        mIsSlowMotionSupported = isSupported;
+                        break;
+                    default:
+                        Log.w(TAG, "Invalid format name " + name);
+                }
+                // Save the name and isSupported into the map for validate later.
+                mFormatSupportedMap.put(name, isSupported);
+            } else {
+                throw new UnsupportedOperationException(
+                        "Format name and supported must both be specified");
+            }
+        }
+
+        /**
+         * Builds a {@link ApplicationMediaCapabilities} object.
+         *
+         * @return a new {@link ApplicationMediaCapabilities} instance successfully initialized
+         * with all the parameters set on this <code>Builder</code>.
+         * @throws UnsupportedOperationException if the parameters set on the
+         *                                       <code>Builder</code> were incompatible, or if they
+         *                                       are not supported by the
+         *                                       device.
+         */
+        @NonNull
+        public ApplicationMediaCapabilities build() {
+            Log.d(TAG,
+                    "Building ApplicationMediaCapabilities with: (Supported HDR: "
+                            + mSupportedHdrTypes.toString() + " Unsupported HDR: "
+                            + mUnsupportedHdrTypes.toString() + ") (Supported Codec: "
+                            + " " + mSupportedVideoMimeTypes.toString() + " Unsupported Codec:"
+                            + mUnsupportedVideoMimeTypes.toString() + ") "
+                            + mIsSlowMotionSupported);
+
+            // If hdr is supported, application must also support hevc.
+            if (!mSupportedHdrTypes.isEmpty() && !mSupportedVideoMimeTypes.contains(
+                    MediaFormat.MIMETYPE_VIDEO_HEVC)) {
+                throw new UnsupportedOperationException("Only support HEVC mime type");
+            }
+            return new ApplicationMediaCapabilities(this);
+        }
+
+        /**
+         * Adds a supported video codec mime type.
+         *
+         * @param codecMime Supported codec mime types. Must be one of the mime type defined
+         *                  in {@link MediaFormat}.
+         * @throws IllegalArgumentException if mime type is not valid.
+         */
+        @NonNull
+        public Builder addSupportedVideoMimeType(
+                @NonNull String codecMime) {
+            mSupportedVideoMimeTypes.add(codecMime);
+            return this;
+        }
+
+        private List<String> getSupportedVideoMimeTypes() {
+            return new ArrayList<>(mSupportedVideoMimeTypes);
+        }
+
+        private boolean isValidVideoCodecMimeType(@NonNull String codecMime) {
+            if (!codecMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)
+                    && !codecMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)
+                    && !codecMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AV1)) {
+                return false;
+            }
+            return true;
+        }
+
+        /**
+         * Adds an unsupported video codec mime type.
+         *
+         * @param codecMime Unsupported codec mime type. Must be one of the mime type defined
+         *                  in {@link MediaFormat}.
+         * @throws IllegalArgumentException if mime type is not valid.
+         */
+        @NonNull
+        public Builder addUnsupportedVideoMimeType(
+                @NonNull String codecMime) {
+            if (!isValidVideoCodecMimeType(codecMime)) {
+                throw new IllegalArgumentException("Invalid codec mime type: " + codecMime);
+            }
+            mUnsupportedVideoMimeTypes.add(codecMime);
+            return this;
+        }
+
+        private List<String> getUnsupportedVideoMimeTypes() {
+            return new ArrayList<>(mUnsupportedVideoMimeTypes);
+        }
+
+        /**
+         * Adds a supported hdr type.
+         *
+         * @param hdrType Supported hdr type. Must be one of the String defined in
+         *                {@link MediaFeature.HdrType}.
+         * @throws IllegalArgumentException if hdrType is not valid.
+         */
+        @NonNull
+        public Builder addSupportedHdrType(
+                @NonNull @MediaFeature.MediaHdrType String hdrType) {
+            if (!isValidVideoCodecHdrType(hdrType)) {
+                throw new IllegalArgumentException("Invalid hdr type: " + hdrType);
+            }
+            mSupportedHdrTypes.add(hdrType);
+            return this;
+        }
+
+        private List<String> getSupportedHdrTypes() {
+            return new ArrayList<>(mSupportedHdrTypes);
+        }
+
+        private boolean isValidVideoCodecHdrType(@NonNull String hdrType) {
+            if (!hdrType.equals(MediaFeature.HdrType.DOLBY_VISION)
+                    && !hdrType.equals(MediaFeature.HdrType.HDR10)
+                    && !hdrType.equals(MediaFeature.HdrType.HDR10_PLUS)
+                    && !hdrType.equals(MediaFeature.HdrType.HLG)) {
+                return false;
+            }
+            return true;
+        }
+
+        /**
+         * Adds an unsupported hdr type.
+         *
+         * @param hdrType Unsupported hdr type. Must be one of the String defined in
+         *                {@link MediaFeature.HdrType}.
+         * @throws IllegalArgumentException if hdrType is not valid.
+         */
+        @NonNull
+        public Builder addUnsupportedHdrType(
+                @NonNull @MediaFeature.MediaHdrType String hdrType) {
+            if (!isValidVideoCodecHdrType(hdrType)) {
+                throw new IllegalArgumentException("Invalid hdr type: " + hdrType);
+            }
+            mUnsupportedHdrTypes.add(hdrType);
+            return this;
+        }
+
+        private List<String> getUnsupportedHdrTypes() {
+            return new ArrayList<>(mUnsupportedHdrTypes);
+        }
+
+        /**
+         * Sets whether slow-motion video is supported.
+         * If an application indicates support for slow-motion, it is application's responsibility
+         * to parse the slow-motion videos using their own parser or using support library.
+         * @see android.media.MediaFormat#KEY_SLOW_MOTION_MARKERS
+         * @hide
+         */
+        @NonNull
+        public Builder setSlowMotionSupported(boolean slowMotionSupported) {
+            mIsSlowMotionSupported = slowMotionSupported;
+            return this;
+        }
+    }
+}
diff --git a/android/media/AsyncPlayer.java b/android/media/AsyncPlayer.java
new file mode 100644
index 0000000..c3dc118
--- /dev/null
+++ b/android/media/AsyncPlayer.java
@@ -0,0 +1,275 @@
+/*
+ * Copyright (C) 2008 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.annotation.NonNull;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.net.Uri;
+import android.os.PowerManager;
+import android.os.SystemClock;
+import android.util.Log;
+
+import java.util.LinkedList;
+
+/**
+ * Plays a series of audio URIs, but does all the hard work on another thread
+ * so that any slowness with preparing or loading doesn't block the calling thread.
+ */
+public class AsyncPlayer {
+    private static final int PLAY = 1;
+    private static final int STOP = 2;
+    private static final boolean mDebug = false;
+
+    private static final class Command {
+        int code;
+        Context context;
+        Uri uri;
+        boolean looping;
+        AudioAttributes attributes;
+        long requestTime;
+
+        public String toString() {
+            return "{ code=" + code + " looping=" + looping + " attr=" + attributes
+                    + " uri=" + uri + " }";
+        }
+    }
+
+    private final LinkedList<Command> mCmdQueue = new LinkedList();
+
+    private void startSound(Command cmd) {
+        // Preparing can be slow, so if there is something else
+        // is playing, let it continue until we're done, so there
+        // is less of a glitch.
+        try {
+            if (mDebug) Log.d(mTag, "Starting playback");
+            MediaPlayer player = new MediaPlayer();
+            player.setAudioAttributes(cmd.attributes);
+            player.setDataSource(cmd.context, cmd.uri);
+            player.setLooping(cmd.looping);
+            player.prepare();
+            player.start();
+            if (mPlayer != null) {
+                mPlayer.release();
+            }
+            mPlayer = player;
+            long delay = SystemClock.uptimeMillis() - cmd.requestTime;
+            if (delay > 1000) {
+                Log.w(mTag, "Notification sound delayed by " + delay + "msecs");
+            }
+        }
+        catch (Exception e) {
+            Log.w(mTag, "error loading sound for " + cmd.uri, e);
+        }
+    }
+
+    private final class Thread extends java.lang.Thread {
+        Thread() {
+            super("AsyncPlayer-" + mTag);
+        }
+
+        public void run() {
+            while (true) {
+                Command cmd = null;
+
+                synchronized (mCmdQueue) {
+                    if (mDebug) Log.d(mTag, "RemoveFirst");
+                    cmd = mCmdQueue.removeFirst();
+                }
+
+                switch (cmd.code) {
+                case PLAY:
+                    if (mDebug) Log.d(mTag, "PLAY");
+                    startSound(cmd);
+                    break;
+                case STOP:
+                    if (mDebug) Log.d(mTag, "STOP");
+                    if (mPlayer != null) {
+                        long delay = SystemClock.uptimeMillis() - cmd.requestTime;
+                        if (delay > 1000) {
+                            Log.w(mTag, "Notification stop delayed by " + delay + "msecs");
+                        }
+                        mPlayer.stop();
+                        mPlayer.release();
+                        mPlayer = null;
+                    } else {
+                        Log.w(mTag, "STOP command without a player");
+                    }
+                    break;
+                }
+
+                synchronized (mCmdQueue) {
+                    if (mCmdQueue.size() == 0) {
+                        // nothing left to do, quit
+                        // doing this check after we're done prevents the case where they
+                        // added it during the operation from spawning two threads and
+                        // trying to do them in parallel.
+                        mThread = null;
+                        releaseWakeLock();
+                        return;
+                    }
+                }
+            }
+        }
+    }
+
+    private String mTag;
+    private Thread mThread;
+    private MediaPlayer mPlayer;
+    private PowerManager.WakeLock mWakeLock;
+
+    // The current state according to the caller.  Reality lags behind
+    // because of the asynchronous nature of this class.
+    private int mState = STOP;
+
+    /**
+     * Construct an AsyncPlayer object.
+     *
+     * @param tag a string to use for debugging
+     */
+    public AsyncPlayer(String tag) {
+        if (tag != null) {
+            mTag = tag;
+        } else {
+            mTag = "AsyncPlayer";
+        }
+    }
+
+    /**
+     * Start playing the sound.  It will actually start playing at some
+     * point in the future.  There are no guarantees about latency here.
+     * Calling this before another audio file is done playing will stop
+     * that one and start the new one.
+     *
+     * @param context Your application's context.
+     * @param uri The URI to play.  (see {@link MediaPlayer#setDataSource(Context, Uri)})
+     * @param looping Whether the audio should loop forever.  
+     *          (see {@link MediaPlayer#setLooping(boolean)})
+     * @param stream the AudioStream to use.
+     *          (see {@link MediaPlayer#setAudioStreamType(int)})
+     * @deprecated use {@link #play(Context, Uri, boolean, AudioAttributes)} instead
+     */
+    public void play(Context context, Uri uri, boolean looping, int stream) {
+        PlayerBase.deprecateStreamTypeForPlayback(stream, "AsyncPlayer", "play()");
+        if (context == null || uri == null) {
+            return;
+        }
+        try {
+            play(context, uri, looping,
+                    new AudioAttributes.Builder().setInternalLegacyStreamType(stream).build());
+        } catch (IllegalArgumentException e) {
+            Log.e(mTag, "Call to deprecated AsyncPlayer.play() method caused:", e);
+        }
+    }
+
+    /**
+     * Start playing the sound.  It will actually start playing at some
+     * point in the future.  There are no guarantees about latency here.
+     * Calling this before another audio file is done playing will stop
+     * that one and start the new one.
+     *
+     * @param context the non-null application's context.
+     * @param uri the non-null URI to play.  (see {@link MediaPlayer#setDataSource(Context, Uri)})
+     * @param looping whether the audio should loop forever.
+     *          (see {@link MediaPlayer#setLooping(boolean)})
+     * @param attributes the non-null {@link AudioAttributes} to use.
+     *          (see {@link MediaPlayer#setAudioAttributes(AudioAttributes)})
+     * @throws IllegalArgumentException
+     */
+    public void play(@NonNull Context context, @NonNull Uri uri, boolean looping,
+            @NonNull AudioAttributes attributes) throws IllegalArgumentException {
+        if (context == null || uri == null || attributes == null) {
+            throw new IllegalArgumentException("Illegal null AsyncPlayer.play() argument");
+        }
+        Command cmd = new Command();
+        cmd.requestTime = SystemClock.uptimeMillis();
+        cmd.code = PLAY;
+        cmd.context = context;
+        cmd.uri = uri;
+        cmd.looping = looping;
+        cmd.attributes = attributes;
+        synchronized (mCmdQueue) {
+            enqueueLocked(cmd);
+            mState = PLAY;
+        }
+    }
+
+    /**
+     * Stop a previously played sound.  It can't be played again or unpaused
+     * at this point.  Calling this multiple times has no ill effects.
+     */
+    public void stop() {
+        synchronized (mCmdQueue) {
+            // This check allows stop to be called multiple times without starting
+            // a thread that ends up doing nothing.
+            if (mState != STOP) {
+                Command cmd = new Command();
+                cmd.requestTime = SystemClock.uptimeMillis();
+                cmd.code = STOP;
+                enqueueLocked(cmd);
+                mState = STOP;
+            }
+        }
+    }
+
+    private void enqueueLocked(Command cmd) {
+        mCmdQueue.add(cmd);
+        if (mThread == null) {
+            acquireWakeLock();
+            mThread = new Thread();
+            mThread.start();
+        }
+    }
+
+    /**
+     * We want to hold a wake lock while we do the prepare and play.  The stop probably is
+     * optional, but it won't hurt to have it too.  The problem is that if you start a sound
+     * while you're holding a wake lock (e.g. an alarm starting a notification), you want the
+     * sound to play, but if the CPU turns off before mThread gets to work, it won't.  The
+     * simplest way to deal with this is to make it so there is a wake lock held while the
+     * thread is starting or running.  You're going to need the WAKE_LOCK permission if you're
+     * going to call this.
+     *
+     * This must be called before the first time play is called.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public void setUsesWakeLock(Context context) {
+        if (mWakeLock != null || mThread != null) {
+            // if either of these has happened, we've already played something.
+            // and our releases will be out of sync.
+            throw new RuntimeException("assertion failed mWakeLock=" + mWakeLock
+                    + " mThread=" + mThread);
+        }
+        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, mTag);
+    }
+
+    private void acquireWakeLock() {
+        if (mWakeLock != null) {
+            mWakeLock.acquire();
+        }
+    }
+
+    private void releaseWakeLock() {
+        if (mWakeLock != null) {
+            mWakeLock.release();
+        }
+    }
+}
+
diff --git a/android/media/AudioAttributes.java b/android/media/AudioAttributes.java
new file mode 100644
index 0000000..a031b4c
--- /dev/null
+++ b/android/media/AudioAttributes.java
@@ -0,0 +1,1656 @@
+/*
+ * Copyright (C) 2014 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.audio.policy.configuration.V7_0.AudioUsage;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.media.audiopolicy.AudioProductStrategy;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.SparseIntArray;
+import android.util.proto.ProtoOutputStream;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * A class to encapsulate a collection of attributes describing information about an audio
+ * stream.
+ * <p><code>AudioAttributes</code> supersede the notion of stream types (see for instance
+ * {@link AudioManager#STREAM_MUSIC} or {@link AudioManager#STREAM_ALARM}) for defining the
+ * behavior of audio playback. Attributes allow an application to specify more information than is
+ * conveyed in a stream type by allowing the application to define:
+ * <ul>
+ * <li>usage: "why" you are playing a sound, what is this sound used for. This is achieved with
+ *     the "usage" information. Examples of usage are {@link #USAGE_MEDIA} and {@link #USAGE_ALARM}.
+ *     These two examples are the closest to stream types, but more detailed use cases are
+ *     available. Usage information is more expressive than a stream type, and allows certain
+ *     platforms or routing policies to use this information for more refined volume or routing
+ *     decisions. Usage is the most important information to supply in <code>AudioAttributes</code>
+ *     and it is recommended to build any instance with this information supplied, see
+ *     {@link AudioAttributes.Builder} for exceptions.</li>
+ * <li>content type: "what" you are playing. The content type expresses the general category of
+ *     the content. This information is optional. But in case it is known (for instance
+ *     {@link #CONTENT_TYPE_MOVIE} for a movie streaming service or {@link #CONTENT_TYPE_MUSIC} for
+ *     a music playback application) this information might be used by the audio framework to
+ *     selectively configure some audio post-processing blocks.</li>
+ * <li>flags: "how" is playback to be affected, see the flag definitions for the specific playback
+ *     behaviors they control. </li>
+ * </ul>
+ * <p><code>AudioAttributes</code> are used for example in one of the {@link AudioTrack}
+ * constructors (see {@link AudioTrack#AudioTrack(AudioAttributes, AudioFormat, int, int, int)}),
+ * to configure a {@link MediaPlayer}
+ * (see {@link MediaPlayer#setAudioAttributes(AudioAttributes)} or a
+ * {@link android.app.Notification} (see {@link android.app.Notification#audioAttributes}). An
+ * <code>AudioAttributes</code> instance is built through its builder,
+ * {@link AudioAttributes.Builder}.
+ */
+public final class AudioAttributes implements Parcelable {
+    private final static String TAG = "AudioAttributes";
+
+    /**
+     * Content type value to use when the content type is unknown, or other than the ones defined.
+     */
+    public final static int CONTENT_TYPE_UNKNOWN = 0;
+    /**
+     * Content type value to use when the content type is speech.
+     */
+    public final static int CONTENT_TYPE_SPEECH = 1;
+    /**
+     * Content type value to use when the content type is music.
+     */
+    public final static int CONTENT_TYPE_MUSIC = 2;
+    /**
+     * Content type value to use when the content type is a soundtrack, typically accompanying
+     * a movie or TV program.
+     */
+    public final static int CONTENT_TYPE_MOVIE = 3;
+    /**
+     * Content type value to use when the content type is a sound used to accompany a user
+     * action, such as a beep or sound effect expressing a key click, or event, such as the
+     * type of a sound for a bonus being received in a game. These sounds are mostly synthesized
+     * or short Foley sounds.
+     */
+    public final static int CONTENT_TYPE_SONIFICATION = 4;
+
+    /**
+     * Invalid value, only ever used for an uninitialized usage value
+     */
+    private static final int USAGE_INVALID = -1;
+    /**
+     * Usage value to use when the usage is unknown.
+     */
+    public final static int USAGE_UNKNOWN = 0;
+    /**
+     * Usage value to use when the usage is media, such as music, or movie
+     * soundtracks.
+     */
+    public final static int USAGE_MEDIA = 1;
+    /**
+     * Usage value to use when the usage is voice communications, such as telephony
+     * or VoIP.
+     */
+    public final static int USAGE_VOICE_COMMUNICATION = 2;
+    /**
+     * Usage value to use when the usage is in-call signalling, such as with
+     * a "busy" beep, or DTMF tones.
+     */
+    public final static int USAGE_VOICE_COMMUNICATION_SIGNALLING = 3;
+    /**
+     * Usage value to use when the usage is an alarm (e.g. wake-up alarm).
+     */
+    public final static int USAGE_ALARM = 4;
+    /**
+     * Usage value to use when the usage is notification. See other
+     * notification usages for more specialized uses.
+     */
+    public final static int USAGE_NOTIFICATION = 5;
+    /**
+     * Usage value to use when the usage is telephony ringtone.
+     */
+    public final static int USAGE_NOTIFICATION_RINGTONE = 6;
+    /**
+     * Usage value to use when the usage is a request to enter/end a
+     * communication, such as a VoIP communication or video-conference.
+     */
+    public final static int USAGE_NOTIFICATION_COMMUNICATION_REQUEST = 7;
+    /**
+     * Usage value to use when the usage is notification for an "instant"
+     * communication such as a chat, or SMS.
+     */
+    public final static int USAGE_NOTIFICATION_COMMUNICATION_INSTANT = 8;
+    /**
+     * Usage value to use when the usage is notification for a
+     * non-immediate type of communication such as e-mail.
+     */
+    public final static int USAGE_NOTIFICATION_COMMUNICATION_DELAYED = 9;
+    /**
+     * Usage value to use when the usage is to attract the user's attention,
+     * such as a reminder or low battery warning.
+     */
+    public final static int USAGE_NOTIFICATION_EVENT = 10;
+    /**
+     * Usage value to use when the usage is for accessibility, such as with
+     * a screen reader.
+     */
+    public final static int USAGE_ASSISTANCE_ACCESSIBILITY = 11;
+    /**
+     * Usage value to use when the usage is driving or navigation directions.
+     */
+    public final static int USAGE_ASSISTANCE_NAVIGATION_GUIDANCE = 12;
+    /**
+     * Usage value to use when the usage is sonification, such as  with user
+     * interface sounds.
+     */
+    public final static int USAGE_ASSISTANCE_SONIFICATION = 13;
+    /**
+     * Usage value to use when the usage is for game audio.
+     */
+    public final static int USAGE_GAME = 14;
+    /**
+     * @hide
+     * Usage value to use when feeding audio to the platform and replacing "traditional" audio
+     * source, such as audio capture devices.
+     */
+    public final static int USAGE_VIRTUAL_SOURCE = 15;
+    /**
+     * Usage value to use for audio responses to user queries, audio instructions or help
+     * utterances.
+     */
+    public final static int USAGE_ASSISTANT = 16;
+    /**
+     * @hide
+     * Usage value to use for assistant voice interaction with remote caller on Cell and VoIP calls.
+     */
+    @SystemApi
+    @RequiresPermission(allOf = {
+            android.Manifest.permission.MODIFY_PHONE_STATE,
+            android.Manifest.permission.MODIFY_AUDIO_ROUTING
+    })
+    public static final int USAGE_CALL_ASSISTANT = 17;
+
+    private static final int SYSTEM_USAGE_OFFSET = 1000;
+
+    /**
+     * @hide
+     * Usage value to use when the usage is an emergency.
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public static final int USAGE_EMERGENCY = SYSTEM_USAGE_OFFSET;
+    /**
+     * @hide
+     * Usage value to use when the usage is a safety sound.
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public static final int USAGE_SAFETY = SYSTEM_USAGE_OFFSET + 1;
+    /**
+     * @hide
+     * Usage value to use when the usage is a vehicle status.
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public static final int USAGE_VEHICLE_STATUS = SYSTEM_USAGE_OFFSET + 2;
+    /**
+     * @hide
+     * Usage value to use when the usage is an announcement.
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public static final int USAGE_ANNOUNCEMENT = SYSTEM_USAGE_OFFSET + 3;
+
+    /**
+     * IMPORTANT: when adding new usage types, add them to SDK_USAGES and update SUPPRESSIBLE_USAGES
+     *            if applicable, as well as audioattributes.proto.
+     *            Also consider adding them to <aaudio/AAudio.h> for the NDK.
+     *            Also consider adding them to UsageTypeConverter for service dump and etc.
+     */
+
+    /**
+     * @hide
+     * Denotes a usage for notifications that do not expect immediate intervention from the user,
+     * will be muted when the Zen mode disables notifications
+     * @see #SUPPRESSIBLE_USAGES
+     */
+    public final static int SUPPRESSIBLE_NOTIFICATION = 1;
+    /**
+     * @hide
+     * Denotes a usage for notifications that do expect immediate intervention from the user,
+     * will be muted when the Zen mode disables calls
+     * @see #SUPPRESSIBLE_USAGES
+     */
+    public final static int SUPPRESSIBLE_CALL = 2;
+    /**
+     * @hide
+     * Denotes a usage that is never going to be muted, even in Total Silence.
+     * @see #SUPPRESSIBLE_USAGES
+     */
+    public final static int SUPPRESSIBLE_NEVER = 3;
+    /**
+     * @hide
+     * Denotes a usage for alarms,
+     * will be muted when the Zen mode priority doesn't allow alarms or in Alarms Only Mode
+     * @see #SUPPRESSIBLE_USAGES
+     */
+    public final static int SUPPRESSIBLE_ALARM = 4;
+    /**
+     * @hide
+     * Denotes a usage for media, game, assistant, and navigation
+     * will be muted when the Zen priority mode doesn't allow media
+     * @see #SUPPRESSIBLE_USAGES
+     */
+    public final static int SUPPRESSIBLE_MEDIA = 5;
+    /**
+     * @hide
+     * Denotes a usage for sounds not caught in SUPPRESSIBLE_NOTIFICATION,
+     * SUPPRESSIBLE_CALL,SUPPRESSIBLE_NEVER, SUPPRESSIBLE_ALARM or SUPPRESSIBLE_MEDIA.
+     * This includes sonification sounds.
+     * These will be muted when the Zen priority mode doesn't allow system sounds
+     * @see #SUPPRESSIBLE_USAGES
+     */
+    public final static int SUPPRESSIBLE_SYSTEM = 6;
+
+    /**
+     * @hide
+     * Array of all usage types for calls and notifications to assign the suppression behavior,
+     * used by the Zen mode restrictions.
+     * @see com.android.server.notification.ZenModeHelper
+     */
+    public static final SparseIntArray SUPPRESSIBLE_USAGES;
+
+    static {
+        SUPPRESSIBLE_USAGES = new SparseIntArray();
+        SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION,                      SUPPRESSIBLE_NOTIFICATION);
+        SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_RINGTONE,             SUPPRESSIBLE_CALL);
+        SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_COMMUNICATION_REQUEST,SUPPRESSIBLE_CALL);
+        SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_COMMUNICATION_INSTANT,SUPPRESSIBLE_NOTIFICATION);
+        SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_COMMUNICATION_DELAYED,SUPPRESSIBLE_NOTIFICATION);
+        SUPPRESSIBLE_USAGES.put(USAGE_NOTIFICATION_EVENT,                SUPPRESSIBLE_NOTIFICATION);
+        SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_ACCESSIBILITY,          SUPPRESSIBLE_NEVER);
+        SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION,               SUPPRESSIBLE_NEVER);
+        SUPPRESSIBLE_USAGES.put(USAGE_VOICE_COMMUNICATION_SIGNALLING,    SUPPRESSIBLE_NEVER);
+        SUPPRESSIBLE_USAGES.put(USAGE_ALARM,                             SUPPRESSIBLE_ALARM);
+        SUPPRESSIBLE_USAGES.put(USAGE_MEDIA,                             SUPPRESSIBLE_MEDIA);
+        SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,    SUPPRESSIBLE_MEDIA);
+        SUPPRESSIBLE_USAGES.put(USAGE_GAME,                              SUPPRESSIBLE_MEDIA);
+        SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANT,                         SUPPRESSIBLE_MEDIA);
+        SUPPRESSIBLE_USAGES.put(USAGE_CALL_ASSISTANT,                    SUPPRESSIBLE_NEVER);
+        /** default volume assignment is STREAM_MUSIC, handle unknown usage as media */
+        SUPPRESSIBLE_USAGES.put(USAGE_UNKNOWN,                           SUPPRESSIBLE_MEDIA);
+        SUPPRESSIBLE_USAGES.put(USAGE_ASSISTANCE_SONIFICATION,           SUPPRESSIBLE_SYSTEM);
+    }
+
+    /**
+     * @hide
+     * Array of all usage types exposed in the SDK that applications can use.
+     */
+    public final static int[] SDK_USAGES = {
+            USAGE_UNKNOWN,
+            USAGE_MEDIA,
+            USAGE_VOICE_COMMUNICATION,
+            USAGE_VOICE_COMMUNICATION_SIGNALLING,
+            USAGE_ALARM,
+            USAGE_NOTIFICATION,
+            USAGE_NOTIFICATION_RINGTONE,
+            USAGE_NOTIFICATION_COMMUNICATION_REQUEST,
+            USAGE_NOTIFICATION_COMMUNICATION_INSTANT,
+            USAGE_NOTIFICATION_COMMUNICATION_DELAYED,
+            USAGE_NOTIFICATION_EVENT,
+            USAGE_ASSISTANCE_ACCESSIBILITY,
+            USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+            USAGE_ASSISTANCE_SONIFICATION,
+            USAGE_GAME,
+            USAGE_ASSISTANT,
+    };
+
+    /**
+     * Flag defining a behavior where the audibility of the sound will be ensured by the system.
+     */
+    public final static int FLAG_AUDIBILITY_ENFORCED = 0x1 << 0;
+    /**
+     * @hide
+     * Flag defining a behavior where the playback of the sound is ensured without
+     * degradation only when going to a secure sink.
+     */
+    // FIXME not guaranteed yet
+    // TODO  add in FLAG_ALL_PUBLIC when supported and in public API
+    public final static int FLAG_SECURE = 0x1 << 1;
+    /**
+     * @hide
+     * Flag to enable when the stream is associated with SCO usage.
+     * Internal use only for dealing with legacy STREAM_BLUETOOTH_SCO
+     */
+    public final static int FLAG_SCO = 0x1 << 2;
+    /**
+     * @hide
+     * Flag defining a behavior where the system ensures that the playback of the sound will
+     * be compatible with its use as a broadcast for surrounding people and/or devices.
+     * Ensures audibility with no or minimal post-processing applied.
+     */
+    @SystemApi
+    public final static int FLAG_BEACON = 0x1 << 3;
+
+    /**
+     * Flag requesting the use of an output stream supporting hardware A/V synchronization.
+     */
+    public final static int FLAG_HW_AV_SYNC = 0x1 << 4;
+
+    /**
+     * @hide
+     * Flag requesting capture from the source used for hardware hotword detection.
+     * To be used with capture preset MediaRecorder.AudioSource.HOTWORD or
+     * MediaRecorder.AudioSource.VOICE_RECOGNITION.
+     */
+    @SystemApi
+    public final static int FLAG_HW_HOTWORD = 0x1 << 5;
+
+    /**
+     * @hide
+     * Flag requesting audible playback even under limited interruptions.
+     */
+    @SystemApi
+    public final static int FLAG_BYPASS_INTERRUPTION_POLICY = 0x1 << 6;
+
+    /**
+     * @hide
+     * Flag requesting audible playback even when the underlying stream is muted.
+     */
+    @SystemApi
+    public final static int FLAG_BYPASS_MUTE = 0x1 << 7;
+
+    /**
+     * Flag requesting a low latency path when creating an AudioTrack.
+     * When using this flag, the sample rate must match the native sample rate
+     * of the device. Effects processing is also unavailable.
+     *
+     * Note that if this flag is used without specifying a bufferSizeInBytes then the
+     * AudioTrack's actual buffer size may be too small. It is recommended that a fairly
+     * large buffer should be specified when the AudioTrack is created.
+     * Then the actual size can be reduced by calling
+     * {@link AudioTrack#setBufferSizeInFrames(int)}. The buffer size can be optimized
+     * by lowering it after each write() call until the audio glitches, which is detected by calling
+     * {@link AudioTrack#getUnderrunCount()}. Then the buffer size can be increased
+     * until there are no glitches.
+     * This tuning step should be done while playing silence.
+     * This technique provides a compromise between latency and glitch rate.
+     *
+     * @deprecated Use {@link AudioTrack.Builder#setPerformanceMode(int)} with
+     * {@link AudioTrack#PERFORMANCE_MODE_LOW_LATENCY} to control performance.
+     */
+    public final static int FLAG_LOW_LATENCY = 0x1 << 8;
+
+    /**
+     * @hide
+     * Flag requesting a deep buffer path when creating an {@code AudioTrack}.
+     *
+     * A deep buffer path, if available, may consume less power and is
+     * suitable for media playback where latency is not a concern.
+     * Use {@link AudioTrack.Builder#setPerformanceMode(int)} with
+     * {@link AudioTrack#PERFORMANCE_MODE_POWER_SAVING} to enable.
+     */
+    public final static int FLAG_DEEP_BUFFER = 0x1 << 9;
+
+    /**
+     * @hide
+     * Flag specifying that the audio shall not be captured by third-party apps
+     * with a MediaProjection.
+     */
+    public static final int FLAG_NO_MEDIA_PROJECTION = 0x1 << 10;
+
+    /**
+     * @hide
+     * Flag indicating force muting haptic channels.
+     */
+    public static final int FLAG_MUTE_HAPTIC = 0x1 << 11;
+
+    /**
+     * @hide
+     * Flag specifying that the audio shall not be captured by any apps, not even system apps.
+     */
+    public static final int FLAG_NO_SYSTEM_CAPTURE = 0x1 << 12;
+
+    /**
+     * @hide
+     * Flag requesting private audio capture. When set in audio attributes passed to an
+     * AudioRecord, this prevents a privileged Assistant from capturing audio while this
+     * AudioRecord is active.
+     */
+    public static final int FLAG_CAPTURE_PRIVATE = 0x1 << 13;
+
+
+    // Note that even though FLAG_MUTE_HAPTIC is stored as a flag bit, it is not here since
+    // it is known as a boolean value outside of AudioAttributes.
+    private static final int FLAG_ALL = FLAG_AUDIBILITY_ENFORCED | FLAG_SECURE | FLAG_SCO
+            | FLAG_BEACON | FLAG_HW_AV_SYNC | FLAG_HW_HOTWORD | FLAG_BYPASS_INTERRUPTION_POLICY
+            | FLAG_BYPASS_MUTE | FLAG_LOW_LATENCY | FLAG_DEEP_BUFFER | FLAG_NO_MEDIA_PROJECTION
+            | FLAG_NO_SYSTEM_CAPTURE | FLAG_CAPTURE_PRIVATE;
+    private final static int FLAG_ALL_PUBLIC = FLAG_AUDIBILITY_ENFORCED |
+            FLAG_HW_AV_SYNC | FLAG_LOW_LATENCY;
+    /* mask of flags that can be set by SDK and System APIs through the Builder */
+    private static final int FLAG_ALL_API_SET = FLAG_ALL_PUBLIC
+            | FLAG_BYPASS_INTERRUPTION_POLICY
+            | FLAG_BYPASS_MUTE;
+
+    /**
+     * Indicates that the audio may be captured by any app.
+     *
+     * For privacy, the following usages cannot be recorded: VOICE_COMMUNICATION*,
+     * USAGE_NOTIFICATION*, USAGE_ASSISTANCE* and USAGE_ASSISTANT.
+     *
+     * On {@link android.os.Build.VERSION_CODES#Q}, this means only {@link #USAGE_UNKNOWN},
+     * {@link #USAGE_MEDIA} and {@link #USAGE_GAME} may be captured.
+     *
+     * See {@link android.media.projection.MediaProjection} and
+     * {@link Builder#setAllowedCapturePolicy}.
+     */
+    public static final int ALLOW_CAPTURE_BY_ALL = 1;
+    /**
+     * Indicates that the audio may only be captured by system apps.
+     *
+     * System apps can capture for many purposes like accessibility, live captions, user guidance...
+     * but abide to the following restrictions:
+     *  - the audio cannot leave the device
+     *  - the audio cannot be passed to a third party app
+     *  - the audio cannot be recorded at a higher quality than 16kHz 16bit mono
+     *
+     * See {@link Builder#setAllowedCapturePolicy}.
+     */
+    public static final int ALLOW_CAPTURE_BY_SYSTEM = 2;
+    /**
+     * Indicates that the audio is not to be recorded by any app, even if it is a system app.
+     *
+     * It is encouraged to use {@link #ALLOW_CAPTURE_BY_SYSTEM} instead of this value as system apps
+     * provide significant and useful features for the user (such as live captioning
+     * and accessibility).
+     *
+     * See {@link Builder#setAllowedCapturePolicy}.
+     */
+    public static final int ALLOW_CAPTURE_BY_NONE = 3;
+
+    /** @hide */
+    @IntDef({
+        ALLOW_CAPTURE_BY_ALL,
+        ALLOW_CAPTURE_BY_SYSTEM,
+        ALLOW_CAPTURE_BY_NONE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CapturePolicy {}
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private int mUsage = USAGE_UNKNOWN;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private int mContentType = CONTENT_TYPE_UNKNOWN;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private int mSource = MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private int mFlags = 0x0;
+    private HashSet<String> mTags;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private String mFormattedTags;
+    private Bundle mBundle; // lazy-initialized, may be null
+
+    private AudioAttributes() {
+    }
+
+    /**
+     * Return the content type.
+     * @return one of the values that can be set in {@link Builder#setContentType(int)}
+     */
+    public int getContentType() {
+        return mContentType;
+    }
+
+    /**
+     * Return the usage.
+     * @return one of the values that can be set in {@link Builder#setUsage(int)}
+     */
+    public int getUsage() {
+        if (isSystemUsage(mUsage)) {
+            return USAGE_UNKNOWN;
+        }
+        return mUsage;
+    }
+
+    /**
+     * @hide
+     * Return the system usage.
+     * @return one of the values that can be set in {@link Builder#setUsage(int)} or
+     * {@link Builder#setSystemUsage(int)}
+     */
+    @SystemApi
+    public int getSystemUsage() {
+        return mUsage;
+    }
+
+    /**
+     * @hide
+     * Return the capture preset.
+     * @return one of the values that can be set in {@link Builder#setCapturePreset(int)} or a
+     *    negative value if none has been set.
+     */
+    @SystemApi
+    public int getCapturePreset() {
+        return mSource;
+    }
+
+    /**
+     * Return the flags.
+     * @return a combined mask of all flags
+     */
+    public int getFlags() {
+        // only return the flags that are public
+        return (mFlags & (FLAG_ALL_PUBLIC));
+    }
+
+    /**
+     * @hide
+     * Return all the flags, even the non-public ones.
+     * Internal use only
+     * @return a combined mask of all flags
+     */
+    @SystemApi
+    public int getAllFlags() {
+        return (mFlags & FLAG_ALL);
+    }
+
+    /**
+     * @hide
+     * Return the Bundle of data.
+     * @return a copy of the Bundle for this instance, may be null.
+     */
+    @SystemApi
+    public Bundle getBundle() {
+        if (mBundle == null) {
+            return mBundle;
+        } else {
+            return new Bundle(mBundle);
+        }
+    }
+
+    /**
+     * @hide
+     * Return the set of tags.
+     * @return a read-only set of all tags stored as strings.
+     */
+    public Set<String> getTags() {
+        return Collections.unmodifiableSet(mTags);
+    }
+
+    /**
+     * Return if haptic channels are muted.
+     * @return {@code true} if haptic channels are muted, {@code false} otherwise.
+     */
+    public boolean areHapticChannelsMuted() {
+        return (mFlags & FLAG_MUTE_HAPTIC) != 0;
+    }
+
+    /**
+     * Return the capture policy.
+     * @return the capture policy set by {@link Builder#setAllowedCapturePolicy(int)} or
+     *         the default if it was not called.
+     */
+    @CapturePolicy
+    public int getAllowedCapturePolicy() {
+        if ((mFlags & FLAG_NO_SYSTEM_CAPTURE) == FLAG_NO_SYSTEM_CAPTURE) {
+            return ALLOW_CAPTURE_BY_NONE;
+        }
+        if ((mFlags & FLAG_NO_MEDIA_PROJECTION) == FLAG_NO_MEDIA_PROJECTION) {
+            return ALLOW_CAPTURE_BY_SYSTEM;
+        }
+        return ALLOW_CAPTURE_BY_ALL;
+    }
+
+
+    /**
+     * Builder class for {@link AudioAttributes} objects.
+     * <p> Here is an example where <code>Builder</code> is used to define the
+     * {@link AudioAttributes} to be used by a new <code>AudioTrack</code> instance:
+     *
+     * <pre class="prettyprint">
+     * AudioTrack myTrack = new AudioTrack(
+     *         new AudioAttributes.Builder()
+     *             .setUsage(AudioAttributes.USAGE_MEDIA)
+     *             .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+     *             .build(),
+     *         myFormat, myBuffSize, AudioTrack.MODE_STREAM, mySession);
+     * </pre>
+     *
+     * <p>By default all types of information (usage, content type, flags) conveyed by an
+     * <code>AudioAttributes</code> instance are set to "unknown". Unknown information will be
+     * interpreted as a default value that is dependent on the context of use, for instance a
+     * {@link MediaPlayer} will use a default usage of {@link AudioAttributes#USAGE_MEDIA}.
+     */
+    public static class Builder {
+        private int mUsage = USAGE_INVALID;
+        private int mSystemUsage = USAGE_INVALID;
+        private int mContentType = CONTENT_TYPE_UNKNOWN;
+        private int mSource = MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID;
+        private int mFlags = 0x0;
+        private boolean mMuteHapticChannels = true;
+        private HashSet<String> mTags = new HashSet<String>();
+        private Bundle mBundle;
+        private int mPrivacySensitive = PRIVACY_SENSITIVE_DEFAULT;
+
+        private static final int PRIVACY_SENSITIVE_DEFAULT = -1;
+        private static final int PRIVACY_SENSITIVE_DISABLED = 0;
+        private static final int PRIVACY_SENSITIVE_ENABLED = 1;
+
+        /**
+         * Constructs a new Builder with the defaults.
+         * By default, usage and content type are respectively {@link AudioAttributes#USAGE_UNKNOWN}
+         * and {@link AudioAttributes#CONTENT_TYPE_UNKNOWN}, and flags are 0. It is recommended to
+         * configure the usage (with {@link #setUsage(int)}) or deriving attributes from a legacy
+         * stream type (with {@link #setLegacyStreamType(int)}) before calling {@link #build()}
+         * to override any default playback behavior in terms of routing and volume management.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Constructs a new Builder from a given AudioAttributes
+         * @param aa the AudioAttributes object whose data will be reused in the new Builder.
+         */
+        @SuppressWarnings("unchecked") // for cloning of mTags
+        public Builder(AudioAttributes aa) {
+            mUsage = aa.mUsage;
+            mContentType = aa.mContentType;
+            mFlags = aa.getAllFlags();
+            mTags = (HashSet<String>) aa.mTags.clone();
+            mMuteHapticChannels = aa.areHapticChannelsMuted();
+        }
+
+        /**
+         * Combines all of the attributes that have been set and return a new
+         * {@link AudioAttributes} object.
+         * @return a new {@link AudioAttributes} object
+         */
+        @SuppressWarnings("unchecked") // for cloning of mTags
+        public AudioAttributes build() {
+            AudioAttributes aa = new AudioAttributes();
+            aa.mContentType = mContentType;
+
+            if (mUsage == USAGE_INVALID) {
+                if (mSystemUsage == USAGE_INVALID) {
+                    aa.mUsage = USAGE_UNKNOWN;
+                } else {
+                    aa.mUsage = mSystemUsage;
+                }
+            } else {
+                if (mSystemUsage == USAGE_INVALID) {
+                    aa.mUsage = mUsage;
+                } else {
+                    throw new IllegalArgumentException(
+                            "Cannot set both usage and system usage on same builder");
+                }
+            }
+
+            aa.mSource = mSource;
+            aa.mFlags = mFlags;
+            if (mMuteHapticChannels) {
+                aa.mFlags |= FLAG_MUTE_HAPTIC;
+            }
+
+            if (mPrivacySensitive == PRIVACY_SENSITIVE_DEFAULT) {
+                // capturing for camcorder or communication is private by default to
+                // reflect legacy behavior
+                if (mSource == MediaRecorder.AudioSource.VOICE_COMMUNICATION
+                        || mSource == MediaRecorder.AudioSource.CAMCORDER) {
+                    aa.mFlags |= FLAG_CAPTURE_PRIVATE;
+                } else {
+                    aa.mFlags &= ~FLAG_CAPTURE_PRIVATE;
+                }
+            } else if (mPrivacySensitive == PRIVACY_SENSITIVE_ENABLED) {
+                aa.mFlags |= FLAG_CAPTURE_PRIVATE;
+            } else {
+                aa.mFlags &= ~FLAG_CAPTURE_PRIVATE;
+            }
+            aa.mTags = (HashSet<String>) mTags.clone();
+            aa.mFormattedTags = TextUtils.join(";", mTags);
+            if (mBundle != null) {
+                aa.mBundle = new Bundle(mBundle);
+            }
+
+            // Allow the FLAG_HW_HOTWORD only for AudioSource.VOICE_RECOGNITION
+            if (mSource != MediaRecorder.AudioSource.VOICE_RECOGNITION
+                    && (mFlags & FLAG_HW_HOTWORD) == FLAG_HW_HOTWORD) {
+                aa.mFlags &= ~FLAG_HW_HOTWORD;
+            }
+
+            return aa;
+        }
+
+        /**
+         * Sets the attribute describing what is the intended use of the audio signal,
+         * such as alarm or ringtone.
+         * @param usage one of {@link AttributeSdkUsage#USAGE_UNKNOWN},
+         *     {@link AttributeSdkUsage#USAGE_MEDIA},
+         *     {@link AttributeSdkUsage#USAGE_VOICE_COMMUNICATION},
+         *     {@link AttributeSdkUsage#USAGE_VOICE_COMMUNICATION_SIGNALLING},
+         *     {@link AttributeSdkUsage#USAGE_ALARM}, {@link AudioAttributes#USAGE_NOTIFICATION},
+         *     {@link AttributeSdkUsage#USAGE_NOTIFICATION_RINGTONE},
+         *     {@link AttributeSdkUsage#USAGE_NOTIFICATION_COMMUNICATION_REQUEST},
+         *     {@link AttributeSdkUsage#USAGE_NOTIFICATION_COMMUNICATION_INSTANT},
+         *     {@link AttributeSdkUsage#USAGE_NOTIFICATION_COMMUNICATION_DELAYED},
+         *     {@link AttributeSdkUsage#USAGE_NOTIFICATION_EVENT},
+         *     {@link AttributeSdkUsage#USAGE_ASSISTANT},
+         *     {@link AttributeSdkUsage#USAGE_ASSISTANCE_ACCESSIBILITY},
+         *     {@link AttributeSdkUsage#USAGE_ASSISTANCE_NAVIGATION_GUIDANCE},
+         *     {@link AttributeSdkUsage#USAGE_ASSISTANCE_SONIFICATION},
+         *     {@link AttributeSdkUsage#USAGE_GAME}.
+         * @return the same Builder instance.
+         */
+        public Builder setUsage(@AttributeSdkUsage int usage) {
+            switch (usage) {
+                case USAGE_UNKNOWN:
+                case USAGE_MEDIA:
+                case USAGE_VOICE_COMMUNICATION:
+                case USAGE_VOICE_COMMUNICATION_SIGNALLING:
+                case USAGE_ALARM:
+                case USAGE_NOTIFICATION:
+                case USAGE_NOTIFICATION_RINGTONE:
+                case USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
+                case USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
+                case USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
+                case USAGE_NOTIFICATION_EVENT:
+                case USAGE_ASSISTANCE_ACCESSIBILITY:
+                case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
+                case USAGE_ASSISTANCE_SONIFICATION:
+                case USAGE_GAME:
+                case USAGE_VIRTUAL_SOURCE:
+                case USAGE_ASSISTANT:
+                    mUsage = usage;
+                    break;
+                default:
+                    throw new IllegalArgumentException("Invalid usage " + usage);
+            }
+            return this;
+        }
+
+        /**
+         * @hide
+         * Sets the attribute describing what is the intended use of the audio signal for categories
+         * of sounds restricted to the system, such as vehicle status or emergency.
+         *
+         * <p>Note that the AudioAttributes have a single usage value, therefore it is illegal to
+         * call both this method and {@link #setUsage(int)}.
+         * @param systemUsage the system-restricted usage.
+         * @return the same Builder instance.
+         */
+        @SystemApi
+        @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+        public @NonNull Builder setSystemUsage(@AttributeSystemUsage int systemUsage) {
+            if (isSystemUsage(systemUsage)) {
+                mSystemUsage = systemUsage;
+            } else {
+                throw new IllegalArgumentException("Invalid system usage " + systemUsage);
+            }
+
+            return this;
+        }
+
+        /**
+         * Sets the attribute describing the content type of the audio signal, such as speech,
+         * or music.
+         * @param contentType the content type values, one of
+         *     {@link AudioAttributes#CONTENT_TYPE_MOVIE},
+         *     {@link AudioAttributes#CONTENT_TYPE_MUSIC},
+         *     {@link AudioAttributes#CONTENT_TYPE_SONIFICATION},
+         *     {@link AudioAttributes#CONTENT_TYPE_SPEECH},
+         *     {@link AudioAttributes#CONTENT_TYPE_UNKNOWN}.
+         * @return the same Builder instance.
+         */
+        public Builder setContentType(@AttributeContentType int contentType) {
+            switch (contentType) {
+                case CONTENT_TYPE_UNKNOWN:
+                case CONTENT_TYPE_MOVIE:
+                case CONTENT_TYPE_MUSIC:
+                case CONTENT_TYPE_SONIFICATION:
+                case CONTENT_TYPE_SPEECH:
+                    mContentType = contentType;
+                    break;
+                default:
+                    throw new IllegalArgumentException("Invalid content type " + contentType);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the combination of flags.
+         *
+         * This is a bitwise OR with the existing flags.
+         * @param flags a combination of {@link AudioAttributes#FLAG_AUDIBILITY_ENFORCED},
+         *    {@link AudioAttributes#FLAG_HW_AV_SYNC}.
+         * @return the same Builder instance.
+         */
+        public Builder setFlags(int flags) {
+            flags &= AudioAttributes.FLAG_ALL_API_SET;
+            mFlags |= flags;
+            return this;
+        }
+
+        /**
+         * @hide
+         * Request for capture in hotword mode.
+         *
+         * Requests an audio path optimized for Hotword detection use cases from
+         * the low power audio DSP. This is valid only for capture with
+         * audio source {@link MediaRecorder.AudioSource#VOICE_RECOGNITION}.
+         * There is no guarantee that this mode is available on the device.
+         * @return the same Builder instance.
+         */
+        @SystemApi
+        @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD)
+        public @NonNull Builder setHotwordModeEnabled(boolean enable) {
+            if (enable) {
+                mFlags |= FLAG_HW_HOTWORD;
+            } else {
+                mFlags &= ~FLAG_HW_HOTWORD;
+            }
+            return this;
+        }
+
+        /**
+         * Specifies whether the audio may or may not be captured by other apps or the system.
+         *
+         * The default is {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}.
+         *
+         * There are multiple ways to set this policy:
+         * <ul>
+         * <li> for each track independently, with this method </li>
+         * <li> application-wide at runtime, with
+         *      {@link AudioManager#setAllowedCapturePolicy(int)} </li>
+         * <li> application-wide at build time, see {@code allowAudioPlaybackCapture} in the
+         *      application manifest. </li>
+         * </ul>
+         * The most restrictive policy is always applied.
+         *
+         * See {@link AudioPlaybackCaptureConfiguration} for more details on
+         * which audio signals can be captured.
+         *
+         * @return the same Builder instance
+         * @throws IllegalArgumentException if the argument is not a valid value.
+         */
+        public @NonNull Builder setAllowedCapturePolicy(@CapturePolicy int capturePolicy) {
+            mFlags = capturePolicyToFlags(capturePolicy, mFlags);
+            return this;
+        }
+
+        /**
+         * @hide
+         * Replaces flags.
+         * @param flags any combination of {@link AudioAttributes#FLAG_ALL}.
+         * @return the same Builder instance.
+         */
+        public Builder replaceFlags(int flags) {
+            mFlags = flags & AudioAttributes.FLAG_ALL;
+            return this;
+        }
+
+        /**
+         * @hide
+         * Adds a Bundle of data
+         * @param bundle a non-null Bundle
+         * @return the same builder instance
+         */
+        @SystemApi
+        public Builder addBundle(@NonNull Bundle bundle) {
+            if (bundle == null) {
+                throw new IllegalArgumentException("Illegal null bundle");
+            }
+            if (mBundle == null) {
+                mBundle = new Bundle(bundle);
+            } else {
+                mBundle.putAll(bundle);
+            }
+            return this;
+        }
+
+        /**
+         * @hide
+         * Add a custom tag stored as a string
+         * @param tag
+         * @return the same Builder instance.
+         */
+        @UnsupportedAppUsage
+        public Builder addTag(String tag) {
+            mTags.add(tag);
+            return this;
+        }
+
+        /**
+         * Sets attributes as inferred from the legacy stream types.
+         * Warning: do not use this method in combination with setting any other attributes such as
+         * usage, content type, flags or haptic control, as this method will overwrite (the more
+         * accurate) information describing the use case previously set in the <code>Builder</code>.
+         * In general, avoid using it and prefer setting usage and content type directly
+         * with {@link #setUsage(int)} and {@link #setContentType(int)}.
+         * <p>Use this method when building an {@link AudioAttributes} instance to initialize some
+         * of the attributes by information derived from a legacy stream type.
+         * @param streamType one of {@link AudioManager#STREAM_VOICE_CALL},
+         *   {@link AudioManager#STREAM_SYSTEM}, {@link AudioManager#STREAM_RING},
+         *   {@link AudioManager#STREAM_MUSIC}, {@link AudioManager#STREAM_ALARM},
+         *    or {@link AudioManager#STREAM_NOTIFICATION}.
+         * @return the same Builder instance.
+         */
+        public Builder setLegacyStreamType(int streamType) {
+            if (streamType == AudioManager.STREAM_ACCESSIBILITY) {
+                throw new IllegalArgumentException("STREAM_ACCESSIBILITY is not a legacy stream "
+                        + "type that was used for audio playback");
+            }
+            setInternalLegacyStreamType(streamType);
+            return this;
+        }
+
+        /**
+         * @hide
+         * For internal framework use only, enables building from hidden stream types.
+         * @param streamType
+         * @return the same Builder instance.
+         */
+        @UnsupportedAppUsage
+        public Builder setInternalLegacyStreamType(int streamType) {
+            mContentType = CONTENT_TYPE_UNKNOWN;
+            mUsage = USAGE_UNKNOWN;
+            if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
+                AudioAttributes attributes =
+                        AudioProductStrategy.getAudioAttributesForStrategyWithLegacyStreamType(
+                                streamType);
+                if (attributes != null) {
+                    mUsage = attributes.mUsage;
+                    mContentType = attributes.mContentType;
+                    mFlags = attributes.getAllFlags();
+                    mMuteHapticChannels = attributes.areHapticChannelsMuted();
+                    mTags = attributes.mTags;
+                    mBundle = attributes.mBundle;
+                    mSource = attributes.mSource;
+                }
+            }
+            if (mContentType == CONTENT_TYPE_UNKNOWN) {
+                switch (streamType) {
+                    case AudioSystem.STREAM_VOICE_CALL:
+                        mContentType = CONTENT_TYPE_SPEECH;
+                        break;
+                    case AudioSystem.STREAM_SYSTEM_ENFORCED:
+                        mFlags |= FLAG_AUDIBILITY_ENFORCED;
+                        // intended fall through, attributes in common with STREAM_SYSTEM
+                    case AudioSystem.STREAM_SYSTEM:
+                        mContentType = CONTENT_TYPE_SONIFICATION;
+                        break;
+                    case AudioSystem.STREAM_RING:
+                        mContentType = CONTENT_TYPE_SONIFICATION;
+                        break;
+                    case AudioSystem.STREAM_MUSIC:
+                        mContentType = CONTENT_TYPE_MUSIC;
+                        break;
+                    case AudioSystem.STREAM_ALARM:
+                        mContentType = CONTENT_TYPE_SONIFICATION;
+                        break;
+                    case AudioSystem.STREAM_NOTIFICATION:
+                        mContentType = CONTENT_TYPE_SONIFICATION;
+                        break;
+                    case AudioSystem.STREAM_BLUETOOTH_SCO:
+                        mContentType = CONTENT_TYPE_SPEECH;
+                        mFlags |= FLAG_SCO;
+                        break;
+                    case AudioSystem.STREAM_DTMF:
+                        mContentType = CONTENT_TYPE_SONIFICATION;
+                        break;
+                    case AudioSystem.STREAM_TTS:
+                        mContentType = CONTENT_TYPE_SONIFICATION;
+                        mFlags |= FLAG_BEACON;
+                        break;
+                    case AudioSystem.STREAM_ACCESSIBILITY:
+                        mContentType = CONTENT_TYPE_SPEECH;
+                        break;
+                    default:
+                        Log.e(TAG, "Invalid stream type " + streamType + " for AudioAttributes");
+                }
+            }
+            if (mUsage == USAGE_UNKNOWN) {
+                mUsage = usageForStreamType(streamType);
+            }
+            return this;
+        }
+
+        /**
+         * @hide
+         * Sets the capture preset.
+         * Use this audio attributes configuration method when building an {@link AudioRecord}
+         * instance with {@link AudioRecord#AudioRecord(AudioAttributes, AudioFormat, int)}.
+         * @param preset one of {@link MediaRecorder.AudioSource#DEFAULT},
+         *     {@link MediaRecorder.AudioSource#MIC}, {@link MediaRecorder.AudioSource#CAMCORDER},
+         *     {@link MediaRecorder.AudioSource#VOICE_RECOGNITION},
+         *     {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION},
+         *     {@link MediaRecorder.AudioSource#UNPROCESSED} or
+         *     {@link MediaRecorder.AudioSource#VOICE_PERFORMANCE}
+         * @return the same Builder instance.
+         */
+        @SystemApi
+        public Builder setCapturePreset(int preset) {
+            switch (preset) {
+                case MediaRecorder.AudioSource.DEFAULT:
+                case MediaRecorder.AudioSource.MIC:
+                case MediaRecorder.AudioSource.CAMCORDER:
+                case MediaRecorder.AudioSource.VOICE_RECOGNITION:
+                case MediaRecorder.AudioSource.VOICE_COMMUNICATION:
+                case MediaRecorder.AudioSource.UNPROCESSED:
+                case MediaRecorder.AudioSource.VOICE_PERFORMANCE:
+                    mSource = preset;
+                    break;
+                default:
+                    Log.e(TAG, "Invalid capture preset " + preset + " for AudioAttributes");
+            }
+            return this;
+        }
+
+        /**
+         * @hide
+         * Same as {@link #setCapturePreset(int)} but authorizes the use of HOTWORD,
+         * REMOTE_SUBMIX, RADIO_TUNER, VOICE_DOWNLINK, VOICE_UPLINK, VOICE_CALL and ECHO_REFERENCE.
+         * @param preset
+         * @return the same Builder instance.
+         */
+        @SystemApi
+        public Builder setInternalCapturePreset(int preset) {
+            if ((preset == MediaRecorder.AudioSource.HOTWORD)
+                    || (preset == MediaRecorder.AudioSource.REMOTE_SUBMIX)
+                    || (preset == MediaRecorder.AudioSource.RADIO_TUNER)
+                    || (preset == MediaRecorder.AudioSource.VOICE_DOWNLINK)
+                    || (preset == MediaRecorder.AudioSource.VOICE_UPLINK)
+                    || (preset == MediaRecorder.AudioSource.VOICE_CALL)
+                    || (preset == MediaRecorder.AudioSource.ECHO_REFERENCE)) {
+                mSource = preset;
+            } else {
+                setCapturePreset(preset);
+            }
+            return this;
+        }
+
+        /**
+         * Specifying if haptic should be muted or not when playing audio-haptic coupled data.
+         * By default, haptic channels are disabled.
+         * @param muted true to force muting haptic channels.
+         * @return the same Builder instance.
+         */
+        public @NonNull Builder setHapticChannelsMuted(boolean muted) {
+            mMuteHapticChannels = muted;
+            return this;
+        }
+
+        /**
+         * @hide
+         * Indicates if an AudioRecord build with this AudioAttributes is privacy sensitive or not.
+         * See {@link AudioRecord.Builder#setPrivacySensitive(boolean)}.
+         * @param privacySensitive True if capture must be marked as privacy sensitive,
+         * false otherwise.
+         * @return the same Builder instance.
+         */
+        public @NonNull Builder setPrivacySensitive(boolean privacySensitive) {
+            mPrivacySensitive =
+                privacySensitive ? PRIVACY_SENSITIVE_ENABLED : PRIVACY_SENSITIVE_DISABLED;
+            return this;
+        }
+    };
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * @hide
+     * Used to indicate that when parcelling, the tags should be parcelled through the flattened
+     * formatted string, not through the array of strings.
+     * Keep in sync with frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
+     * see definition of kAudioAttributesMarshallTagFlattenTags
+     */
+    public final static int FLATTEN_TAGS = 0x1;
+
+    private final static int ATTR_PARCEL_IS_NULL_BUNDLE = -1977;
+    private final static int ATTR_PARCEL_IS_VALID_BUNDLE = 1980;
+
+    /**
+     * When adding tags for writeToParcel(Parcel, int), add them in the list of flags (| NEW_FLAG)
+     */
+    private final static int ALL_PARCEL_FLAGS = FLATTEN_TAGS;
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mUsage);
+        dest.writeInt(mContentType);
+        dest.writeInt(mSource);
+        dest.writeInt(mFlags);
+        dest.writeInt(flags & ALL_PARCEL_FLAGS);
+        if ((flags & FLATTEN_TAGS) == 0) {
+            String[] tagsArray = new String[mTags.size()];
+            mTags.toArray(tagsArray);
+            dest.writeStringArray(tagsArray);
+        } else if ((flags & FLATTEN_TAGS) == FLATTEN_TAGS) {
+            dest.writeString(mFormattedTags);
+        }
+        if (mBundle == null) {
+            dest.writeInt(ATTR_PARCEL_IS_NULL_BUNDLE);
+        } else {
+            dest.writeInt(ATTR_PARCEL_IS_VALID_BUNDLE);
+            dest.writeBundle(mBundle);
+        }
+    }
+
+    private AudioAttributes(Parcel in) {
+        mUsage = in.readInt();
+        mContentType = in.readInt();
+        mSource = in.readInt();
+        mFlags = in.readInt();
+        boolean hasFlattenedTags = ((in.readInt() & FLATTEN_TAGS) == FLATTEN_TAGS);
+        mTags = new HashSet<String>();
+        if (hasFlattenedTags) {
+            mFormattedTags = new String(in.readString());
+            mTags.add(mFormattedTags);
+        } else {
+            String[] tagsArray = in.readStringArray();
+            for (int i = tagsArray.length - 1 ; i >= 0 ; i--) {
+                mTags.add(tagsArray[i]);
+            }
+            mFormattedTags = TextUtils.join(";", mTags);
+        }
+        switch (in.readInt()) {
+            case ATTR_PARCEL_IS_NULL_BUNDLE:
+                mBundle = null;
+                break;
+            case ATTR_PARCEL_IS_VALID_BUNDLE:
+                mBundle = new Bundle(in.readBundle());
+                break;
+            default:
+                Log.e(TAG, "Illegal value unmarshalling AudioAttributes, can't initialize bundle");
+        }
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<AudioAttributes> CREATOR
+            = new Parcelable.Creator<AudioAttributes>() {
+        /**
+         * Rebuilds an AudioAttributes previously stored with writeToParcel().
+         * @param p Parcel object to read the AudioAttributes from
+         * @return a new AudioAttributes created from the data in the parcel
+         */
+        public AudioAttributes createFromParcel(Parcel p) {
+            return new AudioAttributes(p);
+        }
+        public AudioAttributes[] newArray(int size) {
+            return new AudioAttributes[size];
+        }
+    };
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        AudioAttributes that = (AudioAttributes) o;
+
+        return ((mContentType == that.mContentType)
+                && (mFlags == that.mFlags)
+                && (mSource == that.mSource)
+                && (mUsage == that.mUsage)
+                //mFormattedTags is never null due to assignment in Builder or unmarshalling
+                && (mFormattedTags.equals(that.mFormattedTags)));
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mContentType, mFlags, mSource, mUsage, mFormattedTags, mBundle);
+    }
+
+    @Override
+    public String toString () {
+        return new String("AudioAttributes:"
+                + " usage=" + usageToString()
+                + " content=" + contentTypeToString()
+                + " flags=0x" + Integer.toHexString(mFlags).toUpperCase()
+                + " tags=" + mFormattedTags
+                + " bundle=" + (mBundle == null ? "null" : mBundle.toString()));
+    }
+
+    /** @hide */
+    public void dumpDebug(ProtoOutputStream proto, long fieldId) {
+        final long token = proto.start(fieldId);
+
+        proto.write(AudioAttributesProto.USAGE, mUsage);
+        proto.write(AudioAttributesProto.CONTENT_TYPE, mContentType);
+        proto.write(AudioAttributesProto.FLAGS, mFlags);
+        // mFormattedTags is never null due to assignment in Builder or unmarshalling.
+        for (String t : mFormattedTags.split(";")) {
+            t = t.trim();
+            if (t != "") {
+                proto.write(AudioAttributesProto.TAGS, t);
+            }
+        }
+        // TODO: is the data in mBundle useful for debugging?
+
+        proto.end(token);
+    }
+
+    /** @hide */
+    public String usageToString() {
+        return usageToString(mUsage);
+    }
+
+    /**
+     * Returns the string representation for the usage constant passed as parameter.
+     *
+     * @param usage one of the {@link AudioAttributes} usage constants
+     * @return string representing the {@link AudioAttributes} usage constant passed as a parameter
+     *
+     * @hide
+     */
+    @NonNull
+    public static String usageToString(@AttributeSdkUsage int usage) {
+        switch(usage) {
+            case USAGE_UNKNOWN:
+                return "USAGE_UNKNOWN";
+            case USAGE_MEDIA:
+                return "USAGE_MEDIA";
+            case USAGE_VOICE_COMMUNICATION:
+                return "USAGE_VOICE_COMMUNICATION";
+            case USAGE_VOICE_COMMUNICATION_SIGNALLING:
+                return "USAGE_VOICE_COMMUNICATION_SIGNALLING";
+            case USAGE_ALARM:
+                return "USAGE_ALARM";
+            case USAGE_NOTIFICATION:
+                return "USAGE_NOTIFICATION";
+            case USAGE_NOTIFICATION_RINGTONE:
+                return "USAGE_NOTIFICATION_RINGTONE";
+            case USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
+                return "USAGE_NOTIFICATION_COMMUNICATION_REQUEST";
+            case USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
+                return "USAGE_NOTIFICATION_COMMUNICATION_INSTANT";
+            case USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
+                return "USAGE_NOTIFICATION_COMMUNICATION_DELAYED";
+            case USAGE_NOTIFICATION_EVENT:
+                return "USAGE_NOTIFICATION_EVENT";
+            case USAGE_ASSISTANCE_ACCESSIBILITY:
+                return "USAGE_ASSISTANCE_ACCESSIBILITY";
+            case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
+                return "USAGE_ASSISTANCE_NAVIGATION_GUIDANCE";
+            case USAGE_ASSISTANCE_SONIFICATION:
+                return "USAGE_ASSISTANCE_SONIFICATION";
+            case USAGE_GAME:
+                return "USAGE_GAME";
+            case USAGE_ASSISTANT:
+                return "USAGE_ASSISTANT";
+            case USAGE_CALL_ASSISTANT:
+                return "USAGE_CALL_ASSISTANT";
+            case USAGE_EMERGENCY:
+                return "USAGE_EMERGENCY";
+            case USAGE_SAFETY:
+                return "USAGE_SAFETY";
+            case USAGE_VEHICLE_STATUS:
+                return "USAGE_VEHICLE_STATUS";
+            case USAGE_ANNOUNCEMENT:
+                return "USAGE_ANNOUNCEMENT";
+            default:
+                return "unknown usage " + usage;
+        }
+    }
+
+    /** @hide **/
+    @TestApi
+    @NonNull
+    public static String usageToXsdString(@AttributeUsage int usage) {
+        switch (usage) {
+            case AudioAttributes.USAGE_UNKNOWN:
+                return AudioUsage.AUDIO_USAGE_UNKNOWN.toString();
+            case AudioAttributes.USAGE_MEDIA:
+                return AudioUsage.AUDIO_USAGE_MEDIA.toString();
+            case AudioAttributes.USAGE_VOICE_COMMUNICATION:
+                return AudioUsage.AUDIO_USAGE_VOICE_COMMUNICATION.toString();
+            case AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING:
+                return AudioUsage.AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING.toString();
+            case AudioAttributes.USAGE_ALARM:
+                return AudioUsage.AUDIO_USAGE_ALARM.toString();
+            case AudioAttributes.USAGE_NOTIFICATION:
+                return AudioUsage.AUDIO_USAGE_NOTIFICATION.toString();
+            case AudioAttributes.USAGE_NOTIFICATION_RINGTONE:
+                return AudioUsage.AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE.toString();
+            case AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY:
+                return AudioUsage.AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY.toString();
+            case AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
+                return AudioUsage.AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE.toString();
+            case AudioAttributes.USAGE_ASSISTANCE_SONIFICATION:
+                return AudioUsage.AUDIO_USAGE_ASSISTANCE_SONIFICATION.toString();
+            case AudioAttributes.USAGE_GAME:
+                return AudioUsage.AUDIO_USAGE_GAME.toString();
+            case AudioAttributes.USAGE_VIRTUAL_SOURCE:
+                return AudioUsage.AUDIO_USAGE_VIRTUAL_SOURCE.toString();
+            case AudioAttributes.USAGE_ASSISTANT:
+                return AudioUsage.AUDIO_USAGE_ASSISTANT.toString();
+            case AudioAttributes.USAGE_CALL_ASSISTANT:
+                return AudioUsage.AUDIO_USAGE_CALL_ASSISTANT.toString();
+            case AudioAttributes.USAGE_EMERGENCY:
+                return AudioUsage.AUDIO_USAGE_EMERGENCY.toString();
+            case AudioAttributes.USAGE_SAFETY:
+                return AudioUsage.AUDIO_USAGE_SAFETY.toString();
+            case AudioAttributes.USAGE_VEHICLE_STATUS:
+                return AudioUsage.AUDIO_USAGE_VEHICLE_STATUS.toString();
+            case AudioAttributes.USAGE_ANNOUNCEMENT:
+                return AudioUsage.AUDIO_USAGE_ANNOUNCEMENT.toString();
+            default:
+                Log.w(TAG, "Unknown usage value " + usage);
+                return AudioUsage.AUDIO_USAGE_UNKNOWN.toString();
+        }
+    }
+
+    private static final Map<String, Integer> sXsdStringToUsage = new HashMap<>();
+
+    static {
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_UNKNOWN.toString(), USAGE_UNKNOWN);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_UNKNOWN.toString(), USAGE_UNKNOWN);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_MEDIA.toString(), USAGE_MEDIA);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_VOICE_COMMUNICATION.toString(),
+                USAGE_VOICE_COMMUNICATION);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING.toString(),
+                USAGE_VOICE_COMMUNICATION_SIGNALLING);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_ALARM.toString(), USAGE_ALARM);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_NOTIFICATION.toString(), USAGE_NOTIFICATION);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE.toString(),
+                USAGE_NOTIFICATION_RINGTONE);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY.toString(),
+                USAGE_ASSISTANCE_ACCESSIBILITY);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE.toString(),
+                USAGE_ASSISTANCE_NAVIGATION_GUIDANCE);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_ASSISTANCE_SONIFICATION.toString(),
+                USAGE_ASSISTANCE_SONIFICATION);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_GAME.toString(), USAGE_GAME);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_VIRTUAL_SOURCE.toString(),
+                USAGE_VIRTUAL_SOURCE);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_ASSISTANT.toString(), USAGE_ASSISTANT);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_CALL_ASSISTANT.toString(),
+                USAGE_CALL_ASSISTANT);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_EMERGENCY.toString(), USAGE_EMERGENCY);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_SAFETY.toString(), USAGE_SAFETY);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_VEHICLE_STATUS.toString(),
+                USAGE_VEHICLE_STATUS);
+        sXsdStringToUsage.put(AudioUsage.AUDIO_USAGE_ANNOUNCEMENT.toString(), USAGE_ANNOUNCEMENT);
+    }
+
+    /** @hide **/
+    @TestApi
+    public static @AttributeUsage int xsdStringToUsage(@NonNull String xsdUsage) {
+        if (sXsdStringToUsage.containsKey(xsdUsage)) {
+            return sXsdStringToUsage.get(xsdUsage);
+        } else {
+            Log.w(TAG, "Usage name not found in AudioUsage enum: " + xsdUsage);
+            return USAGE_UNKNOWN;
+        }
+    }
+
+    /** @hide */
+    public String contentTypeToString() {
+        switch(mContentType) {
+            case CONTENT_TYPE_UNKNOWN:
+                return new String("CONTENT_TYPE_UNKNOWN");
+            case CONTENT_TYPE_SPEECH: return new String("CONTENT_TYPE_SPEECH");
+            case CONTENT_TYPE_MUSIC: return new String("CONTENT_TYPE_MUSIC");
+            case CONTENT_TYPE_MOVIE: return new String("CONTENT_TYPE_MOVIE");
+            case CONTENT_TYPE_SONIFICATION: return new String("CONTENT_TYPE_SONIFICATION");
+            default: return new String("unknown content type " + mContentType);
+        }
+    }
+
+    private static int usageForStreamType(int streamType) {
+        switch(streamType) {
+            case AudioSystem.STREAM_VOICE_CALL:
+                return USAGE_VOICE_COMMUNICATION;
+            case AudioSystem.STREAM_SYSTEM_ENFORCED:
+            case AudioSystem.STREAM_SYSTEM:
+                return USAGE_ASSISTANCE_SONIFICATION;
+            case AudioSystem.STREAM_RING:
+                return USAGE_NOTIFICATION_RINGTONE;
+            case AudioSystem.STREAM_MUSIC:
+                return USAGE_MEDIA;
+            case AudioSystem.STREAM_ALARM:
+                return USAGE_ALARM;
+            case AudioSystem.STREAM_NOTIFICATION:
+                return USAGE_NOTIFICATION;
+            case AudioSystem.STREAM_BLUETOOTH_SCO:
+                return USAGE_VOICE_COMMUNICATION;
+            case AudioSystem.STREAM_DTMF:
+                return USAGE_VOICE_COMMUNICATION_SIGNALLING;
+            case AudioSystem.STREAM_ACCESSIBILITY:
+                return USAGE_ASSISTANCE_ACCESSIBILITY;
+            case AudioSystem.STREAM_TTS:
+            default:
+                return USAGE_UNKNOWN;
+        }
+    }
+
+    /**
+     * @param usage one of {@link AttributeSystemUsage},
+     *     {@link AttributeSystemUsage#USAGE_CALL_ASSISTANT},
+     *     {@link AttributeSystemUsage#USAGE_EMERGENCY},
+     *     {@link AttributeSystemUsage#USAGE_SAFETY},
+     *     {@link AttributeSystemUsage#USAGE_VEHICLE_STATUS},
+     *     {@link AttributeSystemUsage#USAGE_ANNOUNCEMENT}
+     * @return boolean indicating if the usage is a system usage or not
+     * @hide
+     */
+    @SystemApi
+    public static boolean isSystemUsage(@AttributeSystemUsage int usage) {
+        return (usage == USAGE_CALL_ASSISTANT
+                || usage == USAGE_EMERGENCY
+                || usage == USAGE_SAFETY
+                || usage == USAGE_VEHICLE_STATUS
+                || usage == USAGE_ANNOUNCEMENT);
+    }
+
+    /**
+     * Returns the stream type matching this {@code AudioAttributes} instance for volume control.
+     * Use this method to derive the stream type needed to configure the volume
+     * control slider in an {@link android.app.Activity} with
+     * {@link android.app.Activity#setVolumeControlStream(int)} for playback conducted with these
+     * attributes.
+     * <BR>Do not use this method to set the stream type on an audio player object
+     * (e.g. {@link AudioTrack}, {@link MediaPlayer}) as this is deprecated,
+     * use {@code AudioAttributes} instead.
+     * @return a valid stream type for {@code Activity} or stream volume control that matches
+     *     the attributes, or {@link AudioManager#USE_DEFAULT_STREAM_TYPE} if there isn't a direct
+     *     match. Note that {@code USE_DEFAULT_STREAM_TYPE} is not a valid value
+     *     for {@link AudioManager#setStreamVolume(int, int, int)}.
+     */
+    public int getVolumeControlStream() {
+        return toVolumeStreamType(true /*fromGetVolumeControlStream*/, this);
+    }
+
+    /**
+     * @hide
+     * Only use to get which stream type should be used for volume control, NOT for audio playback
+     * (all audio playback APIs are supposed to take AudioAttributes as input parameters)
+     * @param aa non-null AudioAttributes.
+     * @return a valid stream type for volume control that matches the attributes.
+     */
+    @UnsupportedAppUsage
+    public static int toLegacyStreamType(@NonNull AudioAttributes aa) {
+        return toVolumeStreamType(false /*fromGetVolumeControlStream*/, aa);
+    }
+
+    private static int toVolumeStreamType(boolean fromGetVolumeControlStream, AudioAttributes aa) {
+        // flags to stream type mapping
+        if ((aa.getFlags() & FLAG_AUDIBILITY_ENFORCED) == FLAG_AUDIBILITY_ENFORCED) {
+            return fromGetVolumeControlStream ?
+                    AudioSystem.STREAM_SYSTEM : AudioSystem.STREAM_SYSTEM_ENFORCED;
+        }
+        if ((aa.getAllFlags() & FLAG_SCO) == FLAG_SCO) {
+            return fromGetVolumeControlStream ?
+                    AudioSystem.STREAM_VOICE_CALL : AudioSystem.STREAM_BLUETOOTH_SCO;
+        }
+        if ((aa.getAllFlags() & FLAG_BEACON) == FLAG_BEACON) {
+            return fromGetVolumeControlStream ?
+                    AudioSystem.STREAM_MUSIC : AudioSystem.STREAM_TTS;
+        }
+
+        if (AudioProductStrategy.getAudioProductStrategies().size() > 0) {
+            return AudioProductStrategy.getLegacyStreamTypeForStrategyWithAudioAttributes(aa);
+        }
+        // usage to stream type mapping
+        switch (aa.getUsage()) {
+            case USAGE_MEDIA:
+            case USAGE_GAME:
+            case USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
+            case USAGE_ASSISTANT:
+                return AudioSystem.STREAM_MUSIC;
+            case USAGE_ASSISTANCE_SONIFICATION:
+                return AudioSystem.STREAM_SYSTEM;
+            case USAGE_VOICE_COMMUNICATION:
+            case USAGE_CALL_ASSISTANT:
+                return AudioSystem.STREAM_VOICE_CALL;
+            case USAGE_VOICE_COMMUNICATION_SIGNALLING:
+                return fromGetVolumeControlStream ?
+                        AudioSystem.STREAM_VOICE_CALL : AudioSystem.STREAM_DTMF;
+            case USAGE_ALARM:
+                return AudioSystem.STREAM_ALARM;
+            case USAGE_NOTIFICATION_RINGTONE:
+                return AudioSystem.STREAM_RING;
+            case USAGE_NOTIFICATION:
+            case USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
+            case USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
+            case USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
+            case USAGE_NOTIFICATION_EVENT:
+                return AudioSystem.STREAM_NOTIFICATION;
+            case USAGE_ASSISTANCE_ACCESSIBILITY:
+                return AudioSystem.STREAM_ACCESSIBILITY;
+            case USAGE_EMERGENCY:
+            case USAGE_SAFETY:
+            case USAGE_VEHICLE_STATUS:
+            case USAGE_ANNOUNCEMENT:
+            case USAGE_UNKNOWN:
+                return AudioSystem.STREAM_MUSIC;
+            default:
+                if (fromGetVolumeControlStream) {
+                    throw new IllegalArgumentException("Unknown usage value " + aa.getUsage() +
+                            " in audio attributes");
+                } else {
+                    return AudioSystem.STREAM_MUSIC;
+                }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static int capturePolicyToFlags(@CapturePolicy int capturePolicy, int flags) {
+        switch (capturePolicy) {
+            case ALLOW_CAPTURE_BY_NONE:
+                flags |= FLAG_NO_MEDIA_PROJECTION | FLAG_NO_SYSTEM_CAPTURE;
+                break;
+            case ALLOW_CAPTURE_BY_SYSTEM:
+                flags |= FLAG_NO_MEDIA_PROJECTION;
+                flags &= ~FLAG_NO_SYSTEM_CAPTURE;
+                break;
+            case ALLOW_CAPTURE_BY_ALL:
+                flags &= ~FLAG_NO_SYSTEM_CAPTURE & ~FLAG_NO_MEDIA_PROJECTION;
+                break;
+            default:
+                throw new IllegalArgumentException("Unknown allow playback capture policy");
+        }
+        return flags;
+    }
+
+    /** @hide */
+    @IntDef({
+            USAGE_CALL_ASSISTANT,
+            USAGE_EMERGENCY,
+            USAGE_SAFETY,
+            USAGE_VEHICLE_STATUS,
+            USAGE_ANNOUNCEMENT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AttributeSystemUsage {}
+
+    /** @hide */
+    @IntDef({
+            USAGE_UNKNOWN,
+            USAGE_MEDIA,
+            USAGE_VOICE_COMMUNICATION,
+            USAGE_VOICE_COMMUNICATION_SIGNALLING,
+            USAGE_ALARM,
+            USAGE_NOTIFICATION,
+            USAGE_NOTIFICATION_RINGTONE,
+            USAGE_NOTIFICATION_COMMUNICATION_REQUEST,
+            USAGE_NOTIFICATION_COMMUNICATION_INSTANT,
+            USAGE_NOTIFICATION_COMMUNICATION_DELAYED,
+            USAGE_NOTIFICATION_EVENT,
+            USAGE_ASSISTANCE_ACCESSIBILITY,
+            USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+            USAGE_ASSISTANCE_SONIFICATION,
+            USAGE_GAME,
+            USAGE_ASSISTANT,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AttributeSdkUsage {}
+
+    /** @hide */
+    @IntDef({
+        USAGE_UNKNOWN,
+        USAGE_MEDIA,
+        USAGE_VOICE_COMMUNICATION,
+        USAGE_VOICE_COMMUNICATION_SIGNALLING,
+        USAGE_ALARM,
+        USAGE_NOTIFICATION,
+        USAGE_NOTIFICATION_RINGTONE,
+        USAGE_NOTIFICATION_COMMUNICATION_REQUEST,
+        USAGE_NOTIFICATION_COMMUNICATION_INSTANT,
+        USAGE_NOTIFICATION_COMMUNICATION_DELAYED,
+        USAGE_NOTIFICATION_EVENT,
+        USAGE_ASSISTANCE_ACCESSIBILITY,
+        USAGE_ASSISTANCE_NAVIGATION_GUIDANCE,
+        USAGE_ASSISTANCE_SONIFICATION,
+        USAGE_GAME,
+        USAGE_ASSISTANT,
+        USAGE_CALL_ASSISTANT,
+        USAGE_EMERGENCY,
+        USAGE_SAFETY,
+        USAGE_VEHICLE_STATUS,
+        USAGE_ANNOUNCEMENT,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AttributeUsage {}
+
+    /** @hide */
+    @IntDef({
+        CONTENT_TYPE_UNKNOWN,
+        CONTENT_TYPE_SPEECH,
+        CONTENT_TYPE_MUSIC,
+        CONTENT_TYPE_MOVIE,
+        CONTENT_TYPE_SONIFICATION
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AttributeContentType {}
+}
diff --git a/android/media/AudioDescriptor.java b/android/media/AudioDescriptor.java
new file mode 100644
index 0000000..11371b1
--- /dev/null
+++ b/android/media/AudioDescriptor.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2021 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.annotation.IntDef;
+import android.annotation.NonNull;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * The AudioDescriptor contains the information to describe the audio playback/capture
+ * capabilities. The capabilities are described by a byte array, which is defined by a
+ * particular standard. This is used when the format is unrecognized to the platform.
+ */
+public class AudioDescriptor {
+    /**
+     * The audio standard is not specified.
+     */
+    public static final int STANDARD_NONE = 0;
+    /**
+     * The Extended Display Identification Data (EDID) standard for a short audio descriptor.
+     */
+    public static final int STANDARD_EDID = 1;
+
+    /** @hide */
+    @IntDef({
+            STANDARD_NONE,
+            STANDARD_EDID,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioDescriptorStandard {}
+
+    private final int mStandard;
+    private final byte[] mDescriptor;
+    private final int mEncapsulationType;
+
+    AudioDescriptor(int standard, int encapsulationType, @NonNull byte[] descriptor) {
+        mStandard = standard;
+        mEncapsulationType = encapsulationType;
+        mDescriptor = descriptor;
+    }
+
+    /**
+     * @return the standard that defines audio playback/capture capabilities.
+     */
+    public @AudioDescriptorStandard int getStandard() {
+        return mStandard;
+    }
+
+    /**
+     * @return a byte array that describes audio playback/capture capabilities as encoded by the
+     * standard for this AudioDescriptor.
+     */
+    public @NonNull byte[] getDescriptor() {
+        return mDescriptor;
+    }
+
+    /**
+     * The encapsulation type indicates what encapsulation type is required when the framework is
+     * using this extra audio descriptor for playing to a device exposing this audio profile.
+     * When encapsulation is required, only playback with {@link android.media.AudioTrack} API is
+     * supported. But playback with {@link android.media.MediaPlayer} is not.
+     * When an encapsulation type is required, the {@link AudioFormat} encoding selected when
+     * creating the {@link AudioTrack} must match the encapsulation type, e.g
+     * AudioFormat#ENCODING_IEC61937 for AudioProfile.AUDIO_ENCAPSULATION_TYPE_IEC61937.
+     *
+     * @return an integer representing the encapsulation type
+     *
+     * @see AudioProfile#AUDIO_ENCAPSULATION_TYPE_NONE
+     * @see AudioProfile#AUDIO_ENCAPSULATION_TYPE_IEC61937
+     */
+    public @AudioProfile.EncapsulationType int getEncapsulationType() {
+        return mEncapsulationType;
+    }
+}
diff --git a/android/media/AudioDeviceAttributes.java b/android/media/AudioDeviceAttributes.java
new file mode 100644
index 0000000..7caac89
--- /dev/null
+++ b/android/media/AudioDeviceAttributes.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright (C) 2019 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * @hide
+ * Class to represent the attributes of an audio device: its type (speaker, headset...), address
+ * (if known) and role (input, output).
+ * <p>Unlike {@link AudioDeviceInfo}, the device
+ * doesn't need to be connected to be uniquely identified, it can
+ * for instance represent a specific A2DP headset even after a
+ * disconnection, whereas the corresponding <code>AudioDeviceInfo</code>
+ * would then be invalid.
+ * <p>While creating / obtaining an instance is not protected by a
+ * permission, APIs using one rely on MODIFY_AUDIO_ROUTING.
+ */
+@SystemApi
+public final class AudioDeviceAttributes implements Parcelable {
+
+    /**
+     * A role identifying input devices, such as microphones.
+     */
+    public static final int ROLE_INPUT = AudioPort.ROLE_SOURCE;
+    /**
+     * A role identifying output devices, such as speakers or headphones.
+     */
+    public static final int ROLE_OUTPUT = AudioPort.ROLE_SINK;
+
+    /** @hide */
+    @IntDef(flag = false, prefix = "ROLE_", value = {
+            ROLE_INPUT, ROLE_OUTPUT }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Role {}
+
+    /**
+     * The audio device type, as defined in {@link AudioDeviceInfo}
+     */
+    private final @AudioDeviceInfo.AudioDeviceType int mType;
+    /**
+     * The unique address of the device. Some devices don't have addresses, only an empty string.
+     */
+    private final @NonNull String mAddress;
+
+    /**
+     * Is input or output device
+     */
+    private final @Role int mRole;
+
+    /**
+     * The internal audio device type
+     */
+    private final int mNativeType;
+
+    /**
+     * @hide
+     * Constructor from a valid {@link AudioDeviceInfo}
+     * @param deviceInfo the connected audio device from which to obtain the device-identifying
+     *                   type and address.
+     */
+    @SystemApi
+    public AudioDeviceAttributes(@NonNull AudioDeviceInfo deviceInfo) {
+        Objects.requireNonNull(deviceInfo);
+        mRole = deviceInfo.isSink() ? ROLE_OUTPUT : ROLE_INPUT;
+        mType = deviceInfo.getType();
+        mAddress = deviceInfo.getAddress();
+        mNativeType = deviceInfo.getInternalType();
+    }
+
+    /**
+     * @hide
+     * Constructor from role, device type and address
+     * @param role indicates input or output role
+     * @param type the device type, as defined in {@link AudioDeviceInfo}
+     * @param address the address of the device, or an empty string for devices without one
+     */
+    @SystemApi
+    public AudioDeviceAttributes(@Role int role, @AudioDeviceInfo.AudioDeviceType int type,
+                              @NonNull String address) {
+        Objects.requireNonNull(address);
+        if (role != ROLE_OUTPUT && role != ROLE_INPUT) {
+            throw new IllegalArgumentException("Invalid role " + role);
+        }
+        if (role == ROLE_OUTPUT) {
+            AudioDeviceInfo.enforceValidAudioDeviceTypeOut(type);
+            mNativeType = AudioDeviceInfo.convertDeviceTypeToInternalDevice(type);
+        } else if (role == ROLE_INPUT) {
+            AudioDeviceInfo.enforceValidAudioDeviceTypeIn(type);
+            mNativeType = AudioDeviceInfo.convertDeviceTypeToInternalInputDevice(type);
+        } else {
+            mNativeType = AudioSystem.DEVICE_NONE;
+        }
+
+        mRole = role;
+        mType = type;
+        mAddress = address;
+    }
+
+    /**
+     * @hide
+     * Constructor from internal device type and address
+     * @param type the internal device type, as defined in {@link AudioSystem}
+     * @param address the address of the device, or an empty string for devices without one
+     */
+    public AudioDeviceAttributes(int nativeType, @NonNull String address) {
+        mRole = (nativeType & AudioSystem.DEVICE_BIT_IN) != 0 ? ROLE_INPUT : ROLE_OUTPUT;
+        mType = AudioDeviceInfo.convertInternalDeviceToDeviceType(nativeType);
+        mAddress = address;
+        mNativeType = nativeType;
+    }
+
+    /**
+     * @hide
+     * Returns the role of a device
+     * @return the role
+     */
+    @SystemApi
+    public @Role int getRole() {
+        return mRole;
+    }
+
+    /**
+     * @hide
+     * Returns the audio device type of a device
+     * @return the type, as defined in {@link AudioDeviceInfo}
+     */
+    @SystemApi
+    public @AudioDeviceInfo.AudioDeviceType int getType() {
+        return mType;
+    }
+
+    /**
+     * @hide
+     * Returns the address of the audio device, or an empty string for devices without one
+     * @return the device address
+     */
+    @SystemApi
+    public @NonNull String getAddress() {
+        return mAddress;
+    }
+
+    /**
+     * @hide
+     * Returns the internal device type of a device
+     * @return the internal device type
+     */
+    public int getInternalType() {
+        return mNativeType;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mRole, mType, mAddress);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        AudioDeviceAttributes that = (AudioDeviceAttributes) o;
+        return ((mRole == that.mRole)
+                && (mType == that.mType)
+                && mAddress.equals(that.mAddress));
+    }
+
+    /** @hide */
+    public static String roleToString(@Role int role) {
+        return (role == ROLE_OUTPUT ? "output" : "input");
+    }
+
+    @Override
+    public String toString() {
+        return new String("AudioDeviceAttributes:"
+                + " role:" + roleToString(mRole)
+                + " type:" + (mRole == ROLE_OUTPUT ? AudioSystem.getOutputDeviceName(mNativeType)
+                        : AudioSystem.getInputDeviceName(mNativeType))
+                + " addr:" + mAddress);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mRole);
+        dest.writeInt(mType);
+        dest.writeString(mAddress);
+        dest.writeInt(mNativeType);
+    }
+
+    private AudioDeviceAttributes(@NonNull Parcel in) {
+        mRole = in.readInt();
+        mType = in.readInt();
+        mAddress = in.readString();
+        mNativeType = in.readInt();
+    }
+
+    public static final @NonNull Parcelable.Creator<AudioDeviceAttributes> CREATOR =
+            new Parcelable.Creator<AudioDeviceAttributes>() {
+        /**
+         * Rebuilds an AudioDeviceAttributes previously stored with writeToParcel().
+         * @param p Parcel object to read the AudioDeviceAttributes from
+         * @return a new AudioDeviceAttributes created from the data in the parcel
+         */
+        public AudioDeviceAttributes createFromParcel(Parcel p) {
+            return new AudioDeviceAttributes(p);
+        }
+
+        public AudioDeviceAttributes[] newArray(int size) {
+            return new AudioDeviceAttributes[size];
+        }
+    };
+}
diff --git a/android/media/AudioDeviceCallback.java b/android/media/AudioDeviceCallback.java
new file mode 100644
index 0000000..a5b1d24
--- /dev/null
+++ b/android/media/AudioDeviceCallback.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 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;
+
+/**
+ * AudioDeviceCallback defines the mechanism by which applications can receive notifications
+ * of audio device connection and disconnection events.
+ * @see AudioManager#registerAudioDeviceCallback(AudioDeviceCallback, android.os.Handler handler).
+ */
+public abstract class AudioDeviceCallback {
+    /**
+     * Called by the {@link AudioManager} to indicate that one or more audio devices have been
+     * connected.
+     * @param addedDevices  An array of {@link AudioDeviceInfo} objects corresponding to any
+     * newly added audio devices.
+     */
+    public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {}
+
+    /**
+     * Called by the {@link AudioManager} to indicate that one or more audio devices have been
+     * disconnected.
+     * @param removedDevices  An array of {@link AudioDeviceInfo} objects corresponding to any
+     * newly removed audio devices.
+     */
+    public void onAudioDevicesRemoved(AudioDeviceInfo[] removedDevices) {}
+}
diff --git a/android/media/AudioDeviceInfo.java b/android/media/AudioDeviceInfo.java
new file mode 100644
index 0000000..a186566
--- /dev/null
+++ b/android/media/AudioDeviceInfo.java
@@ -0,0 +1,720 @@
+/*
+ * Copyright (C) 2014 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.Manifest;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.TestApi;
+import android.util.SparseIntArray;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.Objects;
+import java.util.TreeSet;
+
+/**
+ * Provides information about an audio device.
+ */
+public final class AudioDeviceInfo {
+
+    /**
+     * A device type associated with an unknown or uninitialized device.
+     */
+    public static final int TYPE_UNKNOWN          = 0;
+    /**
+     * A device type describing the attached earphone speaker.
+     */
+    public static final int TYPE_BUILTIN_EARPIECE = 1;
+    /**
+     * A device type describing the speaker system (i.e. a mono speaker or stereo speakers) built
+     * in a device.
+     */
+    public static final int TYPE_BUILTIN_SPEAKER  = 2;
+    /**
+     * A device type describing a headset, which is the combination of a headphones and microphone.
+     */
+    public static final int TYPE_WIRED_HEADSET    = 3;
+    /**
+     * A device type describing a pair of wired headphones.
+     */
+    public static final int TYPE_WIRED_HEADPHONES = 4;
+    /**
+     * A device type describing an analog line-level connection.
+     */
+    public static final int TYPE_LINE_ANALOG      = 5;
+    /**
+     * A device type describing a digital line connection (e.g. SPDIF).
+     */
+    public static final int TYPE_LINE_DIGITAL     = 6;
+    /**
+     * A device type describing a Bluetooth device typically used for telephony.
+     */
+    public static final int TYPE_BLUETOOTH_SCO    = 7;
+    /**
+     * A device type describing a Bluetooth device supporting the A2DP profile.
+     */
+    public static final int TYPE_BLUETOOTH_A2DP   = 8;
+    /**
+     * A device type describing an HDMI connection .
+     */
+    public static final int TYPE_HDMI             = 9;
+    /**
+     * A device type describing the Audio Return Channel of an HDMI connection.
+     */
+    public static final int TYPE_HDMI_ARC         = 10;
+    /**
+     * A device type describing a USB audio device.
+     */
+    public static final int TYPE_USB_DEVICE       = 11;
+    /**
+     * A device type describing a USB audio device in accessory mode.
+     */
+    public static final int TYPE_USB_ACCESSORY    = 12;
+    /**
+     * A device type describing the audio device associated with a dock.
+     */
+    public static final int TYPE_DOCK             = 13;
+    /**
+     * A device type associated with the transmission of audio signals over FM.
+     */
+    public static final int TYPE_FM               = 14;
+    /**
+     * A device type describing the microphone(s) built in a device.
+     */
+    public static final int TYPE_BUILTIN_MIC      = 15;
+    /**
+     * A device type for accessing the audio content transmitted over FM.
+     */
+    public static final int TYPE_FM_TUNER         = 16;
+    /**
+     * A device type for accessing the audio content transmitted over the TV tuner system.
+     */
+    public static final int TYPE_TV_TUNER         = 17;
+    /**
+     * A device type describing the transmission of audio signals over the telephony network.
+     */
+    public static final int TYPE_TELEPHONY        = 18;
+    /**
+     * A device type describing the auxiliary line-level connectors.
+     */
+    public static final int TYPE_AUX_LINE         = 19;
+    /**
+     * A device type connected over IP.
+     */
+    public static final int TYPE_IP               = 20;
+    /**
+     * A type-agnostic device used for communication with external audio systems
+     */
+    public static final int TYPE_BUS              = 21;
+    /**
+     * A device type describing a USB audio headset.
+     */
+    public static final int TYPE_USB_HEADSET       = 22;
+    /**
+     * A device type describing a Hearing Aid.
+     */
+    public static final int TYPE_HEARING_AID   = 23;
+    /**
+     * A device type describing the speaker system (i.e. a mono speaker or stereo speakers) built
+     * in a device, that is specifically tuned for outputting sounds like notifications and alarms
+     * (i.e. sounds the user couldn't necessarily anticipate).
+     * <p>Note that this physical audio device may be the same as {@link #TYPE_BUILTIN_SPEAKER}
+     * but is driven differently to safely accommodate the different use case.</p>
+     */
+    public static final int TYPE_BUILTIN_SPEAKER_SAFE = 24;
+    /**
+     * A device type for rerouting audio within the Android framework between mixes and
+     * system applications.
+     * This type is for instance encountered when querying the output device of a track
+     * (with {@link AudioTrack#getRoutedDevice()} playing from a device in screen mirroring mode,
+     * where the audio is not heard on the device, but on the remote device.
+     */
+    // Typically created when using
+    // {@link android.media.audiopolicy.AudioPolicy} for mixes created with the
+    // {@link android.media.audiopolicy.AudioMix#ROUTE_FLAG_LOOP_BACK} flag.
+    public static final int TYPE_REMOTE_SUBMIX = 25;
+
+    /**
+     * A device type describing a Bluetooth Low Energy (BLE) audio headset or headphones.
+     * Headphones are grouped with headsets when the device is a sink:
+     * the features of headsets and headphones with regard to playback are the same.
+     */
+    public static final int TYPE_BLE_HEADSET   = 26;
+
+    /**
+     * A device type describing a Bluetooth Low Energy (BLE) audio speaker.
+     */
+    public static final int TYPE_BLE_SPEAKER   = 27;
+
+    /**
+     * A device type describing an Echo Canceller loopback Reference.
+     * This device is only used when capturing with MediaRecorder.AudioSource.ECHO_REFERENCE,
+     * which requires privileged permission
+     * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT}.
+     * @hide */
+    @RequiresPermission(Manifest.permission.CAPTURE_AUDIO_OUTPUT)
+    public static final int TYPE_ECHO_REFERENCE   = 28;
+
+    /**
+     * A device type describing the Enhanced Audio Return Channel of an HDMI connection.
+     */
+    public static final int TYPE_HDMI_EARC         = 29;
+
+    /** @hide */
+    @IntDef(flag = false, prefix = "TYPE", value = {
+            TYPE_BUILTIN_EARPIECE,
+            TYPE_BUILTIN_SPEAKER,
+            TYPE_WIRED_HEADSET,
+            TYPE_WIRED_HEADPHONES,
+            TYPE_BLUETOOTH_SCO,
+            TYPE_BLUETOOTH_A2DP,
+            TYPE_HDMI,
+            TYPE_DOCK,
+            TYPE_USB_ACCESSORY,
+            TYPE_USB_DEVICE,
+            TYPE_USB_HEADSET,
+            TYPE_TELEPHONY,
+            TYPE_LINE_ANALOG,
+            TYPE_HDMI_ARC,
+            TYPE_HDMI_EARC,
+            TYPE_LINE_DIGITAL,
+            TYPE_FM,
+            TYPE_AUX_LINE,
+            TYPE_IP,
+            TYPE_BUS,
+            TYPE_HEARING_AID,
+            TYPE_BUILTIN_MIC,
+            TYPE_FM_TUNER,
+            TYPE_TV_TUNER,
+            TYPE_BUILTIN_SPEAKER_SAFE,
+            TYPE_REMOTE_SUBMIX,
+            TYPE_BLE_HEADSET,
+            TYPE_BLE_SPEAKER,
+            TYPE_ECHO_REFERENCE}
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioDeviceType {}
+
+    /** @hide */
+    @IntDef(flag = false, prefix = "TYPE", value = {
+            TYPE_BUILTIN_MIC,
+            TYPE_BLUETOOTH_SCO,
+            TYPE_BLUETOOTH_A2DP,
+            TYPE_WIRED_HEADSET,
+            TYPE_HDMI,
+            TYPE_TELEPHONY,
+            TYPE_DOCK,
+            TYPE_USB_ACCESSORY,
+            TYPE_USB_DEVICE,
+            TYPE_USB_HEADSET,
+            TYPE_FM_TUNER,
+            TYPE_TV_TUNER,
+            TYPE_LINE_ANALOG,
+            TYPE_LINE_DIGITAL,
+            TYPE_IP,
+            TYPE_BUS,
+            TYPE_REMOTE_SUBMIX,
+            TYPE_BLE_HEADSET,
+            TYPE_HDMI_ARC,
+            TYPE_HDMI_EARC,
+            TYPE_ECHO_REFERENCE}
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioDeviceTypeIn {}
+
+    /** @hide */
+    @IntDef(flag = false, prefix = "TYPE", value = {
+            TYPE_BUILTIN_EARPIECE,
+            TYPE_BUILTIN_SPEAKER,
+            TYPE_WIRED_HEADSET,
+            TYPE_WIRED_HEADPHONES,
+            TYPE_BLUETOOTH_SCO,
+            TYPE_BLUETOOTH_A2DP,
+            TYPE_HDMI,
+            TYPE_DOCK,
+            TYPE_USB_ACCESSORY,
+            TYPE_USB_DEVICE,
+            TYPE_USB_HEADSET,
+            TYPE_TELEPHONY,
+            TYPE_LINE_ANALOG,
+            TYPE_HDMI_ARC,
+            TYPE_HDMI_EARC,
+            TYPE_LINE_DIGITAL,
+            TYPE_FM,
+            TYPE_AUX_LINE,
+            TYPE_IP,
+            TYPE_BUS,
+            TYPE_HEARING_AID,
+            TYPE_BUILTIN_SPEAKER_SAFE,
+            TYPE_BLE_HEADSET,
+            TYPE_BLE_SPEAKER}
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioDeviceTypeOut {}
+
+    /** @hide */
+    /*package*/ static boolean isValidAudioDeviceTypeOut(int type) {
+        switch (type) {
+            case TYPE_BUILTIN_EARPIECE:
+            case TYPE_BUILTIN_SPEAKER:
+            case TYPE_WIRED_HEADSET:
+            case TYPE_WIRED_HEADPHONES:
+            case TYPE_BLUETOOTH_SCO:
+            case TYPE_BLUETOOTH_A2DP:
+            case TYPE_HDMI:
+            case TYPE_DOCK:
+            case TYPE_USB_ACCESSORY:
+            case TYPE_USB_DEVICE:
+            case TYPE_USB_HEADSET:
+            case TYPE_TELEPHONY:
+            case TYPE_LINE_ANALOG:
+            case TYPE_HDMI_ARC:
+            case TYPE_HDMI_EARC:
+            case TYPE_LINE_DIGITAL:
+            case TYPE_FM:
+            case TYPE_AUX_LINE:
+            case TYPE_IP:
+            case TYPE_BUS:
+            case TYPE_HEARING_AID:
+            case TYPE_BUILTIN_SPEAKER_SAFE:
+            case TYPE_BLE_HEADSET:
+            case TYPE_BLE_SPEAKER:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /** @hide */
+    /*package*/ static boolean isValidAudioDeviceTypeIn(int type) {
+        switch (type) {
+            case TYPE_BUILTIN_MIC:
+            case TYPE_BLUETOOTH_SCO:
+            case TYPE_BLUETOOTH_A2DP:
+            case TYPE_WIRED_HEADSET:
+            case TYPE_HDMI:
+            case TYPE_TELEPHONY:
+            case TYPE_DOCK:
+            case TYPE_USB_ACCESSORY:
+            case TYPE_USB_DEVICE:
+            case TYPE_USB_HEADSET:
+            case TYPE_FM_TUNER:
+            case TYPE_TV_TUNER:
+            case TYPE_LINE_ANALOG:
+            case TYPE_LINE_DIGITAL:
+            case TYPE_IP:
+            case TYPE_BUS:
+            case TYPE_REMOTE_SUBMIX:
+            case TYPE_BLE_HEADSET:
+            case TYPE_HDMI_ARC:
+            case TYPE_HDMI_EARC:
+            case TYPE_ECHO_REFERENCE:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * @hide
+     * Enforces whether the audio device type is acceptable for output.
+     *
+     * A vendor implemented output type should modify isValidAudioDeviceTypeOut()
+     * appropriately to accept the new type.  Do not remove already acceptable types.
+     *
+     * @throws IllegalArgumentException on an invalid output device type.
+     * @param type
+     */
+    @TestApi
+    public static void enforceValidAudioDeviceTypeOut(int type) {
+        if (!isValidAudioDeviceTypeOut(type)) {
+            throw new IllegalArgumentException("Illegal output device type " + type);
+        }
+    }
+
+    /**
+     * @hide
+     * Enforces whether the audio device type is acceptable for input.
+     *
+     * A vendor implemented input type should modify isValidAudioDeviceTypeIn()
+     * appropriately to accept the new type.  Do not remove already acceptable types.
+     *
+     * @throws IllegalArgumentException on an invalid input device type.
+     * @param type
+     */
+    @TestApi
+    public static void enforceValidAudioDeviceTypeIn(int type) {
+        if (!isValidAudioDeviceTypeIn(type)) {
+            throw new IllegalArgumentException("Illegal input device type " + type);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        AudioDeviceInfo that = (AudioDeviceInfo) o;
+        return Objects.equals(getPort(), that.getPort());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(getPort());
+    }
+
+    private final AudioDevicePort mPort;
+
+    AudioDeviceInfo(AudioDevicePort port) {
+       mPort = port;
+    }
+
+    /**
+     * @hide
+     * @return The underlying {@link AudioDevicePort} instance.
+     */
+    public AudioDevicePort getPort() {
+        return mPort;
+    }
+
+    /**
+     * @hide
+     * @return the internal device type
+     */
+    public int getInternalType() {
+        return mPort.type();
+    }
+
+    /**
+     * @return The internal device ID.
+     */
+    public int getId() {
+        return mPort.handle().id();
+    }
+
+    /**
+     * @return The human-readable name of the audio device.
+     */
+    public CharSequence getProductName() {
+        String portName = mPort.name();
+        return portName.length() != 0 ? portName : android.os.Build.MODEL;
+    }
+
+    /**
+     * @return The "address" string of the device. This generally contains device-specific
+     * parameters.
+     */
+    public @NonNull String getAddress() {
+        return mPort.address();
+    }
+
+   /**
+     * @return true if the audio device is a source for audio data (e.e an input).
+     */
+    public boolean isSource() {
+        return mPort.role() == AudioPort.ROLE_SOURCE;
+    }
+
+    /**
+     * @return true if the audio device is a sink for audio data (i.e. an output).
+     */
+    public boolean isSink() {
+        return mPort.role() == AudioPort.ROLE_SINK;
+    }
+
+    /**
+     * @return An array of sample rates supported by the audio device.
+     *
+     * Note: an empty array indicates that the device supports arbitrary rates.
+     */
+    public @NonNull int[] getSampleRates() {
+        return mPort.samplingRates();
+    }
+
+    /**
+     * @return An array of channel position masks (e.g. {@link AudioFormat#CHANNEL_IN_STEREO},
+     * {@link AudioFormat#CHANNEL_OUT_7POINT1}) for which this audio device can be configured.
+     *
+     * @see AudioFormat
+     *
+     * Note: an empty array indicates that the device supports arbitrary channel masks.
+     */
+    public @NonNull int[] getChannelMasks() {
+        return mPort.channelMasks();
+    }
+
+    /**
+     * @return An array of channel index masks for which this audio device can be configured.
+     *
+     * @see AudioFormat
+     *
+     * Note: an empty array indicates that the device supports arbitrary channel index masks.
+     */
+    public @NonNull int[] getChannelIndexMasks() {
+        return mPort.channelIndexMasks();
+    }
+
+    /**
+     * @return An array of channel counts (1, 2, 4, ...) for which this audio device
+     * can be configured.
+     *
+     * Note: an empty array indicates that the device supports arbitrary channel counts.
+     */
+    public @NonNull int[] getChannelCounts() {
+        TreeSet<Integer> countSet = new TreeSet<Integer>();
+
+        // Channel Masks
+        for (int mask : getChannelMasks()) {
+            countSet.add(isSink() ?
+                    AudioFormat.channelCountFromOutChannelMask(mask)
+                    : AudioFormat.channelCountFromInChannelMask(mask));
+        }
+
+        // Index Masks
+        for (int index_mask : getChannelIndexMasks()) {
+            countSet.add(Integer.bitCount(index_mask));
+        }
+
+        int[] counts = new int[countSet.size()];
+        int index = 0;
+        for (int count : countSet) {
+            counts[index++] = count; 
+        }
+        return counts;
+    }
+
+    /**
+     * @return An array of audio encodings (e.g. {@link AudioFormat#ENCODING_PCM_16BIT},
+     * {@link AudioFormat#ENCODING_PCM_FLOAT}) supported by the audio device.
+     * <code>ENCODING_PCM_FLOAT</code> indicates the device supports more
+     * than 16 bits of integer precision.  As there is no AudioFormat constant
+     * specifically defined for 24-bit PCM, the value <code>ENCODING_PCM_FLOAT</code>
+     * indicates that {@link AudioTrack} or {@link AudioRecord} can preserve at least 24 bits of
+     * integer precision to that device.
+     *
+     * @see AudioFormat
+     *
+     * Note: an empty array indicates that the device supports arbitrary encodings.
+     * For forward compatibility, applications should ignore entries it does not recognize.
+     */
+    public @NonNull int[] getEncodings() {
+        return AudioFormat.filterPublicFormats(mPort.formats());
+    }
+
+    /**
+     * @return A list of {@link AudioProfile} supported by the audio devices.
+     */
+    public @NonNull List<AudioProfile> getAudioProfiles() {
+        return mPort.profiles();
+    }
+
+    /**
+     * @return A list of {@link AudioDescriptor} supported by the audio devices.
+     */
+    public @NonNull List<AudioDescriptor> getAudioDescriptors() {
+        return mPort.audioDescriptors();
+    }
+
+    /**
+     * Returns an array of supported encapsulation modes for the device.
+     *
+     * The array can include any of the {@code AudioTrack} encapsulation modes,
+     * e.g. {@link AudioTrack#ENCAPSULATION_MODE_ELEMENTARY_STREAM}.
+     *
+     * @return An array of supported encapsulation modes for the device.  This
+     *     may be an empty array if no encapsulation modes are supported.
+     */
+    public @NonNull @AudioTrack.EncapsulationMode int[] getEncapsulationModes() {
+        return mPort.encapsulationModes();
+    }
+
+    /**
+     * Returns an array of supported encapsulation metadata types for the device.
+     *
+     * The metadata type returned should be allowed for all encapsulation modes supported
+     * by the device.  Some metadata types may apply only to certain
+     * compressed stream formats, the returned list is the union of subsets.
+     *
+     * The array can include any of
+     * {@link AudioTrack#ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER},
+     * {@link AudioTrack#ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR}.
+     *
+     * @return An array of supported encapsulation metadata types for the device.  This
+     *     may be an empty array if no metadata types are supported.
+     */
+    public @NonNull @AudioTrack.EncapsulationMetadataType int[] getEncapsulationMetadataTypes() {
+        return mPort.encapsulationMetadataTypes();
+    }
+
+   /**
+     * @return The device type identifier of the audio device (i.e. TYPE_BUILTIN_SPEAKER).
+     */
+    public int getType() {
+        return INT_TO_EXT_DEVICE_MAPPING.get(mPort.type(), TYPE_UNKNOWN);
+    }
+
+    /** @hide */
+    public static int convertDeviceTypeToInternalDevice(int deviceType) {
+        return EXT_TO_INT_DEVICE_MAPPING.get(deviceType, AudioSystem.DEVICE_NONE);
+    }
+
+    /** @hide */
+    public static int convertInternalDeviceToDeviceType(int intDevice) {
+        return INT_TO_EXT_DEVICE_MAPPING.get(intDevice, TYPE_UNKNOWN);
+    }
+
+    /** @hide */
+    public static int convertDeviceTypeToInternalInputDevice(int deviceType) {
+        return EXT_TO_INT_INPUT_DEVICE_MAPPING.get(deviceType, AudioSystem.DEVICE_NONE);
+    }
+
+    private static final SparseIntArray INT_TO_EXT_DEVICE_MAPPING;
+
+    private static final SparseIntArray EXT_TO_INT_DEVICE_MAPPING;
+
+    /**
+     * EXT_TO_INT_INPUT_DEVICE_MAPPING aims at mapping external device type to internal input device
+     * type.
+     */
+    private static final SparseIntArray EXT_TO_INT_INPUT_DEVICE_MAPPING;
+
+    static {
+        INT_TO_EXT_DEVICE_MAPPING = new SparseIntArray();
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_EARPIECE, TYPE_BUILTIN_EARPIECE);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPEAKER, TYPE_BUILTIN_SPEAKER);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_WIRED_HEADSET, TYPE_WIRED_HEADSET);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, TYPE_WIRED_HEADPHONES);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, TYPE_BLUETOOTH_SCO);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT, TYPE_BLUETOOTH_SCO);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, TYPE_BLUETOOTH_A2DP);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, TYPE_BLUETOOTH_A2DP);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, TYPE_BLUETOOTH_A2DP);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI, TYPE_HDMI);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, TYPE_DOCK);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, TYPE_DOCK);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_ACCESSORY, TYPE_USB_ACCESSORY);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_DEVICE, TYPE_USB_DEVICE);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_HEADSET, TYPE_USB_HEADSET);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_TELEPHONY_TX, TYPE_TELEPHONY);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_LINE, TYPE_LINE_ANALOG);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI_ARC, TYPE_HDMI_ARC);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI_EARC, TYPE_HDMI_EARC);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPDIF, TYPE_LINE_DIGITAL);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_FM, TYPE_FM);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_AUX_LINE, TYPE_AUX_LINE);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_IP, TYPE_IP);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BUS, TYPE_BUS);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HEARING_AID, TYPE_HEARING_AID);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPEAKER_SAFE,
+                TYPE_BUILTIN_SPEAKER_SAFE);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_REMOTE_SUBMIX, TYPE_REMOTE_SUBMIX);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLE_HEADSET, TYPE_BLE_HEADSET);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLE_SPEAKER, TYPE_BLE_SPEAKER);
+
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUILTIN_MIC, TYPE_BUILTIN_MIC);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_WIRED_HEADSET, TYPE_WIRED_HEADSET);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_HDMI, TYPE_HDMI);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_TELEPHONY_RX, TYPE_TELEPHONY);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BACK_MIC, TYPE_BUILTIN_MIC);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET, TYPE_DOCK);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET, TYPE_DOCK);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_ACCESSORY, TYPE_USB_ACCESSORY);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_DEVICE, TYPE_USB_DEVICE);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_HEADSET, TYPE_USB_HEADSET);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_FM_TUNER, TYPE_FM_TUNER);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_TV_TUNER, TYPE_TV_TUNER);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_LINE, TYPE_LINE_ANALOG);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_SPDIF, TYPE_LINE_DIGITAL);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, TYPE_BLUETOOTH_A2DP);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_IP, TYPE_IP);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUS, TYPE_BUS);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_REMOTE_SUBMIX, TYPE_REMOTE_SUBMIX);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLE_HEADSET, TYPE_BLE_HEADSET);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_HDMI_ARC, TYPE_HDMI_ARC);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_HDMI_EARC, TYPE_HDMI_EARC);
+        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_ECHO_REFERENCE, TYPE_ECHO_REFERENCE);
+
+
+        // privileges mapping to output device
+        EXT_TO_INT_DEVICE_MAPPING = new SparseIntArray();
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_EARPIECE, AudioSystem.DEVICE_OUT_EARPIECE);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_SPEAKER, AudioSystem.DEVICE_OUT_SPEAKER);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_WIRED_HEADSET, AudioSystem.DEVICE_OUT_WIRED_HEADSET);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_WIRED_HEADPHONES, AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_LINE_ANALOG, AudioSystem.DEVICE_OUT_LINE);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_LINE_DIGITAL, AudioSystem.DEVICE_OUT_SPDIF);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLUETOOTH_SCO, AudioSystem.DEVICE_OUT_BLUETOOTH_SCO);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLUETOOTH_A2DP, AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HDMI, AudioSystem.DEVICE_OUT_HDMI);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HDMI_ARC, AudioSystem.DEVICE_OUT_HDMI_ARC);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HDMI_EARC, AudioSystem.DEVICE_OUT_HDMI_EARC);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_DEVICE, AudioSystem.DEVICE_OUT_USB_DEVICE);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_HEADSET, AudioSystem.DEVICE_OUT_USB_HEADSET);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_ACCESSORY, AudioSystem.DEVICE_OUT_USB_ACCESSORY);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_FM, AudioSystem.DEVICE_OUT_FM);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_MIC, AudioSystem.DEVICE_IN_BUILTIN_MIC);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_FM_TUNER, AudioSystem.DEVICE_IN_FM_TUNER);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_TV_TUNER, AudioSystem.DEVICE_IN_TV_TUNER);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_TELEPHONY, AudioSystem.DEVICE_OUT_TELEPHONY_TX);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_AUX_LINE, AudioSystem.DEVICE_OUT_AUX_LINE);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_IP, AudioSystem.DEVICE_OUT_IP);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUS, AudioSystem.DEVICE_OUT_BUS);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HEARING_AID, AudioSystem.DEVICE_OUT_HEARING_AID);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_SPEAKER_SAFE,
+                AudioSystem.DEVICE_OUT_SPEAKER_SAFE);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_REMOTE_SUBMIX, AudioSystem.DEVICE_OUT_REMOTE_SUBMIX);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_HEADSET, AudioSystem.DEVICE_OUT_BLE_HEADSET);
+        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLE_SPEAKER, AudioSystem.DEVICE_OUT_BLE_SPEAKER);
+
+        // privileges mapping to input device
+        EXT_TO_INT_INPUT_DEVICE_MAPPING = new SparseIntArray();
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_BUILTIN_MIC, AudioSystem.DEVICE_IN_BUILTIN_MIC);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+                TYPE_BLUETOOTH_SCO, AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+                TYPE_WIRED_HEADSET, AudioSystem.DEVICE_IN_WIRED_HEADSET);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_HDMI, AudioSystem.DEVICE_IN_HDMI);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_TELEPHONY, AudioSystem.DEVICE_IN_TELEPHONY_RX);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+                TYPE_USB_ACCESSORY, AudioSystem.DEVICE_IN_USB_ACCESSORY);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_USB_DEVICE, AudioSystem.DEVICE_IN_USB_DEVICE);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_USB_HEADSET, AudioSystem.DEVICE_IN_USB_HEADSET);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_FM_TUNER, AudioSystem.DEVICE_IN_FM_TUNER);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_TV_TUNER, AudioSystem.DEVICE_IN_TV_TUNER);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_LINE_ANALOG, AudioSystem.DEVICE_IN_LINE);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_LINE_DIGITAL, AudioSystem.DEVICE_IN_SPDIF);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+                TYPE_BLUETOOTH_A2DP, AudioSystem.DEVICE_IN_BLUETOOTH_A2DP);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_IP, AudioSystem.DEVICE_IN_IP);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_BUS, AudioSystem.DEVICE_IN_BUS);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+                TYPE_REMOTE_SUBMIX, AudioSystem.DEVICE_IN_REMOTE_SUBMIX);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_BLE_HEADSET, AudioSystem.DEVICE_IN_BLE_HEADSET);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_HDMI_ARC, AudioSystem.DEVICE_IN_HDMI_ARC);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(TYPE_HDMI_EARC, AudioSystem.DEVICE_IN_HDMI_EARC);
+        EXT_TO_INT_INPUT_DEVICE_MAPPING.put(
+                TYPE_ECHO_REFERENCE, AudioSystem.DEVICE_IN_ECHO_REFERENCE);
+
+    }
+}
+
diff --git a/android/media/AudioDevicePort.java b/android/media/AudioDevicePort.java
new file mode 100644
index 0000000..ebe0882
--- /dev/null
+++ b/android/media/AudioDevicePort.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright (C) 2014 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.annotation.NonNull;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * The AudioDevicePort is a specialized type of AudioPort
+ * describing an input (e.g microphone) or output device (e.g speaker)
+ * of the system.
+ * An AudioDevicePort is an AudioPort controlled by the audio HAL, almost always a physical
+ * device at the boundary of the audio system.
+ * In addition to base audio port attributes, the device descriptor contains:
+ * - the device type (e.g AudioManager.DEVICE_OUT_SPEAKER)
+ * - the device address (e.g MAC adddress for AD2P sink).
+ * @see AudioPort
+ * @hide
+ */
+
+public class AudioDevicePort extends AudioPort {
+
+    private final int mType;
+    private final String mAddress;
+    private final int[] mEncapsulationModes;
+    private final int[] mEncapsulationMetadataTypes;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    AudioDevicePort(AudioHandle handle, String deviceName,
+            int[] samplingRates, int[] channelMasks, int[] channelIndexMasks,
+            int[] formats, AudioGain[] gains, int type, String address, int[] encapsulationModes,
+            @AudioTrack.EncapsulationMetadataType int[] encapsulationMetadataTypes) {
+        super(handle,
+             (AudioManager.isInputDevice(type) == true)  ?
+                        AudioPort.ROLE_SOURCE : AudioPort.ROLE_SINK,
+             deviceName, samplingRates, channelMasks, channelIndexMasks, formats, gains);
+        mType = type;
+        mAddress = address;
+        mEncapsulationModes = encapsulationModes;
+        mEncapsulationMetadataTypes = encapsulationMetadataTypes;
+    }
+
+    AudioDevicePort(AudioHandle handle, String deviceName, List<AudioProfile> profiles,
+            AudioGain[] gains, int type, String address, int[] encapsulationModes,
+            @AudioTrack.EncapsulationMetadataType int[] encapsulationMetadataTypes,
+            List<AudioDescriptor> descriptors) {
+        super(handle,
+                AudioManager.isInputDevice(type) ? AudioPort.ROLE_SOURCE : AudioPort.ROLE_SINK,
+                deviceName, profiles, gains, descriptors);
+        mType = type;
+        mAddress = address;
+        mEncapsulationModes = encapsulationModes;
+        mEncapsulationMetadataTypes = encapsulationMetadataTypes;
+    }
+
+    /**
+     * Get the device type (e.g AudioManager.DEVICE_OUT_SPEAKER)
+     */
+    @UnsupportedAppUsage
+    public int type() {
+        return mType;
+    }
+
+    /**
+     * Get the device address. Address format varies with the device type.
+     * - USB devices ({@link AudioManager#DEVICE_OUT_USB_DEVICE},
+     * {@link AudioManager#DEVICE_IN_USB_DEVICE}) use an address composed of the ALSA card number
+     * and device number: "card=2;device=1"
+     * - Bluetooth devices ({@link AudioManager#DEVICE_OUT_BLUETOOTH_SCO},
+     * {@link AudioManager#DEVICE_OUT_BLUETOOTH_SCO},
+     * {@link AudioManager#DEVICE_OUT_BLUETOOTH_A2DP}),
+     * {@link AudioManager#DEVICE_OUT_BLE_HEADSET}, {@link AudioManager#DEVICE_OUT_BLE_SPEAKER})
+     * use the MAC address of the bluetooth device in the form "00:11:22:AA:BB:CC" as reported by
+     * {@link BluetoothDevice#getAddress()}.
+     * - Deivces that do not have an address will indicate an empty string "".
+     */
+    public String address() {
+        return mAddress;
+    }
+
+    /**
+     * Get supported encapsulation modes.
+     */
+    public @NonNull @AudioTrack.EncapsulationMode int[] encapsulationModes() {
+        if (mEncapsulationModes == null) {
+            return new int[0];
+        }
+        return Arrays.stream(mEncapsulationModes).boxed()
+                .filter(mode -> mode != AudioTrack.ENCAPSULATION_MODE_HANDLE)
+                .mapToInt(Integer::intValue).toArray();
+    }
+
+    /**
+     * Get supported encapsulation metadata types.
+     */
+    public @NonNull @AudioTrack.EncapsulationMetadataType int[] encapsulationMetadataTypes() {
+        if (mEncapsulationMetadataTypes == null) {
+            return new int[0];
+        }
+        int[] encapsulationMetadataTypes = new int[mEncapsulationMetadataTypes.length];
+        System.arraycopy(mEncapsulationMetadataTypes, 0,
+                         encapsulationMetadataTypes, 0, mEncapsulationMetadataTypes.length);
+        return encapsulationMetadataTypes;
+    }
+
+    /**
+     * Build a specific configuration of this audio device port for use by methods
+     * like AudioManager.connectAudioPatch().
+     */
+    public AudioDevicePortConfig buildConfig(int samplingRate, int channelMask, int format,
+                                          AudioGainConfig gain) {
+        return new AudioDevicePortConfig(this, samplingRate, channelMask, format, gain);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || !(o instanceof AudioDevicePort)) {
+            return false;
+        }
+        AudioDevicePort other = (AudioDevicePort)o;
+        if (mType != other.type()) {
+            return false;
+        }
+        if (mAddress == null && other.address() != null) {
+            return false;
+        }
+        if (!mAddress.equals(other.address())) {
+            return false;
+        }
+        return super.equals(o);
+    }
+
+    @Override
+    public String toString() {
+        String type = (mRole == ROLE_SOURCE ?
+                            AudioSystem.getInputDeviceName(mType) :
+                            AudioSystem.getOutputDeviceName(mType));
+        return "{" + super.toString()
+                + ", mType: " + type
+                + ", mAddress: " + mAddress
+                + "}";
+    }
+}
diff --git a/android/media/AudioDevicePortConfig.java b/android/media/AudioDevicePortConfig.java
new file mode 100644
index 0000000..69fd82b
--- /dev/null
+++ b/android/media/AudioDevicePortConfig.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2014 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.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+
+/**
+ * An AudioDevicePortConfig describes a possible configuration of an output or input device
+ * (speaker, headphone, microphone ...).
+ * It is used to specify a sink or source when creating a connection with
+ * AudioManager.connectAudioPatch().
+ * An AudioDevicePortConfig is obtained from AudioDevicePort.buildConfig().
+ * @hide
+ */
+
+public class AudioDevicePortConfig extends AudioPortConfig {
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    AudioDevicePortConfig(AudioDevicePort devicePort, int samplingRate, int channelMask,
+            int format, AudioGainConfig gain) {
+        super((AudioPort)devicePort, samplingRate, channelMask, format, gain);
+    }
+
+    AudioDevicePortConfig(AudioDevicePortConfig config) {
+        this(config.port(), config.samplingRate(), config.channelMask(), config.format(),
+                config.gain());
+    }
+
+    /**
+     * Returns the audio device port this AudioDevicePortConfig is issued from.
+     */
+    public AudioDevicePort port() {
+        return (AudioDevicePort)mPort;
+    }
+}
+
diff --git a/android/media/AudioFocusInfo.java b/android/media/AudioFocusInfo.java
new file mode 100644
index 0000000..3647b6e
--- /dev/null
+++ b/android/media/AudioFocusInfo.java
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2014 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * @hide
+ * A class to encapsulate information about an audio focus owner or request.
+ */
+@SystemApi
+public final class AudioFocusInfo implements Parcelable {
+
+    private final @NonNull AudioAttributes mAttributes;
+    private final int mClientUid;
+    private final @NonNull String mClientId;
+    private final @NonNull String mPackageName;
+    private final int mSdkTarget;
+    private int mGainRequest;
+    private int mLossReceived;
+    private int mFlags;
+
+    // generation count for the validity of a request/response async exchange between
+    // external focus policy and MediaFocusControl
+    private long mGenCount = -1;
+
+
+    /**
+     * Class constructor
+     * @param aa
+     * @param clientId
+     * @param packageName
+     * @param gainRequest
+     * @param lossReceived
+     * @param flags
+     * @hide
+     */
+    public AudioFocusInfo(AudioAttributes aa, int clientUid, String clientId, String packageName,
+            int gainRequest, int lossReceived, int flags, int sdk) {
+        mAttributes = aa == null ? new AudioAttributes.Builder().build() : aa;
+        mClientUid = clientUid;
+        mClientId = clientId == null ? "" : clientId;
+        mPackageName = packageName == null ? "" : packageName;
+        mGainRequest = gainRequest;
+        mLossReceived = lossReceived;
+        mFlags = flags;
+        mSdkTarget = sdk;
+    }
+
+    /** @hide */
+    public void setGen(long g) {
+        mGenCount = g;
+    }
+
+    /** @hide */
+    public long getGen() {
+        return mGenCount;
+    }
+
+
+    /**
+     * The audio attributes for the audio focus request.
+     * @return non-null {@link AudioAttributes}.
+     */
+    public @NonNull AudioAttributes getAttributes() {
+        return mAttributes;
+    }
+
+    public int getClientUid() {
+        return mClientUid;
+    }
+
+    public @NonNull String getClientId() {
+        return mClientId;
+    }
+
+    public @NonNull String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * The type of audio focus gain request.
+     * @return one of {@link AudioManager#AUDIOFOCUS_GAIN},
+     *     {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT},
+     *     {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK},
+     *     {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}.
+     */
+    public int getGainRequest() { return mGainRequest; }
+
+    /**
+     * The type of audio focus loss that was received by the
+     * {@link AudioManager.OnAudioFocusChangeListener} if one was set.
+     * @return 0 if focus wasn't lost, or one of {@link AudioManager#AUDIOFOCUS_LOSS},
+     *   {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT} or
+     *   {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}.
+     */
+    public int getLossReceived() { return mLossReceived; }
+
+    /** @hide */
+    public int getSdkTarget() { return mSdkTarget; }
+
+    /** @hide */
+    public void clearLossReceived() { mLossReceived = 0; }
+
+    /**
+     * The flags set in the audio focus request.
+     * @return 0 or a combination of {link AudioManager#AUDIOFOCUS_FLAG_DELAY_OK},
+     *     {@link AudioManager#AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS}, and
+     *     {@link AudioManager#AUDIOFOCUS_FLAG_LOCK}.
+     */
+    public int getFlags() { return mFlags; }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        mAttributes.writeToParcel(dest, flags);
+        dest.writeInt(mClientUid);
+        dest.writeString(mClientId);
+        dest.writeString(mPackageName);
+        dest.writeInt(mGainRequest);
+        dest.writeInt(mLossReceived);
+        dest.writeInt(mFlags);
+        dest.writeInt(mSdkTarget);
+        dest.writeLong(mGenCount);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mAttributes, mClientUid, mClientId, mPackageName, mGainRequest, mFlags);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        AudioFocusInfo other = (AudioFocusInfo) obj;
+        if (!mAttributes.equals(other.mAttributes)) {
+            return false;
+        }
+        if (mClientUid != other.mClientUid) {
+            return false;
+        }
+        if (!mClientId.equals(other.mClientId)) {
+            return false;
+        }
+        if (!mPackageName.equals(other.mPackageName)) {
+            return false;
+        }
+        if (mGainRequest != other.mGainRequest) {
+            return false;
+        }
+        if (mLossReceived != other.mLossReceived) {
+            return false;
+        }
+        if (mFlags != other.mFlags) {
+            return false;
+        }
+        if (mSdkTarget != other.mSdkTarget) {
+            return false;
+        }
+        // mGenCount is not used to verify equality between two focus holds as multiple requests
+        // (hence of different generations) could correspond to the same hold
+        return true;
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<AudioFocusInfo> CREATOR
+            = new Parcelable.Creator<AudioFocusInfo>() {
+
+        public AudioFocusInfo createFromParcel(Parcel in) {
+            final AudioFocusInfo afi = new AudioFocusInfo(
+                    AudioAttributes.CREATOR.createFromParcel(in), //AudioAttributes aa
+                    in.readInt(), // int clientUid
+                    in.readString(), //String clientId
+                    in.readString(), //String packageName
+                    in.readInt(), //int gainRequest
+                    in.readInt(), //int lossReceived
+                    in.readInt(), //int flags
+                    in.readInt()  //int sdkTarget
+                    );
+            afi.setGen(in.readLong());
+            return afi;
+        }
+
+        public AudioFocusInfo[] newArray(int size) {
+            return new AudioFocusInfo[size];
+        }
+    };
+}
diff --git a/android/media/AudioFocusRequest.java b/android/media/AudioFocusRequest.java
new file mode 100644
index 0000000..4c0850b
--- /dev/null
+++ b/android/media/AudioFocusRequest.java
@@ -0,0 +1,584 @@
+/*
+ * Copyright (C) 2017 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.media.AudioManager.OnAudioFocusChangeListener;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+
+/**
+ * A class to encapsulate information about an audio focus request.
+ * An {@code AudioFocusRequest} instance is built by {@link Builder}, and is used to
+ * request and abandon audio focus, respectively
+ * with {@link AudioManager#requestAudioFocus(AudioFocusRequest)} and
+ * {@link AudioManager#abandonAudioFocusRequest(AudioFocusRequest)}.
+ *
+ * <h3>What is audio focus?</h3>
+ * <p>Audio focus is a concept introduced in API 8. It is used to convey the fact that a user can
+ * only focus on a single audio stream at a time, e.g. listening to music or a podcast, but not
+ * both at the same time. In some cases, multiple audio streams can be playing at the same time,
+ * but there is only one the user would really listen to (focus on), while the other plays in
+ * the background. An example of this is driving directions being spoken while music plays at
+ * a reduced volume (a.k.a. ducking).
+ * <p>When an application requests audio focus, it expresses its intention to “own” audio focus to
+ * play audio. Let’s review the different types of focus requests, the return value after a request,
+ * and the responses to a loss.
+ * <p class="note">Note: applications should not play anything until granted focus.</p>
+ *
+ * <h3>The different types of focus requests</h3>
+ * <p>There are four focus request types. A successful focus request with each will yield different
+ * behaviors by the system and the other application that previously held audio focus.
+ * <ul>
+ * <li>{@link AudioManager#AUDIOFOCUS_GAIN} expresses the fact that your application is now the
+ * sole source of audio that the user is listening to. The duration of the audio playback is
+ * unknown, and is possibly very long: after the user finishes interacting with your application,
+ * (s)he doesn’t expect another audio stream to resume. Examples of uses of this focus gain are
+ * for music playback, for a game or a video player.</li>
+ *
+ * <li>{@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT} is for a situation when you know your
+ * application is temporarily grabbing focus from the current owner, but the user expects playback
+ * to go back to where it was once your application no longer requires audio focus. An example is
+ * for playing an alarm, or during a VoIP call. The playback is known to be finite: the alarm will
+ * time-out or be dismissed, the VoIP call has a beginning and an end. When any of those events
+ * ends, and if the user was listening to music when it started, the user expects music to resume,
+ * but didn’t wish to listen to both at the same time.</li>
+ *
+ * <li>{@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}: this focus request type is similar
+ * to {@code AUDIOFOCUS_GAIN_TRANSIENT} for the temporary aspect of the focus request, but it also
+ * expresses the fact during the time you own focus, you allow another application to keep playing
+ * at a reduced volume, “ducked”. Examples are when playing driving directions or notifications,
+ * it’s ok for music to keep playing, but not loud enough that it would prevent the directions to
+ * be hard to understand. A typical attenuation by the “ducked” application is a factor of 0.2f
+ * (or -14dB), that can for instance be applied with {@code MediaPlayer.setVolume(0.2f)} when
+ * using this class for playback.</li>
+ *
+ * <li>{@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} is also for a temporary request,
+ * but also expresses that your application expects the device to not play anything else. This is
+ * typically used if you are doing audio recording or speech recognition, and don’t want for
+ * examples notifications to be played by the system during that time.</li>
+ * </ul>
+ *
+ * <p>An {@code AudioFocusRequest} instance always contains one of the four types of requests
+ * explained above. It is passed when building an {@code AudioFocusRequest} instance with its
+ * builder in the {@link Builder} constructor
+ * {@link AudioFocusRequest.Builder#Builder(int)}, or
+ * with {@link AudioFocusRequest.Builder#setFocusGain(int)} after copying an existing instance with
+ * {@link AudioFocusRequest.Builder#Builder(AudioFocusRequest)}.
+ *
+ * <h3>Qualifying your focus request</h3>
+ * <h4>Use case requiring a focus request</h4>
+ * <p>Any focus request is qualified by the {@link AudioAttributes}
+ * (see {@link Builder#setAudioAttributes(AudioAttributes)}) that describe the audio use case that
+ * will follow the request (once it's successful or granted). It is recommended to use the
+ * same {@code AudioAttributes} for the request as the attributes you are using for audio/media
+ * playback.
+ * <br>If no attributes are set, default attributes of {@link AudioAttributes#USAGE_MEDIA} are used.
+ *
+ * <h4>Delayed focus</h4>
+ * <p>Audio focus can be "locked" by the system for a number of reasons: during a phone call, when
+ * the car to which the device is connected plays an emergency message... To support these
+ * situations, the application can request to be notified when its request is fulfilled, by flagging
+ * its request as accepting delayed focus, with {@link Builder#setAcceptsDelayedFocusGain(boolean)}.
+ * <br>If focus is requested while being locked by the system,
+ * {@link AudioManager#requestAudioFocus(AudioFocusRequest)} will return
+ * {@link AudioManager#AUDIOFOCUS_REQUEST_DELAYED}. When focus isn't locked anymore, the focus
+ * listener set with {@link Builder#setOnAudioFocusChangeListener(OnAudioFocusChangeListener)}
+ * or with {@link Builder#setOnAudioFocusChangeListener(OnAudioFocusChangeListener, Handler)} will
+ * be called to notify the application it now owns audio focus.
+ *
+ * <h4>Pausing vs ducking</h4>
+ * <p>When an application requested audio focus with
+ * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, the system will duck the current focus
+ * owner.
+ * <p class="note">Note: this behavior is <b>new for Android O</b>, whereas applications targeting
+ * SDK level up to API 25 had to implement the ducking themselves when they received a focus
+ * loss of {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}.
+ * <p>But ducking is not always the behavior expected by the user. A typical example is when the
+ * device plays driving directions while the user is listening to an audio book or podcast, and
+ * expects the audio playback to pause, instead of duck, as it is hard to understand a navigation
+ * prompt and spoken content at the same time. Therefore the system will not automatically duck
+ * when it detects it would be ducking spoken content: such content is detected when the
+ * {@code AudioAttributes} of the player are qualified by
+ * {@link AudioAttributes#CONTENT_TYPE_SPEECH}. Refer for instance to
+ * {@link AudioAttributes.Builder#setContentType(int)} and
+ * {@link MediaPlayer#setAudioAttributes(AudioAttributes)} if you are writing a media playback
+ * application for audio book, podcasts... Since the system will not automatically duck applications
+ * that play speech, it calls their focus listener instead to notify them of
+ * {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}, so they can pause instead. Note that
+ * this behavior is independent of the use of {@code AudioFocusRequest}, but tied to the use
+ * of {@code AudioAttributes}.
+ * <p>If your application requires pausing instead of ducking for any other reason than playing
+ * speech, you can also declare so with {@link Builder#setWillPauseWhenDucked(boolean)}, which will
+ * cause the system to call your focus listener instead of automatically ducking.
+ *
+ * <h4>Example</h4>
+ * <p>The example below covers the following steps to be found in any application that would play
+ * audio, and use audio focus. Here we play an audio book, and our application is intended to pause
+ * rather than duck when it loses focus. These steps consist in:
+ * <ul>
+ * <li>Creating {@code AudioAttributes} to be used for the playback and the focus request.</li>
+ * <li>Configuring and creating the {@code AudioFocusRequest} instance that defines the intended
+ *     focus behaviors.</li>
+ * <li>Requesting audio focus and checking the return code to see if playback can happen right
+ *     away, or is delayed.</li>
+ * <li>Implementing a focus change listener to respond to focus gains and losses.</li>
+ * </ul>
+ * <p>
+ * <pre class="prettyprint">
+ * // initialization of the audio attributes and focus request
+ * mAudioManager = (AudioManager) Context.getSystemService(Context.AUDIO_SERVICE);
+ * mPlaybackAttributes = new AudioAttributes.Builder()
+ *         .setUsage(AudioAttributes.USAGE_MEDIA)
+ *         .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH)
+ *         .build();
+ * mFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN)
+ *         .setAudioAttributes(mPlaybackAttributes)
+ *         .setAcceptsDelayedFocusGain(true)
+ *         .setWillPauseWhenDucked(true)
+ *         .setOnAudioFocusChangeListener(this, mMyHandler)
+ *         .build();
+ * mMediaPlayer = new MediaPlayer();
+ * mMediaPlayer.setAudioAttributes(mPlaybackAttributes);
+ * final Object mFocusLock = new Object();
+ *
+ * boolean mPlaybackDelayed = false;
+ *
+ * // requesting audio focus
+ * int res = mAudioManager.requestAudioFocus(mFocusRequest);
+ * synchronized (mFocusLock) {
+ *     if (res == AudioManager.AUDIOFOCUS_REQUEST_FAILED) {
+ *         mPlaybackDelayed = false;
+ *     } else if (res == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
+ *         mPlaybackDelayed = false;
+ *         playbackNow();
+ *     } else if (res == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) {
+ *        mPlaybackDelayed = true;
+ *     }
+ * }
+ *
+ * // implementation of the OnAudioFocusChangeListener
+ * &#64;Override
+ * public void onAudioFocusChange(int focusChange) {
+ *     switch (focusChange) {
+ *         case AudioManager.AUDIOFOCUS_GAIN:
+ *             if (mPlaybackDelayed || mResumeOnFocusGain) {
+ *                 synchronized (mFocusLock) {
+ *                     mPlaybackDelayed = false;
+ *                     mResumeOnFocusGain = false;
+ *                 }
+ *                 playbackNow();
+ *             }
+ *             break;
+ *         case AudioManager.AUDIOFOCUS_LOSS:
+ *             synchronized (mFocusLock) {
+ *                 // this is not a transient loss, we shouldn't automatically resume for now
+ *                 mResumeOnFocusGain = false;
+ *                 mPlaybackDelayed = false;
+ *             }
+ *             pausePlayback();
+ *             break;
+ *         case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT:
+ *         case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK:
+ *             // we handle all transient losses the same way because we never duck audio books
+ *             synchronized (mFocusLock) {
+ *                 // we should only resume if playback was interrupted
+ *                 mResumeOnFocusGain = mMediaPlayer.isPlaying();
+ *                 mPlaybackDelayed = false;
+ *             }
+ *             pausePlayback();
+ *             break;
+ *     }
+ * }
+ *
+ * // Important:
+ * // Also set "mResumeOnFocusGain" to false when the user pauses or stops playback: this way your
+ * // application doesn't automatically restart when it gains focus, even though the user had
+ * // stopped it.
+ * </pre>
+ */
+
+public final class AudioFocusRequest {
+
+    // default attributes for the request when not specified
+    private final static AudioAttributes FOCUS_DEFAULT_ATTR = new AudioAttributes.Builder()
+            .setUsage(AudioAttributes.USAGE_MEDIA).build();
+
+    /** @hide */
+    public static final String KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING = "a11y_force_ducking";
+
+    private final @Nullable OnAudioFocusChangeListener mFocusListener;
+    private final @Nullable Handler mListenerHandler;
+    private final @NonNull AudioAttributes mAttr;
+    private final int mFocusGain;
+    private final int mFlags;
+
+    private AudioFocusRequest(OnAudioFocusChangeListener listener, Handler handler,
+            AudioAttributes attr, int focusGain, int flags) {
+        mFocusListener = listener;
+        mListenerHandler = handler;
+        mFocusGain = focusGain;
+        mAttr = attr;
+        mFlags = flags;
+    }
+
+    /**
+     * @hide
+     * Checks whether a focus gain constant is a valid value for an audio focus request.
+     * @param focusGain value to check
+     * @return true if focusGain is a valid value for an audio focus request.
+     */
+    final static boolean isValidFocusGain(int focusGain) {
+        switch (focusGain) {
+            case AudioManager.AUDIOFOCUS_GAIN:
+            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT:
+            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
+            case AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * @hide
+     * Returns the focus change listener set for this {@code AudioFocusRequest}.
+     * @return null if no {@link AudioManager.OnAudioFocusChangeListener} was set.
+     */
+    @TestApi
+    public @Nullable OnAudioFocusChangeListener getOnAudioFocusChangeListener() {
+        return mFocusListener;
+    }
+
+    /**
+     * @hide
+     * Returns the {@link Handler} to be used for the focus change listener.
+     * @return the same {@code Handler} set in.
+     *   {@link Builder#setOnAudioFocusChangeListener(OnAudioFocusChangeListener, Handler)}, or null
+     *   if no listener was set.
+     */
+    public @Nullable Handler getOnAudioFocusChangeListenerHandler() {
+        return mListenerHandler;
+    }
+
+    /**
+     * Returns the {@link AudioAttributes} set for this {@code AudioFocusRequest}, or the default
+     * attributes if none were set.
+     * @return non-null {@link AudioAttributes}.
+     */
+    public @NonNull AudioAttributes getAudioAttributes() {
+        return mAttr;
+    }
+
+    /**
+     * Returns the type of audio focus request configured for this {@code AudioFocusRequest}.
+     * @return one of {@link AudioManager#AUDIOFOCUS_GAIN},
+     * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT},
+     * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and
+     * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}.
+     */
+    public int getFocusGain() {
+        return mFocusGain;
+    }
+
+    /**
+     * Returns whether the application that would use this {@code AudioFocusRequest} would pause
+     * when it is requested to duck.
+     * @return the duck/pause behavior.
+     */
+    public boolean willPauseWhenDucked() {
+        return (mFlags & AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS)
+                == AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS;
+    }
+
+    /**
+     * Returns whether the application that would use this {@code AudioFocusRequest} supports
+     * a focus gain granted after a temporary request failure.
+     * @return whether delayed focus gain is supported.
+     */
+    public boolean acceptsDelayedFocusGain() {
+        return (mFlags & AudioManager.AUDIOFOCUS_FLAG_DELAY_OK)
+                == AudioManager.AUDIOFOCUS_FLAG_DELAY_OK;
+    }
+
+    /**
+     * @hide
+     * Returns whether audio focus will be locked (i.e. focus cannot change) as a result of this
+     * focus request being successful.
+     * @return whether this request will lock focus.
+     */
+    @SystemApi
+    public boolean locksFocus() {
+        return (mFlags & AudioManager.AUDIOFOCUS_FLAG_LOCK)
+                == AudioManager.AUDIOFOCUS_FLAG_LOCK;
+    }
+
+    int getFlags() {
+        return mFlags;
+    }
+
+    /**
+     * Builder class for {@link AudioFocusRequest} objects.
+     * <p>See {@link AudioFocusRequest} for an example of building an instance with this builder.
+     * <br>The default values for the instance to be built are:
+     * <table>
+     * <tr><td>focus listener and handler</td><td>none</td></tr>
+     * <tr><td>{@code AudioAttributes}</td><td>attributes with usage set to
+     *     {@link AudioAttributes#USAGE_MEDIA}</td></tr>
+     * <tr><td>pauses on duck</td><td>false</td></tr>
+     * <tr><td>supports delayed focus grant</td><td>false</td></tr>
+     * </table>
+     */
+    public static final class Builder {
+        private OnAudioFocusChangeListener mFocusListener;
+        private Handler mListenerHandler;
+        private AudioAttributes mAttr = FOCUS_DEFAULT_ATTR;
+        private int mFocusGain;
+        private boolean mPausesOnDuck = false;
+        private boolean mDelayedFocus = false;
+        private boolean mFocusLocked = false;
+        private boolean mA11yForceDucking = false;
+
+        /**
+         * Constructs a new {@code Builder}, and specifies how audio focus
+         * will be requested. Valid values for focus requests are
+         * {@link AudioManager#AUDIOFOCUS_GAIN}, {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT},
+         * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and
+         * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}.
+         * <p>By default there is no focus change listener, delayed focus is not supported, ducking
+         * is suitable for the application, and the <code>AudioAttributes</code>
+         * have a usage of {@link AudioAttributes#USAGE_MEDIA}.
+         * @param focusGain the type of audio focus gain that will be requested
+         * @throws IllegalArgumentException thrown when an invalid focus gain type is used
+         */
+        public Builder(int focusGain) {
+            setFocusGain(focusGain);
+        }
+
+        /**
+         * Constructs a new {@code Builder} with all the properties of the {@code AudioFocusRequest}
+         * passed as parameter.
+         * Use this method when you want a new request to differ only by some properties.
+         * @param requestToCopy the non-null {@code AudioFocusRequest} to build a duplicate from.
+         * @throws IllegalArgumentException thrown when a null {@code AudioFocusRequest} is used.
+         */
+        public Builder(@NonNull AudioFocusRequest requestToCopy) {
+            if (requestToCopy == null) {
+                throw new IllegalArgumentException("Illegal null AudioFocusRequest");
+            }
+            mAttr = requestToCopy.mAttr;
+            mFocusListener = requestToCopy.mFocusListener;
+            mListenerHandler = requestToCopy.mListenerHandler;
+            mFocusGain = requestToCopy.mFocusGain;
+            mPausesOnDuck = requestToCopy.willPauseWhenDucked();
+            mDelayedFocus = requestToCopy.acceptsDelayedFocusGain();
+        }
+
+        /**
+         * Sets the type of focus gain that will be requested.
+         * Use this method to replace the focus gain when building a request by modifying an
+         * existing {@code AudioFocusRequest} instance.
+         * @param focusGain the type of audio focus gain that will be requested.
+         * @return this {@code Builder} instance
+         * @throws IllegalArgumentException thrown when an invalid focus gain type is used
+         */
+        public @NonNull Builder setFocusGain(int focusGain) {
+            if (!isValidFocusGain(focusGain)) {
+                throw new IllegalArgumentException("Illegal audio focus gain type " + focusGain);
+            }
+            mFocusGain = focusGain;
+            return this;
+        }
+
+        /**
+         * Sets the listener called when audio focus changes after being requested with
+         *   {@link AudioManager#requestAudioFocus(AudioFocusRequest)}, and until being abandoned
+         *   with {@link AudioManager#abandonAudioFocusRequest(AudioFocusRequest)}.
+         *   Note that only focus changes (gains and losses) affecting the focus owner are reported,
+         *   not gains and losses of other focus requesters in the system.<br>
+         *   Notifications are delivered on the {@link Looper} associated with the one of
+         *   the creation of the {@link AudioManager} used to request focus
+         *   (see {@link AudioManager#requestAudioFocus(AudioFocusRequest)}).
+         * @param listener the listener receiving the focus change notifications.
+         * @return this {@code Builder} instance.
+         * @throws NullPointerException thrown when a null focus listener is used.
+         */
+        public @NonNull Builder setOnAudioFocusChangeListener(
+                @NonNull OnAudioFocusChangeListener listener) {
+            if (listener == null) {
+                throw new NullPointerException("Illegal null focus listener");
+            }
+            mFocusListener = listener;
+            mListenerHandler = null;
+            return this;
+        }
+
+        /**
+         * @hide
+         * Internal listener setter, no null checks on listener nor handler
+         * @param listener
+         * @param handler
+         * @return this {@code Builder} instance.
+         */
+        @NonNull Builder setOnAudioFocusChangeListenerInt(
+                OnAudioFocusChangeListener listener, Handler handler) {
+            mFocusListener = listener;
+            mListenerHandler = handler;
+            return this;
+        }
+
+        /**
+         * Sets the listener called when audio focus changes after being requested with
+         *   {@link AudioManager#requestAudioFocus(AudioFocusRequest)}, and until being abandoned
+         *   with {@link AudioManager#abandonAudioFocusRequest(AudioFocusRequest)}.
+         *   Note that only focus changes (gains and losses) affecting the focus owner are reported,
+         *   not gains and losses of other focus requesters in the system.
+         * @param listener the listener receiving the focus change notifications.
+         * @param handler the {@link Handler} for the thread on which to execute
+         *   the notifications.
+         * @return this {@code Builder} instance.
+         * @throws NullPointerException thrown when a null focus listener or handler is used.
+         */
+        public @NonNull Builder setOnAudioFocusChangeListener(
+                @NonNull OnAudioFocusChangeListener listener, @NonNull Handler handler) {
+            if (listener == null || handler == null) {
+                throw new NullPointerException("Illegal null focus listener or handler");
+            }
+            mFocusListener = listener;
+            mListenerHandler = handler;
+            return this;
+        }
+
+        /**
+         * Sets the {@link AudioAttributes} to be associated with the focus request, and which
+         * describe the use case for which focus is requested.
+         * As the focus requests typically precede audio playback, this information is used on
+         * certain platforms to declare the subsequent playback use case. It is therefore good
+         * practice to use in this method the same {@code AudioAttributes} as used for
+         * playback, see for example {@link MediaPlayer#setAudioAttributes(AudioAttributes)} in
+         * {@code MediaPlayer} or {@link AudioTrack.Builder#setAudioAttributes(AudioAttributes)}
+         * in {@code AudioTrack}.
+         * @param attributes the {@link AudioAttributes} for the focus request.
+         * @return this {@code Builder} instance.
+         * @throws NullPointerException thrown when using null for the attributes.
+         */
+        public @NonNull Builder setAudioAttributes(@NonNull AudioAttributes attributes) {
+            if (attributes == null) {
+                throw new NullPointerException("Illegal null AudioAttributes");
+            }
+            mAttr = attributes;
+            return this;
+        }
+
+        /**
+         * Declare the intended behavior of the application with regards to audio ducking.
+         * See more details in the {@link AudioFocusRequest} class documentation.
+         * @param pauseOnDuck use {@code true} if the application intends to pause audio playback
+         *    when losing focus with {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}.
+         *    If {@code true}, note that you must also set a focus listener to receive such an
+         *    event, with
+         *    {@link #setOnAudioFocusChangeListener(OnAudioFocusChangeListener, Handler)}.
+         * @return this {@code Builder} instance.
+         */
+        public @NonNull Builder setWillPauseWhenDucked(boolean pauseOnDuck) {
+            mPausesOnDuck = pauseOnDuck;
+            return this;
+        }
+
+        /**
+         * Marks this focus request as compatible with delayed focus.
+         * See more details about delayed focus in the {@link AudioFocusRequest} class
+         * documentation.
+         * @param acceptsDelayedFocusGain use {@code true} if the application supports delayed
+         *    focus. If {@code true}, note that you must also set a focus listener to be notified
+         *    of delayed focus gain, with
+         *    {@link #setOnAudioFocusChangeListener(OnAudioFocusChangeListener, Handler)}.
+         * @return this {@code Builder} instance
+         */
+        public @NonNull Builder setAcceptsDelayedFocusGain(boolean acceptsDelayedFocusGain) {
+            mDelayedFocus = acceptsDelayedFocusGain;
+            return this;
+        }
+
+        /**
+         * @hide
+         * Marks this focus request as locking audio focus so granting is temporarily disabled.
+         * This feature can only be used by owners of a registered
+         * {@link android.media.audiopolicy.AudioPolicy} in
+         * {@link AudioManager#requestAudioFocus(AudioFocusRequest, android.media.audiopolicy.AudioPolicy)}.
+         * Setting to false is the same as the default behavior.
+         * @param focusLocked true when locking focus
+         * @return this {@code Builder} instance
+         */
+        @SystemApi
+        public @NonNull Builder setLocksFocus(boolean focusLocked) {
+            mFocusLocked = focusLocked;
+            return this;
+        }
+
+        /**
+         * Marks this focus request as forcing ducking, regardless of the conditions in which
+         * the system would or would not enforce ducking.
+         * Forcing ducking will only be honored when requesting AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK
+         * with an {@link AudioAttributes} usage of
+         * {@link AudioAttributes#USAGE_ASSISTANCE_ACCESSIBILITY}, coming from an accessibility
+         * service, and will be ignored otherwise.
+         * @param forceDucking {@code true} to force ducking
+         * @return this {@code Builder} instance
+         */
+        public @NonNull Builder setForceDucking(boolean forceDucking) {
+            mA11yForceDucking = forceDucking;
+            return this;
+        }
+
+        /**
+         * Builds a new {@code AudioFocusRequest} instance combining all the information gathered
+         * by this {@code Builder}'s configuration methods.
+         * @return the {@code AudioFocusRequest} instance qualified by all the properties set
+         *   on this {@code Builder}.
+         * @throws IllegalStateException thrown when attempting to build a focus request that is set
+         *    to accept delayed focus, or to pause on duck, but no focus change listener was set.
+         */
+        public AudioFocusRequest build() {
+            if ((mDelayedFocus || mPausesOnDuck) && (mFocusListener == null)) {
+                throw new IllegalStateException(
+                        "Can't use delayed focus or pause on duck without a listener");
+            }
+            if (mA11yForceDucking) {
+                final Bundle extraInfo;
+                if (mAttr.getBundle() == null) {
+                    extraInfo = new Bundle();
+                } else {
+                    extraInfo = mAttr.getBundle();
+                }
+                // checking of usage and focus request is done server side
+                extraInfo.putBoolean(KEY_ACCESSIBILITY_FORCE_FOCUS_DUCKING, true);
+                mAttr = new AudioAttributes.Builder(mAttr).addBundle(extraInfo).build();
+            }
+            final int flags = 0
+                    | (mDelayedFocus ? AudioManager.AUDIOFOCUS_FLAG_DELAY_OK : 0)
+                    | (mPausesOnDuck ? AudioManager.AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS : 0)
+                    | (mFocusLocked  ? AudioManager.AUDIOFOCUS_FLAG_LOCK : 0);
+            return new AudioFocusRequest(mFocusListener, mListenerHandler,
+                    mAttr, mFocusGain, flags);
+        }
+    }
+}
diff --git a/android/media/AudioFormat.java b/android/media/AudioFormat.java
new file mode 100644
index 0000000..1644ec8
--- /dev/null
+++ b/android/media/AudioFormat.java
@@ -0,0 +1,1400 @@
+/*
+ * Copyright (C) 2008 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.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * The {@link AudioFormat} class is used to access a number of audio format and
+ * channel configuration constants. They are for instance used
+ * in {@link AudioTrack} and {@link AudioRecord}, as valid values in individual parameters of
+ * constructors like {@link AudioTrack#AudioTrack(int, int, int, int, int, int)}, where the fourth
+ * parameter is one of the <code>AudioFormat.ENCODING_*</code> constants.
+ * The <code>AudioFormat</code> constants are also used in {@link MediaFormat} to specify
+ * audio related values commonly used in media, such as for {@link MediaFormat#KEY_CHANNEL_MASK}.
+ * <p>The {@link AudioFormat.Builder} class can be used to create instances of
+ * the <code>AudioFormat</code> format class.
+ * Refer to
+ * {@link AudioFormat.Builder} for documentation on the mechanics of the configuration and building
+ * of such instances. Here we describe the main concepts that the <code>AudioFormat</code> class
+ * allow you to convey in each instance, they are:
+ * <ol>
+ * <li><a href="#sampleRate">sample rate</a>
+ * <li><a href="#encoding">encoding</a>
+ * <li><a href="#channelMask">channel masks</a>
+ * </ol>
+ * <p>Closely associated with the <code>AudioFormat</code> is the notion of an
+ * <a href="#audioFrame">audio frame</a>, which is used throughout the documentation
+ * to represent the minimum size complete unit of audio data.
+ *
+ * <h4 id="sampleRate">Sample rate</h4>
+ * <p>Expressed in Hz, the sample rate in an <code>AudioFormat</code> instance expresses the number
+ * of audio samples for each channel per second in the content you are playing or recording. It is
+ * not the sample rate
+ * at which content is rendered or produced. For instance a sound at a media sample rate of 8000Hz
+ * can be played on a device operating at a sample rate of 48000Hz; the sample rate conversion is
+ * automatically handled by the platform, it will not play at 6x speed.
+ *
+ * <p>As of API {@link android.os.Build.VERSION_CODES#M},
+ * sample rates up to 192kHz are supported
+ * for <code>AudioRecord</code> and <code>AudioTrack</code>, with sample rate conversion
+ * performed as needed.
+ * To improve efficiency and avoid lossy conversions, it is recommended to match the sample rate
+ * for <code>AudioRecord</code> and <code>AudioTrack</code> to the endpoint device
+ * sample rate, and limit the sample rate to no more than 48kHz unless there are special
+ * device capabilities that warrant a higher rate.
+ *
+ * <h4 id="encoding">Encoding</h4>
+ * <p>Audio encoding is used to describe the bit representation of audio data, which can be
+ * either linear PCM or compressed audio, such as AC3 or DTS.
+ * <p>For linear PCM, the audio encoding describes the sample size, 8 bits, 16 bits, or 32 bits,
+ * and the sample representation, integer or float.
+ * <ul>
+ * <li> {@link #ENCODING_PCM_8BIT}: The audio sample is a 8 bit unsigned integer in the
+ * range [0, 255], with a 128 offset for zero. This is typically stored as a Java byte in a
+ * byte array or ByteBuffer. Since the Java byte is <em>signed</em>,
+ * be careful with math operations and conversions as the most significant bit is inverted.
+ * </li>
+ * <li> {@link #ENCODING_PCM_16BIT}: The audio sample is a 16 bit signed integer
+ * typically stored as a Java short in a short array, but when the short
+ * is stored in a ByteBuffer, it is native endian (as compared to the default Java big endian).
+ * The short has full range from [-32768, 32767],
+ * and is sometimes interpreted as fixed point Q.15 data.
+ * </li>
+ * <li> {@link #ENCODING_PCM_FLOAT}: Introduced in
+ * API {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this encoding specifies that
+ * the audio sample is a 32 bit IEEE single precision float. The sample can be
+ * manipulated as a Java float in a float array, though within a ByteBuffer
+ * it is stored in native endian byte order.
+ * The nominal range of <code>ENCODING_PCM_FLOAT</code> audio data is [-1.0, 1.0].
+ * It is implementation dependent whether the positive maximum of 1.0 is included
+ * in the interval. Values outside of the nominal range are clamped before
+ * sending to the endpoint device. Beware that
+ * the handling of NaN is undefined; subnormals may be treated as zero; and
+ * infinities are generally clamped just like other values for <code>AudioTrack</code>
+ * &ndash; try to avoid infinities because they can easily generate a NaN.
+ * <br>
+ * To achieve higher audio bit depth than a signed 16 bit integer short,
+ * it is recommended to use <code>ENCODING_PCM_FLOAT</code> for audio capture, processing,
+ * and playback.
+ * Floats are efficiently manipulated by modern CPUs,
+ * have greater precision than 24 bit signed integers,
+ * and have greater dynamic range than 32 bit signed integers.
+ * <code>AudioRecord</code> as of API {@link android.os.Build.VERSION_CODES#M} and
+ * <code>AudioTrack</code> as of API {@link android.os.Build.VERSION_CODES#LOLLIPOP}
+ * support <code>ENCODING_PCM_FLOAT</code>.
+ * </li>
+ * <li> {@link #ENCODING_PCM_24BIT_PACKED}: Introduced in
+ * API {@link android.os.Build.VERSION_CODES#S},
+ * this encoding specifies the audio sample is an
+ * extended precision 24 bit signed integer
+ * stored as a 3 Java bytes in a {@code ByteBuffer} or byte array in native endian
+ * (see {@link java.nio.ByteOrder#nativeOrder()}).
+ * Each sample has full range from [-8388608, 8388607],
+ * and can be interpreted as fixed point Q.23 data.
+ * </li>
+ * <li> {@link #ENCODING_PCM_32BIT}: Introduced in
+ * API {@link android.os.Build.VERSION_CODES#S},
+ * this encoding specifies the audio sample is an
+ * extended precision 32 bit signed integer
+ * stored as a 4 Java bytes in a {@code ByteBuffer} or byte array in native endian
+ * (see {@link java.nio.ByteOrder#nativeOrder()}).
+ * Each sample has full range from [-2147483648, 2147483647],
+ * and can be interpreted as fixed point Q.31 data.
+ * </li>
+ * </ul>
+ * <p>For compressed audio, the encoding specifies the method of compression,
+ * for example {@link #ENCODING_AC3} and {@link #ENCODING_DTS}. The compressed
+ * audio data is typically stored as bytes in
+ * a byte array or ByteBuffer. When a compressed audio encoding is specified
+ * for an <code>AudioTrack</code>, it creates a direct (non-mixed) track
+ * for output to an endpoint (such as HDMI) capable of decoding the compressed audio.
+ * For (most) other endpoints, which are not capable of decoding such compressed audio,
+ * you will need to decode the data first, typically by creating a {@link MediaCodec}.
+ * Alternatively, one may use {@link MediaPlayer} for playback of compressed
+ * audio files or streams.
+ * <p>When compressed audio is sent out through a direct <code>AudioTrack</code>,
+ * it need not be written in exact multiples of the audio access unit;
+ * this differs from <code>MediaCodec</code> input buffers.
+ *
+ * <h4 id="channelMask">Channel mask</h4>
+ * <p>Channel masks are used in <code>AudioTrack</code> and <code>AudioRecord</code> to describe
+ * the samples and their arrangement in the audio frame. They are also used in the endpoint (e.g.
+ * a USB audio interface, a DAC connected to headphones) to specify allowable configurations of a
+ * particular device.
+ * <br>As of API {@link android.os.Build.VERSION_CODES#M}, there are two types of channel masks:
+ * channel position masks and channel index masks.
+ *
+ * <h5 id="channelPositionMask">Channel position masks</h5>
+ * Channel position masks are the original Android channel masks, and are used since API
+ * {@link android.os.Build.VERSION_CODES#BASE}.
+ * For input and output, they imply a positional nature - the location of a speaker or a microphone
+ * for recording or playback.
+ * <br>For a channel position mask, each allowed channel position corresponds to a bit in the
+ * channel mask. If that channel position is present in the audio frame, that bit is set,
+ * otherwise it is zero. The order of the bits (from lsb to msb) corresponds to the order of that
+ * position's sample in the audio frame.
+ * <br>The canonical channel position masks by channel count are as follows:
+ * <br><table>
+ * <tr><td>channel count</td><td>channel position mask</td></tr>
+ * <tr><td>1</td><td>{@link #CHANNEL_OUT_MONO}</td></tr>
+ * <tr><td>2</td><td>{@link #CHANNEL_OUT_STEREO}</td></tr>
+ * <tr><td>3</td><td>{@link #CHANNEL_OUT_STEREO} | {@link #CHANNEL_OUT_FRONT_CENTER}</td></tr>
+ * <tr><td>4</td><td>{@link #CHANNEL_OUT_QUAD}</td></tr>
+ * <tr><td>5</td><td>{@link #CHANNEL_OUT_QUAD} | {@link #CHANNEL_OUT_FRONT_CENTER}</td></tr>
+ * <tr><td>6</td><td>{@link #CHANNEL_OUT_5POINT1}</td></tr>
+ * <tr><td>7</td><td>{@link #CHANNEL_OUT_5POINT1} | {@link #CHANNEL_OUT_BACK_CENTER}</td></tr>
+ * <tr><td>8</td><td>{@link #CHANNEL_OUT_7POINT1_SURROUND}</td></tr>
+ * </table>
+ * <br>These masks are an ORed composite of individual channel masks. For example
+ * {@link #CHANNEL_OUT_STEREO} is composed of {@link #CHANNEL_OUT_FRONT_LEFT} and
+ * {@link #CHANNEL_OUT_FRONT_RIGHT}.
+ *
+ * <h5 id="channelIndexMask">Channel index masks</h5>
+ * Channel index masks are introduced in API {@link android.os.Build.VERSION_CODES#M}. They allow
+ * the selection of a particular channel from the source or sink endpoint by number, i.e. the first
+ * channel, the second channel, and so forth. This avoids problems with artificially assigning
+ * positions to channels of an endpoint, or figuring what the i<sup>th</sup> position bit is within
+ * an endpoint's channel position mask etc.
+ * <br>Here's an example where channel index masks address this confusion: dealing with a 4 channel
+ * USB device. Using a position mask, and based on the channel count, this would be a
+ * {@link #CHANNEL_OUT_QUAD} device, but really one is only interested in channel 0
+ * through channel 3. The USB device would then have the following individual bit channel masks:
+ * {@link #CHANNEL_OUT_FRONT_LEFT},
+ * {@link #CHANNEL_OUT_FRONT_RIGHT}, {@link #CHANNEL_OUT_BACK_LEFT}
+ * and {@link #CHANNEL_OUT_BACK_RIGHT}. But which is channel 0 and which is
+ * channel 3?
+ * <br>For a channel index mask, each channel number is represented as a bit in the mask, from the
+ * lsb (channel 0) upwards to the msb, numerically this bit value is
+ * <code>1 << channelNumber</code>.
+ * A set bit indicates that channel is present in the audio frame, otherwise it is cleared.
+ * The order of the bits also correspond to that channel number's sample order in the audio frame.
+ * <br>For the previous 4 channel USB device example, the device would have a channel index mask
+ * <code>0xF</code>. Suppose we wanted to select only the first and the third channels; this would
+ * correspond to a channel index mask <code>0x5</code> (the first and third bits set). If an
+ * <code>AudioTrack</code> uses this channel index mask, the audio frame would consist of two
+ * samples, the first sample of each frame routed to channel 0, and the second sample of each frame
+ * routed to channel 2.
+ * The canonical channel index masks by channel count are given by the formula
+ * <code>(1 << channelCount) - 1</code>.
+ *
+ * <h5>Use cases</h5>
+ * <ul>
+ * <li><i>Channel position mask for an endpoint:</i> <code>CHANNEL_OUT_FRONT_LEFT</code>,
+ *  <code>CHANNEL_OUT_FRONT_CENTER</code>, etc. for HDMI home theater purposes.
+ * <li><i>Channel position mask for an audio stream:</i> Creating an <code>AudioTrack</code>
+ *  to output movie content, where 5.1 multichannel output is to be written.
+ * <li><i>Channel index mask for an endpoint:</i> USB devices for which input and output do not
+ *  correspond to left or right speaker or microphone.
+ * <li><i>Channel index mask for an audio stream:</i> An <code>AudioRecord</code> may only want the
+ *  third and fourth audio channels of the endpoint (i.e. the second channel pair), and not care the
+ *  about position it corresponds to, in which case the channel index mask is <code>0xC</code>.
+ *  Multichannel <code>AudioRecord</code> sessions should use channel index masks.
+ * </ul>
+ * <h4 id="audioFrame">Audio Frame</h4>
+ * <p>For linear PCM, an audio frame consists of a set of samples captured at the same time,
+ * whose count and
+ * channel association are given by the <a href="#channelMask">channel mask</a>,
+ * and whose sample contents are specified by the <a href="#encoding">encoding</a>.
+ * For example, a stereo 16 bit PCM frame consists of
+ * two 16 bit linear PCM samples, with a frame size of 4 bytes.
+ * For compressed audio, an audio frame may alternately
+ * refer to an access unit of compressed data bytes that is logically grouped together for
+ * decoding and bitstream access (e.g. {@link MediaCodec}),
+ * or a single byte of compressed data (e.g. {@link AudioTrack#getBufferSizeInFrames()
+ * AudioTrack.getBufferSizeInFrames()}),
+ * or the linear PCM frame result from decoding the compressed data
+ * (e.g.{@link AudioTrack#getPlaybackHeadPosition()
+ * AudioTrack.getPlaybackHeadPosition()}),
+ * depending on the context where audio frame is used.
+ * For the purposes of {@link AudioFormat#getFrameSizeInBytes()}, a compressed data format
+ * returns a frame size of 1 byte.
+ */
+public final class AudioFormat implements Parcelable {
+
+    //---------------------------------------------------------
+    // Constants
+    //--------------------
+    /** Invalid audio data format */
+    public static final int ENCODING_INVALID = 0;
+    /** Default audio data format */
+    public static final int ENCODING_DEFAULT = 1;
+
+    // These values must be kept in sync with core/jni/android_media_AudioFormat.h
+    // Also sync av/services/audiopolicy/managerdefault/ConfigParsingUtils.h
+    /** Audio data format: PCM 16 bit per sample. Guaranteed to be supported by devices. */
+    public static final int ENCODING_PCM_16BIT = 2;
+    /** Audio data format: PCM 8 bit per sample. Not guaranteed to be supported by devices. */
+    public static final int ENCODING_PCM_8BIT = 3;
+    /** Audio data format: single-precision floating-point per sample */
+    public static final int ENCODING_PCM_FLOAT = 4;
+    /** Audio data format: AC-3 compressed, also known as Dolby Digital */
+    public static final int ENCODING_AC3 = 5;
+    /** Audio data format: E-AC-3 compressed, also known as Dolby Digital Plus or DD+ */
+    public static final int ENCODING_E_AC3 = 6;
+    /** Audio data format: DTS compressed */
+    public static final int ENCODING_DTS = 7;
+    /** Audio data format: DTS HD compressed */
+    public static final int ENCODING_DTS_HD = 8;
+    /** Audio data format: MP3 compressed */
+    public static final int ENCODING_MP3 = 9;
+    /** Audio data format: AAC LC compressed */
+    public static final int ENCODING_AAC_LC = 10;
+    /** Audio data format: AAC HE V1 compressed */
+    public static final int ENCODING_AAC_HE_V1 = 11;
+    /** Audio data format: AAC HE V2 compressed */
+    public static final int ENCODING_AAC_HE_V2 = 12;
+
+    /** Audio data format: compressed audio wrapped in PCM for HDMI
+     * or S/PDIF passthrough.
+     * For devices whose SDK version is less than {@link android.os.Build.VERSION_CODES#S}, the
+     * channel mask of IEC61937 track must be {@link #CHANNEL_OUT_STEREO}.
+     * Data should be written to the stream in a short[] array.
+     * If the data is written in a byte[] array then there may be endian problems
+     * on some platforms when converting to short internally.
+     */
+    public static final int ENCODING_IEC61937 = 13;
+    /** Audio data format: DOLBY TRUEHD compressed
+     **/
+    public static final int ENCODING_DOLBY_TRUEHD = 14;
+    /** Audio data format: AAC ELD compressed */
+    public static final int ENCODING_AAC_ELD = 15;
+    /** Audio data format: AAC xHE compressed */
+    public static final int ENCODING_AAC_XHE = 16;
+    /** Audio data format: AC-4 sync frame transport format */
+    public static final int ENCODING_AC4 = 17;
+    /** Audio data format: E-AC-3-JOC compressed
+     * E-AC-3-JOC streams can be decoded by downstream devices supporting {@link #ENCODING_E_AC3}.
+     * Use {@link #ENCODING_E_AC3} as the AudioTrack encoding when the downstream device
+     * supports {@link #ENCODING_E_AC3} but not {@link #ENCODING_E_AC3_JOC}.
+     **/
+    public static final int ENCODING_E_AC3_JOC = 18;
+    /** Audio data format: Dolby MAT (Metadata-enhanced Audio Transmission)
+     * Dolby MAT bitstreams are used to transmit Dolby TrueHD, channel-based PCM, or PCM with
+     * metadata (object audio) over HDMI (e.g. Dolby Atmos content).
+     **/
+    public static final int ENCODING_DOLBY_MAT = 19;
+    /** Audio data format: OPUS compressed. */
+    public static final int ENCODING_OPUS = 20;
+
+    /** @hide
+     * We do not permit legacy short array reads or writes for encodings
+     * introduced after this threshold.
+     */
+    public static final int ENCODING_LEGACY_SHORT_ARRAY_THRESHOLD = ENCODING_OPUS;
+
+    /** Audio data format: PCM 24 bit per sample packed as 3 bytes.
+     *
+     * The bytes are in little-endian order, so the least significant byte
+     * comes first in the byte array.
+     *
+     * Not guaranteed to be supported by devices, may be emulated if not supported. */
+    public static final int ENCODING_PCM_24BIT_PACKED = 21;
+    /** Audio data format: PCM 32 bit per sample.
+     * Not guaranteed to be supported by devices, may be emulated if not supported. */
+    public static final int ENCODING_PCM_32BIT = 22;
+
+    /** Audio data format: MPEG-H baseline profile, level 3 */
+    public static final int ENCODING_MPEGH_BL_L3 = 23;
+    /** Audio data format: MPEG-H baseline profile, level 4 */
+    public static final int ENCODING_MPEGH_BL_L4 = 24;
+    /** Audio data format: MPEG-H low complexity profile, level 3 */
+    public static final int ENCODING_MPEGH_LC_L3 = 25;
+    /** Audio data format: MPEG-H low complexity profile, level 4 */
+    public static final int ENCODING_MPEGH_LC_L4 = 26;
+    /** Audio data format: DTS UHD compressed */
+    public static final int ENCODING_DTS_UHD = 27;
+    /** Audio data format: DRA compressed */
+    public static final int ENCODING_DRA = 28;
+
+    /** @hide */
+    public static String toLogFriendlyEncoding(int enc) {
+        switch(enc) {
+            case ENCODING_INVALID:
+                return "ENCODING_INVALID";
+            case ENCODING_PCM_16BIT:
+                return "ENCODING_PCM_16BIT";
+            case ENCODING_PCM_8BIT:
+                return "ENCODING_PCM_8BIT";
+            case ENCODING_PCM_FLOAT:
+                return "ENCODING_PCM_FLOAT";
+            case ENCODING_AC3:
+                return "ENCODING_AC3";
+            case ENCODING_E_AC3:
+                return "ENCODING_E_AC3";
+            case ENCODING_DTS:
+                return "ENCODING_DTS";
+            case ENCODING_DTS_HD:
+                return "ENCODING_DTS_HD";
+            case ENCODING_MP3:
+                return "ENCODING_MP3";
+            case ENCODING_AAC_LC:
+                return "ENCODING_AAC_LC";
+            case ENCODING_AAC_HE_V1:
+                return "ENCODING_AAC_HE_V1";
+            case ENCODING_AAC_HE_V2:
+                return "ENCODING_AAC_HE_V2";
+            case ENCODING_IEC61937:
+                return "ENCODING_IEC61937";
+            case ENCODING_DOLBY_TRUEHD:
+                return "ENCODING_DOLBY_TRUEHD";
+            case ENCODING_AAC_ELD:
+                return "ENCODING_AAC_ELD";
+            case ENCODING_AAC_XHE:
+                return "ENCODING_AAC_XHE";
+            case ENCODING_AC4:
+                return "ENCODING_AC4";
+            case ENCODING_E_AC3_JOC:
+                return "ENCODING_E_AC3_JOC";
+            case ENCODING_DOLBY_MAT:
+                return "ENCODING_DOLBY_MAT";
+            case ENCODING_OPUS:
+                return "ENCODING_OPUS";
+            case ENCODING_PCM_24BIT_PACKED:
+                return "ENCODING_PCM_24BIT_PACKED";
+            case ENCODING_PCM_32BIT:
+                return "ENCODING_PCM_32BIT";
+            case ENCODING_MPEGH_BL_L3:
+                return "ENCODING_MPEGH_BL_L3";
+            case ENCODING_MPEGH_BL_L4:
+                return "ENCODING_MPEGH_BL_L4";
+            case ENCODING_MPEGH_LC_L3:
+                return "ENCODING_MPEGH_LC_L3";
+            case ENCODING_MPEGH_LC_L4:
+                return "ENCODING_MPEGH_LC_L4";
+            case ENCODING_DTS_UHD:
+                return "ENCODING_DTS_UHD";
+            case ENCODING_DRA:
+                return "ENCODING_DRA";
+            default :
+                return "invalid encoding " + enc;
+        }
+    }
+
+    /** Invalid audio channel configuration */
+    /** @deprecated Use {@link #CHANNEL_INVALID} instead.  */
+    @Deprecated    public static final int CHANNEL_CONFIGURATION_INVALID   = 0;
+    /** Default audio channel configuration */
+    /** @deprecated Use {@link #CHANNEL_OUT_DEFAULT} or {@link #CHANNEL_IN_DEFAULT} instead.  */
+    @Deprecated    public static final int CHANNEL_CONFIGURATION_DEFAULT   = 1;
+    /** Mono audio configuration */
+    /** @deprecated Use {@link #CHANNEL_OUT_MONO} or {@link #CHANNEL_IN_MONO} instead.  */
+    @Deprecated    public static final int CHANNEL_CONFIGURATION_MONO      = 2;
+    /** Stereo (2 channel) audio configuration */
+    /** @deprecated Use {@link #CHANNEL_OUT_STEREO} or {@link #CHANNEL_IN_STEREO} instead.  */
+    @Deprecated    public static final int CHANNEL_CONFIGURATION_STEREO    = 3;
+
+    /** Invalid audio channel mask */
+    public static final int CHANNEL_INVALID = 0;
+    /** Default audio channel mask */
+    public static final int CHANNEL_OUT_DEFAULT = 1;
+
+    // Output channel mask definitions below are translated to the native values defined in
+    //  in /system/media/audio/include/system/audio.h in the JNI code of AudioTrack
+    public static final int CHANNEL_OUT_FRONT_LEFT = 0x4;
+    public static final int CHANNEL_OUT_FRONT_RIGHT = 0x8;
+    public static final int CHANNEL_OUT_FRONT_CENTER = 0x10;
+    public static final int CHANNEL_OUT_LOW_FREQUENCY = 0x20;
+    public static final int CHANNEL_OUT_BACK_LEFT = 0x40;
+    public static final int CHANNEL_OUT_BACK_RIGHT = 0x80;
+    public static final int CHANNEL_OUT_FRONT_LEFT_OF_CENTER = 0x100;
+    public static final int CHANNEL_OUT_FRONT_RIGHT_OF_CENTER = 0x200;
+    public static final int CHANNEL_OUT_BACK_CENTER = 0x400;
+    public static final int CHANNEL_OUT_SIDE_LEFT =         0x800;
+    public static final int CHANNEL_OUT_SIDE_RIGHT =       0x1000;
+    /** @hide */
+    public static final int CHANNEL_OUT_TOP_CENTER =       0x2000;
+    /** @hide */
+    public static final int CHANNEL_OUT_TOP_FRONT_LEFT =   0x4000;
+    /** @hide */
+    public static final int CHANNEL_OUT_TOP_FRONT_CENTER = 0x8000;
+    /** @hide */
+    public static final int CHANNEL_OUT_TOP_FRONT_RIGHT = 0x10000;
+    /** @hide */
+    public static final int CHANNEL_OUT_TOP_BACK_LEFT =   0x20000;
+    /** @hide */
+    public static final int CHANNEL_OUT_TOP_BACK_CENTER = 0x40000;
+    /** @hide */
+    public static final int CHANNEL_OUT_TOP_BACK_RIGHT =  0x80000;
+    /** @hide */
+    public static final int CHANNEL_OUT_TOP_SIDE_LEFT = 0x100000;
+    /** @hide */
+    public static final int CHANNEL_OUT_TOP_SIDE_RIGHT = 0x200000;
+    /** @hide */
+    public static final int CHANNEL_OUT_BOTTOM_FRONT_LEFT = 0x400000;
+    /** @hide */
+    public static final int CHANNEL_OUT_BOTTOM_FRONT_CENTER = 0x800000;
+    /** @hide */
+    public static final int CHANNEL_OUT_BOTTOM_FRONT_RIGHT = 0x1000000;
+    /** @hide */
+    public static final int CHANNEL_OUT_LOW_FREQUENCY_2 = 0x2000000;
+
+    public static final int CHANNEL_OUT_MONO = CHANNEL_OUT_FRONT_LEFT;
+    public static final int CHANNEL_OUT_STEREO = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT);
+    // aka QUAD_BACK
+    public static final int CHANNEL_OUT_QUAD = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+            CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT);
+    /** @hide */
+    public static final int CHANNEL_OUT_QUAD_SIDE = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+            CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT);
+    public static final int CHANNEL_OUT_SURROUND = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+            CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_BACK_CENTER);
+    // aka 5POINT1_BACK
+    public static final int CHANNEL_OUT_5POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+            CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT);
+    /** @hide */
+    public static final int CHANNEL_OUT_5POINT1_SIDE = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+            CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY |
+            CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT);
+    // different from AUDIO_CHANNEL_OUT_7POINT1 used internally, and not accepted by AudioRecord.
+    /** @deprecated Not the typical 7.1 surround configuration. Use {@link #CHANNEL_OUT_7POINT1_SURROUND} instead. */
+    @Deprecated    public static final int CHANNEL_OUT_7POINT1 = (CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_RIGHT |
+            CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_LOW_FREQUENCY | CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
+            CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER);
+    // matches AUDIO_CHANNEL_OUT_7POINT1
+    public static final int CHANNEL_OUT_7POINT1_SURROUND = (
+            CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_FRONT_RIGHT |
+            CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT |
+            CHANNEL_OUT_BACK_LEFT | CHANNEL_OUT_BACK_RIGHT |
+            CHANNEL_OUT_LOW_FREQUENCY);
+    /** @hide */
+    public static final int CHANNEL_OUT_5POINT1POINT2 = (CHANNEL_OUT_5POINT1 |
+            CHANNEL_OUT_TOP_SIDE_LEFT | CHANNEL_OUT_TOP_SIDE_RIGHT);
+    /** @hide */
+    public static final int CHANNEL_OUT_5POINT1POINT4 = (CHANNEL_OUT_5POINT1 |
+            CHANNEL_OUT_TOP_FRONT_LEFT | CHANNEL_OUT_TOP_FRONT_RIGHT |
+            CHANNEL_OUT_TOP_BACK_LEFT | CHANNEL_OUT_TOP_BACK_RIGHT);
+    /** @hide */
+    public static final int CHANNEL_OUT_7POINT1POINT2 = (CHANNEL_OUT_7POINT1_SURROUND |
+            CHANNEL_OUT_TOP_SIDE_LEFT | CHANNEL_OUT_TOP_SIDE_RIGHT);
+    /** @hide */
+    public static final int CHANNEL_OUT_7POINT1POINT4 = (CHANNEL_OUT_7POINT1_SURROUND |
+            CHANNEL_OUT_TOP_FRONT_LEFT | CHANNEL_OUT_TOP_FRONT_RIGHT |
+            CHANNEL_OUT_TOP_BACK_LEFT | CHANNEL_OUT_TOP_BACK_RIGHT);
+    /** @hide */
+    public static final int CHANNEL_OUT_13POINT_360RA = (
+            CHANNEL_OUT_FRONT_LEFT | CHANNEL_OUT_FRONT_CENTER | CHANNEL_OUT_FRONT_RIGHT |
+            CHANNEL_OUT_SIDE_LEFT | CHANNEL_OUT_SIDE_RIGHT |
+            CHANNEL_OUT_TOP_FRONT_LEFT | CHANNEL_OUT_TOP_FRONT_CENTER |
+            CHANNEL_OUT_TOP_FRONT_RIGHT |
+            CHANNEL_OUT_TOP_BACK_LEFT | CHANNEL_OUT_TOP_BACK_RIGHT |
+            CHANNEL_OUT_BOTTOM_FRONT_LEFT | CHANNEL_OUT_BOTTOM_FRONT_CENTER |
+            CHANNEL_OUT_BOTTOM_FRONT_RIGHT);
+    /** @hide */
+    public static final int CHANNEL_OUT_22POINT2 = (CHANNEL_OUT_7POINT1POINT4 |
+            CHANNEL_OUT_FRONT_LEFT_OF_CENTER | CHANNEL_OUT_FRONT_RIGHT_OF_CENTER |
+            CHANNEL_OUT_BACK_CENTER | CHANNEL_OUT_TOP_CENTER |
+            CHANNEL_OUT_TOP_FRONT_CENTER | CHANNEL_OUT_TOP_BACK_CENTER |
+            CHANNEL_OUT_TOP_SIDE_LEFT | CHANNEL_OUT_TOP_SIDE_RIGHT |
+            CHANNEL_OUT_BOTTOM_FRONT_LEFT | CHANNEL_OUT_BOTTOM_FRONT_RIGHT |
+            CHANNEL_OUT_BOTTOM_FRONT_CENTER |
+            CHANNEL_OUT_LOW_FREQUENCY_2);
+    // CHANNEL_OUT_ALL is not yet defined; if added then it should match AUDIO_CHANNEL_OUT_ALL
+
+    /** Minimum value for sample rate,
+     *  assuming AudioTrack and AudioRecord share the same limitations.
+     * @hide
+     */
+    // never unhide
+    public static final int SAMPLE_RATE_HZ_MIN = AudioSystem.SAMPLE_RATE_HZ_MIN;
+    /** Maximum value for sample rate,
+     *  assuming AudioTrack and AudioRecord share the same limitations.
+     * @hide
+     */
+    // never unhide
+    public static final int SAMPLE_RATE_HZ_MAX = AudioSystem.SAMPLE_RATE_HZ_MAX;
+    /** Sample rate will be a route-dependent value.
+     * For AudioTrack, it is usually the sink sample rate,
+     * and for AudioRecord it is usually the source sample rate.
+     */
+    public static final int SAMPLE_RATE_UNSPECIFIED = 0;
+
+    /**
+     * @hide
+     * Return the input channel mask corresponding to an output channel mask.
+     * This can be used for submix rerouting for the mask of the recorder to map to that of the mix.
+     * @param outMask a combination of the CHANNEL_OUT_* definitions, but not CHANNEL_OUT_DEFAULT
+     * @return a combination of CHANNEL_IN_* definitions matching an output channel mask
+     * @throws IllegalArgumentException
+     */
+    public static int inChannelMaskFromOutChannelMask(int outMask) throws IllegalArgumentException {
+        if (outMask == CHANNEL_OUT_DEFAULT) {
+            throw new IllegalArgumentException(
+                    "Illegal CHANNEL_OUT_DEFAULT channel mask for input.");
+        }
+        switch (channelCountFromOutChannelMask(outMask)) {
+            case 1:
+                return CHANNEL_IN_MONO;
+            case 2:
+                return CHANNEL_IN_STEREO;
+            default:
+                throw new IllegalArgumentException("Unsupported channel configuration for input.");
+        }
+    }
+
+    /**
+     * @hide
+     * Return the number of channels from an input channel mask
+     * @param mask a combination of the CHANNEL_IN_* definitions, even CHANNEL_IN_DEFAULT
+     * @return number of channels for the mask
+     */
+    @TestApi
+    public static int channelCountFromInChannelMask(int mask) {
+        return Integer.bitCount(mask);
+    }
+    /**
+     * @hide
+     * Return the number of channels from an output channel mask
+     * @param mask a combination of the CHANNEL_OUT_* definitions, but not CHANNEL_OUT_DEFAULT
+     * @return number of channels for the mask
+     */
+    @TestApi
+    public static int channelCountFromOutChannelMask(int mask) {
+        return Integer.bitCount(mask);
+    }
+    /**
+     * @hide
+     * Return a channel mask ready to be used by native code
+     * @param mask a combination of the CHANNEL_OUT_* definitions, but not CHANNEL_OUT_DEFAULT
+     * @return a native channel mask
+     */
+    public static int convertChannelOutMaskToNativeMask(int javaMask) {
+        return (javaMask >> 2);
+    }
+
+    /**
+     * @hide
+     * Return a java output channel mask
+     * @param mask a native channel mask
+     * @return a combination of the CHANNEL_OUT_* definitions
+     */
+    public static int convertNativeChannelMaskToOutMask(int nativeMask) {
+        return (nativeMask << 2);
+    }
+
+    public static final int CHANNEL_IN_DEFAULT = 1;
+    // These directly match native
+    public static final int CHANNEL_IN_LEFT = 0x4;
+    public static final int CHANNEL_IN_RIGHT = 0x8;
+    public static final int CHANNEL_IN_FRONT = 0x10;
+    public static final int CHANNEL_IN_BACK = 0x20;
+    public static final int CHANNEL_IN_LEFT_PROCESSED = 0x40;
+    public static final int CHANNEL_IN_RIGHT_PROCESSED = 0x80;
+    public static final int CHANNEL_IN_FRONT_PROCESSED = 0x100;
+    public static final int CHANNEL_IN_BACK_PROCESSED = 0x200;
+    public static final int CHANNEL_IN_PRESSURE = 0x400;
+    public static final int CHANNEL_IN_X_AXIS = 0x800;
+    public static final int CHANNEL_IN_Y_AXIS = 0x1000;
+    public static final int CHANNEL_IN_Z_AXIS = 0x2000;
+    public static final int CHANNEL_IN_VOICE_UPLINK = 0x4000;
+    public static final int CHANNEL_IN_VOICE_DNLINK = 0x8000;
+    public static final int CHANNEL_IN_MONO = CHANNEL_IN_FRONT;
+    public static final int CHANNEL_IN_STEREO = (CHANNEL_IN_LEFT | CHANNEL_IN_RIGHT);
+    /** @hide */
+    public static final int CHANNEL_IN_FRONT_BACK = CHANNEL_IN_FRONT | CHANNEL_IN_BACK;
+    // CHANNEL_IN_ALL is not yet defined; if added then it should match AUDIO_CHANNEL_IN_ALL
+
+    /** @hide */
+    @TestApi
+    public static int getBytesPerSample(int audioFormat)
+    {
+        switch (audioFormat) {
+            case ENCODING_PCM_8BIT:
+                return 1;
+            case ENCODING_PCM_16BIT:
+            case ENCODING_IEC61937:
+            case ENCODING_DEFAULT:
+                return 2;
+            case ENCODING_PCM_24BIT_PACKED:
+                return 3;
+            case ENCODING_PCM_FLOAT:
+            case ENCODING_PCM_32BIT:
+                return 4;
+            case ENCODING_INVALID:
+            default:
+                throw new IllegalArgumentException("Bad audio format " + audioFormat);
+        }
+    }
+
+    /** @hide */
+    public static boolean isValidEncoding(int audioFormat)
+    {
+        switch (audioFormat) {
+            case ENCODING_PCM_16BIT:
+            case ENCODING_PCM_8BIT:
+            case ENCODING_PCM_FLOAT:
+            case ENCODING_AC3:
+            case ENCODING_E_AC3:
+            case ENCODING_DTS:
+            case ENCODING_DTS_HD:
+            case ENCODING_MP3:
+            case ENCODING_AAC_LC:
+            case ENCODING_AAC_HE_V1:
+            case ENCODING_AAC_HE_V2:
+            case ENCODING_IEC61937:
+            case ENCODING_DOLBY_TRUEHD:
+            case ENCODING_AAC_ELD:
+            case ENCODING_AAC_XHE:
+            case ENCODING_AC4:
+            case ENCODING_E_AC3_JOC:
+            case ENCODING_DOLBY_MAT:
+            case ENCODING_OPUS:
+            case ENCODING_PCM_24BIT_PACKED:
+            case ENCODING_PCM_32BIT:
+            case ENCODING_MPEGH_BL_L3:
+            case ENCODING_MPEGH_BL_L4:
+            case ENCODING_MPEGH_LC_L3:
+            case ENCODING_MPEGH_LC_L4:
+            case ENCODING_DTS_UHD:
+            case ENCODING_DRA:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /** @hide */
+    public static boolean isPublicEncoding(int audioFormat)
+    {
+        switch (audioFormat) {
+            case ENCODING_PCM_16BIT:
+            case ENCODING_PCM_8BIT:
+            case ENCODING_PCM_FLOAT:
+            case ENCODING_AC3:
+            case ENCODING_E_AC3:
+            case ENCODING_DTS:
+            case ENCODING_DTS_HD:
+            case ENCODING_MP3:
+            case ENCODING_AAC_LC:
+            case ENCODING_AAC_HE_V1:
+            case ENCODING_AAC_HE_V2:
+            case ENCODING_IEC61937:
+            case ENCODING_DOLBY_TRUEHD:
+            case ENCODING_AAC_ELD:
+            case ENCODING_AAC_XHE:
+            case ENCODING_AC4:
+            case ENCODING_E_AC3_JOC:
+            case ENCODING_DOLBY_MAT:
+            case ENCODING_OPUS:
+            case ENCODING_PCM_24BIT_PACKED:
+            case ENCODING_PCM_32BIT:
+            case ENCODING_MPEGH_BL_L3:
+            case ENCODING_MPEGH_BL_L4:
+            case ENCODING_MPEGH_LC_L3:
+            case ENCODING_MPEGH_LC_L4:
+            case ENCODING_DTS_UHD:
+            case ENCODING_DRA:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /** @hide */
+    @TestApi
+    public static boolean isEncodingLinearPcm(int audioFormat)
+    {
+        switch (audioFormat) {
+            case ENCODING_PCM_16BIT:
+            case ENCODING_PCM_8BIT:
+            case ENCODING_PCM_FLOAT:
+            case ENCODING_PCM_24BIT_PACKED:
+            case ENCODING_PCM_32BIT:
+            case ENCODING_DEFAULT:
+                return true;
+            case ENCODING_AC3:
+            case ENCODING_E_AC3:
+            case ENCODING_DTS:
+            case ENCODING_DTS_HD:
+            case ENCODING_MP3:
+            case ENCODING_AAC_LC:
+            case ENCODING_AAC_HE_V1:
+            case ENCODING_AAC_HE_V2:
+            case ENCODING_IEC61937: // wrapped in PCM but compressed
+            case ENCODING_DOLBY_TRUEHD:
+            case ENCODING_AAC_ELD:
+            case ENCODING_AAC_XHE:
+            case ENCODING_AC4:
+            case ENCODING_E_AC3_JOC:
+            case ENCODING_DOLBY_MAT:
+            case ENCODING_OPUS:
+            case ENCODING_MPEGH_BL_L3:
+            case ENCODING_MPEGH_BL_L4:
+            case ENCODING_MPEGH_LC_L3:
+            case ENCODING_MPEGH_LC_L4:
+            case ENCODING_DTS_UHD:
+            case ENCODING_DRA:
+                return false;
+            case ENCODING_INVALID:
+            default:
+                throw new IllegalArgumentException("Bad audio format " + audioFormat);
+        }
+    }
+
+    /** @hide */
+    public static boolean isEncodingLinearFrames(int audioFormat)
+    {
+        switch (audioFormat) {
+            case ENCODING_PCM_16BIT:
+            case ENCODING_PCM_8BIT:
+            case ENCODING_PCM_FLOAT:
+            case ENCODING_IEC61937: // same size as stereo PCM
+            case ENCODING_PCM_24BIT_PACKED:
+            case ENCODING_PCM_32BIT:
+            case ENCODING_DEFAULT:
+                return true;
+            case ENCODING_AC3:
+            case ENCODING_E_AC3:
+            case ENCODING_DTS:
+            case ENCODING_DTS_HD:
+            case ENCODING_MP3:
+            case ENCODING_AAC_LC:
+            case ENCODING_AAC_HE_V1:
+            case ENCODING_AAC_HE_V2:
+            case ENCODING_DOLBY_TRUEHD:
+            case ENCODING_AAC_ELD:
+            case ENCODING_AAC_XHE:
+            case ENCODING_AC4:
+            case ENCODING_E_AC3_JOC:
+            case ENCODING_DOLBY_MAT:
+            case ENCODING_OPUS:
+            case ENCODING_MPEGH_BL_L3:
+            case ENCODING_MPEGH_BL_L4:
+            case ENCODING_MPEGH_LC_L3:
+            case ENCODING_MPEGH_LC_L4:
+            case ENCODING_DTS_UHD:
+            case ENCODING_DRA:
+                return false;
+            case ENCODING_INVALID:
+            default:
+                throw new IllegalArgumentException("Bad audio format " + audioFormat);
+        }
+    }
+    /**
+     * Returns an array of public encoding values extracted from an array of
+     * encoding values.
+     * @hide
+     */
+    public static int[] filterPublicFormats(int[] formats) {
+        if (formats == null) {
+            return null;
+        }
+        int[] myCopy = Arrays.copyOf(formats, formats.length);
+        int size = 0;
+        for (int i = 0; i < myCopy.length; i++) {
+            if (isPublicEncoding(myCopy[i])) {
+                if (size != i) {
+                    myCopy[size] = myCopy[i];
+                }
+                size++;
+            }
+        }
+        return Arrays.copyOf(myCopy, size);
+    }
+
+    /** @removed */
+    public AudioFormat()
+    {
+        throw new UnsupportedOperationException("There is no valid usage of this constructor");
+    }
+
+    /**
+     * Constructor used by the JNI.  Parameters are not checked for validity.
+     */
+    // Update sound trigger JNI in core/jni/android_hardware_SoundTrigger.cpp when modifying this
+    // constructor
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private AudioFormat(int encoding, int sampleRate, int channelMask, int channelIndexMask) {
+        this(
+             AUDIO_FORMAT_HAS_PROPERTY_ENCODING
+             | AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE
+             | AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK
+             | AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK,
+             encoding, sampleRate, channelMask, channelIndexMask
+             );
+    }
+
+    private AudioFormat(int propertySetMask,
+            int encoding, int sampleRate, int channelMask, int channelIndexMask) {
+        mPropertySetMask = propertySetMask;
+        mEncoding = (propertySetMask & AUDIO_FORMAT_HAS_PROPERTY_ENCODING) != 0
+                ? encoding : ENCODING_INVALID;
+        mSampleRate = (propertySetMask & AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) != 0
+                ? sampleRate : SAMPLE_RATE_UNSPECIFIED;
+        mChannelMask = (propertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) != 0
+                ? channelMask : CHANNEL_INVALID;
+        mChannelIndexMask = (propertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK) != 0
+                ? channelIndexMask : CHANNEL_INVALID;
+
+        // Compute derived values.
+
+        final int channelIndexCount = Integer.bitCount(getChannelIndexMask());
+        int channelCount = channelCountFromOutChannelMask(getChannelMask());
+        if (channelCount == 0) {
+            channelCount = channelIndexCount;
+        } else if (channelCount != channelIndexCount && channelIndexCount != 0) {
+            channelCount = 0; // position and index channel count mismatch
+        }
+        mChannelCount = channelCount;
+
+        int frameSizeInBytes = 1;
+        try {
+            frameSizeInBytes = getBytesPerSample(mEncoding) * channelCount;
+        } catch (IllegalArgumentException iae) {
+            // ignored
+        }
+        // it is possible that channel count is 0, so ensure we return 1 for
+        // mFrameSizeInBytes for consistency.
+        mFrameSizeInBytes = frameSizeInBytes != 0 ? frameSizeInBytes : 1;
+    }
+
+    /** @hide */
+    public final static int AUDIO_FORMAT_HAS_PROPERTY_NONE = 0x0;
+    /** @hide */
+    public final static int AUDIO_FORMAT_HAS_PROPERTY_ENCODING = 0x1 << 0;
+    /** @hide */
+    public final static int AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE = 0x1 << 1;
+    /** @hide */
+    public final static int AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK = 0x1 << 2;
+    /** @hide */
+    public final static int AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK = 0x1 << 3;
+
+    // This is an immutable class, all member variables are final.
+
+    // Essential values.
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private final int mEncoding;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private final int mSampleRate;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private final int mChannelMask;
+    private final int mChannelIndexMask;
+    private final int mPropertySetMask;
+
+    // Derived values computed in the constructor, cached here.
+    private final int mChannelCount;
+    private final int mFrameSizeInBytes;
+
+    /**
+     * Return the encoding.
+     * See the section on <a href="#encoding">encodings</a> for more information about the different
+     * types of supported audio encoding.
+     * @return one of the values that can be set in {@link Builder#setEncoding(int)} or
+     * {@link AudioFormat#ENCODING_INVALID} if not set.
+     */
+    public int getEncoding() {
+        return mEncoding;
+    }
+
+    /**
+     * Return the sample rate.
+     * @return one of the values that can be set in {@link Builder#setSampleRate(int)} or
+     * {@link #SAMPLE_RATE_UNSPECIFIED} if not set.
+     */
+    public int getSampleRate() {
+        return mSampleRate;
+    }
+
+    /**
+     * Return the channel mask.
+     * See the section on <a href="#channelMask">channel masks</a> for more information about
+     * the difference between index-based masks(as returned by {@link #getChannelIndexMask()}) and
+     * the position-based mask returned by this function.
+     * @return one of the values that can be set in {@link Builder#setChannelMask(int)} or
+     * {@link AudioFormat#CHANNEL_INVALID} if not set.
+     */
+    public int getChannelMask() {
+        return mChannelMask;
+    }
+
+    /**
+     * Return the channel index mask.
+     * See the section on <a href="#channelMask">channel masks</a> for more information about
+     * the difference between index-based masks, and position-based masks (as returned
+     * by {@link #getChannelMask()}).
+     * @return one of the values that can be set in {@link Builder#setChannelIndexMask(int)} or
+     * {@link AudioFormat#CHANNEL_INVALID} if not set or an invalid mask was used.
+     */
+    public int getChannelIndexMask() {
+        return mChannelIndexMask;
+    }
+
+    /**
+     * Return the channel count.
+     * @return the channel count derived from the channel position mask or the channel index mask.
+     * Zero is returned if both the channel position mask and the channel index mask are not set.
+     */
+    public int getChannelCount() {
+        return mChannelCount;
+    }
+
+    /**
+     * Return the frame size in bytes.
+     *
+     * For PCM or PCM packed compressed data this is the size of a sample multiplied
+     * by the channel count. For all other cases, including invalid/unset channel masks,
+     * this will return 1 byte.
+     * As an example, a stereo 16-bit PCM format would have a frame size of 4 bytes,
+     * an 8 channel float PCM format would have a frame size of 32 bytes,
+     * and a compressed data format (not packed in PCM) would have a frame size of 1 byte.
+     *
+     * Both {@link AudioRecord} or {@link AudioTrack} process data in multiples of
+     * this frame size.
+     *
+     * @return The audio frame size in bytes corresponding to the encoding and the channel mask.
+     */
+    public @IntRange(from = 1) int getFrameSizeInBytes() {
+        return mFrameSizeInBytes;
+    }
+
+    /** @hide */
+    public int getPropertySetMask() {
+        return mPropertySetMask;
+    }
+
+    /** @hide */
+    public String toLogFriendlyString() {
+        return String.format("%dch %dHz %s",
+                mChannelCount, mSampleRate, toLogFriendlyEncoding(mEncoding));
+    }
+
+    /**
+     * Builder class for {@link AudioFormat} objects.
+     * Use this class to configure and create an AudioFormat instance. By setting format
+     * characteristics such as audio encoding, channel mask or sample rate, you indicate which
+     * of those are to vary from the default behavior on this device wherever this audio format
+     * is used. See {@link AudioFormat} for a complete description of the different parameters that
+     * can be used to configure an <code>AudioFormat</code> instance.
+     * <p>{@link AudioFormat} is for instance used in
+     * {@link AudioTrack#AudioTrack(AudioAttributes, AudioFormat, int, int, int)}. In this
+     * constructor, every format characteristic set on the <code>Builder</code> (e.g. with
+     * {@link #setSampleRate(int)}) will alter the default values used by an
+     * <code>AudioTrack</code>. In this case for audio playback with <code>AudioTrack</code>, the
+     * sample rate set in the <code>Builder</code> would override the platform output sample rate
+     * which would otherwise be selected by default.
+     */
+    public static class Builder {
+        private int mEncoding = ENCODING_INVALID;
+        private int mSampleRate = SAMPLE_RATE_UNSPECIFIED;
+        private int mChannelMask = CHANNEL_INVALID;
+        private int mChannelIndexMask = 0;
+        private int mPropertySetMask = AUDIO_FORMAT_HAS_PROPERTY_NONE;
+
+        /**
+         * Constructs a new Builder with none of the format characteristics set.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Constructs a new Builder from a given {@link AudioFormat}.
+         * @param af the {@link AudioFormat} object whose data will be reused in the new Builder.
+         */
+        public Builder(AudioFormat af) {
+            mEncoding = af.mEncoding;
+            mSampleRate = af.mSampleRate;
+            mChannelMask = af.mChannelMask;
+            mChannelIndexMask = af.mChannelIndexMask;
+            mPropertySetMask = af.mPropertySetMask;
+        }
+
+        /**
+         * Combines all of the format characteristics that have been set and return a new
+         * {@link AudioFormat} object.
+         * @return a new {@link AudioFormat} object
+         */
+        public AudioFormat build() {
+            AudioFormat af = new AudioFormat(
+                    mPropertySetMask,
+                    mEncoding,
+                    mSampleRate,
+                    mChannelMask,
+                    mChannelIndexMask
+                    );
+            return af;
+        }
+
+        /**
+         * Sets the data encoding format.
+         * @param encoding the specified encoding or default.
+         * @return the same Builder instance.
+         * @throws java.lang.IllegalArgumentException
+         */
+        public Builder setEncoding(@Encoding int encoding) throws IllegalArgumentException {
+            switch (encoding) {
+                case ENCODING_DEFAULT:
+                    mEncoding = ENCODING_PCM_16BIT;
+                    break;
+                case ENCODING_PCM_16BIT:
+                case ENCODING_PCM_8BIT:
+                case ENCODING_PCM_FLOAT:
+                case ENCODING_AC3:
+                case ENCODING_E_AC3:
+                case ENCODING_DTS:
+                case ENCODING_DTS_HD:
+                case ENCODING_MP3:
+                case ENCODING_AAC_LC:
+                case ENCODING_AAC_HE_V1:
+                case ENCODING_AAC_HE_V2:
+                case ENCODING_IEC61937:
+                case ENCODING_DOLBY_TRUEHD:
+                case ENCODING_AAC_ELD:
+                case ENCODING_AAC_XHE:
+                case ENCODING_AC4:
+                case ENCODING_E_AC3_JOC:
+                case ENCODING_DOLBY_MAT:
+                case ENCODING_OPUS:
+                case ENCODING_PCM_24BIT_PACKED:
+                case ENCODING_PCM_32BIT:
+                case ENCODING_MPEGH_BL_L3:
+                case ENCODING_MPEGH_BL_L4:
+                case ENCODING_MPEGH_LC_L3:
+                case ENCODING_MPEGH_LC_L4:
+                case ENCODING_DTS_UHD:
+                case ENCODING_DRA:
+                    mEncoding = encoding;
+                    break;
+                case ENCODING_INVALID:
+                default:
+                    throw new IllegalArgumentException("Invalid encoding " + encoding);
+            }
+            mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_ENCODING;
+            return this;
+        }
+
+        /**
+         * Sets the channel position mask.
+         * The channel position mask specifies the association between audio samples in a frame
+         * with named endpoint channels. The samples in the frame correspond to the
+         * named set bits in the channel position mask, in ascending bit order.
+         * See {@link #setChannelIndexMask(int)} to specify channels
+         * based on endpoint numbered channels. This <a href="#channelPositionMask">description of
+         * channel position masks</a> covers the concept in more details.
+         * @param channelMask describes the configuration of the audio channels.
+         *    <p> For output, the channelMask can be an OR-ed combination of
+         *    channel position masks, e.g.
+         *    {@link AudioFormat#CHANNEL_OUT_FRONT_LEFT},
+         *    {@link AudioFormat#CHANNEL_OUT_FRONT_RIGHT},
+         *    {@link AudioFormat#CHANNEL_OUT_FRONT_CENTER},
+         *    {@link AudioFormat#CHANNEL_OUT_LOW_FREQUENCY}
+         *    {@link AudioFormat#CHANNEL_OUT_BACK_LEFT},
+         *    {@link AudioFormat#CHANNEL_OUT_BACK_RIGHT},
+         *    {@link AudioFormat#CHANNEL_OUT_BACK_CENTER},
+         *    {@link AudioFormat#CHANNEL_OUT_SIDE_LEFT},
+         *    {@link AudioFormat#CHANNEL_OUT_SIDE_RIGHT}.
+         *    <p> For a valid {@link AudioTrack} channel position mask,
+         *    the following conditions apply:
+         *    <br> (1) at most eight channel positions may be used;
+         *    <br> (2) right/left pairs should be matched.
+         *    <p> For input or {@link AudioRecord}, the mask should be
+         *    {@link AudioFormat#CHANNEL_IN_MONO} or
+         *    {@link AudioFormat#CHANNEL_IN_STEREO}.  {@link AudioFormat#CHANNEL_IN_MONO} is
+         *    guaranteed to work on all devices.
+         * @return the same <code>Builder</code> instance.
+         * @throws IllegalArgumentException if the channel mask is invalid or
+         *    if both channel index mask and channel position mask
+         *    are specified but do not have the same channel count.
+         */
+        public @NonNull Builder setChannelMask(int channelMask) {
+            if (channelMask == CHANNEL_INVALID) {
+                throw new IllegalArgumentException("Invalid zero channel mask");
+            } else if (/* channelMask != 0 && */ mChannelIndexMask != 0 &&
+                    Integer.bitCount(channelMask) != Integer.bitCount(mChannelIndexMask)) {
+                throw new IllegalArgumentException("Mismatched channel count for mask " +
+                        Integer.toHexString(channelMask).toUpperCase());
+            }
+            mChannelMask = channelMask;
+            mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK;
+            return this;
+        }
+
+        /**
+         * Sets the channel index mask.
+         * A channel index mask specifies the association of audio samples in the frame
+         * with numbered endpoint channels. The i-th bit in the channel index
+         * mask corresponds to the i-th endpoint channel.
+         * For example, an endpoint with four channels is represented
+         * as index mask bits 0 through 3. This <a href="#channelIndexMask>description of channel
+         * index masks</a> covers the concept in more details.
+         * See {@link #setChannelMask(int)} for a positional mask interpretation.
+         * <p> Both {@link AudioTrack} and {@link AudioRecord} support
+         * a channel index mask.
+         * If a channel index mask is specified it is used,
+         * otherwise the channel position mask specified
+         * by <code>setChannelMask</code> is used.
+         * For <code>AudioTrack</code> and <code>AudioRecord</code>,
+         * a channel position mask is not required if a channel index mask is specified.
+         *
+         * @param channelIndexMask describes the configuration of the audio channels.
+         *    <p> For output, the <code>channelIndexMask</code> is an OR-ed combination of
+         *    bits representing the mapping of <code>AudioTrack</code> write samples
+         *    to output sink channels.
+         *    For example, a mask of <code>0xa</code>, or binary <code>1010</code>,
+         *    means the <code>AudioTrack</code> write frame consists of two samples,
+         *    which are routed to the second and the fourth channels of the output sink.
+         *    Unmatched output sink channels are zero filled and unmatched
+         *    <code>AudioTrack</code> write samples are dropped.
+         *    <p> For input, the <code>channelIndexMask</code> is an OR-ed combination of
+         *    bits representing the mapping of input source channels to
+         *    <code>AudioRecord</code> read samples.
+         *    For example, a mask of <code>0x5</code>, or binary
+         *    <code>101</code>, will read from the first and third channel of the input
+         *    source device and store them in the first and second sample of the
+         *    <code>AudioRecord</code> read frame.
+         *    Unmatched input source channels are dropped and
+         *    unmatched <code>AudioRecord</code> read samples are zero filled.
+         * @return the same <code>Builder</code> instance.
+         * @throws IllegalArgumentException if the channel index mask is invalid or
+         *    if both channel index mask and channel position mask
+         *    are specified but do not have the same channel count.
+         */
+        public @NonNull Builder setChannelIndexMask(int channelIndexMask) {
+            if (channelIndexMask == 0) {
+                throw new IllegalArgumentException("Invalid zero channel index mask");
+            } else if (/* channelIndexMask != 0 && */ mChannelMask != 0 &&
+                    Integer.bitCount(channelIndexMask) != Integer.bitCount(mChannelMask)) {
+                throw new IllegalArgumentException("Mismatched channel count for index mask " +
+                        Integer.toHexString(channelIndexMask).toUpperCase());
+            }
+            mChannelIndexMask = channelIndexMask;
+            mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK;
+            return this;
+        }
+
+        /**
+         * Sets the sample rate.
+         * @param sampleRate the sample rate expressed in Hz
+         * @return the same Builder instance.
+         * @throws java.lang.IllegalArgumentException
+         */
+        public Builder setSampleRate(int sampleRate) throws IllegalArgumentException {
+            // TODO Consider whether to keep the MIN and MAX range checks here.
+            // It is not necessary and poses the problem of defining the limits independently from
+            // native implementation or platform capabilities.
+            if (((sampleRate < SAMPLE_RATE_HZ_MIN) || (sampleRate > SAMPLE_RATE_HZ_MAX)) &&
+                    sampleRate != SAMPLE_RATE_UNSPECIFIED) {
+                throw new IllegalArgumentException("Invalid sample rate " + sampleRate);
+            }
+            mSampleRate = sampleRate;
+            mPropertySetMask |= AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE;
+            return this;
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        AudioFormat that = (AudioFormat) o;
+
+        if (mPropertySetMask != that.mPropertySetMask) return false;
+
+        // return false if any of the properties is set and the values differ
+        return !((((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_ENCODING) != 0)
+                            && (mEncoding != that.mEncoding))
+                    || (((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_SAMPLE_RATE) != 0)
+                            && (mSampleRate != that.mSampleRate))
+                    || (((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) != 0)
+                            && (mChannelMask != that.mChannelMask))
+                    || (((mPropertySetMask & AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK) != 0)
+                            && (mChannelIndexMask != that.mChannelIndexMask)));
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mPropertySetMask, mSampleRate, mEncoding, mChannelMask,
+                mChannelIndexMask);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mPropertySetMask);
+        dest.writeInt(mEncoding);
+        dest.writeInt(mSampleRate);
+        dest.writeInt(mChannelMask);
+        dest.writeInt(mChannelIndexMask);
+    }
+
+    private AudioFormat(Parcel in) {
+        this(
+             in.readInt(), // propertySetMask
+             in.readInt(), // encoding
+             in.readInt(), // sampleRate
+             in.readInt(), // channelMask
+             in.readInt()  // channelIndexMask
+            );
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<AudioFormat> CREATOR =
+            new Parcelable.Creator<AudioFormat>() {
+        public AudioFormat createFromParcel(Parcel p) {
+            return new AudioFormat(p);
+        }
+        public AudioFormat[] newArray(int size) {
+            return new AudioFormat[size];
+        }
+    };
+
+    @Override
+    public String toString () {
+        return new String("AudioFormat:"
+                + " props=" + mPropertySetMask
+                + " enc=" + mEncoding
+                + " chan=0x" + Integer.toHexString(mChannelMask).toUpperCase()
+                + " chan_index=0x" + Integer.toHexString(mChannelIndexMask).toUpperCase()
+                + " rate=" + mSampleRate);
+    }
+
+    /** @hide */
+    @IntDef(flag = false, prefix = "ENCODING", value = {
+        ENCODING_DEFAULT,
+        ENCODING_PCM_16BIT,
+        ENCODING_PCM_8BIT,
+        ENCODING_PCM_FLOAT,
+        ENCODING_AC3,
+        ENCODING_E_AC3,
+        ENCODING_DTS,
+        ENCODING_DTS_HD,
+        ENCODING_MP3,
+        ENCODING_AAC_LC,
+        ENCODING_AAC_HE_V1,
+        ENCODING_AAC_HE_V2,
+        ENCODING_IEC61937,
+        ENCODING_DOLBY_TRUEHD,
+        ENCODING_AAC_ELD,
+        ENCODING_AAC_XHE,
+        ENCODING_AC4,
+        ENCODING_E_AC3_JOC,
+        ENCODING_DOLBY_MAT,
+        ENCODING_OPUS,
+        ENCODING_PCM_24BIT_PACKED,
+        ENCODING_PCM_32BIT,
+        ENCODING_MPEGH_BL_L3,
+        ENCODING_MPEGH_BL_L4,
+        ENCODING_MPEGH_LC_L3,
+        ENCODING_MPEGH_LC_L4,
+        ENCODING_DTS_UHD,
+        ENCODING_DRA }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Encoding {}
+
+    /** @hide */
+    public static final int[] SURROUND_SOUND_ENCODING = {
+            ENCODING_AC3,
+            ENCODING_E_AC3,
+            ENCODING_DTS,
+            ENCODING_DTS_HD,
+            ENCODING_AAC_LC,
+            ENCODING_DOLBY_TRUEHD,
+            ENCODING_AC4,
+            ENCODING_E_AC3_JOC,
+            ENCODING_DOLBY_MAT,
+            ENCODING_MPEGH_BL_L3,
+            ENCODING_MPEGH_BL_L4,
+            ENCODING_MPEGH_LC_L3,
+            ENCODING_MPEGH_LC_L4,
+            ENCODING_DTS_UHD,
+            ENCODING_DRA
+    };
+
+    /** @hide */
+    @IntDef(flag = false, prefix = "ENCODING", value = {
+            ENCODING_AC3,
+            ENCODING_E_AC3,
+            ENCODING_DTS,
+            ENCODING_DTS_HD,
+            ENCODING_AAC_LC,
+            ENCODING_DOLBY_TRUEHD,
+            ENCODING_AC4,
+            ENCODING_E_AC3_JOC,
+            ENCODING_DOLBY_MAT,
+            ENCODING_MPEGH_BL_L3,
+            ENCODING_MPEGH_BL_L4,
+            ENCODING_MPEGH_LC_L3,
+            ENCODING_MPEGH_LC_L4,
+            ENCODING_DTS_UHD,
+            ENCODING_DRA }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SurroundSoundEncoding {}
+
+    /**
+     * @hide
+     *
+     * Return default name for a surround format. This is not an International name.
+     * It is just a default to use if an international name is not available.
+     *
+     * @param audioFormat a surround format
+     * @return short default name for the format.
+     */
+    public static String toDisplayName(@SurroundSoundEncoding int audioFormat) {
+        switch (audioFormat) {
+            case ENCODING_AC3:
+                return "Dolby Digital";
+            case ENCODING_E_AC3:
+                return "Dolby Digital Plus";
+            case ENCODING_DTS:
+                return "DTS";
+            case ENCODING_DTS_HD:
+                return "DTS HD";
+            case ENCODING_AAC_LC:
+                return "AAC";
+            case ENCODING_DOLBY_TRUEHD:
+                return "Dolby TrueHD";
+            case ENCODING_AC4:
+                return "Dolby AC-4";
+            case ENCODING_E_AC3_JOC:
+                return "Dolby Atmos in Dolby Digital Plus";
+            case ENCODING_DOLBY_MAT:
+                return "Dolby MAT";
+            case ENCODING_MPEGH_BL_L3:
+                return "MPEG-H 3D Audio baseline profile level 3";
+            case ENCODING_MPEGH_BL_L4:
+                return "MPEG-H 3D Audio baseline profile level 4";
+            case ENCODING_MPEGH_LC_L3:
+                return "MPEG-H 3D Audio low complexity profile level 3";
+            case ENCODING_MPEGH_LC_L4:
+                return "MPEG-H 3D Audio low complexity profile level 4";
+            case ENCODING_DTS_UHD:
+                return "DTS UHD";
+            case ENCODING_DRA:
+                return "DRA";
+            default:
+                return "Unknown surround sound format";
+        }
+    }
+
+}
diff --git a/android/media/AudioGain.java b/android/media/AudioGain.java
new file mode 100644
index 0000000..98dc06a
--- /dev/null
+++ b/android/media/AudioGain.java
@@ -0,0 +1,163 @@
+/*
+ * Copyright (C) 2014 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.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+
+/**
+ * The AudioGain describes a gain controller. Gain controllers are exposed by
+ * audio ports when the gain is configurable at this port's input or output.
+ * Gain values are expressed in millibels.
+ * A gain controller has the following attributes:
+ * - mode: defines modes of operation or features
+ *    MODE_JOINT: all channel gains are controlled simultaneously
+ *    MODE_CHANNELS: each channel gain is controlled individually
+ *    MODE_RAMP: ramps can be applied when gain changes
+ * - channel mask: indicates for which channels the gain can be controlled
+ * - min value: minimum gain value in millibel
+ * - max value: maximum gain value in millibel
+ * - default value: gain value after reset in millibel
+ * - step value: granularity of gain control in millibel
+ * - min ramp duration: minimum ramp duration in milliseconds
+ * - max ramp duration: maximum ramp duration in milliseconds
+ *
+ * This object is always created by the framework and read only by applications.
+ * Applications get a list of AudioGainDescriptors from AudioPortDescriptor.gains() and can build a
+ * valid gain configuration from AudioGain.buildConfig()
+ * @hide
+ */
+public class AudioGain {
+
+    /**
+     * Bit of AudioGain.mode() field indicating that
+     * all channel gains are controlled simultaneously
+     */
+    public static final int MODE_JOINT = 1;
+    /**
+     * Bit of AudioGain.mode() field indicating that
+     * each channel gain is controlled individually
+     */
+    public static final int MODE_CHANNELS = 2;
+    /**
+     * Bit of AudioGain.mode() field indicating that
+     * ramps can be applied when gain changes. The type of ramp (linear, log etc...) is
+     * implementation specific.
+     */
+    public static final int MODE_RAMP = 4;
+
+    private final int mIndex;
+    private final int mMode;
+    private final int mChannelMask;
+    private final int mMinValue;
+    private final int mMaxValue;
+    private final int mDefaultValue;
+    private final int mStepValue;
+    private final int mRampDurationMinMs;
+    private final int mRampDurationMaxMs;
+
+    // The channel mask passed to the constructor is as specified in AudioFormat
+    // (e.g. AudioFormat.CHANNEL_OUT_STEREO)
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    AudioGain(int index, int mode, int channelMask,
+                        int minValue, int maxValue, int defaultValue, int stepValue,
+                        int rampDurationMinMs, int rampDurationMaxMs) {
+        mIndex = index;
+        mMode = mode;
+        mChannelMask = channelMask;
+        mMinValue = minValue;
+        mMaxValue = maxValue;
+        mDefaultValue = defaultValue;
+        mStepValue = stepValue;
+        mRampDurationMinMs = rampDurationMinMs;
+        mRampDurationMaxMs = rampDurationMaxMs;
+    }
+
+    /**
+     * Bit field indicating supported modes of operation
+     */
+    public int mode() {
+        return mMode;
+    }
+
+    /**
+     * Indicates for which channels the gain can be controlled
+     * (e.g. AudioFormat.CHANNEL_OUT_STEREO)
+     */
+    public int channelMask() {
+        return mChannelMask;
+    }
+
+    /**
+     * Minimum gain value in millibel
+     */
+    public int minValue() {
+        return mMinValue;
+    }
+
+    /**
+     * Maximum gain value in millibel
+     */
+    public int maxValue() {
+        return mMaxValue;
+    }
+
+    /**
+     * Default gain value in millibel
+     */
+    public int defaultValue() {
+        return mDefaultValue;
+    }
+
+    /**
+     * Granularity of gain control in millibel
+     */
+    public int stepValue() {
+        return mStepValue;
+    }
+
+    /**
+     * Minimum ramp duration in milliseconds
+     * 0 if MODE_RAMP not set
+     */
+    public int rampDurationMinMs() {
+        return mRampDurationMinMs;
+    }
+
+    /**
+     * Maximum ramp duration in milliseconds
+     * 0 if MODE_RAMP not set
+     */
+    public int rampDurationMaxMs() {
+        return mRampDurationMaxMs;
+    }
+
+    /**
+     * Build a valid gain configuration for this gain controller for use by
+     * AudioPortDescriptor.setGain()
+     * @param mode: desired mode of operation
+     * @param channelMask: channels of which the gain should be modified.
+     * @param values: gain values for each channels.
+     * @param rampDurationMs: ramp duration if mode MODE_RAMP is set.
+     * ignored if MODE_JOINT.
+     */
+    public AudioGainConfig buildConfig(int mode, int channelMask,
+                                       int[] values, int rampDurationMs) {
+        //TODO: check params here
+        return new AudioGainConfig(mIndex, this, mode, channelMask, values, rampDurationMs);
+    }
+}
diff --git a/android/media/AudioGainConfig.java b/android/media/AudioGainConfig.java
new file mode 100644
index 0000000..dfefa86
--- /dev/null
+++ b/android/media/AudioGainConfig.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2014 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.compat.annotation.UnsupportedAppUsage;
+
+/**
+ * The AudioGainConfig is used by APIs setting or getting values on a given gain
+ * controller. It contains a valid configuration (value, channels...) for a gain controller
+ * exposed by an audio port.
+ * @see AudioGain
+ * @see AudioPort
+ * @hide
+ */
+public class AudioGainConfig {
+    AudioGain mGain;
+    @UnsupportedAppUsage
+    private final int mIndex;
+    @UnsupportedAppUsage
+    private final int mMode;
+    @UnsupportedAppUsage
+    private final int mChannelMask;
+    @UnsupportedAppUsage
+    private final int mValues[];
+    @UnsupportedAppUsage
+    private final int mRampDurationMs;
+
+    @UnsupportedAppUsage
+    AudioGainConfig(int index, AudioGain gain, int mode, int channelMask,
+            int[] values, int rampDurationMs) {
+        mIndex = index;
+        mGain = gain;
+        mMode = mode;
+        mChannelMask = channelMask;
+        mValues = values;
+        mRampDurationMs = rampDurationMs;
+    }
+
+    /**
+     * get the index of the parent gain.
+     * frameworks use only.
+     */
+    int index() {
+        return mIndex;
+    }
+
+    /**
+     * Bit field indicating requested modes of operation. See {@link AudioGain#MODE_JOINT},
+     * {@link AudioGain#MODE_CHANNELS}, {@link AudioGain#MODE_RAMP}
+     */
+    public int mode() {
+        return mMode;
+    }
+
+    /**
+     * Indicates for which channels the gain is set.
+     * See {@link AudioFormat#CHANNEL_OUT_STEREO}, {@link AudioFormat#CHANNEL_OUT_MONO} ...
+     */
+    public int channelMask() {
+        return mChannelMask;
+    }
+
+    /**
+     * Gain values for each channel in the order of bits set in
+     * channelMask() from LSB to MSB
+     */
+    public int[] values() {
+        return mValues;
+    }
+
+    /**
+     * Ramp duration in milliseconds. N/A if mode() does not
+     * specify MODE_RAMP.
+     */
+    public int rampDurationMs() {
+        return mRampDurationMs;
+    }
+}
diff --git a/android/media/AudioHandle.java b/android/media/AudioHandle.java
new file mode 100644
index 0000000..ce51b5a
--- /dev/null
+++ b/android/media/AudioHandle.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2014 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.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+
+/**
+ * The AudioHandle is used by the audio framework implementation to
+ * uniquely identify a particular component of the routing topology
+ * (AudioPort or AudioPatch)
+ * It is not visible or used at the API.
+ */
+class AudioHandle {
+    @UnsupportedAppUsage
+    private final int mId;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    AudioHandle(int id) {
+        mId = id;
+    }
+
+    int id() {
+        return mId;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || !(o instanceof AudioHandle)) {
+            return false;
+        }
+        AudioHandle ah = (AudioHandle)o;
+        return mId == ah.id();
+    }
+
+    @Override
+    public int hashCode() {
+        return mId;
+    }
+
+    @Override
+    public String toString() {
+        return Integer.toString(mId);
+    }
+}
diff --git a/android/media/AudioManager.java b/android/media/AudioManager.java
new file mode 100644
index 0000000..3b9c05b
--- /dev/null
+++ b/android/media/AudioManager.java
@@ -0,0 +1,7837 @@
+/*
+ * Copyright (C) 2007 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.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.annotation.TestApi;
+import android.app.NotificationManager;
+import android.app.PendingIntent;
+import android.bluetooth.BluetoothCodecConfig;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothProfile;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.media.AudioAttributes.AttributeSystemUsage;
+import android.media.audiopolicy.AudioPolicy;
+import android.media.audiopolicy.AudioPolicy.AudioPolicyFocusListener;
+import android.media.audiopolicy.AudioProductStrategy;
+import android.media.audiopolicy.AudioVolumeGroup;
+import android.media.audiopolicy.AudioVolumeGroupChangeHandler;
+import android.media.projection.MediaProjection;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionLegacyHelper;
+import android.media.session.MediaSessionManager;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Pair;
+import android.view.KeyEvent;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.TreeMap;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+
+
+/**
+ * AudioManager provides access to volume and ringer mode control.
+ */
+@SystemService(Context.AUDIO_SERVICE)
+public class AudioManager {
+
+    private Context mOriginalContext;
+    private Context mApplicationContext;
+    private long mVolumeKeyUpTime;
+    private boolean mUseFixedVolumeInitialized;
+    private boolean mUseFixedVolume;
+    private static final String TAG = "AudioManager";
+    private static final boolean DEBUG = false;
+    private static final AudioPortEventHandler sAudioPortEventHandler = new AudioPortEventHandler();
+    private static final AudioVolumeGroupChangeHandler sAudioAudioVolumeGroupChangedHandler =
+            new AudioVolumeGroupChangeHandler();
+
+    private static WeakReference<Context> sContext;
+
+    /**
+     * Broadcast intent, a hint for applications that audio is about to become
+     * 'noisy' due to a change in audio outputs. For example, this intent may
+     * be sent when a wired headset is unplugged, or when an A2DP audio
+     * sink is disconnected, and the audio system is about to automatically
+     * switch audio route to the speaker. Applications that are controlling
+     * audio streams may consider pausing, reducing volume or some other action
+     * on receipt of this intent so as not to surprise the user with audio
+     * from the speaker.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_AUDIO_BECOMING_NOISY = "android.media.AUDIO_BECOMING_NOISY";
+
+    /**
+     * Sticky broadcast intent action indicating that the ringer mode has
+     * changed. Includes the new ringer mode.
+     *
+     * @see #EXTRA_RINGER_MODE
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String RINGER_MODE_CHANGED_ACTION = "android.media.RINGER_MODE_CHANGED";
+
+    /**
+     * @hide
+     * Sticky broadcast intent action indicating that the internal ringer mode has
+     * changed. Includes the new ringer mode.
+     *
+     * @see #EXTRA_RINGER_MODE
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String INTERNAL_RINGER_MODE_CHANGED_ACTION =
+            "android.media.INTERNAL_RINGER_MODE_CHANGED_ACTION";
+
+    /**
+     * The new ringer mode.
+     *
+     * @see #RINGER_MODE_CHANGED_ACTION
+     * @see #RINGER_MODE_NORMAL
+     * @see #RINGER_MODE_SILENT
+     * @see #RINGER_MODE_VIBRATE
+     */
+    public static final String EXTRA_RINGER_MODE = "android.media.EXTRA_RINGER_MODE";
+
+    /**
+     * Broadcast intent action indicating that the vibrate setting has
+     * changed. Includes the vibrate type and its new setting.
+     *
+     * @see #EXTRA_VIBRATE_TYPE
+     * @see #EXTRA_VIBRATE_SETTING
+     * @deprecated Applications should maintain their own vibrate policy based on
+     * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String VIBRATE_SETTING_CHANGED_ACTION =
+        "android.media.VIBRATE_SETTING_CHANGED";
+
+    /**
+     * @hide Broadcast intent when the volume for a particular stream type changes.
+     * Includes the stream, the new volume and previous volumes.
+     * Notes:
+     *  - for internal platform use only, do not make public,
+     *  - never used for "remote" volume changes
+     *
+     * @see #EXTRA_VOLUME_STREAM_TYPE
+     * @see #EXTRA_VOLUME_STREAM_VALUE
+     * @see #EXTRA_PREV_VOLUME_STREAM_VALUE
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    @UnsupportedAppUsage
+    public static final String VOLUME_CHANGED_ACTION = "android.media.VOLUME_CHANGED_ACTION";
+
+    /**
+     * @hide Broadcast intent when the devices for a particular stream type changes.
+     * Includes the stream, the new devices and previous devices.
+     * Notes:
+     *  - for internal platform use only, do not make public,
+     *  - never used for "remote" volume changes
+     *
+     * @see #EXTRA_VOLUME_STREAM_TYPE
+     * @see #EXTRA_VOLUME_STREAM_DEVICES
+     * @see #EXTRA_PREV_VOLUME_STREAM_DEVICES
+     * @see #getDevicesForStream
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String STREAM_DEVICES_CHANGED_ACTION =
+        "android.media.STREAM_DEVICES_CHANGED_ACTION";
+
+    /**
+     * @hide Broadcast intent when a stream mute state changes.
+     * Includes the stream that changed and the new mute state
+     *
+     * @see #EXTRA_VOLUME_STREAM_TYPE
+     * @see #EXTRA_STREAM_VOLUME_MUTED
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String STREAM_MUTE_CHANGED_ACTION =
+        "android.media.STREAM_MUTE_CHANGED_ACTION";
+
+    /**
+     * @hide Broadcast intent when the master mute state changes.
+     * Includes the the new volume
+     *
+     * @see #EXTRA_MASTER_VOLUME_MUTED
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String MASTER_MUTE_CHANGED_ACTION =
+        "android.media.MASTER_MUTE_CHANGED_ACTION";
+
+    /**
+     * The new vibrate setting for a particular type.
+     *
+     * @see #VIBRATE_SETTING_CHANGED_ACTION
+     * @see #EXTRA_VIBRATE_TYPE
+     * @see #VIBRATE_SETTING_ON
+     * @see #VIBRATE_SETTING_OFF
+     * @see #VIBRATE_SETTING_ONLY_SILENT
+     * @deprecated Applications should maintain their own vibrate policy based on
+     * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead.
+     */
+    public static final String EXTRA_VIBRATE_SETTING = "android.media.EXTRA_VIBRATE_SETTING";
+
+    /**
+     * The vibrate type whose setting has changed.
+     *
+     * @see #VIBRATE_SETTING_CHANGED_ACTION
+     * @see #VIBRATE_TYPE_NOTIFICATION
+     * @see #VIBRATE_TYPE_RINGER
+     * @deprecated Applications should maintain their own vibrate policy based on
+     * current ringer mode and listen to {@link #RINGER_MODE_CHANGED_ACTION} instead.
+     */
+    public static final String EXTRA_VIBRATE_TYPE = "android.media.EXTRA_VIBRATE_TYPE";
+
+    /**
+     * @hide The stream type for the volume changed intent.
+     */
+    @UnsupportedAppUsage
+    public static final String EXTRA_VOLUME_STREAM_TYPE = "android.media.EXTRA_VOLUME_STREAM_TYPE";
+
+    /**
+     * @hide
+     * The stream type alias for the volume changed intent.
+     * For instance the intent may indicate a change of the {@link #STREAM_NOTIFICATION} stream
+     * type (as indicated by the {@link #EXTRA_VOLUME_STREAM_TYPE} extra), but this is also
+     * reflected by a change of the volume of its alias, {@link #STREAM_RING} on some devices,
+     * {@link #STREAM_MUSIC} on others (e.g. a television).
+     */
+    public static final String EXTRA_VOLUME_STREAM_TYPE_ALIAS =
+            "android.media.EXTRA_VOLUME_STREAM_TYPE_ALIAS";
+
+    /**
+     * @hide The volume associated with the stream for the volume changed intent.
+     */
+    @UnsupportedAppUsage
+    public static final String EXTRA_VOLUME_STREAM_VALUE =
+        "android.media.EXTRA_VOLUME_STREAM_VALUE";
+
+    /**
+     * @hide The previous volume associated with the stream for the volume changed intent.
+     */
+    public static final String EXTRA_PREV_VOLUME_STREAM_VALUE =
+        "android.media.EXTRA_PREV_VOLUME_STREAM_VALUE";
+
+    /**
+     * @hide The devices associated with the stream for the stream devices changed intent.
+     */
+    public static final String EXTRA_VOLUME_STREAM_DEVICES =
+        "android.media.EXTRA_VOLUME_STREAM_DEVICES";
+
+    /**
+     * @hide The previous devices associated with the stream for the stream devices changed intent.
+     */
+    public static final String EXTRA_PREV_VOLUME_STREAM_DEVICES =
+        "android.media.EXTRA_PREV_VOLUME_STREAM_DEVICES";
+
+    /**
+     * @hide The new master volume mute state for the master mute changed intent.
+     * Value is boolean
+     */
+    public static final String EXTRA_MASTER_VOLUME_MUTED =
+        "android.media.EXTRA_MASTER_VOLUME_MUTED";
+
+    /**
+     * @hide The new stream volume mute state for the stream mute changed intent.
+     * Value is boolean
+     */
+    public static final String EXTRA_STREAM_VOLUME_MUTED =
+        "android.media.EXTRA_STREAM_VOLUME_MUTED";
+
+    /**
+     * Broadcast Action: Wired Headset plugged in or unplugged.
+     *
+     * You <em>cannot</em> receive this through components declared
+     * in manifests, only by explicitly registering for it with
+     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
+     * Context.registerReceiver()}.
+     *
+     * <p>The intent will have the following extra values:
+     * <ul>
+     *   <li><em>state</em> - 0 for unplugged, 1 for plugged. </li>
+     *   <li><em>name</em> - Headset type, human readable string </li>
+     *   <li><em>microphone</em> - 1 if headset has a microphone, 0 otherwise </li>
+     * </ul>
+     * </ul>
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_HEADSET_PLUG =
+            "android.intent.action.HEADSET_PLUG";
+
+    /**
+     * Broadcast Action: A sticky broadcast indicating an HDMI cable was plugged or unplugged.
+     *
+     * The intent will have the following extra values: {@link #EXTRA_AUDIO_PLUG_STATE},
+     * {@link #EXTRA_MAX_CHANNEL_COUNT}, {@link #EXTRA_ENCODINGS}.
+     * <p>It can only be received by explicitly registering for it with
+     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)}.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_HDMI_AUDIO_PLUG =
+            "android.media.action.HDMI_AUDIO_PLUG";
+
+    /**
+     * Extra used in {@link #ACTION_HDMI_AUDIO_PLUG} to communicate whether HDMI is plugged in
+     * or unplugged.
+     * An integer value of 1 indicates a plugged-in state, 0 is unplugged.
+     */
+    public static final String EXTRA_AUDIO_PLUG_STATE = "android.media.extra.AUDIO_PLUG_STATE";
+
+    /**
+     * Extra used in {@link #ACTION_HDMI_AUDIO_PLUG} to define the maximum number of channels
+     * supported by the HDMI device.
+     * The corresponding integer value is only available when the device is plugged in (as expressed
+     * by {@link #EXTRA_AUDIO_PLUG_STATE}).
+     */
+    public static final String EXTRA_MAX_CHANNEL_COUNT = "android.media.extra.MAX_CHANNEL_COUNT";
+
+    /**
+     * Extra used in {@link #ACTION_HDMI_AUDIO_PLUG} to define the audio encodings supported by
+     * the connected HDMI device.
+     * The corresponding array of encoding values is only available when the device is plugged in
+     * (as expressed by {@link #EXTRA_AUDIO_PLUG_STATE}). Encoding values are defined in
+     * {@link AudioFormat} (for instance see {@link AudioFormat#ENCODING_PCM_16BIT}). Use
+     * {@link android.content.Intent#getIntArrayExtra(String)} to retrieve the encoding values.
+     */
+    public static final String EXTRA_ENCODINGS = "android.media.extra.ENCODINGS";
+
+    /** Used to identify the volume of audio streams for phone calls */
+    public static final int STREAM_VOICE_CALL = AudioSystem.STREAM_VOICE_CALL;
+    /** Used to identify the volume of audio streams for system sounds */
+    public static final int STREAM_SYSTEM = AudioSystem.STREAM_SYSTEM;
+    /** Used to identify the volume of audio streams for the phone ring */
+    public static final int STREAM_RING = AudioSystem.STREAM_RING;
+    /** Used to identify the volume of audio streams for music playback */
+    public static final int STREAM_MUSIC = AudioSystem.STREAM_MUSIC;
+    /** Used to identify the volume of audio streams for alarms */
+    public static final int STREAM_ALARM = AudioSystem.STREAM_ALARM;
+    /** Used to identify the volume of audio streams for notifications */
+    public static final int STREAM_NOTIFICATION = AudioSystem.STREAM_NOTIFICATION;
+    /** @hide Used to identify the volume of audio streams for phone calls when connected
+     *        to bluetooth */
+    @UnsupportedAppUsage
+    public static final int STREAM_BLUETOOTH_SCO = AudioSystem.STREAM_BLUETOOTH_SCO;
+    /** @hide Used to identify the volume of audio streams for enforced system sounds
+     *        in certain countries (e.g camera in Japan) */
+    @UnsupportedAppUsage
+    public static final int STREAM_SYSTEM_ENFORCED = AudioSystem.STREAM_SYSTEM_ENFORCED;
+    /** Used to identify the volume of audio streams for DTMF Tones */
+    public static final int STREAM_DTMF = AudioSystem.STREAM_DTMF;
+    /** @hide Used to identify the volume of audio streams exclusively transmitted through the
+     *        speaker (TTS) of the device */
+    @UnsupportedAppUsage
+    public static final int STREAM_TTS = AudioSystem.STREAM_TTS;
+    /** Used to identify the volume of audio streams for accessibility prompts */
+    public static final int STREAM_ACCESSIBILITY = AudioSystem.STREAM_ACCESSIBILITY;
+    /** @hide Used to identify the volume of audio streams for virtual assistant */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public static final int STREAM_ASSISTANT = AudioSystem.STREAM_ASSISTANT;
+
+    /** Number of audio streams */
+    /**
+     * @deprecated Do not iterate on volume stream type values.
+     */
+    @Deprecated public static final int NUM_STREAMS = AudioSystem.NUM_STREAMS;
+
+    /**
+     * Increase the ringer volume.
+     *
+     * @see #adjustVolume(int, int)
+     * @see #adjustStreamVolume(int, int, int)
+     */
+    public static final int ADJUST_RAISE = 1;
+
+    /**
+     * Decrease the ringer volume.
+     *
+     * @see #adjustVolume(int, int)
+     * @see #adjustStreamVolume(int, int, int)
+     */
+    public static final int ADJUST_LOWER = -1;
+
+    /**
+     * Maintain the previous ringer volume. This may be useful when needing to
+     * show the volume toast without actually modifying the volume.
+     *
+     * @see #adjustVolume(int, int)
+     * @see #adjustStreamVolume(int, int, int)
+     */
+    public static final int ADJUST_SAME = 0;
+
+    /**
+     * Mute the volume. Has no effect if the stream is already muted.
+     *
+     * @see #adjustVolume(int, int)
+     * @see #adjustStreamVolume(int, int, int)
+     */
+    public static final int ADJUST_MUTE = -100;
+
+    /**
+     * Unmute the volume. Has no effect if the stream is not muted.
+     *
+     * @see #adjustVolume(int, int)
+     * @see #adjustStreamVolume(int, int, int)
+     */
+    public static final int ADJUST_UNMUTE = 100;
+
+    /**
+     * Toggle the mute state. If muted the stream will be unmuted. If not muted
+     * the stream will be muted.
+     *
+     * @see #adjustVolume(int, int)
+     * @see #adjustStreamVolume(int, int, int)
+     */
+    public static final int ADJUST_TOGGLE_MUTE = 101;
+
+    /** @hide */
+    @IntDef(flag = false, prefix = "ADJUST", value = {
+            ADJUST_RAISE,
+            ADJUST_LOWER,
+            ADJUST_SAME,
+            ADJUST_MUTE,
+            ADJUST_UNMUTE,
+            ADJUST_TOGGLE_MUTE }
+            )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface VolumeAdjustment {}
+
+    /** @hide */
+    public static final String adjustToString(int adj) {
+        switch (adj) {
+            case ADJUST_RAISE: return "ADJUST_RAISE";
+            case ADJUST_LOWER: return "ADJUST_LOWER";
+            case ADJUST_SAME: return "ADJUST_SAME";
+            case ADJUST_MUTE: return "ADJUST_MUTE";
+            case ADJUST_UNMUTE: return "ADJUST_UNMUTE";
+            case ADJUST_TOGGLE_MUTE: return "ADJUST_TOGGLE_MUTE";
+            default: return new StringBuilder("unknown adjust mode ").append(adj).toString();
+        }
+    }
+
+    // Flags should be powers of 2!
+
+    /**
+     * Show a toast containing the current volume.
+     *
+     * @see #adjustStreamVolume(int, int, int)
+     * @see #adjustVolume(int, int)
+     * @see #setStreamVolume(int, int, int)
+     * @see #setRingerMode(int)
+     */
+    public static final int FLAG_SHOW_UI = 1 << 0;
+
+    /**
+     * Whether to include ringer modes as possible options when changing volume.
+     * For example, if true and volume level is 0 and the volume is adjusted
+     * with {@link #ADJUST_LOWER}, then the ringer mode may switch the silent or
+     * vibrate mode.
+     * <p>
+     * By default this is on for the ring stream. If this flag is included,
+     * this behavior will be present regardless of the stream type being
+     * affected by the ringer mode.
+     *
+     * @see #adjustVolume(int, int)
+     * @see #adjustStreamVolume(int, int, int)
+     */
+    public static final int FLAG_ALLOW_RINGER_MODES = 1 << 1;
+
+    /**
+     * Whether to play a sound when changing the volume.
+     * <p>
+     * If this is given to {@link #adjustVolume(int, int)} or
+     * {@link #adjustSuggestedStreamVolume(int, int, int)}, it may be ignored
+     * in some cases (for example, the decided stream type is not
+     * {@link AudioManager#STREAM_RING}, or the volume is being adjusted
+     * downward).
+     *
+     * @see #adjustStreamVolume(int, int, int)
+     * @see #adjustVolume(int, int)
+     * @see #setStreamVolume(int, int, int)
+     */
+    public static final int FLAG_PLAY_SOUND = 1 << 2;
+
+    /**
+     * Removes any sounds/vibrate that may be in the queue, or are playing (related to
+     * changing volume).
+     */
+    public static final int FLAG_REMOVE_SOUND_AND_VIBRATE = 1 << 3;
+
+    /**
+     * Whether to vibrate if going into the vibrate ringer mode.
+     */
+    public static final int FLAG_VIBRATE = 1 << 4;
+
+    /**
+     * Indicates to VolumePanel that the volume slider should be disabled as user
+     * cannot change the stream volume
+     * @hide
+     */
+    public static final int FLAG_FIXED_VOLUME = 1 << 5;
+
+    /**
+     * Indicates the volume set/adjust call is for Bluetooth absolute volume
+     * @hide
+     */
+    public static final int FLAG_BLUETOOTH_ABS_VOLUME = 1 << 6;
+
+    /**
+     * Adjusting the volume was prevented due to silent mode, display a hint in the UI.
+     * @hide
+     */
+    public static final int FLAG_SHOW_SILENT_HINT = 1 << 7;
+
+    /**
+     * Indicates the volume call is for Hdmi Cec system audio volume
+     * @hide
+     */
+    public static final int FLAG_HDMI_SYSTEM_AUDIO_VOLUME = 1 << 8;
+
+    /**
+     * Indicates that this should only be handled if media is actively playing.
+     * @hide
+     */
+    public static final int FLAG_ACTIVE_MEDIA_ONLY = 1 << 9;
+
+    /**
+     * Like FLAG_SHOW_UI, but only dialog warnings and confirmations, no sliders.
+     * @hide
+     */
+    public static final int FLAG_SHOW_UI_WARNINGS = 1 << 10;
+
+    /**
+     * Adjusting the volume down from vibrated was prevented, display a hint in the UI.
+     * @hide
+     */
+    public static final int FLAG_SHOW_VIBRATE_HINT = 1 << 11;
+
+    /**
+     * Adjusting the volume due to a hardware key press.
+     * This flag can be used in the places in order to denote (or check) that a volume adjustment
+     * request is from a hardware key press. (e.g. {@link MediaController}).
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int FLAG_FROM_KEY = 1 << 12;
+
+    /** @hide */
+    @IntDef(prefix = {"ENCODED_SURROUND_OUTPUT_"}, value = {
+            ENCODED_SURROUND_OUTPUT_UNKNOWN,
+            ENCODED_SURROUND_OUTPUT_AUTO,
+            ENCODED_SURROUND_OUTPUT_NEVER,
+            ENCODED_SURROUND_OUTPUT_ALWAYS,
+            ENCODED_SURROUND_OUTPUT_MANUAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EncodedSurroundOutputMode {}
+
+    /**
+     * The mode for surround sound formats is unknown.
+     */
+    public static final int ENCODED_SURROUND_OUTPUT_UNKNOWN = -1;
+
+    /**
+     * The surround sound formats are available for use if they are detected. This is the default
+     * mode.
+     */
+    public static final int ENCODED_SURROUND_OUTPUT_AUTO = 0;
+
+    /**
+     * The surround sound formats are NEVER available, even if they are detected by the hardware.
+     * Those formats will not be reported.
+     */
+    public static final int ENCODED_SURROUND_OUTPUT_NEVER = 1;
+
+    /**
+     * The surround sound formats are ALWAYS available, even if they are not detected by the
+     * hardware. Those formats will be reported as part of the HDMI output capability.
+     * Applications are then free to use either PCM or encoded output.
+     */
+    public static final int ENCODED_SURROUND_OUTPUT_ALWAYS = 2;
+
+    /**
+     * Surround sound formats are available according to the choice of user, even if they are not
+     * detected by the hardware. Those formats will be reported as part of the HDMI output
+     * capability. Applications are then free to use either PCM or encoded output.
+     */
+    public static final int ENCODED_SURROUND_OUTPUT_MANUAL = 3;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = "FLAG", value = {
+            FLAG_SHOW_UI,
+            FLAG_ALLOW_RINGER_MODES,
+            FLAG_PLAY_SOUND,
+            FLAG_REMOVE_SOUND_AND_VIBRATE,
+            FLAG_VIBRATE,
+            FLAG_FIXED_VOLUME,
+            FLAG_BLUETOOTH_ABS_VOLUME,
+            FLAG_SHOW_SILENT_HINT,
+            FLAG_HDMI_SYSTEM_AUDIO_VOLUME,
+            FLAG_ACTIVE_MEDIA_ONLY,
+            FLAG_SHOW_UI_WARNINGS,
+            FLAG_SHOW_VIBRATE_HINT,
+            FLAG_FROM_KEY,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Flags {}
+
+    // The iterator of TreeMap#entrySet() returns the entries in ascending key order.
+    private static final TreeMap<Integer, String> FLAG_NAMES = new TreeMap<>();
+
+    static {
+        FLAG_NAMES.put(FLAG_SHOW_UI, "FLAG_SHOW_UI");
+        FLAG_NAMES.put(FLAG_ALLOW_RINGER_MODES, "FLAG_ALLOW_RINGER_MODES");
+        FLAG_NAMES.put(FLAG_PLAY_SOUND, "FLAG_PLAY_SOUND");
+        FLAG_NAMES.put(FLAG_REMOVE_SOUND_AND_VIBRATE, "FLAG_REMOVE_SOUND_AND_VIBRATE");
+        FLAG_NAMES.put(FLAG_VIBRATE, "FLAG_VIBRATE");
+        FLAG_NAMES.put(FLAG_FIXED_VOLUME, "FLAG_FIXED_VOLUME");
+        FLAG_NAMES.put(FLAG_BLUETOOTH_ABS_VOLUME, "FLAG_BLUETOOTH_ABS_VOLUME");
+        FLAG_NAMES.put(FLAG_SHOW_SILENT_HINT, "FLAG_SHOW_SILENT_HINT");
+        FLAG_NAMES.put(FLAG_HDMI_SYSTEM_AUDIO_VOLUME, "FLAG_HDMI_SYSTEM_AUDIO_VOLUME");
+        FLAG_NAMES.put(FLAG_ACTIVE_MEDIA_ONLY, "FLAG_ACTIVE_MEDIA_ONLY");
+        FLAG_NAMES.put(FLAG_SHOW_UI_WARNINGS, "FLAG_SHOW_UI_WARNINGS");
+        FLAG_NAMES.put(FLAG_SHOW_VIBRATE_HINT, "FLAG_SHOW_VIBRATE_HINT");
+        FLAG_NAMES.put(FLAG_FROM_KEY, "FLAG_FROM_KEY");
+    }
+
+    /** @hide */
+    public static String flagsToString(int flags) {
+        final StringBuilder sb = new StringBuilder();
+        for (Map.Entry<Integer, String> entry : FLAG_NAMES.entrySet()) {
+            final int flag = entry.getKey();
+            if ((flags & flag) != 0) {
+                if (sb.length() > 0) {
+                    sb.append(',');
+                }
+                sb.append(entry.getValue());
+                flags &= ~flag;
+            }
+        }
+        if (flags != 0) {
+            if (sb.length() > 0) {
+                sb.append(',');
+            }
+            sb.append(flags);
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Ringer mode that will be silent and will not vibrate. (This overrides the
+     * vibrate setting.)
+     *
+     * @see #setRingerMode(int)
+     * @see #getRingerMode()
+     */
+    public static final int RINGER_MODE_SILENT = 0;
+
+    /**
+     * Ringer mode that will be silent and will vibrate. (This will cause the
+     * phone ringer to always vibrate, but the notification vibrate to only
+     * vibrate if set.)
+     *
+     * @see #setRingerMode(int)
+     * @see #getRingerMode()
+     */
+    public static final int RINGER_MODE_VIBRATE = 1;
+
+    /**
+     * Ringer mode that may be audible and may vibrate. It will be audible if
+     * the volume before changing out of this mode was audible. It will vibrate
+     * if the vibrate setting is on.
+     *
+     * @see #setRingerMode(int)
+     * @see #getRingerMode()
+     */
+    public static final int RINGER_MODE_NORMAL = 2;
+
+    /**
+     * Maximum valid ringer mode value. Values must start from 0 and be contiguous.
+     * @hide
+     */
+    public static final int RINGER_MODE_MAX = RINGER_MODE_NORMAL;
+
+    /**
+     * Vibrate type that corresponds to the ringer.
+     *
+     * @see #setVibrateSetting(int, int)
+     * @see #getVibrateSetting(int)
+     * @see #shouldVibrate(int)
+     * @deprecated Applications should maintain their own vibrate policy based on
+     * current ringer mode that can be queried via {@link #getRingerMode()}.
+     */
+    public static final int VIBRATE_TYPE_RINGER = 0;
+
+    /**
+     * Vibrate type that corresponds to notifications.
+     *
+     * @see #setVibrateSetting(int, int)
+     * @see #getVibrateSetting(int)
+     * @see #shouldVibrate(int)
+     * @deprecated Applications should maintain their own vibrate policy based on
+     * current ringer mode that can be queried via {@link #getRingerMode()}.
+     */
+    public static final int VIBRATE_TYPE_NOTIFICATION = 1;
+
+    /**
+     * Vibrate setting that suggests to never vibrate.
+     *
+     * @see #setVibrateSetting(int, int)
+     * @see #getVibrateSetting(int)
+     * @deprecated Applications should maintain their own vibrate policy based on
+     * current ringer mode that can be queried via {@link #getRingerMode()}.
+     */
+    public static final int VIBRATE_SETTING_OFF = 0;
+
+    /**
+     * Vibrate setting that suggests to vibrate when possible.
+     *
+     * @see #setVibrateSetting(int, int)
+     * @see #getVibrateSetting(int)
+     * @deprecated Applications should maintain their own vibrate policy based on
+     * current ringer mode that can be queried via {@link #getRingerMode()}.
+     */
+    public static final int VIBRATE_SETTING_ON = 1;
+
+    /**
+     * Vibrate setting that suggests to only vibrate when in the vibrate ringer
+     * mode.
+     *
+     * @see #setVibrateSetting(int, int)
+     * @see #getVibrateSetting(int)
+     * @deprecated Applications should maintain their own vibrate policy based on
+     * current ringer mode that can be queried via {@link #getRingerMode()}.
+     */
+    public static final int VIBRATE_SETTING_ONLY_SILENT = 2;
+
+    /**
+     * Suggests using the default stream type. This may not be used in all
+     * places a stream type is needed.
+     */
+    public static final int USE_DEFAULT_STREAM_TYPE = Integer.MIN_VALUE;
+
+    private static IAudioService sService;
+
+    /**
+     * @hide
+     * For test purposes only, will throw NPE with some methods that require a Context.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public AudioManager() {
+    }
+
+    /**
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public AudioManager(Context context) {
+        setContext(context);
+    }
+
+    private Context getContext() {
+        if (mApplicationContext == null) {
+            setContext(mOriginalContext);
+        }
+        if (mApplicationContext != null) {
+            return mApplicationContext;
+        }
+        return mOriginalContext;
+    }
+
+    private void setContext(Context context) {
+        mApplicationContext = context.getApplicationContext();
+        if (mApplicationContext != null) {
+            mOriginalContext = null;
+        } else {
+            mOriginalContext = context;
+        }
+        sContext = new WeakReference<>(context);
+    }
+
+    @UnsupportedAppUsage
+    private static IAudioService getService()
+    {
+        if (sService != null) {
+            return sService;
+        }
+        IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
+        sService = IAudioService.Stub.asInterface(b);
+        return sService;
+    }
+
+    /**
+     * Sends a simulated key event for a media button.
+     * To simulate a key press, you must first send a KeyEvent built with a
+     * {@link KeyEvent#ACTION_DOWN} action, then another event with the {@link KeyEvent#ACTION_UP}
+     * action.
+     * <p>The key event will be sent to the current media key event consumer which registered with
+     * {@link AudioManager#registerMediaButtonEventReceiver(PendingIntent)}.
+     * @param keyEvent a {@link KeyEvent} instance whose key code is one of
+     *     {@link KeyEvent#KEYCODE_MUTE},
+     *     {@link KeyEvent#KEYCODE_HEADSETHOOK},
+     *     {@link KeyEvent#KEYCODE_MEDIA_PLAY},
+     *     {@link KeyEvent#KEYCODE_MEDIA_PAUSE},
+     *     {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE},
+     *     {@link KeyEvent#KEYCODE_MEDIA_STOP},
+     *     {@link KeyEvent#KEYCODE_MEDIA_NEXT},
+     *     {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS},
+     *     {@link KeyEvent#KEYCODE_MEDIA_REWIND},
+     *     {@link KeyEvent#KEYCODE_MEDIA_RECORD},
+     *     {@link KeyEvent#KEYCODE_MEDIA_FAST_FORWARD},
+     *     {@link KeyEvent#KEYCODE_MEDIA_CLOSE},
+     *     {@link KeyEvent#KEYCODE_MEDIA_EJECT},
+     *     or {@link KeyEvent#KEYCODE_MEDIA_AUDIO_TRACK}.
+     */
+    public void dispatchMediaKeyEvent(KeyEvent keyEvent) {
+        MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(getContext());
+        helper.sendMediaButtonEvent(keyEvent, false);
+    }
+
+    /**
+     * @hide
+     */
+    public void preDispatchKeyEvent(KeyEvent event, int stream) {
+        /*
+         * If the user hits another key within the play sound delay, then
+         * cancel the sound
+         */
+        int keyCode = event.getKeyCode();
+        if (keyCode != KeyEvent.KEYCODE_VOLUME_DOWN && keyCode != KeyEvent.KEYCODE_VOLUME_UP
+                && keyCode != KeyEvent.KEYCODE_VOLUME_MUTE
+                && mVolumeKeyUpTime + AudioSystem.PLAY_SOUND_DELAY > SystemClock.uptimeMillis()) {
+            /*
+             * The user has hit another key during the delay (e.g., 300ms)
+             * since the last volume key up, so cancel any sounds.
+             */
+            adjustSuggestedStreamVolume(ADJUST_SAME,
+                    stream, AudioManager.FLAG_REMOVE_SOUND_AND_VIBRATE);
+        }
+    }
+
+    /**
+     * Indicates if the device implements a fixed volume policy.
+     * <p>Some devices may not have volume control and may operate at a fixed volume,
+     * and may not enable muting or changing the volume of audio streams.
+     * This method will return true on such devices.
+     * <p>The following APIs have no effect when volume is fixed:
+     * <ul>
+     *   <li> {@link #adjustVolume(int, int)}
+     *   <li> {@link #adjustSuggestedStreamVolume(int, int, int)}
+     *   <li> {@link #adjustStreamVolume(int, int, int)}
+     *   <li> {@link #setStreamVolume(int, int, int)}
+     *   <li> {@link #setRingerMode(int)}
+     *   <li> {@link #setStreamSolo(int, boolean)}
+     *   <li> {@link #setStreamMute(int, boolean)}
+     * </ul>
+     */
+    public boolean isVolumeFixed() {
+        synchronized (this) {
+            try {
+                if (!mUseFixedVolumeInitialized) {
+                    mUseFixedVolume = getContext().getResources().getBoolean(
+                            com.android.internal.R.bool.config_useFixedVolume);
+                }
+            } catch (Exception e) {
+            } finally {
+                // only ever try once, so always consider initialized even if query failed
+                mUseFixedVolumeInitialized = true;
+            }
+        }
+        return mUseFixedVolume;
+    }
+
+    /**
+     * Adjusts the volume of a particular stream by one step in a direction.
+     * <p>
+     * This method should only be used by applications that replace the platform-wide
+     * management of audio settings or the main telephony application.
+     * <p>This method has no effect if the device implements a fixed volume policy
+     * as indicated by {@link #isVolumeFixed()}.
+     * <p>From N onward, ringer mode adjustments that would toggle Do Not Disturb are not allowed
+     * unless the app has been granted Do Not Disturb Access.
+     * See {@link NotificationManager#isNotificationPolicyAccessGranted()}.
+     *
+     * @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL},
+     * {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC},
+     * {@link #STREAM_ALARM} or {@link #STREAM_ACCESSIBILITY}.
+     * @param direction The direction to adjust the volume. One of
+     *            {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
+     *            {@link #ADJUST_SAME}.
+     * @param flags One or more flags.
+     * @see #adjustVolume(int, int)
+     * @see #setStreamVolume(int, int, int)
+     * @throws SecurityException if the adjustment triggers a Do Not Disturb change
+     *   and the caller is not granted notification policy access.
+     */
+    public void adjustStreamVolume(int streamType, int direction, int flags) {
+        final IAudioService service = getService();
+        try {
+            service.adjustStreamVolume(streamType, direction, flags,
+                    getContext().getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Adjusts the volume of the most relevant stream. For example, if a call is
+     * active, it will have the highest priority regardless of if the in-call
+     * screen is showing. Another example, if music is playing in the background
+     * and a call is not active, the music stream will be adjusted.
+     * <p>
+     * This method should only be used by applications that replace the
+     * platform-wide management of audio settings or the main telephony
+     * application.
+     * <p>
+     * This method has no effect if the device implements a fixed volume policy
+     * as indicated by {@link #isVolumeFixed()}.
+     *
+     * @param direction The direction to adjust the volume. One of
+     *            {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE},
+     *            {@link #ADJUST_SAME}, {@link #ADJUST_MUTE},
+     *            {@link #ADJUST_UNMUTE}, or {@link #ADJUST_TOGGLE_MUTE}.
+     * @param flags One or more flags.
+     * @see #adjustSuggestedStreamVolume(int, int, int)
+     * @see #adjustStreamVolume(int, int, int)
+     * @see #setStreamVolume(int, int, int)
+     * @see #isVolumeFixed()
+     */
+    public void adjustVolume(int direction, int flags) {
+        MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(getContext());
+        helper.sendAdjustVolumeBy(USE_DEFAULT_STREAM_TYPE, direction, flags);
+    }
+
+    /**
+     * Adjusts the volume of the most relevant stream, or the given fallback
+     * stream.
+     * <p>
+     * This method should only be used by applications that replace the
+     * platform-wide management of audio settings or the main telephony
+     * application.
+     * <p>
+     * This method has no effect if the device implements a fixed volume policy
+     * as indicated by {@link #isVolumeFixed()}.
+     *
+     * @param direction The direction to adjust the volume. One of
+     *            {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE},
+     *            {@link #ADJUST_SAME}, {@link #ADJUST_MUTE},
+     *            {@link #ADJUST_UNMUTE}, or {@link #ADJUST_TOGGLE_MUTE}.
+     * @param suggestedStreamType The stream type that will be used if there
+     *            isn't a relevant stream. {@link #USE_DEFAULT_STREAM_TYPE} is
+     *            valid here.
+     * @param flags One or more flags.
+     * @see #adjustVolume(int, int)
+     * @see #adjustStreamVolume(int, int, int)
+     * @see #setStreamVolume(int, int, int)
+     * @see #isVolumeFixed()
+     */
+    public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) {
+        MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(getContext());
+        helper.sendAdjustVolumeBy(suggestedStreamType, direction, flags);
+    }
+
+    /** @hide */
+    @UnsupportedAppUsage
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void setMasterMute(boolean mute, int flags) {
+        final IAudioService service = getService();
+        try {
+            service.setMasterMute(mute, flags, getContext().getOpPackageName(),
+                    UserHandle.getCallingUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the current ringtone mode.
+     *
+     * @return The current ringtone mode, one of {@link #RINGER_MODE_NORMAL},
+     *         {@link #RINGER_MODE_SILENT}, or {@link #RINGER_MODE_VIBRATE}.
+     * @see #setRingerMode(int)
+     */
+    public int getRingerMode() {
+        final IAudioService service = getService();
+        try {
+            return service.getRingerModeExternal();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Checks valid ringer mode values.
+     *
+     * @return true if the ringer mode indicated is valid, false otherwise.
+     *
+     * @see #setRingerMode(int)
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public static boolean isValidRingerMode(int ringerMode) {
+        if (ringerMode < 0 || ringerMode > RINGER_MODE_MAX) {
+            return false;
+        }
+        final IAudioService service = getService();
+        try {
+            return service.isValidRingerMode(ringerMode);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the maximum volume index for a particular stream.
+     *
+     * @param streamType The stream type whose maximum volume index is returned.
+     * @return The maximum valid volume index for the stream.
+     * @see #getStreamVolume(int)
+     */
+    public int getStreamMaxVolume(int streamType) {
+        final IAudioService service = getService();
+        try {
+            return service.getStreamMaxVolume(streamType);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the minimum volume index for a particular stream.
+     * @param streamType The stream type whose minimum volume index is returned. Must be one of
+     *     {@link #STREAM_VOICE_CALL}, {@link #STREAM_SYSTEM},
+     *     {@link #STREAM_RING}, {@link #STREAM_MUSIC}, {@link #STREAM_ALARM},
+     *     {@link #STREAM_NOTIFICATION}, {@link #STREAM_DTMF} or {@link #STREAM_ACCESSIBILITY}.
+     * @return The minimum valid volume index for the stream.
+     * @see #getStreamVolume(int)
+     */
+    public int getStreamMinVolume(int streamType) {
+        if (!isPublicStreamType(streamType)) {
+            throw new IllegalArgumentException("Invalid stream type " + streamType);
+        }
+        return getStreamMinVolumeInt(streamType);
+    }
+
+    /**
+     * @hide
+     * Same as {@link #getStreamMinVolume(int)} but without the check on the public stream type.
+     * @param streamType The stream type whose minimum volume index is returned.
+     * @return The minimum valid volume index for the stream.
+     * @see #getStreamVolume(int)
+     */
+    public int getStreamMinVolumeInt(int streamType) {
+        final IAudioService service = getService();
+        try {
+            return service.getStreamMinVolume(streamType);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the current volume index for a particular stream.
+     *
+     * @param streamType The stream type whose volume index is returned.
+     * @return The current volume index for the stream.
+     * @see #getStreamMaxVolume(int)
+     * @see #setStreamVolume(int, int, int)
+     */
+    public int getStreamVolume(int streamType) {
+        final IAudioService service = getService();
+        try {
+            return service.getStreamVolume(streamType);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    // keep in sync with frameworks/av/services/audiopolicy/common/include/Volume.h
+    private static final float VOLUME_MIN_DB = -758.0f;
+
+    /** @hide */
+    @IntDef(flag = false, prefix = "STREAM", value = {
+            STREAM_VOICE_CALL,
+            STREAM_SYSTEM,
+            STREAM_RING,
+            STREAM_MUSIC,
+            STREAM_ALARM,
+            STREAM_NOTIFICATION,
+            STREAM_DTMF,
+            STREAM_ACCESSIBILITY }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PublicStreamTypes {}
+
+    /**
+     * Returns the volume in dB (decibel) for the given stream type at the given volume index, on
+     * the given type of audio output device.
+     * @param streamType stream type for which the volume is queried.
+     * @param index the volume index for which the volume is queried. The index value must be
+     *     between the minimum and maximum index values for the given stream type (see
+     *     {@link #getStreamMinVolume(int)} and {@link #getStreamMaxVolume(int)}).
+     * @param deviceType the type of audio output device for which volume is queried.
+     * @return a volume expressed in dB.
+     *     A negative value indicates the audio signal is attenuated. A typical maximum value
+     *     at the maximum volume index is 0 dB (no attenuation nor amplification). Muting is
+     *     reflected by a value of {@link Float#NEGATIVE_INFINITY}.
+     */
+    public float getStreamVolumeDb(@PublicStreamTypes int streamType, int index,
+            @AudioDeviceInfo.AudioDeviceTypeOut int deviceType) {
+        if (!isPublicStreamType(streamType)) {
+            throw new IllegalArgumentException("Invalid stream type " + streamType);
+        }
+        if (index > getStreamMaxVolume(streamType) || index < getStreamMinVolume(streamType)) {
+            throw new IllegalArgumentException("Invalid stream volume index " + index);
+        }
+        if (!AudioDeviceInfo.isValidAudioDeviceTypeOut(deviceType)) {
+            throw new IllegalArgumentException("Invalid audio output device type " + deviceType);
+        }
+        final float gain = AudioSystem.getStreamVolumeDB(streamType, index,
+                AudioDeviceInfo.convertDeviceTypeToInternalDevice(deviceType));
+        if (gain <= VOLUME_MIN_DB) {
+            return Float.NEGATIVE_INFINITY;
+        } else {
+            return gain;
+        }
+    }
+
+    private static boolean isPublicStreamType(int streamType) {
+        switch (streamType) {
+            case STREAM_VOICE_CALL:
+            case STREAM_SYSTEM:
+            case STREAM_RING:
+            case STREAM_MUSIC:
+            case STREAM_ALARM:
+            case STREAM_NOTIFICATION:
+            case STREAM_DTMF:
+            case STREAM_ACCESSIBILITY:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Get last audible volume before stream was muted.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public int getLastAudibleStreamVolume(int streamType) {
+        final IAudioService service = getService();
+        try {
+            return service.getLastAudibleStreamVolume(streamType);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Get the stream type whose volume is driving the UI sounds volume.
+     * UI sounds are screen lock/unlock, camera shutter, key clicks...
+     * It is assumed that this stream type is also tied to ringer mode changes.
+     * @hide
+     */
+    public int getUiSoundsStreamType() {
+        final IAudioService service = getService();
+        try {
+            return service.getUiSoundsStreamType();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sets the ringer mode.
+     * <p>
+     * Silent mode will mute the volume and will not vibrate. Vibrate mode will
+     * mute the volume and vibrate. Normal mode will be audible and may vibrate
+     * according to user settings.
+     * <p>This method has no effect if the device implements a fixed volume policy
+     * as indicated by {@link #isVolumeFixed()}.
+     * * <p>From N onward, ringer mode adjustments that would toggle Do Not Disturb are not allowed
+     * unless the app has been granted Do Not Disturb Access.
+     * See {@link NotificationManager#isNotificationPolicyAccessGranted()}.
+     * @param ringerMode The ringer mode, one of {@link #RINGER_MODE_NORMAL},
+     *            {@link #RINGER_MODE_SILENT}, or {@link #RINGER_MODE_VIBRATE}.
+     * @see #getRingerMode()
+     * @see #isVolumeFixed()
+     */
+    public void setRingerMode(int ringerMode) {
+        if (!isValidRingerMode(ringerMode)) {
+            return;
+        }
+        final IAudioService service = getService();
+        try {
+            service.setRingerModeExternal(ringerMode, getContext().getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sets the volume index for a particular stream.
+     * <p>This method has no effect if the device implements a fixed volume policy
+     * as indicated by {@link #isVolumeFixed()}.
+     * <p>From N onward, volume adjustments that would toggle Do Not Disturb are not allowed unless
+     * the app has been granted Do Not Disturb Access.
+     * See {@link NotificationManager#isNotificationPolicyAccessGranted()}.
+     * @param streamType The stream whose volume index should be set.
+     * @param index The volume index to set. See
+     *            {@link #getStreamMaxVolume(int)} for the largest valid value.
+     * @param flags One or more flags.
+     * @see #getStreamMaxVolume(int)
+     * @see #getStreamVolume(int)
+     * @see #isVolumeFixed()
+     * @throws SecurityException if the volume change triggers a Do Not Disturb change
+     *   and the caller is not granted notification policy access.
+     */
+    public void setStreamVolume(int streamType, int index, int flags) {
+        final IAudioService service = getService();
+        try {
+            service.setStreamVolume(streamType, index, flags, getContext().getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sets the volume index for a particular {@link AudioAttributes}.
+     * @param attr The {@link AudioAttributes} whose volume index should be set.
+     * @param index The volume index to set. See
+     *          {@link #getMaxVolumeIndexForAttributes(AudioAttributes)} for the largest valid value
+     *          {@link #getMinVolumeIndexForAttributes(AudioAttributes)} for the lowest valid value.
+     * @param flags One or more flags.
+     * @see #getMaxVolumeIndexForAttributes(AudioAttributes)
+     * @see #getMinVolumeIndexForAttributes(AudioAttributes)
+     * @see #isVolumeFixed()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void setVolumeIndexForAttributes(@NonNull AudioAttributes attr, int index, int flags) {
+        Preconditions.checkNotNull(attr, "attr must not be null");
+        final IAudioService service = getService();
+        try {
+            service.setVolumeIndexForAttributes(attr, index, flags,
+                                                getContext().getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the current volume index for a particular {@link AudioAttributes}.
+     *
+     * @param attr The {@link AudioAttributes} whose volume index is returned.
+     * @return The current volume index for the stream.
+     * @see #getMaxVolumeIndexForAttributes(AudioAttributes)
+     * @see #getMinVolumeIndexForAttributes(AudioAttributes)
+     * @see #setVolumeForAttributes(AudioAttributes, int, int)
+     * @hide
+     */
+    @SystemApi
+    @IntRange(from = 0)
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public int getVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
+        Preconditions.checkNotNull(attr, "attr must not be null");
+        final IAudioService service = getService();
+        try {
+            return service.getVolumeIndexForAttributes(attr);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the maximum volume index for a particular {@link AudioAttributes}.
+     *
+     * @param attr The {@link AudioAttributes} whose maximum volume index is returned.
+     * @return The maximum valid volume index for the {@link AudioAttributes}.
+     * @see #getVolumeIndexForAttributes(AudioAttributes)
+     * @hide
+     */
+    @SystemApi
+    @IntRange(from = 0)
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
+        Preconditions.checkNotNull(attr, "attr must not be null");
+        final IAudioService service = getService();
+        try {
+            return service.getMaxVolumeIndexForAttributes(attr);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the minimum volume index for a particular {@link AudioAttributes}.
+     *
+     * @param attr The {@link AudioAttributes} whose minimum volume index is returned.
+     * @return The minimum valid volume index for the {@link AudioAttributes}.
+     * @see #getVolumeIndexForAttributes(AudioAttributes)
+     * @hide
+     */
+    @SystemApi
+    @IntRange(from = 0)
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attr) {
+        Preconditions.checkNotNull(attr, "attr must not be null");
+        final IAudioService service = getService();
+        try {
+            return service.getMinVolumeIndexForAttributes(attr);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set the system usages to be supported on this device.
+     * @param systemUsages array of system usages to support {@link AttributeSystemUsage}
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void setSupportedSystemUsages(@NonNull @AttributeSystemUsage int[] systemUsages) {
+        Objects.requireNonNull(systemUsages, "systemUsages must not be null");
+        final IAudioService service = getService();
+        try {
+            service.setSupportedSystemUsages(systemUsages);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Get the system usages supported on this device.
+     * @return array of supported system usages {@link AttributeSystemUsage}
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public @NonNull @AttributeSystemUsage int[] getSupportedSystemUsages() {
+        final IAudioService service = getService();
+        try {
+            return service.getSupportedSystemUsages();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Solo or unsolo a particular stream.
+     * <p>
+     * Do not use. This method has been deprecated and is now a no-op.
+     * {@link #requestAudioFocus} should be used for exclusive audio playback.
+     *
+     * @param streamType The stream to be soloed/unsoloed.
+     * @param state The required solo state: true for solo ON, false for solo
+     *            OFF
+     * @see #isVolumeFixed()
+     * @deprecated Do not use. If you need exclusive audio playback use
+     *             {@link #requestAudioFocus}.
+     */
+    @Deprecated
+    public void setStreamSolo(int streamType, boolean state) {
+        Log.w(TAG, "setStreamSolo has been deprecated. Do not use.");
+    }
+
+    /**
+     * Mute or unmute an audio stream.
+     * <p>
+     * This method should only be used by applications that replace the
+     * platform-wide management of audio settings or the main telephony
+     * application.
+     * <p>
+     * This method has no effect if the device implements a fixed volume policy
+     * as indicated by {@link #isVolumeFixed()}.
+     * <p>
+     * This method was deprecated in API level 22. Prior to API level 22 this
+     * method had significantly different behavior and should be used carefully.
+     * The following applies only to pre-22 platforms:
+     * <ul>
+     * <li>The mute command is protected against client process death: if a
+     * process with an active mute request on a stream dies, this stream will be
+     * unmuted automatically.</li>
+     * <li>The mute requests for a given stream are cumulative: the AudioManager
+     * can receive several mute requests from one or more clients and the stream
+     * will be unmuted only when the same number of unmute requests are
+     * received.</li>
+     * <li>For a better user experience, applications MUST unmute a muted stream
+     * in onPause() and mute is again in onResume() if appropriate.</li>
+     * </ul>
+     *
+     * @param streamType The stream to be muted/unmuted.
+     * @param state The required mute state: true for mute ON, false for mute
+     *            OFF
+     * @see #isVolumeFixed()
+     * @deprecated Use {@link #adjustStreamVolume(int, int, int)} with
+     *             {@link #ADJUST_MUTE} or {@link #ADJUST_UNMUTE} instead.
+     */
+    @Deprecated
+    public void setStreamMute(int streamType, boolean state) {
+        Log.w(TAG, "setStreamMute is deprecated. adjustStreamVolume should be used instead.");
+        int direction = state ? ADJUST_MUTE : ADJUST_UNMUTE;
+        if (streamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
+            adjustSuggestedStreamVolume(direction, streamType, 0);
+        } else {
+            adjustStreamVolume(streamType, direction, 0);
+        }
+    }
+
+    /**
+     * Returns the current mute state for a particular stream.
+     *
+     * @param streamType The stream to get mute state for.
+     * @return The mute state for the given stream.
+     * @see #adjustStreamVolume(int, int, int)
+     */
+    public boolean isStreamMute(int streamType) {
+        final IAudioService service = getService();
+        try {
+            return service.isStreamMute(streamType);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * get master mute state.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public boolean isMasterMute() {
+        final IAudioService service = getService();
+        try {
+            return service.isMasterMute();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * forces the stream controlled by hard volume keys
+     * specifying streamType == -1 releases control to the
+     * logic.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    @UnsupportedAppUsage
+    public void forceVolumeControlStream(int streamType) {
+        final IAudioService service = getService();
+        try {
+            service.forceVolumeControlStream(streamType, mICallBack);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns whether a particular type should vibrate according to user
+     * settings and the current ringer mode.
+     * <p>
+     * This shouldn't be needed by most clients that use notifications to
+     * vibrate. The notification manager will not vibrate if the policy doesn't
+     * allow it, so the client should always set a vibrate pattern and let the
+     * notification manager control whether or not to actually vibrate.
+     *
+     * @param vibrateType The type of vibrate. One of
+     *            {@link #VIBRATE_TYPE_NOTIFICATION} or
+     *            {@link #VIBRATE_TYPE_RINGER}.
+     * @return Whether the type should vibrate at the instant this method is
+     *         called.
+     * @see #setVibrateSetting(int, int)
+     * @see #getVibrateSetting(int)
+     * @deprecated Applications should maintain their own vibrate policy based on
+     * current ringer mode that can be queried via {@link #getRingerMode()}.
+     */
+    public boolean shouldVibrate(int vibrateType) {
+        final IAudioService service = getService();
+        try {
+            return service.shouldVibrate(vibrateType);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns whether the user's vibrate setting for a vibrate type.
+     * <p>
+     * This shouldn't be needed by most clients that want to vibrate, instead
+     * see {@link #shouldVibrate(int)}.
+     *
+     * @param vibrateType The type of vibrate. One of
+     *            {@link #VIBRATE_TYPE_NOTIFICATION} or
+     *            {@link #VIBRATE_TYPE_RINGER}.
+     * @return The vibrate setting, one of {@link #VIBRATE_SETTING_ON},
+     *         {@link #VIBRATE_SETTING_OFF}, or
+     *         {@link #VIBRATE_SETTING_ONLY_SILENT}.
+     * @see #setVibrateSetting(int, int)
+     * @see #shouldVibrate(int)
+     * @deprecated Applications should maintain their own vibrate policy based on
+     * current ringer mode that can be queried via {@link #getRingerMode()}.
+     */
+    public int getVibrateSetting(int vibrateType) {
+        final IAudioService service = getService();
+        try {
+            return service.getVibrateSetting(vibrateType);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sets the setting for when the vibrate type should vibrate.
+     * <p>
+     * This method should only be used by applications that replace the platform-wide
+     * management of audio settings or the main telephony application.
+     *
+     * @param vibrateType The type of vibrate. One of
+     *            {@link #VIBRATE_TYPE_NOTIFICATION} or
+     *            {@link #VIBRATE_TYPE_RINGER}.
+     * @param vibrateSetting The vibrate setting, one of
+     *            {@link #VIBRATE_SETTING_ON},
+     *            {@link #VIBRATE_SETTING_OFF}, or
+     *            {@link #VIBRATE_SETTING_ONLY_SILENT}.
+     * @see #getVibrateSetting(int)
+     * @see #shouldVibrate(int)
+     * @deprecated Applications should maintain their own vibrate policy based on
+     * current ringer mode that can be queried via {@link #getRingerMode()}.
+     */
+    public void setVibrateSetting(int vibrateType, int vibrateSetting) {
+        final IAudioService service = getService();
+        try {
+            service.setVibrateSetting(vibrateType, vibrateSetting);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sets the speakerphone on or off.
+     * <p>
+     * This method should only be used by applications that replace the platform-wide
+     * management of audio settings or the main telephony application.
+     *
+     * @param on set <var>true</var> to turn on speakerphone;
+     *           <var>false</var> to turn it off
+     */
+    public void setSpeakerphoneOn(boolean on){
+        final IAudioService service = getService();
+        try {
+            service.setSpeakerphoneOn(mICallBack, on);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Checks whether the speakerphone is on or off.
+     *
+     * @return true if speakerphone is on, false if it's off
+     */
+    public boolean isSpeakerphoneOn() {
+        final IAudioService service = getService();
+        try {
+            return service.isSpeakerphoneOn();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+     }
+
+    /**
+     * Specifies whether the audio played by this app may or may not be captured by other apps or
+     * the system.
+     *
+     * The default is {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}.
+     *
+     * There are multiple ways to set this policy:
+     * <ul>
+     * <li> for each track independently, see
+     *    {@link AudioAttributes.Builder#setAllowedCapturePolicy(int)} </li>
+     * <li> application-wide at runtime, with this method </li>
+     * <li> application-wide at build time, see {@code allowAudioPlaybackCapture} in the application
+     *       manifest. </li>
+     * </ul>
+     * The most restrictive policy is always applied.
+     *
+     * See {@link AudioPlaybackCaptureConfiguration} for more details on
+     * which audio signals can be captured.
+     *
+     * @param capturePolicy one of
+     *     {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL},
+     *     {@link AudioAttributes#ALLOW_CAPTURE_BY_SYSTEM},
+     *     {@link AudioAttributes#ALLOW_CAPTURE_BY_NONE}.
+     * @throws RuntimeException if the argument is not a valid value.
+     */
+    public void setAllowedCapturePolicy(@AudioAttributes.CapturePolicy int capturePolicy) {
+        // TODO: also pass the package in case multiple packages have the same UID
+        final IAudioService service = getService();
+        try {
+            int result = service.setAllowedCapturePolicy(capturePolicy);
+            if (result != AudioSystem.AUDIO_STATUS_OK) {
+                Log.e(TAG, "Could not setAllowedCapturePolicy: " + result);
+                return;
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return the capture policy.
+     * @return the capture policy set by {@link #setAllowedCapturePolicy(int)} or
+     *         the default if it was not called.
+     */
+    @AudioAttributes.CapturePolicy
+    public int getAllowedCapturePolicy() {
+        int result = AudioAttributes.ALLOW_CAPTURE_BY_ALL;
+        try {
+            result = getService().getAllowedCapturePolicy();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to query allowed capture policy: " + e);
+        }
+        return result;
+    }
+
+    //====================================================================
+    // Audio Product Strategy routing
+
+    /**
+     * @hide
+     * Set the preferred device for a given strategy, i.e. the audio routing to be used by
+     * this audio strategy. Note that the device may not be available at the time the preferred
+     * device is set, but it will be used once made available.
+     * <p>Use {@link #removePreferredDeviceForStrategy(AudioProductStrategy)} to cancel setting
+     * this preference for this strategy.</p>
+     * @param strategy the audio strategy whose routing will be affected
+     * @param device the audio device to route to when available
+     * @return true if the operation was successful, false otherwise
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public boolean setPreferredDeviceForStrategy(@NonNull AudioProductStrategy strategy,
+            @NonNull AudioDeviceAttributes device) {
+        return setPreferredDevicesForStrategy(strategy, Arrays.asList(device));
+    }
+
+    /**
+     * @hide
+     * Removes the preferred audio device(s) previously set with
+     * {@link #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)} or
+     * {@link #setPreferredDevicesForStrategy(AudioProductStrategy, List<AudioDeviceAttributes>)}.
+     * @param strategy the audio strategy whose routing will be affected
+     * @return true if the operation was successful, false otherwise (invalid strategy, or no
+     *     device set for example)
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public boolean removePreferredDeviceForStrategy(@NonNull AudioProductStrategy strategy) {
+        Objects.requireNonNull(strategy);
+        try {
+            final int status =
+                    getService().removePreferredDevicesForStrategy(strategy.getId());
+            return status == AudioSystem.SUCCESS;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Return the preferred device for an audio strategy, previously set with
+     * {@link #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)} or
+     * {@link #setPreferredDevicesForStrategy(AudioProductStrategy, List<AudioDeviceAttributes>)}
+     * @param strategy the strategy to query
+     * @return the preferred device for that strategy, if multiple devices are set as preferred
+     *    devices, the first one in the list will be returned. Null will be returned if none was
+     *    ever set or if the strategy is invalid
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    @Nullable
+    public AudioDeviceAttributes getPreferredDeviceForStrategy(
+            @NonNull AudioProductStrategy strategy) {
+        List<AudioDeviceAttributes> devices = getPreferredDevicesForStrategy(strategy);
+        return devices.isEmpty() ? null : devices.get(0);
+    }
+
+    /**
+     * @hide
+     * Set the preferred devices for a given strategy, i.e. the audio routing to be used by
+     * this audio strategy. Note that the devices may not be available at the time the preferred
+     * devices is set, but it will be used once made available.
+     * <p>Use {@link #removePreferredDeviceForStrategy(AudioProductStrategy)} to cancel setting
+     * this preference for this strategy.</p>
+     * Note that the list of devices is not a list ranked by preference, but a list of one or more
+     * devices used simultaneously to output the same audio signal.
+     * @param strategy the audio strategy whose routing will be affected
+     * @param devices a non-empty list of the audio devices to route to when available
+     * @return true if the operation was successful, false otherwise
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public boolean setPreferredDevicesForStrategy(@NonNull AudioProductStrategy strategy,
+                                                  @NonNull List<AudioDeviceAttributes> devices) {
+        Objects.requireNonNull(strategy);
+        Objects.requireNonNull(devices);
+        if (devices.isEmpty()) {
+            throw new IllegalArgumentException(
+                    "Tried to set preferred devices for strategy with a empty list");
+        }
+        for (AudioDeviceAttributes device : devices) {
+            Objects.requireNonNull(device);
+        }
+        try {
+            final int status =
+                    getService().setPreferredDevicesForStrategy(strategy.getId(), devices);
+            return status == AudioSystem.SUCCESS;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Return the preferred devices for an audio strategy, previously set with
+     * {@link #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)}
+     * {@link #setPreferredDevicesForStrategy(AudioProductStrategy, List<AudioDeviceAttributes>)}
+     * @param strategy the strategy to query
+     * @return the preferred device for that strategy, or null if none was ever set or if the
+     *    strategy is invalid
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    @NonNull
+    public List<AudioDeviceAttributes> getPreferredDevicesForStrategy(
+            @NonNull AudioProductStrategy strategy) {
+        Objects.requireNonNull(strategy);
+        try {
+            return getService().getPreferredDevicesForStrategy(strategy.getId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Interface to be notified of changes in the preferred audio device set for a given audio
+     * strategy.
+     * <p>Note that this listener will only be invoked whenever
+     * {@link #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)} or
+     * {@link #setPreferredDevicesForStrategy(AudioProductStrategy, List<AudioDeviceAttributes>)}
+     * {@link #removePreferredDeviceForStrategy(AudioProductStrategy)} causes a change in
+     * preferred device. It will not be invoked directly after registration with
+     * {@link #addOnPreferredDeviceForStrategyChangedListener(Executor, OnPreferredDeviceForStrategyChangedListener)}
+     * to indicate which strategies had preferred devices at the time of registration.</p>
+     * @see #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)
+     * @see #removePreferredDeviceForStrategy(AudioProductStrategy)
+     * @see #getPreferredDeviceForStrategy(AudioProductStrategy)
+     * @deprecated use #OnPreferredDevicesForStrategyChangedListener
+     */
+    @SystemApi
+    @Deprecated
+    public interface OnPreferredDeviceForStrategyChangedListener {
+        /**
+         * Called on the listener to indicate that the preferred audio device for the given
+         * strategy has changed.
+         * @param strategy the {@link AudioProductStrategy} whose preferred device changed
+         * @param device <code>null</code> if the preferred device was removed, or the newly set
+         *              preferred audio device
+         */
+        void onPreferredDeviceForStrategyChanged(@NonNull AudioProductStrategy strategy,
+                @Nullable AudioDeviceAttributes device);
+    }
+
+    /**
+     * @hide
+     * Interface to be notified of changes in the preferred audio devices set for a given audio
+     * strategy.
+     * <p>Note that this listener will only be invoked whenever
+     * {@link #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)} or
+     * {@link #setPreferredDevicesForStrategy(AudioProductStrategy, List<AudioDeviceAttributes>)}
+     * {@link #removePreferredDeviceForStrategy(AudioProductStrategy)} causes a change in
+     * preferred device(s). It will not be invoked directly after registration with
+     * {@link #addOnPreferredDevicesForStrategyChangedListener(
+     * Executor, OnPreferredDevicesForStrategyChangedListener)}
+     * to indicate which strategies had preferred devices at the time of registration.</p>
+     * @see #setPreferredDeviceForStrategy(AudioProductStrategy, AudioDeviceAttributes)
+     * @see #setPreferredDevicesForStrategy(AudioProductStrategy, List)
+     * @see #removePreferredDeviceForStrategy(AudioProductStrategy)
+     * @see #getPreferredDeviceForStrategy(AudioProductStrategy)
+     * @see #getPreferredDevicesForStrategy(AudioProductStrategy)
+     */
+    @SystemApi
+    public interface OnPreferredDevicesForStrategyChangedListener {
+        /**
+         * Called on the listener to indicate that the preferred audio devices for the given
+         * strategy has changed.
+         * @param strategy the {@link AudioProductStrategy} whose preferred device changed
+         * @param devices a list of newly set preferred audio devices
+         */
+        void onPreferredDevicesForStrategyChanged(@NonNull AudioProductStrategy strategy,
+                                                  @NonNull List<AudioDeviceAttributes> devices);
+    }
+
+    /**
+     * @hide
+     * Adds a listener for being notified of changes to the strategy-preferred audio device.
+     * @param executor
+     * @param listener
+     * @throws SecurityException if the caller doesn't hold the required permission
+     * @deprecated use {@link #addOnPreferredDevicesForStrategyChangedListener(
+     *             Executor, AudioManager.OnPreferredDevicesForStrategyChangedListener)} instead
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    @Deprecated
+    public void addOnPreferredDeviceForStrategyChangedListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnPreferredDeviceForStrategyChangedListener listener)
+            throws SecurityException {
+        // No-op, the method is deprecated.
+    }
+
+    /**
+     * @hide
+     * Removes a previously added listener of changes to the strategy-preferred audio device.
+     * @param listener
+     * @deprecated use {@link #removeOnPreferredDevicesForStrategyChangedListener(
+     *             AudioManager.OnPreferredDevicesForStrategyChangedListener)} instead
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    @Deprecated
+    public void removeOnPreferredDeviceForStrategyChangedListener(
+            @NonNull OnPreferredDeviceForStrategyChangedListener listener) {
+        // No-op, the method is deprecated.
+    }
+
+    /**
+     * @hide
+     * Adds a listener for being notified of changes to the strategy-preferred audio device.
+     * @param executor
+     * @param listener
+     * @throws SecurityException if the caller doesn't hold the required permission
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void addOnPreferredDevicesForStrategyChangedListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnPreferredDevicesForStrategyChangedListener listener)
+            throws SecurityException {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(listener);
+        synchronized (mPrefDevListenerLock) {
+            if (hasPrefDevListener(listener)) {
+                throw new IllegalArgumentException(
+                        "attempt to call addOnPreferredDevicesForStrategyChangedListener() "
+                                + "on a previously registered listener");
+            }
+            // lazy initialization of the list of strategy-preferred device listener
+            if (mPrefDevListeners == null) {
+                mPrefDevListeners = new ArrayList<>();
+            }
+            final int oldCbCount = mPrefDevListeners.size();
+            mPrefDevListeners.add(new PrefDevListenerInfo(listener, executor));
+            if (oldCbCount == 0 && mPrefDevListeners.size() > 0) {
+                // register binder for callbacks
+                if (mPrefDevDispatcherStub == null) {
+                    mPrefDevDispatcherStub = new StrategyPreferredDevicesDispatcherStub();
+                }
+                try {
+                    getService().registerStrategyPreferredDevicesDispatcher(mPrefDevDispatcherStub);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Removes a previously added listener of changes to the strategy-preferred audio device.
+     * @param listener
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void removeOnPreferredDevicesForStrategyChangedListener(
+            @NonNull OnPreferredDevicesForStrategyChangedListener listener) {
+        Objects.requireNonNull(listener);
+        synchronized (mPrefDevListenerLock) {
+            if (!removePrefDevListener(listener)) {
+                throw new IllegalArgumentException(
+                        "attempt to call removeOnPreferredDeviceForStrategyChangedListener() "
+                                + "on an unregistered listener");
+            }
+            if (mPrefDevListeners.size() == 0) {
+                // unregister binder for callbacks
+                try {
+                    getService().unregisterStrategyPreferredDevicesDispatcher(
+                            mPrefDevDispatcherStub);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                } finally {
+                    mPrefDevDispatcherStub = null;
+                    mPrefDevListeners = null;
+                }
+            }
+        }
+    }
+
+
+    private final Object mPrefDevListenerLock = new Object();
+    /**
+     * List of listeners for preferred device for strategy and their associated Executor.
+     * List is lazy-initialized on first registration
+     */
+    @GuardedBy("mPrefDevListenerLock")
+    private @Nullable ArrayList<PrefDevListenerInfo> mPrefDevListeners;
+
+    private static class PrefDevListenerInfo {
+        final @NonNull OnPreferredDevicesForStrategyChangedListener mListener;
+        final @NonNull Executor mExecutor;
+        PrefDevListenerInfo(OnPreferredDevicesForStrategyChangedListener listener, Executor exe) {
+            mListener = listener;
+            mExecutor = exe;
+        }
+    }
+
+    @GuardedBy("mPrefDevListenerLock")
+    private StrategyPreferredDevicesDispatcherStub mPrefDevDispatcherStub;
+
+    private final class StrategyPreferredDevicesDispatcherStub
+            extends IStrategyPreferredDevicesDispatcher.Stub {
+
+        @Override
+        public void dispatchPrefDevicesChanged(int strategyId,
+                                               @NonNull List<AudioDeviceAttributes> devices) {
+            // make a shallow copy of listeners so callback is not executed under lock
+            final ArrayList<PrefDevListenerInfo> prefDevListeners;
+            synchronized (mPrefDevListenerLock) {
+                if (mPrefDevListeners == null || mPrefDevListeners.size() == 0) {
+                    return;
+                }
+                prefDevListeners = (ArrayList<PrefDevListenerInfo>) mPrefDevListeners.clone();
+            }
+            final AudioProductStrategy strategy =
+                    AudioProductStrategy.getAudioProductStrategyWithId(strategyId);
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                for (PrefDevListenerInfo info : prefDevListeners) {
+                    info.mExecutor.execute(() ->
+                            info.mListener.onPreferredDevicesForStrategyChanged(strategy, devices));
+                }
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    @GuardedBy("mPrefDevListenerLock")
+    private @Nullable PrefDevListenerInfo getPrefDevListenerInfo(
+            OnPreferredDevicesForStrategyChangedListener listener) {
+        if (mPrefDevListeners == null) {
+            return null;
+        }
+        for (PrefDevListenerInfo info : mPrefDevListeners) {
+            if (info.mListener == listener) {
+                return info;
+            }
+        }
+        return null;
+    }
+
+    @GuardedBy("mPrefDevListenerLock")
+    private boolean hasPrefDevListener(OnPreferredDevicesForStrategyChangedListener listener) {
+        return getPrefDevListenerInfo(listener) != null;
+    }
+
+    @GuardedBy("mPrefDevListenerLock")
+    /**
+     * @return true if the listener was removed from the list
+     */
+    private boolean removePrefDevListener(OnPreferredDevicesForStrategyChangedListener listener) {
+        final PrefDevListenerInfo infoToRemove = getPrefDevListenerInfo(listener);
+        if (infoToRemove != null) {
+            mPrefDevListeners.remove(infoToRemove);
+            return true;
+        }
+        return false;
+    }
+
+    //====================================================================
+    // Audio Capture Preset routing
+
+    /**
+     * @hide
+     * Set the preferred device for a given capture preset, i.e. the audio routing to be used by
+     * this capture preset. Note that the device may not be available at the time the preferred
+     * device is set, but it will be used once made available.
+     * <p>Use {@link #clearPreferredDevicesForCapturePreset(int)} to cancel setting this preference
+     * for this capture preset.</p>
+     * @param capturePreset the audio capture preset whose routing will be affected
+     * @param device the audio device to route to when available
+     * @return true if the operation was successful, false otherwise
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public boolean setPreferredDeviceForCapturePreset(@MediaRecorder.SystemSource int capturePreset,
+                                                      @NonNull AudioDeviceAttributes device) {
+        return setPreferredDevicesForCapturePreset(capturePreset, Arrays.asList(device));
+    }
+
+    /**
+     * @hide
+     * Remove all the preferred audio devices previously set
+     * @param capturePreset the audio capture preset whose routing will be affected
+     * @return true if the operation was successful, false otherwise (invalid capture preset, or no
+     *     device set for example)
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public boolean clearPreferredDevicesForCapturePreset(
+            @MediaRecorder.SystemSource int capturePreset) {
+        if (!MediaRecorder.isValidAudioSource(capturePreset)) {
+            return false;
+        }
+        try {
+            final int status = getService().clearPreferredDevicesForCapturePreset(capturePreset);
+            return status == AudioSystem.SUCCESS;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Return the preferred devices for an audio capture preset, previously set with
+     * {@link #setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)}
+     * @param capturePreset the capture preset to query
+     * @return a list that contains preferred devices for that capture preset.
+     */
+    @NonNull
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public List<AudioDeviceAttributes> getPreferredDevicesForCapturePreset(
+            @MediaRecorder.SystemSource int capturePreset) {
+        if (!MediaRecorder.isValidAudioSource(capturePreset)) {
+            return new ArrayList<AudioDeviceAttributes>();
+        }
+        try {
+            return getService().getPreferredDevicesForCapturePreset(capturePreset);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    private boolean setPreferredDevicesForCapturePreset(
+            @MediaRecorder.SystemSource int capturePreset,
+            @NonNull List<AudioDeviceAttributes> devices) {
+        Objects.requireNonNull(devices);
+        if (!MediaRecorder.isValidAudioSource(capturePreset)) {
+            return false;
+        }
+        if (devices.size() != 1) {
+            throw new IllegalArgumentException(
+                    "Only support setting one preferred devices for capture preset");
+        }
+        for (AudioDeviceAttributes device : devices) {
+            Objects.requireNonNull(device);
+        }
+        try {
+            final int status =
+                    getService().setPreferredDevicesForCapturePreset(capturePreset, devices);
+            return status == AudioSystem.SUCCESS;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Interface to be notified of changes in the preferred audio devices set for a given capture
+     * preset.
+     * <p>Note that this listener will only be invoked whenever
+     * {@link #setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)} or
+     * {@link #clearPreferredDevicesForCapturePreset(int)} causes a change in
+     * preferred device. It will not be invoked directly after registration with
+     * {@link #addOnPreferredDevicesForCapturePresetChangedListener(
+     * Executor, OnPreferredDevicesForCapturePresetChangedListener)}
+     * to indicate which strategies had preferred devices at the time of registration.</p>
+     * @see #setPreferredDeviceForCapturePreset(int, AudioDeviceAttributes)
+     * @see #clearPreferredDevicesForCapturePreset(int)
+     * @see #getPreferredDevicesForCapturePreset(int)
+     */
+    @SystemApi
+    public interface OnPreferredDevicesForCapturePresetChangedListener {
+        /**
+         * Called on the listener to indicate that the preferred audio devices for the given
+         * capture preset has changed.
+         * @param capturePreset the capture preset whose preferred device changed
+         * @param devices a list of newly set preferred audio devices
+         */
+        void onPreferredDevicesForCapturePresetChanged(
+                @MediaRecorder.SystemSource int capturePreset,
+                @NonNull List<AudioDeviceAttributes> devices);
+    }
+
+    /**
+     * @hide
+     * Adds a listener for being notified of changes to the capture-preset-preferred audio device.
+     * @param executor
+     * @param listener
+     * @throws SecurityException if the caller doesn't hold the required permission
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void addOnPreferredDevicesForCapturePresetChangedListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnPreferredDevicesForCapturePresetChangedListener listener)
+            throws SecurityException {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(listener);
+        int status = addOnDevRoleForCapturePresetChangedListener(
+                executor, listener, AudioSystem.DEVICE_ROLE_PREFERRED);
+        if (status == AudioSystem.ERROR) {
+            // This must not happen
+            throw new RuntimeException("Unknown error happened");
+        }
+        if (status == AudioSystem.BAD_VALUE) {
+            throw new IllegalArgumentException(
+                    "attempt to call addOnPreferredDevicesForCapturePresetChangedListener() "
+                            + "on a previously registered listener");
+        }
+    }
+
+    /**
+     * @hide
+     * Removes a previously added listener of changes to the capture-preset-preferred audio device.
+     * @param listener
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void removeOnPreferredDevicesForCapturePresetChangedListener(
+            @NonNull OnPreferredDevicesForCapturePresetChangedListener listener) {
+        Objects.requireNonNull(listener);
+        int status = removeOnDevRoleForCapturePresetChangedListener(
+                listener, AudioSystem.DEVICE_ROLE_PREFERRED);
+        if (status == AudioSystem.ERROR) {
+            // This must not happen
+            throw new RuntimeException("Unknown error happened");
+        }
+        if (status == AudioSystem.BAD_VALUE) {
+            throw new IllegalArgumentException(
+                    "attempt to call removeOnPreferredDevicesForCapturePresetChangedListener() "
+                            + "on an unregistered listener");
+        }
+    }
+
+    private <T> int addOnDevRoleForCapturePresetChangedListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull T listener, int deviceRole) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(listener);
+        DevRoleListeners<T> devRoleListeners =
+                (DevRoleListeners<T>) mDevRoleForCapturePresetListeners.get(deviceRole);
+        if (devRoleListeners == null) {
+            return AudioSystem.ERROR;
+        }
+        synchronized (devRoleListeners.mDevRoleListenersLock) {
+            if (devRoleListeners.hasDevRoleListener(listener)) {
+                return AudioSystem.BAD_VALUE;
+            }
+            // lazy initialization of the list of device role listener
+            if (devRoleListeners.mListenerInfos == null) {
+                devRoleListeners.mListenerInfos = new ArrayList<>();
+            }
+            final int oldCbCount = devRoleListeners.mListenerInfos.size();
+            devRoleListeners.mListenerInfos.add(new DevRoleListenerInfo<T>(executor, listener));
+            if (oldCbCount == 0 && devRoleListeners.mListenerInfos.size() > 0) {
+                // register binder for callbacks
+                synchronized (mDevRoleForCapturePresetListenersLock) {
+                    int deviceRoleListenerStatus = mDeviceRoleListenersStatus;
+                    mDeviceRoleListenersStatus |= (1 << deviceRole);
+                    if (deviceRoleListenerStatus != 0) {
+                        // There are already device role changed listeners active.
+                        return AudioSystem.SUCCESS;
+                    }
+                    if (mDevicesRoleForCapturePresetDispatcherStub == null) {
+                        mDevicesRoleForCapturePresetDispatcherStub =
+                                new CapturePresetDevicesRoleDispatcherStub();
+                    }
+                    try {
+                        getService().registerCapturePresetDevicesRoleDispatcher(
+                                mDevicesRoleForCapturePresetDispatcherStub);
+                    } catch (RemoteException e) {
+                        throw e.rethrowFromSystemServer();
+                    }
+                }
+            }
+        }
+        return AudioSystem.SUCCESS;
+    }
+
+    private <T> int removeOnDevRoleForCapturePresetChangedListener(
+            @NonNull T listener, int deviceRole) {
+        Objects.requireNonNull(listener);
+        DevRoleListeners<T> devRoleListeners =
+                (DevRoleListeners<T>) mDevRoleForCapturePresetListeners.get(deviceRole);
+        if (devRoleListeners == null) {
+            return AudioSystem.ERROR;
+        }
+        synchronized (devRoleListeners.mDevRoleListenersLock) {
+            if (!devRoleListeners.removeDevRoleListener(listener)) {
+                return AudioSystem.BAD_VALUE;
+            }
+            if (devRoleListeners.mListenerInfos.size() == 0) {
+                // unregister binder for callbacks
+                synchronized (mDevRoleForCapturePresetListenersLock) {
+                    mDeviceRoleListenersStatus ^= (1 << deviceRole);
+                    if (mDeviceRoleListenersStatus != 0) {
+                        // There are some other device role changed listeners active.
+                        return AudioSystem.SUCCESS;
+                    }
+                    try {
+                        getService().unregisterCapturePresetDevicesRoleDispatcher(
+                                mDevicesRoleForCapturePresetDispatcherStub);
+                    } catch (RemoteException e) {
+                        throw e.rethrowFromSystemServer();
+                    }
+                }
+            }
+        }
+        return AudioSystem.SUCCESS;
+    }
+
+    private final Map<Integer, Object> mDevRoleForCapturePresetListeners = new HashMap<>(){{
+            put(AudioSystem.DEVICE_ROLE_PREFERRED,
+                    new DevRoleListeners<OnPreferredDevicesForCapturePresetChangedListener>());
+        }};
+
+    private class DevRoleListenerInfo<T> {
+        final @NonNull Executor mExecutor;
+        final @NonNull T mListener;
+        DevRoleListenerInfo(Executor executor, T listener) {
+            mExecutor = executor;
+            mListener = listener;
+        }
+    }
+
+    private class DevRoleListeners<T> {
+        private final Object mDevRoleListenersLock = new Object();
+        @GuardedBy("mDevRoleListenersLock")
+        private @Nullable ArrayList<DevRoleListenerInfo<T>> mListenerInfos;
+
+        @GuardedBy("mDevRoleListenersLock")
+        private @Nullable DevRoleListenerInfo<T> getDevRoleListenerInfo(T listener) {
+            if (mListenerInfos == null) {
+                return null;
+            }
+            for (DevRoleListenerInfo<T> listenerInfo : mListenerInfos) {
+                if (listenerInfo.mListener == listener) {
+                    return listenerInfo;
+                }
+            }
+            return null;
+        }
+
+        @GuardedBy("mDevRoleListenersLock")
+        private boolean hasDevRoleListener(T listener) {
+            return getDevRoleListenerInfo(listener) != null;
+        }
+
+        @GuardedBy("mDevRoleListenersLock")
+        private boolean removeDevRoleListener(T listener) {
+            final DevRoleListenerInfo<T> infoToRemove = getDevRoleListenerInfo(listener);
+            if (infoToRemove != null) {
+                mListenerInfos.remove(infoToRemove);
+                return true;
+            }
+            return false;
+        }
+    }
+
+    private final Object mDevRoleForCapturePresetListenersLock = new Object();
+    /**
+     * Record if there is a listener added for device role change. If there is a listener added for
+     * a specified device role change, the bit at position `1 << device_role` is set.
+     */
+    @GuardedBy("mDevRoleForCapturePresetListenersLock")
+    private int mDeviceRoleListenersStatus = 0;
+    @GuardedBy("mDevRoleForCapturePresetListenersLock")
+    private CapturePresetDevicesRoleDispatcherStub mDevicesRoleForCapturePresetDispatcherStub;
+
+    private final class CapturePresetDevicesRoleDispatcherStub
+            extends ICapturePresetDevicesRoleDispatcher.Stub {
+
+        @Override
+        public void dispatchDevicesRoleChanged(
+                int capturePreset, int role, List<AudioDeviceAttributes> devices) {
+            final Object listenersObj = mDevRoleForCapturePresetListeners.get(role);
+            if (listenersObj == null) {
+                return;
+            }
+            switch (role) {
+                case AudioSystem.DEVICE_ROLE_PREFERRED: {
+                    final DevRoleListeners<OnPreferredDevicesForCapturePresetChangedListener>
+                            listeners =
+                            (DevRoleListeners<OnPreferredDevicesForCapturePresetChangedListener>)
+                            listenersObj;
+                    final ArrayList<DevRoleListenerInfo<
+                            OnPreferredDevicesForCapturePresetChangedListener>> prefDevListeners;
+                    synchronized (listeners.mDevRoleListenersLock) {
+                        if (listeners.mListenerInfos.isEmpty()) {
+                            return;
+                        }
+                        prefDevListeners = (ArrayList<DevRoleListenerInfo<
+                                OnPreferredDevicesForCapturePresetChangedListener>>)
+                                listeners.mListenerInfos.clone();
+                    }
+                    final long ident = Binder.clearCallingIdentity();
+                    try {
+                        for (DevRoleListenerInfo<
+                                OnPreferredDevicesForCapturePresetChangedListener> info :
+                                prefDevListeners) {
+                            info.mExecutor.execute(() ->
+                                    info.mListener.onPreferredDevicesForCapturePresetChanged(
+                                            capturePreset, devices));
+                        }
+                    } finally {
+                        Binder.restoreCallingIdentity(ident);
+                    }
+                } break;
+                default:
+                    break;
+            }
+        }
+    }
+
+    //====================================================================
+    // Offload query
+    /**
+     * Returns whether offloaded playback of an audio format is supported on the device.
+     * <p>Offloaded playback is the feature where the decoding and playback of an audio stream
+     * is not competing with other software resources. In general, it is supported by dedicated
+     * hardware, such as audio DSPs.
+     * <p>Note that this query only provides information about the support of an audio format,
+     * it does not indicate whether the resources necessary for the offloaded playback are
+     * available at that instant.
+     * @param format the audio format (codec, sample rate, channels) being checked.
+     * @param attributes the {@link AudioAttributes} to be used for playback
+     * @return true if the given audio format can be offloaded.
+     */
+    public static boolean isOffloadedPlaybackSupported(@NonNull AudioFormat format,
+            @NonNull AudioAttributes attributes) {
+        if (format == null) {
+            throw new NullPointerException("Illegal null AudioFormat");
+        }
+        if (attributes == null) {
+            throw new NullPointerException("Illegal null AudioAttributes");
+        }
+        return AudioSystem.getOffloadSupport(format, attributes) != PLAYBACK_OFFLOAD_NOT_SUPPORTED;
+    }
+
+    /** Return value for {@link #getPlaybackOffloadSupport(AudioFormat, AudioAttributes)}:
+        offload playback not supported */
+    public static final int PLAYBACK_OFFLOAD_NOT_SUPPORTED = AudioSystem.OFFLOAD_NOT_SUPPORTED;
+    /** Return value for {@link #getPlaybackOffloadSupport(AudioFormat, AudioAttributes)}:
+        offload playback supported */
+    public static final int PLAYBACK_OFFLOAD_SUPPORTED = AudioSystem.OFFLOAD_SUPPORTED;
+    /** Return value for {@link #getPlaybackOffloadSupport(AudioFormat, AudioAttributes)}:
+        offload playback supported with gapless transitions */
+    public static final int PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED =
+            AudioSystem.OFFLOAD_GAPLESS_SUPPORTED;
+
+    /** @hide */
+    @IntDef(flag = false, prefix = "PLAYBACK_OFFLOAD_", value = {
+            PLAYBACK_OFFLOAD_NOT_SUPPORTED,
+            PLAYBACK_OFFLOAD_SUPPORTED,
+            PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioOffloadMode {}
+
+    /**
+     * Returns whether offloaded playback of an audio format is supported on the device or not and
+     * when supported whether gapless transitions are possible or not.
+     * <p>Offloaded playback is the feature where the decoding and playback of an audio stream
+     * is not competing with other software resources. In general, it is supported by dedicated
+     * hardware, such as audio DSPs.
+     * <p>Note that this query only provides information about the support of an audio format,
+     * it does not indicate whether the resources necessary for the offloaded playback are
+     * available at that instant.
+     * @param format the audio format (codec, sample rate, channels) being checked.
+     * @param attributes the {@link AudioAttributes} to be used for playback
+     * @return {@link #PLAYBACK_OFFLOAD_NOT_SUPPORTED} if offload playback if not supported,
+     *         {@link #PLAYBACK_OFFLOAD_SUPPORTED} if offload playback is supported or
+     *         {@link #PLAYBACK_OFFLOAD_GAPLESS_SUPPORTED} if gapless transitions are
+     *         also supported.
+     */
+    @AudioOffloadMode
+    public static int getPlaybackOffloadSupport(@NonNull AudioFormat format,
+            @NonNull AudioAttributes attributes) {
+        if (format == null) {
+            throw new NullPointerException("Illegal null AudioFormat");
+        }
+        if (attributes == null) {
+            throw new NullPointerException("Illegal null AudioAttributes");
+        }
+        return AudioSystem.getOffloadSupport(format, attributes);
+    }
+
+    //====================================================================
+    // Bluetooth SCO control
+    /**
+     * Sticky broadcast intent action indicating that the Bluetooth SCO audio
+     * connection state has changed. The intent contains on extra {@link #EXTRA_SCO_AUDIO_STATE}
+     * indicating the new state which is either {@link #SCO_AUDIO_STATE_DISCONNECTED}
+     * or {@link #SCO_AUDIO_STATE_CONNECTED}
+     *
+     * @see #startBluetoothSco()
+     * @deprecated Use  {@link #ACTION_SCO_AUDIO_STATE_UPDATED} instead
+     */
+    @Deprecated
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_SCO_AUDIO_STATE_CHANGED =
+            "android.media.SCO_AUDIO_STATE_CHANGED";
+
+     /**
+     * Sticky broadcast intent action indicating that the Bluetooth SCO audio
+     * connection state has been updated.
+     * <p>This intent has two extras:
+     * <ul>
+     *   <li> {@link #EXTRA_SCO_AUDIO_STATE} - The new SCO audio state. </li>
+     *   <li> {@link #EXTRA_SCO_AUDIO_PREVIOUS_STATE}- The previous SCO audio state. </li>
+     * </ul>
+     * <p> EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE can be any of:
+     * <ul>
+     *   <li> {@link #SCO_AUDIO_STATE_DISCONNECTED}, </li>
+     *   <li> {@link #SCO_AUDIO_STATE_CONNECTING} or </li>
+     *   <li> {@link #SCO_AUDIO_STATE_CONNECTED}, </li>
+     * </ul>
+     * @see #startBluetoothSco()
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_SCO_AUDIO_STATE_UPDATED =
+            "android.media.ACTION_SCO_AUDIO_STATE_UPDATED";
+
+    /**
+     * Extra for intent {@link #ACTION_SCO_AUDIO_STATE_CHANGED} or
+     * {@link #ACTION_SCO_AUDIO_STATE_UPDATED} containing the new bluetooth SCO connection state.
+     */
+    public static final String EXTRA_SCO_AUDIO_STATE =
+            "android.media.extra.SCO_AUDIO_STATE";
+
+    /**
+     * Extra for intent {@link #ACTION_SCO_AUDIO_STATE_UPDATED} containing the previous
+     * bluetooth SCO connection state.
+     */
+    public static final String EXTRA_SCO_AUDIO_PREVIOUS_STATE =
+            "android.media.extra.SCO_AUDIO_PREVIOUS_STATE";
+
+    /**
+     * Value for extra EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE
+     * indicating that the SCO audio channel is not established
+     */
+    public static final int SCO_AUDIO_STATE_DISCONNECTED = 0;
+    /**
+     * Value for extra {@link #EXTRA_SCO_AUDIO_STATE} or {@link #EXTRA_SCO_AUDIO_PREVIOUS_STATE}
+     * indicating that the SCO audio channel is established
+     */
+    public static final int SCO_AUDIO_STATE_CONNECTED = 1;
+    /**
+     * Value for extra EXTRA_SCO_AUDIO_STATE or EXTRA_SCO_AUDIO_PREVIOUS_STATE
+     * indicating that the SCO audio channel is being established
+     */
+    public static final int SCO_AUDIO_STATE_CONNECTING = 2;
+    /**
+     * Value for extra EXTRA_SCO_AUDIO_STATE indicating that
+     * there was an error trying to obtain the state
+     */
+    public static final int SCO_AUDIO_STATE_ERROR = -1;
+
+
+    /**
+     * Indicates if current platform supports use of SCO for off call use cases.
+     * Application wanted to use bluetooth SCO audio when the phone is not in call
+     * must first call this method to make sure that the platform supports this
+     * feature.
+     * @return true if bluetooth SCO can be used for audio when not in call
+     *         false otherwise
+     * @see #startBluetoothSco()
+    */
+    public boolean isBluetoothScoAvailableOffCall() {
+        return getContext().getResources().getBoolean(
+               com.android.internal.R.bool.config_bluetooth_sco_off_call);
+    }
+
+    /**
+     * Start bluetooth SCO audio connection.
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
+     * <p>This method can be used by applications wanting to send and received audio
+     * to/from a bluetooth SCO headset while the phone is not in call.
+     * <p>As the SCO connection establishment can take several seconds,
+     * applications should not rely on the connection to be available when the method
+     * returns but instead register to receive the intent {@link #ACTION_SCO_AUDIO_STATE_UPDATED}
+     * and wait for the state to be {@link #SCO_AUDIO_STATE_CONNECTED}.
+     * <p>As the ACTION_SCO_AUDIO_STATE_UPDATED intent is sticky, the application can check the SCO
+     * audio state before calling startBluetoothSco() by reading the intent returned by the receiver
+     * registration. If the state is already CONNECTED, no state change will be received via the
+     * intent after calling startBluetoothSco(). It is however useful to call startBluetoothSco()
+     * so that the connection stays active in case the current initiator stops the connection.
+     * <p>Unless the connection is already active as described above, the state will always
+     * transition from DISCONNECTED to CONNECTING and then either to CONNECTED if the connection
+     * succeeds or back to DISCONNECTED if the connection fails (e.g no headset is connected).
+     * <p>When finished with the SCO connection or if the establishment fails, the application must
+     * call {@link #stopBluetoothSco()} to clear the request and turn down the bluetooth connection.
+     * <p>Even if a SCO connection is established, the following restrictions apply on audio
+     * output streams so that they can be routed to SCO headset:
+     * <ul>
+     *   <li> the stream type must be {@link #STREAM_VOICE_CALL} </li>
+     *   <li> the format must be mono </li>
+     *   <li> the sampling must be 16kHz or 8kHz </li>
+     * </ul>
+     * <p>The following restrictions apply on input streams:
+     * <ul>
+     *   <li> the format must be mono </li>
+     *   <li> the sampling must be 8kHz </li>
+     * </ul>
+     * <p>Note that the phone application always has the priority on the usage of the SCO
+     * connection for telephony. If this method is called while the phone is in call
+     * it will be ignored. Similarly, if a call is received or sent while an application
+     * is using the SCO connection, the connection will be lost for the application and NOT
+     * returned automatically when the call ends.
+     * <p>NOTE: up to and including API version
+     * {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}, this method initiates a virtual
+     * voice call to the bluetooth headset.
+     * After API version {@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2} only a raw SCO audio
+     * connection is established.
+     * @see #stopBluetoothSco()
+     * @see #ACTION_SCO_AUDIO_STATE_UPDATED
+     */
+    public void startBluetoothSco(){
+        final IAudioService service = getService();
+        try {
+            service.startBluetoothSco(mICallBack,
+                    getContext().getApplicationInfo().targetSdkVersion);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Start bluetooth SCO audio connection in virtual call mode.
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
+     * <p>Similar to {@link #startBluetoothSco()} with explicit selection of virtual call mode.
+     * Telephony and communication applications (VoIP, Video Chat) should preferably select
+     * virtual call mode.
+     * Applications using voice input for search or commands should first try raw audio connection
+     * with {@link #startBluetoothSco()} and fall back to startBluetoothScoVirtualCall() in case of
+     * failure.
+     * @see #startBluetoothSco()
+     * @see #stopBluetoothSco()
+     * @see #ACTION_SCO_AUDIO_STATE_UPDATED
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public void startBluetoothScoVirtualCall() {
+        final IAudioService service = getService();
+        try {
+            service.startBluetoothScoVirtualCall(mICallBack);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Stop bluetooth SCO audio connection.
+     * <p>Requires Permission:
+     *   {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}.
+     * <p>This method must be called by applications having requested the use of
+     * bluetooth SCO audio with {@link #startBluetoothSco()} when finished with the SCO
+     * connection or if connection fails.
+     * @see #startBluetoothSco()
+     */
+    // Also used for connections started with {@link #startBluetoothScoVirtualCall()}
+    public void stopBluetoothSco(){
+        final IAudioService service = getService();
+        try {
+            service.stopBluetoothSco(mICallBack);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Request use of Bluetooth SCO headset for communications.
+     * <p>
+     * This method should only be used by applications that replace the platform-wide
+     * management of audio settings or the main telephony application.
+     *
+     * @param on set <var>true</var> to use bluetooth SCO for communications;
+     *               <var>false</var> to not use bluetooth SCO for communications
+     */
+    public void setBluetoothScoOn(boolean on){
+        final IAudioService service = getService();
+        try {
+            service.setBluetoothScoOn(on);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Checks whether communications use Bluetooth SCO.
+     *
+     * @return true if SCO is used for communications;
+     *         false if otherwise
+     */
+    public boolean isBluetoothScoOn() {
+        final IAudioService service = getService();
+        try {
+            return service.isBluetoothScoOn();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @param on set <var>true</var> to route A2DP audio to/from Bluetooth
+     *           headset; <var>false</var> disable A2DP audio
+     * @deprecated Do not use.
+     */
+    @Deprecated public void setBluetoothA2dpOn(boolean on){
+    }
+
+    /**
+     * Checks whether a Bluetooth A2DP audio peripheral is connected or not.
+     *
+     * @return true if a Bluetooth A2DP peripheral is connected
+     *         false if otherwise
+     * @deprecated Use {@link AudioManager#getDevices(int)} instead to list available audio devices.
+     */
+    public boolean isBluetoothA2dpOn() {
+        if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_BLUETOOTH_A2DP,"")
+                == AudioSystem.DEVICE_STATE_AVAILABLE) {
+            return true;
+        } else if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES,"")
+                == AudioSystem.DEVICE_STATE_AVAILABLE) {
+            return true;
+        } else if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER,"")
+                == AudioSystem.DEVICE_STATE_AVAILABLE) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Sets audio routing to the wired headset on or off.
+     *
+     * @param on set <var>true</var> to route audio to/from wired
+     *           headset; <var>false</var> disable wired headset audio
+     * @deprecated Do not use.
+     */
+    @Deprecated public void setWiredHeadsetOn(boolean on){
+    }
+
+    /**
+     * Checks whether a wired headset is connected or not.
+     * <p>This is not a valid indication that audio playback is
+     * actually over the wired headset as audio routing depends on other conditions.
+     *
+     * @return true if a wired headset is connected.
+     *         false if otherwise
+     * @deprecated Use {@link AudioManager#getDevices(int)} instead to list available audio devices.
+     */
+    public boolean isWiredHeadsetOn() {
+        if (AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADSET,"")
+                == AudioSystem.DEVICE_STATE_UNAVAILABLE &&
+            AudioSystem.getDeviceConnectionState(DEVICE_OUT_WIRED_HEADPHONE,"")
+                == AudioSystem.DEVICE_STATE_UNAVAILABLE &&
+            AudioSystem.getDeviceConnectionState(DEVICE_OUT_USB_HEADSET, "")
+              == AudioSystem.DEVICE_STATE_UNAVAILABLE) {
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Sets the microphone mute on or off.
+     * <p>
+     * This method should only be used by applications that replace the platform-wide
+     * management of audio settings or the main telephony application.
+     *
+     * @param on set <var>true</var> to mute the microphone;
+     *           <var>false</var> to turn mute off
+     */
+    public void setMicrophoneMute(boolean on) {
+        final IAudioService service = getService();
+        try {
+            service.setMicrophoneMute(on, getContext().getOpPackageName(),
+                    UserHandle.getCallingUserId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Sets the microphone from switch mute on or off.
+     * <p>
+     * This method should only be used by InputManager to notify
+     * Audio Subsystem about Microphone Mute switch state.
+     *
+     * @param on set <var>true</var> to mute the microphone;
+     *           <var>false</var> to turn mute off
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public void setMicrophoneMuteFromSwitch(boolean on) {
+        final IAudioService service = getService();
+        try {
+            service.setMicrophoneMuteFromSwitch(on);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Checks whether the microphone mute is on or off.
+     *
+     * @return true if microphone is muted, false if it's not
+     */
+    public boolean isMicrophoneMute() {
+        final IAudioService service = getService();
+        try {
+            return service.isMicrophoneMuted();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Broadcast Action: microphone muting state changed.
+     *
+     * You <em>cannot</em> receive this through components declared
+     * in manifests, only by explicitly registering for it with
+     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
+     * Context.registerReceiver()}.
+     *
+     * <p>The intent has no extra values, use {@link #isMicrophoneMute} to check whether the
+     * microphone is muted.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_MICROPHONE_MUTE_CHANGED =
+            "android.media.action.MICROPHONE_MUTE_CHANGED";
+
+    /**
+     * Broadcast Action: speakerphone state changed.
+     *
+     * You <em>cannot</em> receive this through components declared
+     * in manifests, only by explicitly registering for it with
+     * {@link Context#registerReceiver(BroadcastReceiver, IntentFilter)
+     * Context.registerReceiver()}.
+     *
+     * <p>The intent has no extra values, use {@link #isSpeakerphoneOn} to check whether the
+     * speakerphone functionality is enabled or not.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_SPEAKERPHONE_STATE_CHANGED =
+            "android.media.action.SPEAKERPHONE_STATE_CHANGED";
+
+    /**
+     * Sets the audio mode.
+     * <p>
+     * The audio mode encompasses audio routing AND the behavior of
+     * the telephony layer. Therefore this method should only be used by applications that
+     * replace the platform-wide management of audio settings or the main telephony application.
+     * In particular, the {@link #MODE_IN_CALL} mode should only be used by the telephony
+     * application when it places a phone call, as it will cause signals from the radio layer
+     * to feed the platform mixer.
+     *
+     * @param mode  the requested audio mode.
+     *              Informs the HAL about the current audio state so that
+     *              it can route the audio appropriately.
+     */
+    public void setMode(@AudioMode int mode) {
+        final IAudioService service = getService();
+        try {
+            service.setMode(mode, mICallBack, mApplicationContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the current audio mode.
+     *
+     * @return      the current audio mode.
+     */
+    @AudioMode
+    public int getMode() {
+        final IAudioService service = getService();
+        try {
+            int mode = service.getMode();
+            int sdk;
+            try {
+                sdk = getContext().getApplicationInfo().targetSdkVersion;
+            } catch (NullPointerException e) {
+                // some tests don't have a Context
+                sdk = Build.VERSION.SDK_INT;
+            }
+            if (mode == MODE_CALL_SCREENING && sdk <= Build.VERSION_CODES.Q) {
+                mode = MODE_IN_CALL;
+            }
+            return mode;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Interface definition of a callback that is notified when the audio mode changes
+     */
+    public interface OnModeChangedListener {
+        /**
+         * Called on the listener to indicate that the audio mode has changed
+         *
+         * @param mode The current audio mode
+         */
+        void onModeChanged(@AudioMode int mode);
+    }
+
+    private final Object mModeListenerLock = new Object();
+    /**
+     * List of listeners for audio mode and their associated Executor.
+     * List is lazy-initialized on first registration
+     */
+    @GuardedBy("mModeListenerLock")
+    private @Nullable ArrayList<ModeListenerInfo> mModeListeners;
+
+    @GuardedBy("mModeListenerLock")
+    private ModeDispatcherStub mModeDispatcherStub;
+
+    private final class ModeDispatcherStub
+            extends IAudioModeDispatcher.Stub {
+
+        @Override
+        public void dispatchAudioModeChanged(int mode) {
+            // make a shallow copy of listeners so callback is not executed under lock
+            final ArrayList<ModeListenerInfo> modeListeners;
+            synchronized (mModeListenerLock) {
+                if (mModeListeners == null || mModeListeners.size() == 0) {
+                    return;
+                }
+                modeListeners = (ArrayList<ModeListenerInfo>) mModeListeners.clone();
+            }
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                for (ModeListenerInfo info : modeListeners) {
+                    info.mExecutor.execute(() ->
+                            info.mListener.onModeChanged(mode));
+                }
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    private static class ModeListenerInfo {
+        final @NonNull OnModeChangedListener mListener;
+        final @NonNull Executor mExecutor;
+
+        ModeListenerInfo(OnModeChangedListener listener, Executor exe) {
+            mListener = listener;
+            mExecutor = exe;
+        }
+    }
+
+    @GuardedBy("mModeListenerLock")
+    private boolean hasModeListener(OnModeChangedListener listener) {
+        return getModeListenerInfo(listener) != null;
+    }
+
+    @GuardedBy("mModeListenerLock")
+    private @Nullable ModeListenerInfo getModeListenerInfo(
+            OnModeChangedListener listener) {
+        if (mModeListeners == null) {
+            return null;
+        }
+        for (ModeListenerInfo info : mModeListeners) {
+            if (info.mListener == listener) {
+                return info;
+            }
+        }
+        return null;
+    }
+
+
+    @GuardedBy("mModeListenerLock")
+    /**
+     * @return true if the listener was removed from the list
+     */
+    private boolean removeModeListener(OnModeChangedListener listener) {
+        final ModeListenerInfo infoToRemove = getModeListenerInfo(listener);
+        if (infoToRemove != null) {
+            mModeListeners.remove(infoToRemove);
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Adds a listener to be notified of changes to the audio mode.
+     * See {@link #getMode()}
+     * @param executor
+     * @param listener
+     */
+    public void addOnModeChangedListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnModeChangedListener listener) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(listener);
+        synchronized (mModeListenerLock) {
+            if (hasModeListener(listener)) {
+                throw new IllegalArgumentException("attempt to call addOnModeChangedListener() "
+                        + "on a previously registered listener");
+            }
+            // lazy initialization of the list of strategy-preferred device listener
+            if (mModeListeners == null) {
+                mModeListeners = new ArrayList<>();
+            }
+            final int oldCbCount = mModeListeners.size();
+            mModeListeners.add(new ModeListenerInfo(listener, executor));
+            if (oldCbCount == 0) {
+                // register binder for callbacks
+                if (mModeDispatcherStub == null) {
+                    mModeDispatcherStub = new ModeDispatcherStub();
+                }
+                try {
+                    getService().registerModeDispatcher(mModeDispatcherStub);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes a previously added listener for changes to audio mode.
+     * See {@link #getMode()}
+     * @param listener
+     */
+    public void removeOnModeChangedListener(@NonNull OnModeChangedListener listener) {
+        Objects.requireNonNull(listener);
+        synchronized (mModeListenerLock) {
+            if (!removeModeListener(listener)) {
+                throw new IllegalArgumentException("attempt to call removeOnModeChangedListener() "
+                        + "on an unregistered listener");
+            }
+            if (mModeListeners.size() == 0) {
+                // unregister binder for callbacks
+                try {
+                    getService().unregisterModeDispatcher(mModeDispatcherStub);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                } finally {
+                    mModeDispatcherStub = null;
+                    mModeListeners = null;
+                }
+            }
+        }
+    }
+
+    /**
+    * Indicates if the platform supports a special call screening and call monitoring mode.
+    * <p>
+    * When this mode is supported, it is possible to perform call screening and monitoring
+    * functions while other use cases like music or movie playback are active.
+    * <p>
+    * Use {@link #setMode(int)} with mode {@link #MODE_CALL_SCREENING} to place the platform in
+    * call screening mode.
+    * <p>
+    * If call screening mode is not supported, setting mode to
+    * MODE_CALL_SCREENING will be ignored and will not change current mode reported by
+    *  {@link #getMode()}.
+    * @return true if call screening mode is supported, false otherwise.
+    */
+    public boolean isCallScreeningModeSupported() {
+        final IAudioService service = getService();
+        try {
+            return service.isCallScreeningModeSupported();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /* modes for setMode/getMode/setRoute/getRoute */
+    /**
+     * Audio harware modes.
+     */
+    /**
+     * Invalid audio mode.
+     */
+    public static final int MODE_INVALID            = AudioSystem.MODE_INVALID;
+    /**
+     * Current audio mode. Used to apply audio routing to current mode.
+     */
+    public static final int MODE_CURRENT            = AudioSystem.MODE_CURRENT;
+    /**
+     * Normal audio mode: not ringing and no call established.
+     */
+    public static final int MODE_NORMAL             = AudioSystem.MODE_NORMAL;
+    /**
+     * Ringing audio mode. An incoming is being signaled.
+     */
+    public static final int MODE_RINGTONE           = AudioSystem.MODE_RINGTONE;
+    /**
+     * In call audio mode. A telephony call is established.
+     */
+    public static final int MODE_IN_CALL            = AudioSystem.MODE_IN_CALL;
+    /**
+     * In communication audio mode. An audio/video chat or VoIP call is established.
+     */
+    public static final int MODE_IN_COMMUNICATION   = AudioSystem.MODE_IN_COMMUNICATION;
+    /**
+     * Call screening in progress. Call is connected and audio is accessible to call
+     * screening applications but other audio use cases are still possible.
+     */
+    public static final int MODE_CALL_SCREENING     = AudioSystem.MODE_CALL_SCREENING;
+
+    /** @hide */
+    @IntDef(flag = false, prefix = "MODE_", value = {
+            MODE_NORMAL,
+            MODE_RINGTONE,
+            MODE_IN_CALL,
+            MODE_IN_COMMUNICATION,
+            MODE_CALL_SCREENING }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioMode {}
+
+    /* Routing bits for setRouting/getRouting API */
+    /**
+     * Routing audio output to earpiece
+     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
+     * setBluetoothScoOn() methods instead.
+     */
+    @Deprecated public static final int ROUTE_EARPIECE          = AudioSystem.ROUTE_EARPIECE;
+    /**
+     * Routing audio output to speaker
+     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
+     * setBluetoothScoOn() methods instead.
+     */
+    @Deprecated public static final int ROUTE_SPEAKER           = AudioSystem.ROUTE_SPEAKER;
+    /**
+     * @deprecated use {@link #ROUTE_BLUETOOTH_SCO}
+     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
+     * setBluetoothScoOn() methods instead.
+     */
+    @Deprecated public static final int ROUTE_BLUETOOTH = AudioSystem.ROUTE_BLUETOOTH_SCO;
+    /**
+     * Routing audio output to bluetooth SCO
+     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
+     * setBluetoothScoOn() methods instead.
+     */
+    @Deprecated public static final int ROUTE_BLUETOOTH_SCO     = AudioSystem.ROUTE_BLUETOOTH_SCO;
+    /**
+     * Routing audio output to headset
+     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
+     * setBluetoothScoOn() methods instead.
+     */
+    @Deprecated public static final int ROUTE_HEADSET           = AudioSystem.ROUTE_HEADSET;
+    /**
+     * Routing audio output to bluetooth A2DP
+     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
+     * setBluetoothScoOn() methods instead.
+     */
+    @Deprecated public static final int ROUTE_BLUETOOTH_A2DP    = AudioSystem.ROUTE_BLUETOOTH_A2DP;
+    /**
+     * Used for mask parameter of {@link #setRouting(int,int,int)}.
+     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
+     * setBluetoothScoOn() methods instead.
+     */
+    @Deprecated public static final int ROUTE_ALL               = AudioSystem.ROUTE_ALL;
+
+    /**
+     * Sets the audio routing for a specified mode
+     *
+     * @param mode   audio mode to change route. E.g., MODE_RINGTONE.
+     * @param routes bit vector of routes requested, created from one or
+     *               more of ROUTE_xxx types. Set bits indicate that route should be on
+     * @param mask   bit vector of routes to change, created from one or more of
+     * ROUTE_xxx types. Unset bits indicate the route should be left unchanged
+     *
+     * @deprecated   Do not set audio routing directly, use setSpeakerphoneOn(),
+     * setBluetoothScoOn() methods instead.
+     */
+    @Deprecated
+    public void setRouting(int mode, int routes, int mask) {
+    }
+
+    /**
+     * Returns the current audio routing bit vector for a specified mode.
+     *
+     * @param mode audio mode to get route (e.g., MODE_RINGTONE)
+     * @return an audio route bit vector that can be compared with ROUTE_xxx
+     * bits
+     * @deprecated   Do not query audio routing directly, use isSpeakerphoneOn(),
+     * isBluetoothScoOn(), isBluetoothA2dpOn() and isWiredHeadsetOn() methods instead.
+     */
+    @Deprecated
+    public int getRouting(int mode) {
+        return -1;
+    }
+
+    /**
+     * Checks whether any music is active.
+     *
+     * @return true if any music tracks are active.
+     */
+    public boolean isMusicActive() {
+        final IAudioService service = getService();
+        try {
+            return service.isMusicActive(false /*remotely*/);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Checks whether any music or media is actively playing on a remote device (e.g. wireless
+     *   display). Note that BT audio sinks are not considered remote devices.
+     * @return true if {@link AudioManager#STREAM_MUSIC} is active on a remote device
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public boolean isMusicActiveRemotely() {
+        final IAudioService service = getService();
+        try {
+            return service.isMusicActive(true /*remotely*/);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Checks whether the current audio focus is exclusive.
+     * @return true if the top of the audio focus stack requested focus
+     *     with {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}
+     */
+    public boolean isAudioFocusExclusive() {
+        final IAudioService service = getService();
+        try {
+            return service.getCurrentAudioFocus() == AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return a new audio session identifier not associated with any player or effect.
+     * An audio session identifier is a system wide unique identifier for a set of audio streams
+     * (one or more mixed together).
+     * <p>The primary use of the audio session ID is to associate audio effects to audio players,
+     * such as {@link MediaPlayer} or {@link AudioTrack}: all audio effects sharing the same audio
+     * session ID will be applied to the mixed audio content of the players that share the same
+     * audio session.
+     * <p>This method can for instance be used when creating one of the
+     * {@link android.media.audiofx.AudioEffect} objects to define the audio session of the effect,
+     * or to specify a session for a speech synthesis utterance
+     * in {@link android.speech.tts.TextToSpeech.Engine}.
+     * @return a new unclaimed and unused audio session identifier, or {@link #ERROR} when the
+     *   system failed to generate a new session, a condition in which audio playback or recording
+     *   will subsequently fail as well.
+     */
+    public int generateAudioSessionId() {
+        int session = AudioSystem.newAudioSessionId();
+        if (session > 0) {
+            return session;
+        } else {
+            Log.e(TAG, "Failure to generate a new audio session ID");
+            return ERROR;
+        }
+    }
+
+    /**
+     * A special audio session ID to indicate that the audio session ID isn't known and the
+     * framework should generate a new value. This can be used when building a new
+     * {@link AudioTrack} instance with
+     * {@link AudioTrack#AudioTrack(AudioAttributes, AudioFormat, int, int, int)}.
+     */
+    public static final int AUDIO_SESSION_ID_GENERATE = AudioSystem.AUDIO_SESSION_ALLOCATE;
+
+
+    /*
+     * Sets a generic audio configuration parameter. The use of these parameters
+     * are platform dependant, see libaudio
+     *
+     * ** Temporary interface - DO NOT USE
+     *
+     * TODO: Replace with a more generic key:value get/set mechanism
+     *
+     * param key   name of parameter to set. Must not be null.
+     * param value value of parameter. Must not be null.
+     */
+    /**
+     * @hide
+     * @deprecated Use {@link #setParameters(String)} instead
+     */
+    @Deprecated public void setParameter(String key, String value) {
+        setParameters(key+"="+value);
+    }
+
+    /**
+     * Sets a variable number of parameter values to audio hardware.
+     *
+     * @param keyValuePairs list of parameters key value pairs in the form:
+     *    key1=value1;key2=value2;...
+     *
+     */
+    public void setParameters(String keyValuePairs) {
+        AudioSystem.setParameters(keyValuePairs);
+    }
+
+    /**
+     * Gets a variable number of parameter values from audio hardware.
+     *
+     * @param keys list of parameters
+     * @return list of parameters key value pairs in the form:
+     *    key1=value1;key2=value2;...
+     */
+    public String getParameters(String keys) {
+        return AudioSystem.getParameters(keys);
+    }
+
+    /* Sound effect identifiers */
+    /**
+     * Keyboard and direction pad click sound
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_KEY_CLICK = 0;
+    /**
+     * Focus has moved up
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_FOCUS_NAVIGATION_UP = 1;
+    /**
+     * Focus has moved down
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_FOCUS_NAVIGATION_DOWN = 2;
+    /**
+     * Focus has moved left
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_FOCUS_NAVIGATION_LEFT = 3;
+    /**
+     * Focus has moved right
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_FOCUS_NAVIGATION_RIGHT = 4;
+    /**
+     * IME standard keypress sound
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_KEYPRESS_STANDARD = 5;
+    /**
+     * IME spacebar keypress sound
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_KEYPRESS_SPACEBAR = 6;
+    /**
+     * IME delete keypress sound
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_KEYPRESS_DELETE = 7;
+    /**
+     * IME return_keypress sound
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_KEYPRESS_RETURN = 8;
+
+    /**
+     * Invalid keypress sound
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_KEYPRESS_INVALID = 9;
+
+    /**
+     * Back sound
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_BACK = 10;
+
+    /**
+     * @hide Home sound
+     * <p>
+     * To be played by the framework when the home app becomes active if config_enableHomeSound is
+     * set to true. This is currently only used on TV devices.
+     * Note that this sound is only available if a sound file is specified in audio_assets.xml.
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_HOME = 11;
+
+    /**
+     * @hide Navigation repeat sound 1
+     * <p>
+     * To be played by the framework when a focus navigation is repeatedly triggered
+     * (e.g. due to long-pressing) and {@link #areNavigationRepeatSoundEffectsEnabled()} is true.
+     * This is currently only used on TV devices.
+     * Note that this sound is only available if a sound file is specified in audio_assets.xml
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_FOCUS_NAVIGATION_REPEAT_1 = 12;
+
+    /**
+     * @hide Navigation repeat sound 2
+     * <p>
+     * To be played by the framework when a focus navigation is repeatedly triggered
+     * (e.g. due to long-pressing) and {@link #areNavigationRepeatSoundEffectsEnabled()} is true.
+     * This is currently only used on TV devices.
+     * Note that this sound is only available if a sound file is specified in audio_assets.xml
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_FOCUS_NAVIGATION_REPEAT_2 = 13;
+
+    /**
+     * @hide Navigation repeat sound 3
+     * <p>
+     * To be played by the framework when a focus navigation is repeatedly triggered
+     * (e.g. due to long-pressing) and {@link #areNavigationRepeatSoundEffectsEnabled()} is true.
+     * This is currently only used on TV devices.
+     * Note that this sound is only available if a sound file is specified in audio_assets.xml
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_FOCUS_NAVIGATION_REPEAT_3 = 14;
+
+    /**
+     * @hide Navigation repeat sound 4
+     * <p>
+     * To be played by the framework when a focus navigation is repeatedly triggered
+     * (e.g. due to long-pressing) and {@link #areNavigationRepeatSoundEffectsEnabled()} is true.
+     * This is currently only used on TV devices.
+     * Note that this sound is only available if a sound file is specified in audio_assets.xml
+     * @see #playSoundEffect(int)
+     */
+    public static final int FX_FOCUS_NAVIGATION_REPEAT_4 = 15;
+
+    /**
+     * @hide Number of sound effects
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public static final int NUM_SOUND_EFFECTS = 16;
+
+    /** @hide */
+    @IntDef(prefix = { "FX_" }, value = {
+            FX_KEY_CLICK,
+            FX_FOCUS_NAVIGATION_UP,
+            FX_FOCUS_NAVIGATION_DOWN,
+            FX_FOCUS_NAVIGATION_LEFT,
+            FX_FOCUS_NAVIGATION_RIGHT,
+            FX_KEYPRESS_STANDARD,
+            FX_KEYPRESS_SPACEBAR,
+            FX_KEYPRESS_DELETE,
+            FX_KEYPRESS_RETURN,
+            FX_KEYPRESS_INVALID,
+            FX_BACK
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SystemSoundEffect {}
+
+    /**
+     * @hide Number of FX_FOCUS_NAVIGATION_REPEAT_* sound effects
+     */
+    public static final int NUM_NAVIGATION_REPEAT_SOUND_EFFECTS = 4;
+
+    /**
+     * @hide
+     * @param n a value in [0, {@link #NUM_NAVIGATION_REPEAT_SOUND_EFFECTS}[
+     * @return The id of a navigation repeat sound effect or -1 if out of bounds
+     */
+    public static int getNthNavigationRepeatSoundEffect(int n) {
+        switch (n) {
+            case 0:
+                return FX_FOCUS_NAVIGATION_REPEAT_1;
+            case 1:
+                return FX_FOCUS_NAVIGATION_REPEAT_2;
+            case 2:
+                return FX_FOCUS_NAVIGATION_REPEAT_3;
+            case 3:
+                return FX_FOCUS_NAVIGATION_REPEAT_4;
+            default:
+                Log.w(TAG, "Invalid navigation repeat sound effect id: " + n);
+                return -1;
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public void setNavigationRepeatSoundEffectsEnabled(boolean enabled) {
+        try {
+            getService().setNavigationRepeatSoundEffectsEnabled(enabled);
+        } catch (RemoteException e) {
+
+        }
+    }
+
+    /**
+     * @hide
+     * @return true if the navigation repeat sound effects are enabled
+     */
+    public boolean areNavigationRepeatSoundEffectsEnabled() {
+        try {
+            return getService().areNavigationRepeatSoundEffectsEnabled();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * @param enabled
+     */
+    public void setHomeSoundEffectEnabled(boolean enabled) {
+        try {
+            getService().setHomeSoundEffectEnabled(enabled);
+        } catch (RemoteException e) {
+
+        }
+    }
+
+    /**
+     * @hide
+     * @return true if the home sound effect is enabled
+     */
+    public boolean isHomeSoundEffectEnabled() {
+        try {
+            return getService().isHomeSoundEffectEnabled();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Plays a sound effect (Key clicks, lid open/close...)
+     * @param effectType The type of sound effect.
+     * NOTE: This version uses the UI settings to determine
+     * whether sounds are heard or not.
+     */
+    public void playSoundEffect(@SystemSoundEffect int effectType) {
+        if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) {
+            return;
+        }
+
+        if (!querySoundEffectsEnabled(Process.myUserHandle().getIdentifier())) {
+            return;
+        }
+
+        final IAudioService service = getService();
+        try {
+            service.playSoundEffect(effectType);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Plays a sound effect (Key clicks, lid open/close...)
+     * @param effectType The type of sound effect.
+     * @param userId The current user to pull sound settings from
+     * NOTE: This version uses the UI settings to determine
+     * whether sounds are heard or not.
+     * @hide
+     */
+    public void  playSoundEffect(@SystemSoundEffect int effectType, int userId) {
+        if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) {
+            return;
+        }
+
+        if (!querySoundEffectsEnabled(userId)) {
+            return;
+        }
+
+        final IAudioService service = getService();
+        try {
+            service.playSoundEffect(effectType);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Plays a sound effect (Key clicks, lid open/close...)
+     * @param effectType The type of sound effect.
+     * @param volume Sound effect volume.
+     * The volume value is a raw scalar so UI controls should be scaled logarithmically.
+     * If a volume of -1 is specified, the AudioManager.STREAM_MUSIC stream volume minus 3dB will be used.
+     * NOTE: This version is for applications that have their own
+     * settings panel for enabling and controlling volume.
+     */
+    public void  playSoundEffect(@SystemSoundEffect int effectType, float volume) {
+        if (effectType < 0 || effectType >= NUM_SOUND_EFFECTS) {
+            return;
+        }
+
+        final IAudioService service = getService();
+        try {
+            service.playSoundEffectVolume(effectType, volume);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Settings has an in memory cache, so this is fast.
+     */
+    private boolean querySoundEffectsEnabled(int user) {
+        return Settings.System.getIntForUser(getContext().getContentResolver(),
+                Settings.System.SOUND_EFFECTS_ENABLED, 0, user) != 0;
+    }
+
+    /**
+     *  Load Sound effects.
+     *  This method must be called when sound effects are enabled.
+     */
+    public void loadSoundEffects() {
+        final IAudioService service = getService();
+        try {
+            service.loadSoundEffects();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     *  Unload Sound effects.
+     *  This method can be called to free some memory when
+     *  sound effects are disabled.
+     */
+    public void unloadSoundEffects() {
+        final IAudioService service = getService();
+        try {
+            service.unloadSoundEffects();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static String audioFocusToString(int focus) {
+        switch (focus) {
+            case AUDIOFOCUS_NONE:
+                return "AUDIOFOCUS_NONE";
+            case AUDIOFOCUS_GAIN:
+                return "AUDIOFOCUS_GAIN";
+            case AUDIOFOCUS_GAIN_TRANSIENT:
+                return "AUDIOFOCUS_GAIN_TRANSIENT";
+            case AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK:
+                return "AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK";
+            case AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE:
+                return "AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE";
+            case AUDIOFOCUS_LOSS:
+                return "AUDIOFOCUS_LOSS";
+            case AUDIOFOCUS_LOSS_TRANSIENT:
+                return "AUDIOFOCUS_LOSS_TRANSIENT";
+            case AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: // Note CAN_DUCK not MAY_DUCK.
+                return "AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK";
+            default:
+                return "AUDIO_FOCUS_UNKNOWN(" + focus + ")";
+        }
+    }
+
+    /**
+     * Used to indicate no audio focus has been gained or lost, or requested.
+     */
+    public static final int AUDIOFOCUS_NONE = 0;
+
+    /**
+     * Used to indicate a gain of audio focus, or a request of audio focus, of unknown duration.
+     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
+     * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)
+     */
+    public static final int AUDIOFOCUS_GAIN = 1;
+    /**
+     * Used to indicate a temporary gain or request of audio focus, anticipated to last a short
+     * amount of time. Examples of temporary changes are the playback of driving directions, or an
+     * event notification.
+     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
+     * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)
+     */
+    public static final int AUDIOFOCUS_GAIN_TRANSIENT = 2;
+    /**
+     * Used to indicate a temporary request of audio focus, anticipated to last a short
+     * amount of time, and where it is acceptable for other audio applications to keep playing
+     * after having lowered their output level (also referred to as "ducking").
+     * Examples of temporary changes are the playback of driving directions where playback of music
+     * in the background is acceptable.
+     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
+     * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)
+     */
+    public static final int AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK = 3;
+    /**
+     * Used to indicate a temporary request of audio focus, anticipated to last a short
+     * amount of time, during which no other applications, or system components, should play
+     * anything. Examples of exclusive and transient audio focus requests are voice
+     * memo recording and speech recognition, during which the system shouldn't play any
+     * notifications, and media playback should have paused.
+     * @see #requestAudioFocus(OnAudioFocusChangeListener, int, int)
+     */
+    public static final int AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE = 4;
+    /**
+     * Used to indicate a loss of audio focus of unknown duration.
+     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
+     */
+    public static final int AUDIOFOCUS_LOSS = -1 * AUDIOFOCUS_GAIN;
+    /**
+     * Used to indicate a transient loss of audio focus.
+     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
+     */
+    public static final int AUDIOFOCUS_LOSS_TRANSIENT = -1 * AUDIOFOCUS_GAIN_TRANSIENT;
+    /**
+     * Used to indicate a transient loss of audio focus where the loser of the audio focus can
+     * lower its output volume if it wants to continue playing (also referred to as "ducking"), as
+     * the new focus owner doesn't require others to be silent.
+     * @see OnAudioFocusChangeListener#onAudioFocusChange(int)
+     */
+    public static final int AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK =
+            -1 * AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK;
+
+    /**
+     * Interface definition for a callback to be invoked when the audio focus of the system is
+     * updated.
+     */
+    public interface OnAudioFocusChangeListener {
+        /**
+         * Called on the listener to notify it the audio focus for this listener has been changed.
+         * The focusChange value indicates whether the focus was gained,
+         * whether the focus was lost, and whether that loss is transient, or whether the new focus
+         * holder will hold it for an unknown amount of time.
+         * When losing focus, listeners can use the focus change information to decide what
+         * behavior to adopt when losing focus. A music player could for instance elect to lower
+         * the volume of its music stream (duck) for transient focus losses, and pause otherwise.
+         * @param focusChange the type of focus change, one of {@link AudioManager#AUDIOFOCUS_GAIN},
+         *   {@link AudioManager#AUDIOFOCUS_LOSS}, {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT}
+         *   and {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}.
+         */
+        public void onAudioFocusChange(int focusChange);
+    }
+
+    /**
+     * Internal class to hold the AudioFocusRequest as well as the Handler for the callback
+     */
+    private static class FocusRequestInfo {
+        @NonNull  final AudioFocusRequest mRequest;
+        @Nullable final Handler mHandler;
+        FocusRequestInfo(@NonNull AudioFocusRequest afr, @Nullable Handler handler) {
+            mRequest = afr;
+            mHandler = handler;
+        }
+    }
+
+    /**
+     * Map to convert focus event listener IDs, as used in the AudioService audio focus stack,
+     * to actual listener objects.
+     */
+    @UnsupportedAppUsage
+    private final ConcurrentHashMap<String, FocusRequestInfo> mAudioFocusIdListenerMap =
+            new ConcurrentHashMap<String, FocusRequestInfo>();
+
+    private FocusRequestInfo findFocusRequestInfo(String id) {
+        return mAudioFocusIdListenerMap.get(id);
+    }
+
+    /**
+     * Handler for events (audio focus change, recording config change) coming from the
+     * audio service.
+     */
+    private final ServiceEventHandlerDelegate mServiceEventHandlerDelegate =
+            new ServiceEventHandlerDelegate(null);
+
+    /**
+     * Event types
+     */
+    private final static int MSSG_FOCUS_CHANGE = 0;
+    private final static int MSSG_RECORDING_CONFIG_CHANGE = 1;
+    private final static int MSSG_PLAYBACK_CONFIG_CHANGE = 2;
+
+    /**
+     * Helper class to handle the forwarding of audio service events to the appropriate listener
+     */
+    private class ServiceEventHandlerDelegate {
+        private final Handler mHandler;
+
+        ServiceEventHandlerDelegate(Handler handler) {
+            Looper looper;
+            if (handler == null) {
+                if ((looper = Looper.myLooper()) == null) {
+                    looper = Looper.getMainLooper();
+                }
+            } else {
+                looper = handler.getLooper();
+            }
+
+            if (looper != null) {
+                // implement the event handler delegate to receive events from audio service
+                mHandler = new Handler(looper) {
+                    @Override
+                    public void handleMessage(Message msg) {
+                        switch (msg.what) {
+                            case MSSG_FOCUS_CHANGE: {
+                                final FocusRequestInfo fri = findFocusRequestInfo((String)msg.obj);
+                                if (fri != null)  {
+                                    final OnAudioFocusChangeListener listener =
+                                            fri.mRequest.getOnAudioFocusChangeListener();
+                                    if (listener != null) {
+                                        Log.d(TAG, "dispatching onAudioFocusChange("
+                                                + msg.arg1 + ") to " + msg.obj);
+                                        listener.onAudioFocusChange(msg.arg1);
+                                    }
+                                }
+                            } break;
+                            case MSSG_RECORDING_CONFIG_CHANGE: {
+                                final RecordConfigChangeCallbackData cbData =
+                                        (RecordConfigChangeCallbackData) msg.obj;
+                                if (cbData.mCb != null) {
+                                    cbData.mCb.onRecordingConfigChanged(cbData.mConfigs);
+                                }
+                            } break;
+                            case MSSG_PLAYBACK_CONFIG_CHANGE: {
+                                final PlaybackConfigChangeCallbackData cbData =
+                                        (PlaybackConfigChangeCallbackData) msg.obj;
+                                if (cbData.mCb != null) {
+                                    if (DEBUG) {
+                                        Log.d(TAG, "dispatching onPlaybackConfigChanged()");
+                                    }
+                                    cbData.mCb.onPlaybackConfigChanged(cbData.mConfigs);
+                                }
+                            } break;
+                            default:
+                                Log.e(TAG, "Unknown event " + msg.what);
+                        }
+                    }
+                };
+            } else {
+                mHandler = null;
+            }
+        }
+
+        Handler getHandler() {
+            return mHandler;
+        }
+    }
+
+    private final IAudioFocusDispatcher mAudioFocusDispatcher = new IAudioFocusDispatcher.Stub() {
+        @Override
+        public void dispatchAudioFocusChange(int focusChange, String id) {
+            final FocusRequestInfo fri = findFocusRequestInfo(id);
+            if (fri != null)  {
+                final OnAudioFocusChangeListener listener =
+                        fri.mRequest.getOnAudioFocusChangeListener();
+                if (listener != null) {
+                    final Handler h = (fri.mHandler == null) ?
+                            mServiceEventHandlerDelegate.getHandler() : fri.mHandler;
+                    final Message m = h.obtainMessage(
+                            MSSG_FOCUS_CHANGE/*what*/, focusChange/*arg1*/, 0/*arg2 ignored*/,
+                            id/*obj*/);
+                    h.sendMessage(m);
+                }
+            }
+        }
+
+        @Override
+        public void dispatchFocusResultFromExtPolicy(int requestResult, String clientId) {
+            synchronized (mFocusRequestsLock) {
+                // TODO use generation counter as the key instead
+                final BlockingFocusResultReceiver focusReceiver =
+                        mFocusRequestsAwaitingResult.remove(clientId);
+                if (focusReceiver != null) {
+                    focusReceiver.notifyResult(requestResult);
+                } else {
+                    Log.e(TAG, "dispatchFocusResultFromExtPolicy found no result receiver");
+                }
+            }
+        }
+    };
+
+    private String getIdForAudioFocusListener(OnAudioFocusChangeListener l) {
+        if (l == null) {
+            return new String(this.toString());
+        } else {
+            return new String(this.toString() + l.toString());
+        }
+    }
+
+    /**
+     * @hide
+     * Registers a listener to be called when audio focus changes and keeps track of the associated
+     * focus request (including Handler to use for the listener).
+     * @param afr the full request parameters
+     */
+    public void registerAudioFocusRequest(@NonNull AudioFocusRequest afr) {
+        final Handler h = afr.getOnAudioFocusChangeListenerHandler();
+        final FocusRequestInfo fri = new FocusRequestInfo(afr, (h == null) ? null :
+            new ServiceEventHandlerDelegate(h).getHandler());
+        final String key = getIdForAudioFocusListener(afr.getOnAudioFocusChangeListener());
+        mAudioFocusIdListenerMap.put(key, fri);
+    }
+
+    /**
+     * @hide
+     * Causes the specified listener to not be called anymore when focus is gained or lost.
+     * @param l the listener to unregister.
+     */
+    public void unregisterAudioFocusRequest(OnAudioFocusChangeListener l) {
+        // remove locally
+        mAudioFocusIdListenerMap.remove(getIdForAudioFocusListener(l));
+    }
+
+
+    /**
+     * A failed focus change request.
+     */
+    public static final int AUDIOFOCUS_REQUEST_FAILED = 0;
+    /**
+     * A successful focus change request.
+     */
+    public static final int AUDIOFOCUS_REQUEST_GRANTED = 1;
+     /**
+      * A focus change request whose granting is delayed: the request was successful, but the
+      * requester will only be granted audio focus once the condition that prevented immediate
+      * granting has ended.
+      * See {@link #requestAudioFocus(AudioFocusRequest)} and
+      * {@link AudioFocusRequest.Builder#setAcceptsDelayedFocusGain(boolean)}
+      */
+    public static final int AUDIOFOCUS_REQUEST_DELAYED = 2;
+
+    /** @hide */
+    @IntDef(flag = false, prefix = "AUDIOFOCUS_REQUEST", value = {
+            AUDIOFOCUS_REQUEST_FAILED,
+            AUDIOFOCUS_REQUEST_GRANTED,
+            AUDIOFOCUS_REQUEST_DELAYED }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FocusRequestResult {}
+
+    /**
+     * @hide
+     * code returned when a synchronous focus request on the client-side is to be blocked
+     * until the external audio focus policy decides on the response for the client
+     */
+    public static final int AUDIOFOCUS_REQUEST_WAITING_FOR_EXT_POLICY = 100;
+
+    /**
+     * Timeout duration in ms when waiting on an external focus policy for the result for a
+     * focus request
+     */
+    private static final int EXT_FOCUS_POLICY_TIMEOUT_MS = 200;
+
+    private static final String FOCUS_CLIENT_ID_STRING = "android_audio_focus_client_id";
+
+    private final Object mFocusRequestsLock = new Object();
+    /**
+     * Map of all receivers of focus request results, one per unresolved focus request.
+     * Receivers are added before sending the request to the external focus policy,
+     * and are removed either after receiving the result, or after the timeout.
+     * This variable is lazily initialized.
+     */
+    @GuardedBy("mFocusRequestsLock")
+    private HashMap<String, BlockingFocusResultReceiver> mFocusRequestsAwaitingResult;
+
+
+    /**
+     *  Request audio focus.
+     *  Send a request to obtain the audio focus
+     *  @param l the listener to be notified of audio focus changes
+     *  @param streamType the main audio stream type affected by the focus request
+     *  @param durationHint use {@link #AUDIOFOCUS_GAIN_TRANSIENT} to indicate this focus request
+     *      is temporary, and focus will be abandonned shortly. Examples of transient requests are
+     *      for the playback of driving directions, or notifications sounds.
+     *      Use {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} to indicate also that it's ok for
+     *      the previous focus owner to keep playing if it ducks its audio output.
+     *      Alternatively use {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} for a temporary request
+     *      that benefits from the system not playing disruptive sounds like notifications, for
+     *      usecases such as voice memo recording, or speech recognition.
+     *      Use {@link #AUDIOFOCUS_GAIN} for a focus request of unknown duration such
+     *      as the playback of a song or a video.
+     *  @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}
+     *  @deprecated use {@link #requestAudioFocus(AudioFocusRequest)}
+     */
+    public int requestAudioFocus(OnAudioFocusChangeListener l, int streamType, int durationHint) {
+        PlayerBase.deprecateStreamTypeForPlayback(streamType,
+                "AudioManager", "requestAudioFocus()");
+        int status = AUDIOFOCUS_REQUEST_FAILED;
+
+        try {
+            // status is guaranteed to be either AUDIOFOCUS_REQUEST_FAILED or
+            // AUDIOFOCUS_REQUEST_GRANTED as focus is requested without the
+            // AUDIOFOCUS_FLAG_DELAY_OK flag
+            status = requestAudioFocus(l,
+                    new AudioAttributes.Builder()
+                            .setInternalLegacyStreamType(streamType).build(),
+                    durationHint,
+                    0 /* flags, legacy behavior */);
+        } catch (IllegalArgumentException e) {
+            Log.e(TAG, "Audio focus request denied due to ", e);
+        }
+
+        return status;
+    }
+
+    // when adding new flags, add them to the relevant AUDIOFOCUS_FLAGS_APPS or SYSTEM masks
+    /**
+     * @hide
+     * Use this flag when requesting audio focus to indicate it is ok for the requester to not be
+     * granted audio focus immediately (as indicated by {@link #AUDIOFOCUS_REQUEST_DELAYED}) when
+     * the system is in a state where focus cannot change, but be granted focus later when
+     * this condition ends.
+     */
+    @SystemApi
+    public static final int AUDIOFOCUS_FLAG_DELAY_OK = 0x1 << 0;
+    /**
+     * @hide
+     * Use this flag when requesting audio focus to indicate that the requester
+     * will pause its media playback (if applicable) when losing audio focus with
+     * {@link #AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}, rather than ducking.
+     * <br>On some platforms, the ducking may be handled without the application being aware of it
+     * (i.e. it will not transiently lose focus). For applications that for instance play spoken
+     * content, such as audio book or podcast players, ducking may never be acceptable, and will
+     * thus always pause. This flag enables them to be declared as such whenever they request focus.
+     */
+    @SystemApi
+    public static final int AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS = 0x1 << 1;
+    /**
+     * @hide
+     * Use this flag to lock audio focus so granting is temporarily disabled.
+     * <br>This flag can only be used by owners of a registered
+     * {@link android.media.audiopolicy.AudioPolicy} in
+     * {@link #requestAudioFocus(OnAudioFocusChangeListener, AudioAttributes, int, int, AudioPolicy)}
+     */
+    @SystemApi
+    public static final int AUDIOFOCUS_FLAG_LOCK     = 0x1 << 2;
+
+    /**
+     * @hide
+     * flag set on test API calls,
+     * see {@link #requestAudioFocusForTest(AudioFocusRequest, String, int, int)},
+     * note that it isn't used in conjunction with other flags, it is passed as the single
+     * value for flags */
+    public static final int AUDIOFOCUS_FLAG_TEST = 0x1 << 3;
+    /** @hide */
+    public static final int AUDIOFOCUS_FLAGS_APPS = AUDIOFOCUS_FLAG_DELAY_OK
+            | AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS;
+    /** @hide */
+    public static final int AUDIOFOCUS_FLAGS_SYSTEM = AUDIOFOCUS_FLAG_DELAY_OK
+            | AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS | AUDIOFOCUS_FLAG_LOCK;
+
+    /**
+     * Request audio focus.
+     * See the {@link AudioFocusRequest} for information about the options available to configure
+     * your request, and notification of focus gain and loss.
+     * @param focusRequest a {@link AudioFocusRequest} instance used to configure how focus is
+     *   requested.
+     * @return {@link #AUDIOFOCUS_REQUEST_FAILED}, {@link #AUDIOFOCUS_REQUEST_GRANTED}
+     *     or {@link #AUDIOFOCUS_REQUEST_DELAYED}.
+     *     <br>Note that the return value is never {@link #AUDIOFOCUS_REQUEST_DELAYED} when focus
+     *     is requested without building the {@link AudioFocusRequest} with
+     *     {@link AudioFocusRequest.Builder#setAcceptsDelayedFocusGain(boolean)} set to
+     *     {@code true}.
+     * @throws NullPointerException if passed a null argument
+     */
+    public int requestAudioFocus(@NonNull AudioFocusRequest focusRequest) {
+        return requestAudioFocus(focusRequest, null /* no AudioPolicy*/);
+    }
+
+    /**
+     *  Abandon audio focus. Causes the previous focus owner, if any, to receive focus.
+     *  @param focusRequest the {@link AudioFocusRequest} that was used when requesting focus
+     *      with {@link #requestAudioFocus(AudioFocusRequest)}.
+     *  @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}
+     *  @throws IllegalArgumentException if passed a null argument
+     */
+    public int abandonAudioFocusRequest(@NonNull AudioFocusRequest focusRequest) {
+        if (focusRequest == null) {
+            throw new IllegalArgumentException("Illegal null AudioFocusRequest");
+        }
+        return abandonAudioFocus(focusRequest.getOnAudioFocusChangeListener(),
+                focusRequest.getAudioAttributes());
+    }
+
+    /**
+     * @hide
+     * Request audio focus.
+     * Send a request to obtain the audio focus. This method differs from
+     * {@link #requestAudioFocus(OnAudioFocusChangeListener, int, int)} in that it can express
+     * that the requester accepts delayed grants of audio focus.
+     * @param l the listener to be notified of audio focus changes. It is not allowed to be null
+     *     when the request is flagged with {@link #AUDIOFOCUS_FLAG_DELAY_OK}.
+     * @param requestAttributes non null {@link AudioAttributes} describing the main reason for
+     *     requesting audio focus.
+     * @param durationHint use {@link #AUDIOFOCUS_GAIN_TRANSIENT} to indicate this focus request
+     *      is temporary, and focus will be abandonned shortly. Examples of transient requests are
+     *      for the playback of driving directions, or notifications sounds.
+     *      Use {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} to indicate also that it's ok for
+     *      the previous focus owner to keep playing if it ducks its audio output.
+     *      Alternatively use {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE} for a temporary request
+     *      that benefits from the system not playing disruptive sounds like notifications, for
+     *      usecases such as voice memo recording, or speech recognition.
+     *      Use {@link #AUDIOFOCUS_GAIN} for a focus request of unknown duration such
+     *      as the playback of a song or a video.
+     * @param flags 0 or a combination of {link #AUDIOFOCUS_FLAG_DELAY_OK},
+     *     {@link #AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS} and {@link #AUDIOFOCUS_FLAG_LOCK}.
+     *     <br>Use 0 when not using any flags for the request, which behaves like
+     *     {@link #requestAudioFocus(OnAudioFocusChangeListener, int, int)}, where either audio
+     *     focus is granted immediately, or the grant request fails because the system is in a
+     *     state where focus cannot change (e.g. a phone call).
+     * @return {@link #AUDIOFOCUS_REQUEST_FAILED}, {@link #AUDIOFOCUS_REQUEST_GRANTED}
+     *     or {@link #AUDIOFOCUS_REQUEST_DELAYED}.
+     *     The return value is never {@link #AUDIOFOCUS_REQUEST_DELAYED} when focus is requested
+     *     without the {@link #AUDIOFOCUS_FLAG_DELAY_OK} flag.
+     * @throws IllegalArgumentException
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PHONE_STATE)
+    public int requestAudioFocus(OnAudioFocusChangeListener l,
+            @NonNull AudioAttributes requestAttributes,
+            int durationHint,
+            int flags) throws IllegalArgumentException {
+        if (flags != (flags & AUDIOFOCUS_FLAGS_APPS)) {
+            throw new IllegalArgumentException("Invalid flags 0x"
+                    + Integer.toHexString(flags).toUpperCase());
+        }
+        return requestAudioFocus(l, requestAttributes, durationHint,
+                flags & AUDIOFOCUS_FLAGS_APPS,
+                null /* no AudioPolicy*/);
+    }
+
+    /**
+     * @hide
+     * Request or lock audio focus.
+     * This method is to be used by system components that have registered an
+     * {@link android.media.audiopolicy.AudioPolicy} to request audio focus, but also to "lock" it
+     * so focus granting is temporarily disabled.
+     * @param l see the description of the same parameter in
+     *     {@link #requestAudioFocus(OnAudioFocusChangeListener, AudioAttributes, int, int)}
+     * @param requestAttributes non null {@link AudioAttributes} describing the main reason for
+     *     requesting audio focus.
+     * @param durationHint see the description of the same parameter in
+     *     {@link #requestAudioFocus(OnAudioFocusChangeListener, AudioAttributes, int, int)}
+     * @param flags 0 or a combination of {link #AUDIOFOCUS_FLAG_DELAY_OK},
+     *     {@link #AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS}, and {@link #AUDIOFOCUS_FLAG_LOCK}.
+     *     <br>Use 0 when not using any flags for the request, which behaves like
+     *     {@link #requestAudioFocus(OnAudioFocusChangeListener, int, int)}, where either audio
+     *     focus is granted immediately, or the grant request fails because the system is in a
+     *     state where focus cannot change (e.g. a phone call).
+     * @param ap a registered {@link android.media.audiopolicy.AudioPolicy} instance when locking
+     *     focus, or null.
+     * @return see the description of the same return value in
+     *     {@link #requestAudioFocus(OnAudioFocusChangeListener, AudioAttributes, int, int)}
+     * @throws IllegalArgumentException
+     * @deprecated use {@link #requestAudioFocus(AudioFocusRequest, AudioPolicy)}
+     */
+    @SystemApi
+    @RequiresPermission(anyOf= {
+            android.Manifest.permission.MODIFY_PHONE_STATE,
+            android.Manifest.permission.MODIFY_AUDIO_ROUTING
+    })
+    public int requestAudioFocus(OnAudioFocusChangeListener l,
+            @NonNull AudioAttributes requestAttributes,
+            int durationHint,
+            int flags,
+            AudioPolicy ap) throws IllegalArgumentException {
+        // parameter checking
+        if (requestAttributes == null) {
+            throw new IllegalArgumentException("Illegal null AudioAttributes argument");
+        }
+        if (!AudioFocusRequest.isValidFocusGain(durationHint)) {
+            throw new IllegalArgumentException("Invalid duration hint");
+        }
+        if (flags != (flags & AUDIOFOCUS_FLAGS_SYSTEM)) {
+            throw new IllegalArgumentException("Illegal flags 0x"
+                + Integer.toHexString(flags).toUpperCase());
+        }
+        if (((flags & AUDIOFOCUS_FLAG_DELAY_OK) == AUDIOFOCUS_FLAG_DELAY_OK) && (l == null)) {
+            throw new IllegalArgumentException(
+                    "Illegal null focus listener when flagged as accepting delayed focus grant");
+        }
+        if (((flags & AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS)
+                == AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS) && (l == null)) {
+            throw new IllegalArgumentException(
+                    "Illegal null focus listener when flagged as pausing instead of ducking");
+        }
+        if (((flags & AUDIOFOCUS_FLAG_LOCK) == AUDIOFOCUS_FLAG_LOCK) && (ap == null)) {
+            throw new IllegalArgumentException(
+                    "Illegal null audio policy when locking audio focus");
+        }
+
+        final AudioFocusRequest afr = new AudioFocusRequest.Builder(durationHint)
+                .setOnAudioFocusChangeListenerInt(l, null /* no Handler for this legacy API */)
+                .setAudioAttributes(requestAttributes)
+                .setAcceptsDelayedFocusGain((flags & AUDIOFOCUS_FLAG_DELAY_OK)
+                        == AUDIOFOCUS_FLAG_DELAY_OK)
+                .setWillPauseWhenDucked((flags & AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS)
+                        == AUDIOFOCUS_FLAG_PAUSES_ON_DUCKABLE_LOSS)
+                .setLocksFocus((flags & AUDIOFOCUS_FLAG_LOCK) == AUDIOFOCUS_FLAG_LOCK)
+                .build();
+        return requestAudioFocus(afr, ap);
+    }
+
+    /**
+     * @hide
+     * Test API to request audio focus for an arbitrary client operating from a (fake) given UID.
+     * Used to simulate conditions of the test, not the behavior of the focus requester under test.
+     * @param afr the parameters of the request
+     * @param clientFakeId the identifier of the AudioManager the client would be requesting from
+     * @param clientFakeUid the UID of the client, here an arbitrary int,
+     *                      doesn't have to be a real UID
+     * @param clientTargetSdk the target SDK used by the client
+     * @return return code indicating status of the request
+     */
+    @TestApi
+    @RequiresPermission("android.permission.QUERY_AUDIO_STATE")
+    public @FocusRequestResult int requestAudioFocusForTest(@NonNull AudioFocusRequest afr,
+            @NonNull String clientFakeId, int clientFakeUid, int clientTargetSdk) {
+        Objects.requireNonNull(afr);
+        Objects.requireNonNull(clientFakeId);
+        try {
+            return getService().requestAudioFocusForTest(afr.getAudioAttributes(),
+                    afr.getFocusGain(),
+                    mICallBack,
+                    mAudioFocusDispatcher,
+                    clientFakeId, "com.android.test.fakeclient", clientFakeUid, clientTargetSdk);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Test API to abandon audio focus for an arbitrary client.
+     * Used to simulate conditions of the test, not the behavior of the focus requester under test.
+     * @param afr the parameters used for the request
+     * @param clientFakeId clientFakeId the identifier of the AudioManager from which the client
+     *      would be requesting
+     * @return return code indicating status of the request
+     */
+    @TestApi
+    @RequiresPermission("android.permission.QUERY_AUDIO_STATE")
+    public @FocusRequestResult int abandonAudioFocusForTest(@NonNull AudioFocusRequest afr,
+            @NonNull String clientFakeId) {
+        Objects.requireNonNull(afr);
+        Objects.requireNonNull(clientFakeId);
+        try {
+            return getService().abandonAudioFocusForTest(mAudioFocusDispatcher,
+                    clientFakeId, afr.getAudioAttributes(), "com.android.test.fakeclient");
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Return the duration of the fade out applied when a player of the given AudioAttributes
+     * is losing audio focus
+     * @param aa the AudioAttributes of the player losing focus with {@link #AUDIOFOCUS_LOSS}
+     * @return a duration in ms, 0 indicates no fade out is applied
+     */
+    @TestApi
+    @RequiresPermission("android.permission.QUERY_AUDIO_STATE")
+    public @IntRange(from = 0) long getFadeOutDurationOnFocusLossMillis(@NonNull AudioAttributes aa)
+    {
+        Objects.requireNonNull(aa);
+        try {
+            return getService().getFadeOutDurationOnFocusLossMillis(aa);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Request or lock audio focus.
+     * This method is to be used by system components that have registered an
+     * {@link android.media.audiopolicy.AudioPolicy} to request audio focus, but also to "lock" it
+     * so focus granting is temporarily disabled.
+     * @param afr see the description of the same parameter in
+     *     {@link #requestAudioFocus(AudioFocusRequest)}
+     * @param ap a registered {@link android.media.audiopolicy.AudioPolicy} instance when locking
+     *     focus, or null.
+     * @return {@link #AUDIOFOCUS_REQUEST_FAILED}, {@link #AUDIOFOCUS_REQUEST_GRANTED}
+     *     or {@link #AUDIOFOCUS_REQUEST_DELAYED}.
+     * @throws NullPointerException if the AudioFocusRequest is null
+     * @throws IllegalArgumentException when trying to lock focus without an AudioPolicy
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public int requestAudioFocus(@NonNull AudioFocusRequest afr, @Nullable AudioPolicy ap) {
+        if (afr == null) {
+            throw new NullPointerException("Illegal null AudioFocusRequest");
+        }
+        // this can only be checked now, not during the creation of the AudioFocusRequest instance
+        if (afr.locksFocus() && ap == null) {
+            throw new IllegalArgumentException(
+                    "Illegal null audio policy when locking audio focus");
+        }
+        registerAudioFocusRequest(afr);
+        final IAudioService service = getService();
+        final int status;
+        int sdk;
+        try {
+            sdk = getContext().getApplicationInfo().targetSdkVersion;
+        } catch (NullPointerException e) {
+            // some tests don't have a Context
+            sdk = Build.VERSION.SDK_INT;
+        }
+
+        final String clientId = getIdForAudioFocusListener(afr.getOnAudioFocusChangeListener());
+        final BlockingFocusResultReceiver focusReceiver;
+        synchronized (mFocusRequestsLock) {
+            try {
+                // TODO status contains result and generation counter for ext policy
+                status = service.requestAudioFocus(afr.getAudioAttributes(),
+                        afr.getFocusGain(), mICallBack,
+                        mAudioFocusDispatcher,
+                        clientId,
+                        getContext().getOpPackageName() /* package name */, afr.getFlags(),
+                        ap != null ? ap.cb() : null,
+                        sdk);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            if (status != AudioManager.AUDIOFOCUS_REQUEST_WAITING_FOR_EXT_POLICY) {
+                // default path with no external focus policy
+                return status;
+            }
+            if (mFocusRequestsAwaitingResult == null) {
+                mFocusRequestsAwaitingResult =
+                        new HashMap<String, BlockingFocusResultReceiver>(1);
+            }
+            focusReceiver = new BlockingFocusResultReceiver(clientId);
+            mFocusRequestsAwaitingResult.put(clientId, focusReceiver);
+        }
+        focusReceiver.waitForResult(EXT_FOCUS_POLICY_TIMEOUT_MS);
+        if (DEBUG && !focusReceiver.receivedResult()) {
+            Log.e(TAG, "requestAudio response from ext policy timed out, denying request");
+        }
+        synchronized (mFocusRequestsLock) {
+            mFocusRequestsAwaitingResult.remove(clientId);
+        }
+        return focusReceiver.requestResult();
+    }
+
+    // helper class that abstracts out the handling of spurious wakeups in Object.wait()
+    private static final class SafeWaitObject {
+        private boolean mQuit = false;
+
+        public void safeNotify() {
+            synchronized (this) {
+                mQuit = true;
+                this.notify();
+            }
+        }
+
+        public void safeWait(long millis) throws InterruptedException {
+            final long timeOutTime = java.lang.System.currentTimeMillis() + millis;
+            synchronized (this) {
+                while (!mQuit) {
+                    final long timeToWait = timeOutTime - java.lang.System.currentTimeMillis();
+                    if (timeToWait < 0) { break; }
+                    this.wait(timeToWait);
+                }
+            }
+        }
+    }
+
+    private static final class BlockingFocusResultReceiver {
+        private final SafeWaitObject mLock = new SafeWaitObject();
+        @GuardedBy("mLock")
+        private boolean mResultReceived = false;
+        // request denied by default (e.g. timeout)
+        private int mFocusRequestResult = AudioManager.AUDIOFOCUS_REQUEST_FAILED;
+        private final String mFocusClientId;
+
+        BlockingFocusResultReceiver(String clientId) {
+            mFocusClientId = clientId;
+        }
+
+        boolean receivedResult() { return mResultReceived; }
+        int requestResult() { return mFocusRequestResult; }
+
+        void notifyResult(int requestResult) {
+            synchronized (mLock) {
+                mResultReceived = true;
+                mFocusRequestResult = requestResult;
+                mLock.safeNotify();
+            }
+        }
+
+        public void waitForResult(long timeOutMs) {
+            synchronized (mLock) {
+                if (mResultReceived) {
+                    // the result was received before waiting
+                    return;
+                }
+                try {
+                    mLock.safeWait(timeOutMs);
+                } catch (InterruptedException e) { }
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Used internally by telephony package to request audio focus. Will cause the focus request
+     * to be associated with the "voice communication" identifier only used in AudioService
+     * to identify this use case.
+     * @param streamType use STREAM_RING for focus requests when ringing, VOICE_CALL for
+     *    the establishment of the call
+     * @param durationHint the type of focus request. AUDIOFOCUS_GAIN_TRANSIENT is recommended so
+     *    media applications resume after a call
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public void requestAudioFocusForCall(int streamType, int durationHint) {
+        final IAudioService service = getService();
+        try {
+            service.requestAudioFocus(new AudioAttributes.Builder()
+                        .setInternalLegacyStreamType(streamType).build(),
+                    durationHint, mICallBack, null,
+                    AudioSystem.IN_VOICE_COMM_FOCUS_ID,
+                    getContext().getOpPackageName(),
+                    AUDIOFOCUS_FLAG_LOCK,
+                    null /* policy token */, 0 /* sdk n/a here*/);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Return the volume ramping time for a sound to be played after the given focus request,
+     *   and to play a sound of the given attributes
+     * @param focusGain
+     * @param attr
+     * @return
+     */
+    public int getFocusRampTimeMs(int focusGain, AudioAttributes attr) {
+        final IAudioService service = getService();
+        try {
+            return service.getFocusRampTimeMs(focusGain, attr);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Set the result to the audio focus request received through
+     * {@link AudioPolicyFocusListener#onAudioFocusRequest(AudioFocusInfo, int)}.
+     * @param afi the information about the focus requester
+     * @param requestResult the result to the focus request to be passed to the requester
+     * @param ap a valid registered {@link AudioPolicy} configured as a focus policy.
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void setFocusRequestResult(@NonNull AudioFocusInfo afi,
+            @FocusRequestResult int requestResult, @NonNull AudioPolicy ap) {
+        if (afi == null) {
+            throw new IllegalArgumentException("Illegal null AudioFocusInfo");
+        }
+        if (ap == null) {
+            throw new IllegalArgumentException("Illegal null AudioPolicy");
+        }
+        final IAudioService service = getService();
+        try {
+            service.setFocusRequestResultFromExtPolicy(afi, requestResult, ap.cb());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Notifies an application with a focus listener of gain or loss of audio focus.
+     * This method can only be used by owners of an {@link AudioPolicy} configured with
+     * {@link AudioPolicy.Builder#setIsAudioFocusPolicy(boolean)} set to true.
+     * @param afi the recipient of the focus change, that has previously requested audio focus, and
+     *     that was received by the {@code AudioPolicy} through
+     *     {@link AudioPolicy.AudioPolicyFocusListener#onAudioFocusRequest(AudioFocusInfo, int)}.
+     * @param focusChange one of focus gain types ({@link #AUDIOFOCUS_GAIN},
+     *     {@link #AUDIOFOCUS_GAIN_TRANSIENT}, {@link #AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK} or
+     *     {@link #AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE})
+     *     or one of the focus loss types ({@link AudioManager#AUDIOFOCUS_LOSS},
+     *     {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT},
+     *     or {@link AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}).
+     *     <br>For the focus gain, the change type should be the same as the app requested.
+     * @param ap a valid registered {@link AudioPolicy} configured as a focus policy.
+     * @return {@link #AUDIOFOCUS_REQUEST_GRANTED} if the dispatch was successfully sent, or
+     *     {@link #AUDIOFOCUS_REQUEST_FAILED} if the focus client didn't have a listener, or
+     *     if there was an error sending the request.
+     * @throws NullPointerException if the {@link AudioFocusInfo} or {@link AudioPolicy} are null.
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public int dispatchAudioFocusChange(@NonNull AudioFocusInfo afi, int focusChange,
+            @NonNull AudioPolicy ap) {
+        if (afi == null) {
+            throw new NullPointerException("Illegal null AudioFocusInfo");
+        }
+        if (ap == null) {
+            throw new NullPointerException("Illegal null AudioPolicy");
+        }
+        final IAudioService service = getService();
+        try {
+            return service.dispatchFocusChange(afi, focusChange, ap.cb());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Used internally by telephony package to abandon audio focus, typically after a call or
+     * when ringing ends and the call is rejected or not answered.
+     * Should match one or more calls to {@link #requestAudioFocusForCall(int, int)}.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public void abandonAudioFocusForCall() {
+        final IAudioService service = getService();
+        try {
+            service.abandonAudioFocus(null, AudioSystem.IN_VOICE_COMM_FOCUS_ID,
+                    null /*AudioAttributes, legacy behavior*/, getContext().getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     *  Abandon audio focus. Causes the previous focus owner, if any, to receive focus.
+     *  @param l the listener with which focus was requested.
+     *  @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}
+     *  @deprecated use {@link #abandonAudioFocusRequest(AudioFocusRequest)}
+     */
+    public int abandonAudioFocus(OnAudioFocusChangeListener l) {
+        return abandonAudioFocus(l, null /*AudioAttributes, legacy behavior*/);
+    }
+
+    /**
+     * @hide
+     * Abandon audio focus. Causes the previous focus owner, if any, to receive focus.
+     *  @param l the listener with which focus was requested.
+     * @param aa the {@link AudioAttributes} with which audio focus was requested
+     * @return {@link #AUDIOFOCUS_REQUEST_FAILED} or {@link #AUDIOFOCUS_REQUEST_GRANTED}
+     * @deprecated use {@link #abandonAudioFocusRequest(AudioFocusRequest)}
+     */
+    @SystemApi
+    @SuppressLint("RequiresPermission") // no permission enforcement, but only "undoes" what would
+    // have been done by a matching requestAudioFocus
+    public int abandonAudioFocus(OnAudioFocusChangeListener l, AudioAttributes aa) {
+        int status = AUDIOFOCUS_REQUEST_FAILED;
+        unregisterAudioFocusRequest(l);
+        final IAudioService service = getService();
+        try {
+            status = service.abandonAudioFocus(mAudioFocusDispatcher,
+                    getIdForAudioFocusListener(l), aa, getContext().getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return status;
+    }
+
+    //====================================================================
+    // Remote Control
+    /**
+     * Register a component to be the sole receiver of MEDIA_BUTTON intents.
+     * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}
+     *      that will receive the media button intent. This broadcast receiver must be declared
+     *      in the application manifest. The package of the component must match that of
+     *      the context you're registering from.
+     * @deprecated Use {@link MediaSession#setMediaButtonReceiver(PendingIntent)} instead.
+     */
+    @Deprecated
+    public void registerMediaButtonEventReceiver(ComponentName eventReceiver) {
+        if (eventReceiver == null) {
+            return;
+        }
+        if (!eventReceiver.getPackageName().equals(getContext().getPackageName())) {
+            Log.e(TAG, "registerMediaButtonEventReceiver() error: " +
+                    "receiver and context package names don't match");
+            return;
+        }
+        // construct a PendingIntent for the media button and register it
+        Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+        //     the associated intent will be handled by the component being registered
+        mediaButtonIntent.setComponent(eventReceiver);
+        PendingIntent pi = PendingIntent.getBroadcast(getContext(),
+                0/*requestCode, ignored*/, mediaButtonIntent,
+                PendingIntent.FLAG_IMMUTABLE);
+        registerMediaButtonIntent(pi, eventReceiver);
+    }
+
+    /**
+     * Register a component to be the sole receiver of MEDIA_BUTTON intents.  This is like
+     * {@link #registerMediaButtonEventReceiver(android.content.ComponentName)}, but allows
+     * the buttons to go to any PendingIntent.  Note that you should only use this form if
+     * you know you will continue running for the full time until unregistering the
+     * PendingIntent.
+     * @param eventReceiver target that will receive media button intents.  The PendingIntent
+     * will be sent an {@link Intent#ACTION_MEDIA_BUTTON} event when a media button action
+     * occurs, with {@link Intent#EXTRA_KEY_EVENT} added and holding the key code of the
+     * media button that was pressed.
+     * @deprecated Use {@link MediaSession#setMediaButtonReceiver(PendingIntent)} instead.
+     */
+    @Deprecated
+    public void registerMediaButtonEventReceiver(PendingIntent eventReceiver) {
+        if (eventReceiver == null) {
+            return;
+        }
+        registerMediaButtonIntent(eventReceiver, null);
+    }
+
+    /**
+     * @hide
+     * no-op if (pi == null) or (eventReceiver == null)
+     */
+    public void registerMediaButtonIntent(PendingIntent pi, ComponentName eventReceiver) {
+        if (pi == null) {
+            Log.e(TAG, "Cannot call registerMediaButtonIntent() with a null parameter");
+            return;
+        }
+        MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(getContext());
+        helper.addMediaButtonListener(pi, eventReceiver, getContext());
+    }
+
+    /**
+     * Unregister the receiver of MEDIA_BUTTON intents.
+     * @param eventReceiver identifier of a {@link android.content.BroadcastReceiver}
+     *      that was registered with {@link #registerMediaButtonEventReceiver(ComponentName)}.
+     * @deprecated Use {@link MediaSession} instead.
+     */
+    @Deprecated
+    public void unregisterMediaButtonEventReceiver(ComponentName eventReceiver) {
+        if (eventReceiver == null) {
+            return;
+        }
+        // construct a PendingIntent for the media button and unregister it
+        Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+        //     the associated intent will be handled by the component being registered
+        mediaButtonIntent.setComponent(eventReceiver);
+        PendingIntent pi = PendingIntent.getBroadcast(getContext(),
+                0/*requestCode, ignored*/, mediaButtonIntent,
+                PendingIntent.FLAG_IMMUTABLE);
+        unregisterMediaButtonIntent(pi);
+    }
+
+    /**
+     * Unregister the receiver of MEDIA_BUTTON intents.
+     * @param eventReceiver same PendingIntent that was registed with
+     *      {@link #registerMediaButtonEventReceiver(PendingIntent)}.
+     * @deprecated Use {@link MediaSession} instead.
+     */
+    @Deprecated
+    public void unregisterMediaButtonEventReceiver(PendingIntent eventReceiver) {
+        if (eventReceiver == null) {
+            return;
+        }
+        unregisterMediaButtonIntent(eventReceiver);
+    }
+
+    /**
+     * @hide
+     */
+    public void unregisterMediaButtonIntent(PendingIntent pi) {
+        MediaSessionLegacyHelper helper = MediaSessionLegacyHelper.getHelper(getContext());
+        helper.removeMediaButtonListener(pi);
+    }
+
+    /**
+     * Registers the remote control client for providing information to display on the remote
+     * controls.
+     * @param rcClient The remote control client from which remote controls will receive
+     *      information to display.
+     * @see RemoteControlClient
+     * @deprecated Use {@link MediaSession} instead.
+     */
+    @Deprecated
+    public void registerRemoteControlClient(RemoteControlClient rcClient) {
+        if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) {
+            return;
+        }
+        rcClient.registerWithSession(MediaSessionLegacyHelper.getHelper(getContext()));
+    }
+
+    /**
+     * Unregisters the remote control client that was providing information to display on the
+     * remote controls.
+     * @param rcClient The remote control client to unregister.
+     * @see #registerRemoteControlClient(RemoteControlClient)
+     * @deprecated Use {@link MediaSession} instead.
+     */
+    @Deprecated
+    public void unregisterRemoteControlClient(RemoteControlClient rcClient) {
+        if ((rcClient == null) || (rcClient.getRcMediaIntent() == null)) {
+            return;
+        }
+        rcClient.unregisterWithSession(MediaSessionLegacyHelper.getHelper(getContext()));
+    }
+
+    /**
+     * Registers a {@link RemoteController} instance for it to receive media
+     * metadata updates and playback state information from applications using
+     * {@link RemoteControlClient}, and control their playback.
+     * <p>
+     * Registration requires the {@link RemoteController.OnClientUpdateListener} listener to be
+     * one of the enabled notification listeners (see
+     * {@link android.service.notification.NotificationListenerService}).
+     *
+     * @param rctlr the object to register.
+     * @return true if the {@link RemoteController} was successfully registered,
+     *         false if an error occurred, due to an internal system error, or
+     *         insufficient permissions.
+     * @deprecated Use
+     *             {@link MediaSessionManager#addOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener, ComponentName)}
+     *             and {@link MediaController} instead.
+     */
+    @Deprecated
+    public boolean registerRemoteController(RemoteController rctlr) {
+        if (rctlr == null) {
+            return false;
+        }
+        rctlr.startListeningToSessions();
+        return true;
+    }
+
+    /**
+     * Unregisters a {@link RemoteController}, causing it to no longer receive
+     * media metadata and playback state information, and no longer be capable
+     * of controlling playback.
+     *
+     * @param rctlr the object to unregister.
+     * @deprecated Use
+     *             {@link MediaSessionManager#removeOnActiveSessionsChangedListener(android.media.session.MediaSessionManager.OnActiveSessionsChangedListener)}
+     *             instead.
+     */
+    @Deprecated
+    public void unregisterRemoteController(RemoteController rctlr) {
+        if (rctlr == null) {
+            return;
+        }
+        rctlr.stopListeningToSessions();
+    }
+
+
+    //====================================================================
+    // Audio policy
+    /**
+     * @hide
+     * Register the given {@link AudioPolicy}.
+     * This call is synchronous and blocks until the registration process successfully completed
+     * or failed to complete.
+     * @param policy the non-null {@link AudioPolicy} to register.
+     * @return {@link #ERROR} if there was an error communicating with the registration service
+     *    or if the user doesn't have the required
+     *    {@link android.Manifest.permission#MODIFY_AUDIO_ROUTING} permission,
+     *    {@link #SUCCESS} otherwise.
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public int registerAudioPolicy(@NonNull AudioPolicy policy) {
+        return registerAudioPolicyStatic(policy);
+    }
+
+    static int registerAudioPolicyStatic(@NonNull AudioPolicy policy) {
+        if (policy == null) {
+            throw new IllegalArgumentException("Illegal null AudioPolicy argument");
+        }
+        final IAudioService service = getService();
+        try {
+            MediaProjection projection = policy.getMediaProjection();
+            String regId = service.registerAudioPolicy(policy.getConfig(), policy.cb(),
+                    policy.hasFocusListener(), policy.isFocusPolicy(), policy.isTestFocusPolicy(),
+                    policy.isVolumeController(),
+                    projection == null ? null : projection.getProjection());
+            if (regId == null) {
+                return ERROR;
+            } else {
+                policy.setRegistration(regId);
+            }
+            // successful registration
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return SUCCESS;
+    }
+
+    /**
+     * @hide
+     * Unregisters an {@link AudioPolicy} asynchronously.
+     * @param policy the non-null {@link AudioPolicy} to unregister.
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void unregisterAudioPolicyAsync(@NonNull AudioPolicy policy) {
+        unregisterAudioPolicyAsyncStatic(policy);
+    }
+
+    static void unregisterAudioPolicyAsyncStatic(@NonNull AudioPolicy policy) {
+        if (policy == null) {
+            throw new IllegalArgumentException("Illegal null AudioPolicy argument");
+        }
+        final IAudioService service = getService();
+        try {
+            service.unregisterAudioPolicyAsync(policy.cb());
+            policy.reset();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Unregisters an {@link AudioPolicy} synchronously.
+     * This method also invalidates all {@link AudioRecord} and {@link AudioTrack} objects
+     * associated with mixes of this policy.
+     * @param policy the non-null {@link AudioPolicy} to unregister.
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void unregisterAudioPolicy(@NonNull AudioPolicy policy) {
+        Preconditions.checkNotNull(policy, "Illegal null AudioPolicy argument");
+        final IAudioService service = getService();
+        try {
+            policy.invalidateCaptorsAndInjectors();
+            service.unregisterAudioPolicy(policy.cb());
+            policy.reset();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * @return true if an AudioPolicy was previously registered
+     */
+    @TestApi
+    public boolean hasRegisteredDynamicPolicy() {
+        final IAudioService service = getService();
+        try {
+            return service.hasRegisteredDynamicPolicy();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    //====================================================================
+    // Notification of playback activity & playback configuration
+    /**
+     * Interface for receiving update notifications about the playback activity on the system.
+     * Extend this abstract class and register it with
+     * {@link AudioManager#registerAudioPlaybackCallback(AudioPlaybackCallback, Handler)}
+     * to be notified.
+     * Use {@link AudioManager#getActivePlaybackConfigurations()} to query the current
+     * configuration.
+     * @see AudioPlaybackConfiguration
+     */
+    public static abstract class AudioPlaybackCallback {
+        /**
+         * Called whenever the playback activity and configuration has changed.
+         * @param configs list containing the results of
+         *      {@link AudioManager#getActivePlaybackConfigurations()}.
+         */
+        public void onPlaybackConfigChanged(List<AudioPlaybackConfiguration> configs) {}
+    }
+
+    private static class AudioPlaybackCallbackInfo {
+        final AudioPlaybackCallback mCb;
+        final Handler mHandler;
+        AudioPlaybackCallbackInfo(AudioPlaybackCallback cb, Handler handler) {
+            mCb = cb;
+            mHandler = handler;
+        }
+    }
+
+    private final static class PlaybackConfigChangeCallbackData {
+        final AudioPlaybackCallback mCb;
+        final List<AudioPlaybackConfiguration> mConfigs;
+
+        PlaybackConfigChangeCallbackData(AudioPlaybackCallback cb,
+                List<AudioPlaybackConfiguration> configs) {
+            mCb = cb;
+            mConfigs = configs;
+        }
+    }
+
+    /**
+     * Register a callback to be notified of audio playback changes through
+     * {@link AudioPlaybackCallback}
+     * @param cb non-null callback to register
+     * @param handler the {@link Handler} object for the thread on which to execute
+     * the callback. If <code>null</code>, the {@link Handler} associated with the main
+     * {@link Looper} will be used.
+     */
+    public void registerAudioPlaybackCallback(@NonNull AudioPlaybackCallback cb,
+                                              @Nullable Handler handler)
+    {
+        if (cb == null) {
+            throw new IllegalArgumentException("Illegal null AudioPlaybackCallback argument");
+        }
+
+        synchronized(mPlaybackCallbackLock) {
+            // lazy initialization of the list of playback callbacks
+            if (mPlaybackCallbackList == null) {
+                mPlaybackCallbackList = new ArrayList<AudioPlaybackCallbackInfo>();
+            }
+            final int oldCbCount = mPlaybackCallbackList.size();
+            if (!hasPlaybackCallback_sync(cb)) {
+                mPlaybackCallbackList.add(new AudioPlaybackCallbackInfo(cb,
+                        new ServiceEventHandlerDelegate(handler).getHandler()));
+                final int newCbCount = mPlaybackCallbackList.size();
+                if ((oldCbCount == 0) && (newCbCount > 0)) {
+                    // register binder for callbacks
+                    try {
+                        getService().registerPlaybackCallback(mPlayCb);
+                    } catch (RemoteException e) {
+                        throw e.rethrowFromSystemServer();
+                    }
+                }
+            } else {
+                Log.w(TAG, "attempt to call registerAudioPlaybackCallback() on a previously"
+                        + "registered callback");
+            }
+        }
+    }
+
+    /**
+     * Unregister an audio playback callback previously registered with
+     * {@link #registerAudioPlaybackCallback(AudioPlaybackCallback, Handler)}.
+     * @param cb non-null callback to unregister
+     */
+    public void unregisterAudioPlaybackCallback(@NonNull AudioPlaybackCallback cb) {
+        if (cb == null) {
+            throw new IllegalArgumentException("Illegal null AudioPlaybackCallback argument");
+        }
+        synchronized(mPlaybackCallbackLock) {
+            if (mPlaybackCallbackList == null) {
+                Log.w(TAG, "attempt to call unregisterAudioPlaybackCallback() on a callback"
+                        + " that was never registered");
+                return;
+            }
+            final int oldCbCount = mPlaybackCallbackList.size();
+            if (removePlaybackCallback_sync(cb)) {
+                final int newCbCount = mPlaybackCallbackList.size();
+                if ((oldCbCount > 0) && (newCbCount == 0)) {
+                    // unregister binder for callbacks
+                    try {
+                        getService().unregisterPlaybackCallback(mPlayCb);
+                    } catch (RemoteException e) {
+                        throw e.rethrowFromSystemServer();
+                    }
+                }
+            } else {
+                Log.w(TAG, "attempt to call unregisterAudioPlaybackCallback() on a callback"
+                        + " already unregistered or never registered");
+            }
+        }
+    }
+
+    /**
+     * Returns the current active audio playback configurations of the device
+     * @return a non-null list of playback configurations. An empty list indicates there is no
+     *     playback active when queried.
+     * @see AudioPlaybackConfiguration
+     */
+    public @NonNull List<AudioPlaybackConfiguration> getActivePlaybackConfigurations() {
+        final IAudioService service = getService();
+        try {
+            return service.getActivePlaybackConfigurations();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * All operations on this list are sync'd on mPlaybackCallbackLock.
+     * List is lazy-initialized in
+     * {@link #registerAudioPlaybackCallback(AudioPlaybackCallback, Handler)}.
+     * List can be null.
+     */
+    private List<AudioPlaybackCallbackInfo> mPlaybackCallbackList;
+    private final Object mPlaybackCallbackLock = new Object();
+
+    /**
+     * Must be called synchronized on mPlaybackCallbackLock
+     */
+    private boolean hasPlaybackCallback_sync(@NonNull AudioPlaybackCallback cb) {
+        if (mPlaybackCallbackList != null) {
+            for (int i=0 ; i < mPlaybackCallbackList.size() ; i++) {
+                if (cb.equals(mPlaybackCallbackList.get(i).mCb)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Must be called synchronized on mPlaybackCallbackLock
+     */
+    private boolean removePlaybackCallback_sync(@NonNull AudioPlaybackCallback cb) {
+        if (mPlaybackCallbackList != null) {
+            for (int i=0 ; i < mPlaybackCallbackList.size() ; i++) {
+                if (cb.equals(mPlaybackCallbackList.get(i).mCb)) {
+                    mPlaybackCallbackList.remove(i);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private final IPlaybackConfigDispatcher mPlayCb = new IPlaybackConfigDispatcher.Stub() {
+        @Override
+        public void dispatchPlaybackConfigChange(List<AudioPlaybackConfiguration> configs,
+                boolean flush) {
+            if (flush) {
+                Binder.flushPendingCommands();
+            }
+            synchronized(mPlaybackCallbackLock) {
+                if (mPlaybackCallbackList != null) {
+                    for (int i=0 ; i < mPlaybackCallbackList.size() ; i++) {
+                        final AudioPlaybackCallbackInfo arci = mPlaybackCallbackList.get(i);
+                        if (arci.mHandler != null) {
+                            final Message m = arci.mHandler.obtainMessage(
+                                    MSSG_PLAYBACK_CONFIG_CHANGE/*what*/,
+                                    new PlaybackConfigChangeCallbackData(arci.mCb, configs)/*obj*/);
+                            arci.mHandler.sendMessage(m);
+                        }
+                    }
+                }
+            }
+        }
+
+    };
+
+    //====================================================================
+    // Notification of recording activity & recording configuration
+    /**
+     * Interface for receiving update notifications about the recording configuration. Extend
+     * this abstract class and register it with
+     * {@link AudioManager#registerAudioRecordingCallback(AudioRecordingCallback, Handler)}
+     * to be notified.
+     * Use {@link AudioManager#getActiveRecordingConfigurations()} to query the current
+     * configuration.
+     * @see AudioRecordingConfiguration
+     */
+    public static abstract class AudioRecordingCallback {
+        /**
+         * Called whenever the device recording configuration has changed.
+         * @param configs list containing the results of
+         *      {@link AudioManager#getActiveRecordingConfigurations()}.
+         */
+        public void onRecordingConfigChanged(List<AudioRecordingConfiguration> configs) {}
+    }
+
+    private static class AudioRecordingCallbackInfo {
+        final AudioRecordingCallback mCb;
+        final Handler mHandler;
+        AudioRecordingCallbackInfo(AudioRecordingCallback cb, Handler handler) {
+            mCb = cb;
+            mHandler = handler;
+        }
+    }
+
+    private final static class RecordConfigChangeCallbackData {
+        final AudioRecordingCallback mCb;
+        final List<AudioRecordingConfiguration> mConfigs;
+
+        RecordConfigChangeCallbackData(AudioRecordingCallback cb,
+                List<AudioRecordingConfiguration> configs) {
+            mCb = cb;
+            mConfigs = configs;
+        }
+    }
+
+    /**
+     * Register a callback to be notified of audio recording changes through
+     * {@link AudioRecordingCallback}
+     * @param cb non-null callback to register
+     * @param handler the {@link Handler} object for the thread on which to execute
+     * the callback. If <code>null</code>, the {@link Handler} associated with the main
+     * {@link Looper} will be used.
+     */
+    public void registerAudioRecordingCallback(@NonNull AudioRecordingCallback cb,
+                                               @Nullable Handler handler)
+    {
+        if (cb == null) {
+            throw new IllegalArgumentException("Illegal null AudioRecordingCallback argument");
+        }
+
+        synchronized(mRecordCallbackLock) {
+            // lazy initialization of the list of recording callbacks
+            if (mRecordCallbackList == null) {
+                mRecordCallbackList = new ArrayList<AudioRecordingCallbackInfo>();
+            }
+            final int oldCbCount = mRecordCallbackList.size();
+            if (!hasRecordCallback_sync(cb)) {
+                mRecordCallbackList.add(new AudioRecordingCallbackInfo(cb,
+                        new ServiceEventHandlerDelegate(handler).getHandler()));
+                final int newCbCount = mRecordCallbackList.size();
+                if ((oldCbCount == 0) && (newCbCount > 0)) {
+                    // register binder for callbacks
+                    final IAudioService service = getService();
+                    try {
+                        service.registerRecordingCallback(mRecCb);
+                    } catch (RemoteException e) {
+                        throw e.rethrowFromSystemServer();
+                    }
+                }
+            } else {
+                Log.w(TAG, "attempt to call registerAudioRecordingCallback() on a previously"
+                        + "registered callback");
+            }
+        }
+    }
+
+    /**
+     * Unregister an audio recording callback previously registered with
+     * {@link #registerAudioRecordingCallback(AudioRecordingCallback, Handler)}.
+     * @param cb non-null callback to unregister
+     */
+    public void unregisterAudioRecordingCallback(@NonNull AudioRecordingCallback cb) {
+        if (cb == null) {
+            throw new IllegalArgumentException("Illegal null AudioRecordingCallback argument");
+        }
+        synchronized(mRecordCallbackLock) {
+            if (mRecordCallbackList == null) {
+                return;
+            }
+            final int oldCbCount = mRecordCallbackList.size();
+            if (removeRecordCallback_sync(cb)) {
+                final int newCbCount = mRecordCallbackList.size();
+                if ((oldCbCount > 0) && (newCbCount == 0)) {
+                    // unregister binder for callbacks
+                    final IAudioService service = getService();
+                    try {
+                        service.unregisterRecordingCallback(mRecCb);
+                    } catch (RemoteException e) {
+                        throw e.rethrowFromSystemServer();
+                    }
+                }
+            } else {
+                Log.w(TAG, "attempt to call unregisterAudioRecordingCallback() on a callback"
+                        + " already unregistered or never registered");
+            }
+        }
+    }
+
+    /**
+     * Returns the current active audio recording configurations of the device.
+     * @return a non-null list of recording configurations. An empty list indicates there is
+     *     no recording active when queried.
+     * @see AudioRecordingConfiguration
+     */
+    public @NonNull List<AudioRecordingConfiguration> getActiveRecordingConfigurations() {
+        final IAudioService service = getService();
+        try {
+            return service.getActiveRecordingConfigurations();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * constants for the recording events, to keep in sync
+     * with frameworks/av/include/media/AudioPolicy.h
+     */
+    /** @hide */
+    public static final int RECORD_CONFIG_EVENT_NONE = -1;
+    /** @hide */
+    public static final int RECORD_CONFIG_EVENT_START = 0;
+    /** @hide */
+    public static final int RECORD_CONFIG_EVENT_STOP = 1;
+    /** @hide */
+    public static final int RECORD_CONFIG_EVENT_UPDATE = 2;
+    /** @hide */
+    public static final int RECORD_CONFIG_EVENT_RELEASE = 3;
+    /**
+     * keep in sync with frameworks/native/include/audiomanager/AudioManager.h
+     */
+    /** @hide */
+    public static final int RECORD_RIID_INVALID = -1;
+    /** @hide */
+    public static final int RECORDER_STATE_STARTED = 0;
+    /** @hide */
+    public static final int RECORDER_STATE_STOPPED = 1;
+
+    /**
+     * All operations on this list are sync'd on mRecordCallbackLock.
+     * List is lazy-initialized in
+     * {@link #registerAudioRecordingCallback(AudioRecordingCallback, Handler)}.
+     * List can be null.
+     */
+    private List<AudioRecordingCallbackInfo> mRecordCallbackList;
+    private final Object mRecordCallbackLock = new Object();
+
+    /**
+     * Must be called synchronized on mRecordCallbackLock
+     */
+    private boolean hasRecordCallback_sync(@NonNull AudioRecordingCallback cb) {
+        if (mRecordCallbackList != null) {
+            for (int i=0 ; i < mRecordCallbackList.size() ; i++) {
+                if (cb.equals(mRecordCallbackList.get(i).mCb)) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Must be called synchronized on mRecordCallbackLock
+     */
+    private boolean removeRecordCallback_sync(@NonNull AudioRecordingCallback cb) {
+        if (mRecordCallbackList != null) {
+            for (int i=0 ; i < mRecordCallbackList.size() ; i++) {
+                if (cb.equals(mRecordCallbackList.get(i).mCb)) {
+                    mRecordCallbackList.remove(i);
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private final IRecordingConfigDispatcher mRecCb = new IRecordingConfigDispatcher.Stub() {
+        @Override
+        public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
+            synchronized(mRecordCallbackLock) {
+                if (mRecordCallbackList != null) {
+                    for (int i=0 ; i < mRecordCallbackList.size() ; i++) {
+                        final AudioRecordingCallbackInfo arci = mRecordCallbackList.get(i);
+                        if (arci.mHandler != null) {
+                            final Message m = arci.mHandler.obtainMessage(
+                                    MSSG_RECORDING_CONFIG_CHANGE/*what*/,
+                                    new RecordConfigChangeCallbackData(arci.mCb, configs)/*obj*/);
+                            arci.mHandler.sendMessage(m);
+                        }
+                    }
+                }
+            }
+        }
+
+    };
+
+    //=====================================================================
+
+    /**
+     *  @hide
+     *  Reload audio settings. This method is called by Settings backup
+     *  agent when audio settings are restored and causes the AudioService
+     *  to read and apply restored settings.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public void reloadAudioSettings() {
+        final IAudioService service = getService();
+        try {
+            service.reloadAudioSettings();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Notifies AudioService that it is connected to an A2DP device that supports absolute volume,
+     * so that AudioService can send volume change events to the A2DP device, rather than handling
+     * them.
+     */
+    public void avrcpSupportsAbsoluteVolume(String address, boolean support) {
+        final IAudioService service = getService();
+        try {
+            service.avrcpSupportsAbsoluteVolume(address, support);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+     /**
+      * {@hide}
+      */
+     private final IBinder mICallBack = new Binder();
+
+    /**
+     * Checks whether the phone is in silent mode, with or without vibrate.
+     *
+     * @return true if phone is in silent mode, with or without vibrate.
+     *
+     * @see #getRingerMode()
+     *
+     * @hide pending API Council approval
+     */
+    @UnsupportedAppUsage
+    public boolean isSilentMode() {
+        int ringerMode = getRingerMode();
+        boolean silentMode =
+            (ringerMode == RINGER_MODE_SILENT) ||
+            (ringerMode == RINGER_MODE_VIBRATE);
+        return silentMode;
+    }
+
+    // This section re-defines new output device constants from AudioSystem, because the AudioSystem
+    // class is not used by other parts of the framework, which instead use definitions and methods
+    // from AudioManager. AudioSystem is an internal class used by AudioManager and AudioService.
+
+    /** @hide
+     * The audio device code for representing "no device." */
+    public static final int DEVICE_NONE = AudioSystem.DEVICE_NONE;
+    /** @hide
+     *  The audio output device code for the small speaker at the front of the device used
+     *  when placing calls.  Does not refer to an in-ear headphone without attached microphone,
+     *  such as earbuds, earphones, or in-ear monitors (IEM). Those would be handled as a
+     *  {@link #DEVICE_OUT_WIRED_HEADPHONE}.
+     */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_EARPIECE = AudioSystem.DEVICE_OUT_EARPIECE;
+    /** @hide
+     *  The audio output device code for the built-in speaker */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_SPEAKER = AudioSystem.DEVICE_OUT_SPEAKER;
+    /** @hide
+     * The audio output device code for a wired headset with attached microphone */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_WIRED_HEADSET = AudioSystem.DEVICE_OUT_WIRED_HEADSET;
+    /** @hide
+     * The audio output device code for a wired headphone without attached microphone */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_WIRED_HEADPHONE = AudioSystem.DEVICE_OUT_WIRED_HEADPHONE;
+    /** @hide
+     * The audio output device code for a USB headphone with attached microphone */
+    public static final int DEVICE_OUT_USB_HEADSET = AudioSystem.DEVICE_OUT_USB_HEADSET;
+    /** @hide
+     * The audio output device code for generic Bluetooth SCO, for voice */
+    public static final int DEVICE_OUT_BLUETOOTH_SCO = AudioSystem.DEVICE_OUT_BLUETOOTH_SCO;
+    /** @hide
+     * The audio output device code for Bluetooth SCO Headset Profile (HSP) and
+     * Hands-Free Profile (HFP), for voice
+     */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_BLUETOOTH_SCO_HEADSET =
+            AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
+    /** @hide
+     * The audio output device code for Bluetooth SCO car audio, for voice */
+    public static final int DEVICE_OUT_BLUETOOTH_SCO_CARKIT =
+            AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
+    /** @hide
+     * The audio output device code for generic Bluetooth A2DP, for music */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_BLUETOOTH_A2DP = AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP;
+    /** @hide
+     * The audio output device code for Bluetooth A2DP headphones, for music */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES =
+            AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
+    /** @hide
+     * The audio output device code for Bluetooth A2DP external speaker, for music */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER =
+            AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
+    /** @hide
+     * The audio output device code for S/PDIF (legacy) or HDMI
+     * Deprecated: replaced by {@link #DEVICE_OUT_HDMI} */
+    public static final int DEVICE_OUT_AUX_DIGITAL = AudioSystem.DEVICE_OUT_AUX_DIGITAL;
+    /** @hide
+     * The audio output device code for HDMI */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_HDMI = AudioSystem.DEVICE_OUT_HDMI;
+    /** @hide
+     * The audio output device code for an analog wired headset attached via a
+     *  docking station
+     */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_ANLG_DOCK_HEADSET = AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET;
+    /** @hide
+     * The audio output device code for a digital wired headset attached via a
+     *  docking station
+     */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_DGTL_DOCK_HEADSET = AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET;
+    /** @hide
+     * The audio output device code for a USB audio accessory. The accessory is in USB host
+     * mode and the Android device in USB device mode
+     */
+    public static final int DEVICE_OUT_USB_ACCESSORY = AudioSystem.DEVICE_OUT_USB_ACCESSORY;
+    /** @hide
+     * The audio output device code for a USB audio device. The device is in USB device
+     * mode and the Android device in USB host mode
+     */
+    public static final int DEVICE_OUT_USB_DEVICE = AudioSystem.DEVICE_OUT_USB_DEVICE;
+    /** @hide
+     * The audio output device code for projection output.
+     */
+    public static final int DEVICE_OUT_REMOTE_SUBMIX = AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
+    /** @hide
+     * The audio output device code the telephony voice TX path.
+     */
+    public static final int DEVICE_OUT_TELEPHONY_TX = AudioSystem.DEVICE_OUT_TELEPHONY_TX;
+    /** @hide
+     * The audio output device code for an analog jack with line impedance detected.
+     */
+    public static final int DEVICE_OUT_LINE = AudioSystem.DEVICE_OUT_LINE;
+    /** @hide
+     * The audio output device code for HDMI Audio Return Channel.
+     */
+    public static final int DEVICE_OUT_HDMI_ARC = AudioSystem.DEVICE_OUT_HDMI_ARC;
+    /** @hide
+     * The audio output device code for HDMI enhanced Audio Return Channel.
+     */
+    public static final int DEVICE_OUT_HDMI_EARC = AudioSystem.DEVICE_OUT_HDMI_EARC;
+    /** @hide
+     * The audio output device code for S/PDIF digital connection.
+     */
+    public static final int DEVICE_OUT_SPDIF = AudioSystem.DEVICE_OUT_SPDIF;
+    /** @hide
+     * The audio output device code for built-in FM transmitter.
+     */
+    public static final int DEVICE_OUT_FM = AudioSystem.DEVICE_OUT_FM;
+    /** @hide
+     * The audio output device code for echo reference injection point.
+     */
+    public static final int DEVICE_OUT_ECHO_CANCELLER = AudioSystem.DEVICE_OUT_ECHO_CANCELLER;
+    /** @hide
+     * The audio output device code for a BLE audio headset.
+     */
+    public static final int DEVICE_OUT_BLE_HEADSET = AudioSystem.DEVICE_OUT_BLE_HEADSET;
+    /** @hide
+     * The audio output device code for a BLE audio speaker.
+     */
+    public static final int DEVICE_OUT_BLE_SPEAKER = AudioSystem.DEVICE_OUT_BLE_SPEAKER;
+    /** @hide
+     * This is not used as a returned value from {@link #getDevicesForStream}, but could be
+     *  used in the future in a set method to select whatever default device is chosen by the
+     *  platform-specific implementation.
+     */
+    public static final int DEVICE_OUT_DEFAULT = AudioSystem.DEVICE_OUT_DEFAULT;
+
+    /** @hide
+     * The audio input device code for default built-in microphone
+     */
+    public static final int DEVICE_IN_BUILTIN_MIC = AudioSystem.DEVICE_IN_BUILTIN_MIC;
+    /** @hide
+     * The audio input device code for a Bluetooth SCO headset
+     */
+    public static final int DEVICE_IN_BLUETOOTH_SCO_HEADSET =
+                                    AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET;
+    /** @hide
+     * The audio input device code for wired headset microphone
+     */
+    public static final int DEVICE_IN_WIRED_HEADSET =
+                                    AudioSystem.DEVICE_IN_WIRED_HEADSET;
+    /** @hide
+     * The audio input device code for HDMI
+     */
+    public static final int DEVICE_IN_HDMI =
+                                    AudioSystem.DEVICE_IN_HDMI;
+    /** @hide
+     * The audio input device code for HDMI ARC
+     */
+    public static final int DEVICE_IN_HDMI_ARC =
+                                    AudioSystem.DEVICE_IN_HDMI_ARC;
+
+    /** @hide
+     * The audio input device code for HDMI EARC
+     */
+    public static final int DEVICE_IN_HDMI_EARC =
+                                    AudioSystem.DEVICE_IN_HDMI_EARC;
+
+    /** @hide
+     * The audio input device code for telephony voice RX path
+     */
+    public static final int DEVICE_IN_TELEPHONY_RX =
+                                    AudioSystem.DEVICE_IN_TELEPHONY_RX;
+    /** @hide
+     * The audio input device code for built-in microphone pointing to the back
+     */
+    public static final int DEVICE_IN_BACK_MIC =
+                                    AudioSystem.DEVICE_IN_BACK_MIC;
+    /** @hide
+     * The audio input device code for analog from a docking station
+     */
+    public static final int DEVICE_IN_ANLG_DOCK_HEADSET =
+                                    AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET;
+    /** @hide
+     * The audio input device code for digital from a docking station
+     */
+    public static final int DEVICE_IN_DGTL_DOCK_HEADSET =
+                                    AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET;
+    /** @hide
+     * The audio input device code for a USB audio accessory. The accessory is in USB host
+     * mode and the Android device in USB device mode
+     */
+    public static final int DEVICE_IN_USB_ACCESSORY =
+                                    AudioSystem.DEVICE_IN_USB_ACCESSORY;
+    /** @hide
+     * The audio input device code for a USB audio device. The device is in USB device
+     * mode and the Android device in USB host mode
+     */
+    public static final int DEVICE_IN_USB_DEVICE =
+                                    AudioSystem.DEVICE_IN_USB_DEVICE;
+    /** @hide
+     * The audio input device code for a FM radio tuner
+     */
+    public static final int DEVICE_IN_FM_TUNER = AudioSystem.DEVICE_IN_FM_TUNER;
+    /** @hide
+     * The audio input device code for a TV tuner
+     */
+    public static final int DEVICE_IN_TV_TUNER = AudioSystem.DEVICE_IN_TV_TUNER;
+    /** @hide
+     * The audio input device code for an analog jack with line impedance detected
+     */
+    public static final int DEVICE_IN_LINE = AudioSystem.DEVICE_IN_LINE;
+    /** @hide
+     * The audio input device code for a S/PDIF digital connection
+     */
+    public static final int DEVICE_IN_SPDIF = AudioSystem.DEVICE_IN_SPDIF;
+    /** @hide
+     * The audio input device code for audio loopback
+     */
+    public static final int DEVICE_IN_LOOPBACK = AudioSystem.DEVICE_IN_LOOPBACK;
+    /** @hide
+     * The audio input device code for an echo reference capture point.
+     */
+    public static final int DEVICE_IN_ECHO_REFERENCE = AudioSystem.DEVICE_IN_ECHO_REFERENCE;
+    /** @hide
+     * The audio input device code for a BLE audio headset.
+     */
+    public static final int DEVICE_IN_BLE_HEADSET = AudioSystem.DEVICE_IN_BLE_HEADSET;
+
+    /**
+     * Return true if the device code corresponds to an output device.
+     * @hide
+     */
+    public static boolean isOutputDevice(int device)
+    {
+        return (device & AudioSystem.DEVICE_BIT_IN) == 0;
+    }
+
+    /**
+     * Return true if the device code corresponds to an input device.
+     * @hide
+     */
+    public static boolean isInputDevice(int device)
+    {
+        return (device & AudioSystem.DEVICE_BIT_IN) == AudioSystem.DEVICE_BIT_IN;
+    }
+
+
+    /**
+     * Return the enabled devices for the specified output stream type.
+     *
+     * @param streamType The stream type to query. One of
+     *            {@link #STREAM_VOICE_CALL},
+     *            {@link #STREAM_SYSTEM},
+     *            {@link #STREAM_RING},
+     *            {@link #STREAM_MUSIC},
+     *            {@link #STREAM_ALARM},
+     *            {@link #STREAM_NOTIFICATION},
+     *            {@link #STREAM_DTMF},
+     *            {@link #STREAM_ACCESSIBILITY}.
+     *
+     * @return The bit-mask "or" of audio output device codes for all enabled devices on this
+     *         stream. Zero or more of
+     *            {@link #DEVICE_OUT_EARPIECE},
+     *            {@link #DEVICE_OUT_SPEAKER},
+     *            {@link #DEVICE_OUT_WIRED_HEADSET},
+     *            {@link #DEVICE_OUT_WIRED_HEADPHONE},
+     *            {@link #DEVICE_OUT_BLUETOOTH_SCO},
+     *            {@link #DEVICE_OUT_BLUETOOTH_SCO_HEADSET},
+     *            {@link #DEVICE_OUT_BLUETOOTH_SCO_CARKIT},
+     *            {@link #DEVICE_OUT_BLUETOOTH_A2DP},
+     *            {@link #DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES},
+     *            {@link #DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER},
+     *            {@link #DEVICE_OUT_HDMI},
+     *            {@link #DEVICE_OUT_ANLG_DOCK_HEADSET},
+     *            {@link #DEVICE_OUT_DGTL_DOCK_HEADSET}.
+     *            {@link #DEVICE_OUT_USB_ACCESSORY}.
+     *            {@link #DEVICE_OUT_USB_DEVICE}.
+     *            {@link #DEVICE_OUT_REMOTE_SUBMIX}.
+     *            {@link #DEVICE_OUT_TELEPHONY_TX}.
+     *            {@link #DEVICE_OUT_LINE}.
+     *            {@link #DEVICE_OUT_HDMI_ARC}.
+     *            {@link #DEVICE_OUT_HDMI_EARC}.
+     *            {@link #DEVICE_OUT_SPDIF}.
+     *            {@link #DEVICE_OUT_FM}.
+     *            {@link #DEVICE_OUT_DEFAULT} is not used here.
+     *
+     * The implementation may support additional device codes beyond those listed, so
+     * the application should ignore any bits which it does not recognize.
+     * Note that the information may be imprecise when the implementation
+     * cannot distinguish whether a particular device is enabled.
+     *
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    public int getDevicesForStream(int streamType) {
+        switch (streamType) {
+        case STREAM_VOICE_CALL:
+        case STREAM_SYSTEM:
+        case STREAM_RING:
+        case STREAM_MUSIC:
+        case STREAM_ALARM:
+        case STREAM_NOTIFICATION:
+        case STREAM_DTMF:
+        case STREAM_ACCESSIBILITY:
+            final IAudioService service = getService();
+            try {
+                return service.getDevicesForStream(streamType);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        default:
+            return 0;
+        }
+    }
+
+    /**
+     * @hide
+     * Get the audio devices that would be used for the routing of the given audio attributes.
+     * @param attributes the {@link AudioAttributes} for which the routing is being queried
+     * @return an empty list if there was an issue with the request, a list of audio devices
+     *   otherwise (typically one device, except for duplicated paths).
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.MODIFY_AUDIO_ROUTING,
+            android.Manifest.permission.QUERY_AUDIO_STATE
+    })
+    public @NonNull List<AudioDeviceAttributes> getDevicesForAttributes(
+            @NonNull AudioAttributes attributes) {
+        Objects.requireNonNull(attributes);
+        final IAudioService service = getService();
+        try {
+            return service.getDevicesForAttributes(attributes);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Volume behavior for an audio device that has no particular volume behavior set. Invalid as
+     * an argument to {@link #setDeviceVolumeBehavior(AudioDeviceAttributes, int)} and should not
+     * be returned by {@link #getDeviceVolumeBehavior(AudioDeviceAttributes)}.
+     */
+    public static final int DEVICE_VOLUME_BEHAVIOR_UNSET = -1;
+    /**
+     * @hide
+     * Volume behavior for an audio device where a software attenuation is applied
+     * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     */
+    @SystemApi
+    public static final int DEVICE_VOLUME_BEHAVIOR_VARIABLE = 0;
+    /**
+     * @hide
+     * Volume behavior for an audio device where the volume is always set to provide no attenuation
+     *     nor gain (e.g. unit gain).
+     * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     */
+    @SystemApi
+    public static final int DEVICE_VOLUME_BEHAVIOR_FULL = 1;
+    /**
+     * @hide
+     * Volume behavior for an audio device where the volume is either set to muted, or to provide
+     *     no attenuation nor gain (e.g. unit gain).
+     * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     */
+    @SystemApi
+    public static final int DEVICE_VOLUME_BEHAVIOR_FIXED = 2;
+    /**
+     * @hide
+     * Volume behavior for an audio device where no software attenuation is applied, and
+     *     the volume is kept synchronized between the host and the device itself through a
+     *     device-specific protocol such as BT AVRCP.
+     * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     */
+    @SystemApi
+    public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE = 3;
+    /**
+     * @hide
+     * Volume behavior for an audio device where no software attenuation is applied, and
+     *     the volume is kept synchronized between the host and the device itself through a
+     *     device-specific protocol (such as for hearing aids), based on the audio mode (e.g.
+     *     normal vs in phone call).
+     * @see #setMode(int)
+     * @see #setDeviceVolumeBehavior(AudioDeviceAttributes, int)
+     */
+    @SystemApi
+    public static final int DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE = 4;
+
+    /** @hide */
+    @IntDef({
+            DEVICE_VOLUME_BEHAVIOR_VARIABLE,
+            DEVICE_VOLUME_BEHAVIOR_FULL,
+            DEVICE_VOLUME_BEHAVIOR_FIXED,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DeviceVolumeBehavior {}
+
+    /** @hide */
+    @IntDef({
+            DEVICE_VOLUME_BEHAVIOR_UNSET,
+            DEVICE_VOLUME_BEHAVIOR_VARIABLE,
+            DEVICE_VOLUME_BEHAVIOR_FULL,
+            DEVICE_VOLUME_BEHAVIOR_FIXED,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE,
+            DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DeviceVolumeBehaviorState {}
+
+    /**
+     * @hide
+     * Throws IAE on an invalid volume behavior value
+     * @param volumeBehavior behavior value to check
+     */
+    public static void enforceValidVolumeBehavior(int volumeBehavior) {
+        switch (volumeBehavior) {
+            case DEVICE_VOLUME_BEHAVIOR_VARIABLE:
+            case DEVICE_VOLUME_BEHAVIOR_FULL:
+            case DEVICE_VOLUME_BEHAVIOR_FIXED:
+            case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE:
+            case DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE:
+                return;
+            default:
+                throw new IllegalArgumentException("Illegal volume behavior " + volumeBehavior);
+        }
+    }
+
+    /**
+     * @hide
+     * Sets the volume behavior for an audio output device.
+     * @see #DEVICE_VOLUME_BEHAVIOR_VARIABLE
+     * @see #DEVICE_VOLUME_BEHAVIOR_FULL
+     * @see #DEVICE_VOLUME_BEHAVIOR_FIXED
+     * @see #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE
+     * @see #DEVICE_VOLUME_BEHAVIOR_ABSOLUTE_MULTI_MODE
+     * @param device the device to be affected
+     * @param deviceVolumeBehavior one of the device behaviors
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void setDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device,
+            @DeviceVolumeBehavior int deviceVolumeBehavior) {
+        // verify arguments (validity of device type is enforced in server)
+        Objects.requireNonNull(device);
+        enforceValidVolumeBehavior(deviceVolumeBehavior);
+        // communicate with service
+        final IAudioService service = getService();
+        try {
+            service.setDeviceVolumeBehavior(device, deviceVolumeBehavior,
+                    mApplicationContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Returns the volume device behavior for the given audio device
+     * @param device the audio device
+     * @return the volume behavior for the device
+     */
+    @SystemApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.MODIFY_AUDIO_ROUTING,
+            android.Manifest.permission.QUERY_AUDIO_STATE
+    })
+    public @DeviceVolumeBehavior
+    int getDeviceVolumeBehavior(@NonNull AudioDeviceAttributes device) {
+        // verify arguments (validity of device type is enforced in server)
+        Objects.requireNonNull(device);
+        // communicate with service
+        final IAudioService service = getService();
+        try {
+            return service.getDeviceVolumeBehavior(device);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Returns {@code true} if the volume device behavior is {@link #DEVICE_VOLUME_BEHAVIOR_FULL}.
+     */
+    @TestApi
+    @RequiresPermission(anyOf = {
+            android.Manifest.permission.MODIFY_AUDIO_ROUTING,
+            android.Manifest.permission.QUERY_AUDIO_STATE
+    })
+    public boolean isFullVolumeDevice() {
+        final AudioAttributes attributes = new AudioAttributes.Builder()
+                .setUsage(AudioAttributes.USAGE_MEDIA)
+                .build();
+        final List<AudioDeviceAttributes> devices = getDevicesForAttributes(attributes);
+        for (AudioDeviceAttributes device : devices) {
+            if (getDeviceVolumeBehavior(device) == DEVICE_VOLUME_BEHAVIOR_FULL) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+     /**
+     * Indicate wired accessory connection state change.
+     * @param device type of device connected/disconnected (AudioManager.DEVICE_OUT_xxx)
+     * @param state  new connection state: 1 connected, 0 disconnected
+     * @param name   device name
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void setWiredDeviceConnectionState(int type, int state, String address, String name) {
+        final IAudioService service = getService();
+        try {
+            service.setWiredDeviceConnectionState(type, state, address, name,
+                    mApplicationContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+     /**
+     * Indicate Hearing Aid connection state change and eventually suppress
+     * the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent.
+     * This operation is asynchronous but its execution will still be sequentially scheduled
+     * relative to calls to {@link #setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
+     * * BluetoothDevice, int, int, boolean, int)} and
+     * and {@link #handleBluetoothA2dpDeviceConfigChange(BluetoothDevice)}.
+     * @param device Bluetooth device connected/disconnected
+     * @param state new connection state (BluetoothProfile.STATE_xxx)
+     * @param musicDevice Default get system volume for the connecting device.
+     * (either {@link android.bluetooth.BluetoothProfile.hearingaid} or
+     * {@link android.bluetooth.BluetoothProfile.HEARING_AID})
+     * @param suppressNoisyIntent if true the
+     * {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent will not be sent.
+     * {@hide}
+     */
+    public void setBluetoothHearingAidDeviceConnectionState(
+                BluetoothDevice device, int state, boolean suppressNoisyIntent,
+                int musicDevice) {
+        final IAudioService service = getService();
+        try {
+            service.setBluetoothHearingAidDeviceConnectionState(device,
+                state, suppressNoisyIntent, musicDevice);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+     /**
+     * Indicate A2DP source or sink connection state change and eventually suppress
+     * the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent.
+     * This operation is asynchronous but its execution will still be sequentially scheduled
+     * relative to calls to {@link #setBluetoothHearingAidDeviceConnectionState(BluetoothDevice,
+     * int, boolean, int)} and
+     * {@link #handleBluetoothA2dpDeviceConfigChange(BluetoothDevice)}.
+     * @param device Bluetooth device connected/disconnected
+     * @param state  new connection state, {@link BluetoothProfile#STATE_CONNECTED}
+     *     or {@link BluetoothProfile#STATE_DISCONNECTED}
+     * @param profile profile for the A2DP device
+     * @param a2dpVolume New volume for the connecting device. Does nothing if disconnecting.
+     * (either {@link android.bluetooth.BluetoothProfile.A2DP} or
+     * {@link android.bluetooth.BluetoothProfile.A2DP_SINK})
+     * @param suppressNoisyIntent if true the
+     * {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent will not be sent.
+     * {@hide}
+     */
+    public void setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
+            BluetoothDevice device, int state,
+            int profile, boolean suppressNoisyIntent, int a2dpVolume) {
+        final IAudioService service = getService();
+        try {
+            service.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(device,
+                state, profile, suppressNoisyIntent, a2dpVolume);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+     /**
+     * Indicate A2DP device configuration has changed.
+     * This operation is asynchronous but its execution will still be sequentially scheduled
+     * relative to calls to
+     * {@link #setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(BluetoothDevice, int, int,
+     * boolean, int)} and
+     * {@link #setBluetoothHearingAidDeviceConnectionState(BluetoothDevice, int, boolean, int)}
+     * @param device Bluetooth device whose configuration has changed.
+     * {@hide}
+     */
+    public void handleBluetoothA2dpDeviceConfigChange(BluetoothDevice device) {
+        final IAudioService service = getService();
+        try {
+            service.handleBluetoothA2dpDeviceConfigChange(device);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** {@hide} */
+    public IRingtonePlayer getRingtonePlayer() {
+        try {
+            return getService().getRingtonePlayer();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Used as a key for {@link #getProperty} to request the native or optimal output sample rate
+     * for this device's low latency output stream, in decimal Hz.  Latency-sensitive apps
+     * should use this value as a default, and offer the user the option to override it.
+     * The low latency output stream is typically either the device's primary output stream,
+     * or another output stream with smaller buffers.
+     */
+    // FIXME Deprecate
+    public static final String PROPERTY_OUTPUT_SAMPLE_RATE =
+            "android.media.property.OUTPUT_SAMPLE_RATE";
+
+    /**
+     * Used as a key for {@link #getProperty} to request the native or optimal output buffer size
+     * for this device's low latency output stream, in decimal PCM frames.  Latency-sensitive apps
+     * should use this value as a minimum, and offer the user the option to override it.
+     * The low latency output stream is typically either the device's primary output stream,
+     * or another output stream with smaller buffers.
+     */
+    // FIXME Deprecate
+    public static final String PROPERTY_OUTPUT_FRAMES_PER_BUFFER =
+            "android.media.property.OUTPUT_FRAMES_PER_BUFFER";
+
+    /**
+     * Used as a key for {@link #getProperty} to determine if the default microphone audio source
+     * supports near-ultrasound frequencies (range of 18 - 21 kHz).
+     */
+    public static final String PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND =
+            "android.media.property.SUPPORT_MIC_NEAR_ULTRASOUND";
+
+    /**
+     * Used as a key for {@link #getProperty} to determine if the default speaker audio path
+     * supports near-ultrasound frequencies (range of 18 - 21 kHz).
+     */
+    public static final String PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND =
+            "android.media.property.SUPPORT_SPEAKER_NEAR_ULTRASOUND";
+
+    /**
+     * Used as a key for {@link #getProperty} to determine if the unprocessed audio source is
+     * available and supported with the expected frequency range and level response.
+     */
+    public static final String PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED =
+            "android.media.property.SUPPORT_AUDIO_SOURCE_UNPROCESSED";
+    /**
+     * Returns the value of the property with the specified key.
+     * @param key One of the strings corresponding to a property key: either
+     *            {@link #PROPERTY_OUTPUT_SAMPLE_RATE},
+     *            {@link #PROPERTY_OUTPUT_FRAMES_PER_BUFFER},
+     *            {@link #PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND},
+     *            {@link #PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND}, or
+     *            {@link #PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED}.
+     * @return A string representing the associated value for that property key,
+     *         or null if there is no value for that key.
+     */
+    public String getProperty(String key) {
+        if (PROPERTY_OUTPUT_SAMPLE_RATE.equals(key)) {
+            int outputSampleRate = AudioSystem.getPrimaryOutputSamplingRate();
+            return outputSampleRate > 0 ? Integer.toString(outputSampleRate) : null;
+        } else if (PROPERTY_OUTPUT_FRAMES_PER_BUFFER.equals(key)) {
+            int outputFramesPerBuffer = AudioSystem.getPrimaryOutputFrameCount();
+            return outputFramesPerBuffer > 0 ? Integer.toString(outputFramesPerBuffer) : null;
+        } else if (PROPERTY_SUPPORT_MIC_NEAR_ULTRASOUND.equals(key)) {
+            // Will throw a RuntimeException Resources.NotFoundException if this config value is
+            // not found.
+            return String.valueOf(getContext().getResources().getBoolean(
+                    com.android.internal.R.bool.config_supportMicNearUltrasound));
+        } else if (PROPERTY_SUPPORT_SPEAKER_NEAR_ULTRASOUND.equals(key)) {
+            return String.valueOf(getContext().getResources().getBoolean(
+                    com.android.internal.R.bool.config_supportSpeakerNearUltrasound));
+        } else if (PROPERTY_SUPPORT_AUDIO_SOURCE_UNPROCESSED.equals(key)) {
+            return String.valueOf(getContext().getResources().getBoolean(
+                    com.android.internal.R.bool.config_supportAudioSourceUnprocessed));
+        } else {
+            // null or unknown key
+            return null;
+        }
+    }
+
+    /**
+     * @hide
+     * Sets an additional audio output device delay in milliseconds.
+     *
+     * The additional output delay is a request to the output device to
+     * delay audio presentation (generally with respect to video presentation for better
+     * synchronization).
+     * It may not be supported by all output devices,
+     * and typically increases the audio latency by the amount of additional
+     * audio delay requested.
+     *
+     * If additional audio delay is supported by an audio output device,
+     * it is expected to be supported for all output streams (and configurations)
+     * opened on that device.
+     *
+     * @param device an instance of {@link AudioDeviceInfo} returned from {@link getDevices()}.
+     * @param delayMillis delay in milliseconds desired.  This should be in range of {@code 0}
+     *     to the value returned by {@link #getMaxAdditionalOutputDeviceDelay()}.
+     * @return true if successful, false if the device does not support output device delay
+     *     or the delay is not in range of {@link #getMaxAdditionalOutputDeviceDelay()}.
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public boolean setAdditionalOutputDeviceDelay(
+            @NonNull AudioDeviceInfo device, @IntRange(from = 0) long delayMillis) {
+        Objects.requireNonNull(device);
+        try {
+            return getService().setAdditionalOutputDeviceDelay(
+                new AudioDeviceAttributes(device), delayMillis);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Returns the current additional audio output device delay in milliseconds.
+     *
+     * @param device an instance of {@link AudioDeviceInfo} returned from {@link getDevices()}.
+     * @return the additional output device delay. This is a non-negative number.
+     *     {@code 0} is returned if unsupported.
+     */
+    @SystemApi
+    @IntRange(from = 0)
+    public long getAdditionalOutputDeviceDelay(@NonNull AudioDeviceInfo device) {
+        Objects.requireNonNull(device);
+        try {
+            return getService().getAdditionalOutputDeviceDelay(new AudioDeviceAttributes(device));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Returns the maximum additional audio output device delay in milliseconds.
+     *
+     * @param device an instance of {@link AudioDeviceInfo} returned from {@link getDevices()}.
+     * @return the maximum output device delay in milliseconds that can be set.
+     *     This is a non-negative number
+     *     representing the additional audio delay supported for the device.
+     *     {@code 0} is returned if unsupported.
+     */
+    @SystemApi
+    @IntRange(from = 0)
+    public long getMaxAdditionalOutputDeviceDelay(@NonNull AudioDeviceInfo device) {
+        Objects.requireNonNull(device);
+        try {
+            return getService().getMaxAdditionalOutputDeviceDelay(
+                    new AudioDeviceAttributes(device));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the estimated latency for the given stream type in milliseconds.
+     *
+     * DO NOT UNHIDE. The existing approach for doing A/V sync has too many problems. We need
+     * a better solution.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public int getOutputLatency(int streamType) {
+        return AudioSystem.getOutputLatency(streamType);
+    }
+
+    /**
+     * Registers a global volume controller interface.  Currently limited to SystemUI.
+     *
+     * @hide
+     */
+    public void setVolumeController(IVolumeController controller) {
+        try {
+            getService().setVolumeController(controller);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Notify audio manager about volume controller visibility changes.
+     * Currently limited to SystemUI.
+     *
+     * @hide
+     */
+    public void notifyVolumeControllerVisible(IVolumeController controller, boolean visible) {
+        try {
+            getService().notifyVolumeControllerVisible(controller, visible);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Only useful for volume controllers.
+     * @hide
+     */
+    public boolean isStreamAffectedByRingerMode(int streamType) {
+        try {
+            return getService().isStreamAffectedByRingerMode(streamType);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Only useful for volume controllers.
+     * @hide
+     */
+    public boolean isStreamAffectedByMute(int streamType) {
+        try {
+            return getService().isStreamAffectedByMute(streamType);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Only useful for volume controllers.
+     * @hide
+     */
+    public void disableSafeMediaVolume() {
+        try {
+            getService().disableSafeMediaVolume(mApplicationContext.getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Only useful for volume controllers.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public void setRingerModeInternal(int ringerMode) {
+        try {
+            getService().setRingerModeInternal(ringerMode, getContext().getOpPackageName());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Only useful for volume controllers.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public int getRingerModeInternal() {
+        try {
+            return getService().getRingerModeInternal();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Only useful for volume controllers.
+     * @hide
+     */
+    public void setVolumePolicy(VolumePolicy policy) {
+        try {
+            getService().setVolumePolicy(policy);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set Hdmi Cec system audio mode.
+     *
+     * @param on whether to be on system audio mode
+     * @return output device type. 0 (DEVICE_NONE) if failed to set device.
+     * @hide
+     */
+    public int setHdmiSystemAudioSupported(boolean on) {
+        try {
+            return getService().setHdmiSystemAudioSupported(on);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns true if Hdmi Cec system audio mode is supported.
+     *
+     * @hide
+     */
+    @SystemApi
+    @SuppressLint("RequiresPermission") // FIXME is this still used?
+    public boolean isHdmiSystemAudioSupported() {
+        try {
+            return getService().isHdmiSystemAudioSupported();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return codes for listAudioPorts(), createAudioPatch() ...
+     */
+
+    /** @hide */
+    @SystemApi
+    public static final int SUCCESS = AudioSystem.SUCCESS;
+    /**
+     * A default error code.
+     */
+    public static final int ERROR = AudioSystem.ERROR;
+    /** @hide
+     * CANDIDATE FOR PUBLIC API
+     */
+    public static final int ERROR_BAD_VALUE = AudioSystem.BAD_VALUE;
+    /** @hide
+     */
+    public static final int ERROR_INVALID_OPERATION = AudioSystem.INVALID_OPERATION;
+    /** @hide
+     */
+    public static final int ERROR_PERMISSION_DENIED = AudioSystem.PERMISSION_DENIED;
+    /** @hide
+     */
+    public static final int ERROR_NO_INIT = AudioSystem.NO_INIT;
+    /**
+     * An error code indicating that the object reporting it is no longer valid and needs to
+     * be recreated.
+     */
+    public static final int ERROR_DEAD_OBJECT = AudioSystem.DEAD_OBJECT;
+
+    /**
+     * Returns a list of descriptors for all audio ports managed by the audio framework.
+     * Audio ports are nodes in the audio framework or audio hardware that can be configured
+     * or connected and disconnected with createAudioPatch() or releaseAudioPatch().
+     * See AudioPort for a list of attributes of each audio port.
+     * @param ports An AudioPort ArrayList where the list will be returned.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static int listAudioPorts(ArrayList<AudioPort> ports) {
+        return updateAudioPortCache(ports, null, null);
+    }
+
+    /**
+     * Returns a list of descriptors for all audio ports managed by the audio framework as
+     * it was before the last update calback.
+     * @param ports An AudioPort ArrayList where the list will be returned.
+     * @hide
+     */
+    public static int listPreviousAudioPorts(ArrayList<AudioPort> ports) {
+        return updateAudioPortCache(null, null, ports);
+    }
+
+    /**
+     * Specialized version of listAudioPorts() listing only audio devices (AudioDevicePort)
+     * @see listAudioPorts(ArrayList<AudioPort>)
+     * @hide
+     */
+    public static int listAudioDevicePorts(ArrayList<AudioDevicePort> devices) {
+        if (devices == null) {
+            return ERROR_BAD_VALUE;
+        }
+        ArrayList<AudioPort> ports = new ArrayList<AudioPort>();
+        int status = updateAudioPortCache(ports, null, null);
+        if (status == SUCCESS) {
+            filterDevicePorts(ports, devices);
+        }
+        return status;
+    }
+
+    /**
+     * Specialized version of listPreviousAudioPorts() listing only audio devices (AudioDevicePort)
+     * @see listPreviousAudioPorts(ArrayList<AudioPort>)
+     * @hide
+     */
+    public static int listPreviousAudioDevicePorts(ArrayList<AudioDevicePort> devices) {
+        if (devices == null) {
+            return ERROR_BAD_VALUE;
+        }
+        ArrayList<AudioPort> ports = new ArrayList<AudioPort>();
+        int status = updateAudioPortCache(null, null, ports);
+        if (status == SUCCESS) {
+            filterDevicePorts(ports, devices);
+        }
+        return status;
+    }
+
+    private static void filterDevicePorts(ArrayList<AudioPort> ports,
+                                          ArrayList<AudioDevicePort> devices) {
+        devices.clear();
+        for (int i = 0; i < ports.size(); i++) {
+            if (ports.get(i) instanceof AudioDevicePort) {
+                devices.add((AudioDevicePort)ports.get(i));
+            }
+        }
+    }
+
+    /**
+     * Create a connection between two or more devices. The framework will reject the request if
+     * device types are not compatible or the implementation does not support the requested
+     * configuration.
+     * NOTE: current implementation is limited to one source and one sink per patch.
+     * @param patch AudioPatch array where the newly created patch will be returned.
+     *              As input, if patch[0] is not null, the specified patch will be replaced by the
+     *              new patch created. This avoids calling releaseAudioPatch() when modifying a
+     *              patch and allows the implementation to optimize transitions.
+     * @param sources List of source audio ports. All must be AudioPort.ROLE_SOURCE.
+     * @param sinks   List of sink audio ports. All must be AudioPort.ROLE_SINK.
+     *
+     * @return - {@link #SUCCESS} if connection is successful.
+     *         - {@link #ERROR_BAD_VALUE} if incompatible device types are passed.
+     *         - {@link #ERROR_INVALID_OPERATION} if the requested connection is not supported.
+     *         - {@link #ERROR_PERMISSION_DENIED} if the client does not have permission to create
+     *         a patch.
+     *         - {@link #ERROR_DEAD_OBJECT} if the server process is dead
+     *         - {@link #ERROR} if patch cannot be connected for any other reason.
+     *
+     *         patch[0] contains the newly created patch
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static int createAudioPatch(AudioPatch[] patch,
+                                 AudioPortConfig[] sources,
+                                 AudioPortConfig[] sinks) {
+        return AudioSystem.createAudioPatch(patch, sources, sinks);
+    }
+
+    /**
+     * Releases an existing audio patch connection.
+     * @param patch The audio patch to disconnect.
+     * @return - {@link #SUCCESS} if disconnection is successful.
+     *         - {@link #ERROR_BAD_VALUE} if the specified patch does not exist.
+     *         - {@link #ERROR_PERMISSION_DENIED} if the client does not have permission to release
+     *         a patch.
+     *         - {@link #ERROR_DEAD_OBJECT} if the server process is dead
+     *         - {@link #ERROR} if patch cannot be released for any other reason.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static int releaseAudioPatch(AudioPatch patch) {
+        return AudioSystem.releaseAudioPatch(patch);
+    }
+
+    /**
+     * List all existing connections between audio ports.
+     * @param patches An AudioPatch array where the list will be returned.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public static int listAudioPatches(ArrayList<AudioPatch> patches) {
+        return updateAudioPortCache(null, patches, null);
+    }
+
+    /**
+     * Set the gain on the specified AudioPort. The AudioGainConfig config is build by
+     * AudioGain.buildConfig()
+     * @hide
+     */
+    public static int setAudioPortGain(AudioPort port, AudioGainConfig gain) {
+        if (port == null || gain == null) {
+            return ERROR_BAD_VALUE;
+        }
+        AudioPortConfig activeConfig = port.activeConfig();
+        AudioPortConfig config = new AudioPortConfig(port, activeConfig.samplingRate(),
+                                        activeConfig.channelMask(), activeConfig.format(), gain);
+        config.mConfigMask = AudioPortConfig.GAIN;
+        return AudioSystem.setAudioPortConfig(config);
+    }
+
+    /**
+     * Listener registered by client to be notified upon new audio port connections,
+     * disconnections or attributes update.
+     * @hide
+     */
+    public interface OnAudioPortUpdateListener {
+        /**
+         * Callback method called upon audio port list update.
+         * @param portList the updated list of audio ports
+         */
+        public void onAudioPortListUpdate(AudioPort[] portList);
+
+        /**
+         * Callback method called upon audio patch list update.
+         * @param patchList the updated list of audio patches
+         */
+        public void onAudioPatchListUpdate(AudioPatch[] patchList);
+
+        /**
+         * Callback method called when the mediaserver dies
+         */
+        public void onServiceDied();
+    }
+
+    /**
+     * Register an audio port list update listener.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public void registerAudioPortUpdateListener(OnAudioPortUpdateListener l) {
+        sAudioPortEventHandler.init();
+        sAudioPortEventHandler.registerListener(l);
+    }
+
+    /**
+     * Unregister an audio port list update listener.
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public void unregisterAudioPortUpdateListener(OnAudioPortUpdateListener l) {
+        sAudioPortEventHandler.unregisterListener(l);
+    }
+
+    //
+    // AudioPort implementation
+    //
+
+    static final int AUDIOPORT_GENERATION_INIT = 0;
+    static Integer sAudioPortGeneration = new Integer(AUDIOPORT_GENERATION_INIT);
+    static ArrayList<AudioPort> sAudioPortsCached = new ArrayList<AudioPort>();
+    static ArrayList<AudioPort> sPreviousAudioPortsCached = new ArrayList<AudioPort>();
+    static ArrayList<AudioPatch> sAudioPatchesCached = new ArrayList<AudioPatch>();
+
+    static int resetAudioPortGeneration() {
+        int generation;
+        synchronized (sAudioPortGeneration) {
+            generation = sAudioPortGeneration;
+            sAudioPortGeneration = AUDIOPORT_GENERATION_INIT;
+        }
+        return generation;
+    }
+
+    static int updateAudioPortCache(ArrayList<AudioPort> ports, ArrayList<AudioPatch> patches,
+                                    ArrayList<AudioPort> previousPorts) {
+        sAudioPortEventHandler.init();
+        synchronized (sAudioPortGeneration) {
+
+            if (sAudioPortGeneration == AUDIOPORT_GENERATION_INIT) {
+                int[] patchGeneration = new int[1];
+                int[] portGeneration = new int[1];
+                int status;
+                ArrayList<AudioPort> newPorts = new ArrayList<AudioPort>();
+                ArrayList<AudioPatch> newPatches = new ArrayList<AudioPatch>();
+
+                do {
+                    newPorts.clear();
+                    status = AudioSystem.listAudioPorts(newPorts, portGeneration);
+                    if (status != SUCCESS) {
+                        Log.w(TAG, "updateAudioPortCache: listAudioPorts failed");
+                        return status;
+                    }
+                    newPatches.clear();
+                    status = AudioSystem.listAudioPatches(newPatches, patchGeneration);
+                    if (status != SUCCESS) {
+                        Log.w(TAG, "updateAudioPortCache: listAudioPatches failed");
+                        return status;
+                    }
+                    // Loop until patch generation is the same as port generation unless audio ports
+                    // and audio patches are not null.
+                } while (patchGeneration[0] != portGeneration[0]
+                        && (ports == null || patches == null));
+                // If the patch generation doesn't equal port generation, return ERROR here in case
+                // of mismatch between audio ports and audio patches.
+                if (patchGeneration[0] != portGeneration[0]) {
+                    return ERROR;
+                }
+
+                for (int i = 0; i < newPatches.size(); i++) {
+                    for (int j = 0; j < newPatches.get(i).sources().length; j++) {
+                        AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sources()[j],
+                                                                   newPorts);
+                        newPatches.get(i).sources()[j] = portCfg;
+                    }
+                    for (int j = 0; j < newPatches.get(i).sinks().length; j++) {
+                        AudioPortConfig portCfg = updatePortConfig(newPatches.get(i).sinks()[j],
+                                                                   newPorts);
+                        newPatches.get(i).sinks()[j] = portCfg;
+                    }
+                }
+                for (Iterator<AudioPatch> i = newPatches.iterator(); i.hasNext(); ) {
+                    AudioPatch newPatch = i.next();
+                    boolean hasInvalidPort = false;
+                    for (AudioPortConfig portCfg : newPatch.sources()) {
+                        if (portCfg == null) {
+                            hasInvalidPort = true;
+                            break;
+                        }
+                    }
+                    for (AudioPortConfig portCfg : newPatch.sinks()) {
+                        if (portCfg == null) {
+                            hasInvalidPort = true;
+                            break;
+                        }
+                    }
+                    if (hasInvalidPort) {
+                        // Temporarily remove patches with invalid ports. One who created the patch
+                        // is responsible for dealing with the port change.
+                        i.remove();
+                    }
+                }
+
+                sPreviousAudioPortsCached = sAudioPortsCached;
+                sAudioPortsCached = newPorts;
+                sAudioPatchesCached = newPatches;
+                sAudioPortGeneration = portGeneration[0];
+            }
+            if (ports != null) {
+                ports.clear();
+                ports.addAll(sAudioPortsCached);
+            }
+            if (patches != null) {
+                patches.clear();
+                patches.addAll(sAudioPatchesCached);
+            }
+            if (previousPorts != null) {
+                previousPorts.clear();
+                previousPorts.addAll(sPreviousAudioPortsCached);
+            }
+        }
+        return SUCCESS;
+    }
+
+    static AudioPortConfig updatePortConfig(AudioPortConfig portCfg, ArrayList<AudioPort> ports) {
+        AudioPort port = portCfg.port();
+        int k;
+        for (k = 0; k < ports.size(); k++) {
+            // compare handles because the port returned by JNI is not of the correct
+            // subclass
+            if (ports.get(k).handle().equals(port.handle())) {
+                port = ports.get(k);
+                break;
+            }
+        }
+        if (k == ports.size()) {
+            // this hould never happen
+            Log.e(TAG, "updatePortConfig port not found for handle: "+port.handle().id());
+            return null;
+        }
+        AudioGainConfig gainCfg = portCfg.gain();
+        if (gainCfg != null) {
+            AudioGain gain = port.gain(gainCfg.index());
+            gainCfg = gain.buildConfig(gainCfg.mode(),
+                                       gainCfg.channelMask(),
+                                       gainCfg.values(),
+                                       gainCfg.rampDurationMs());
+        }
+        return port.buildConfig(portCfg.samplingRate(),
+                                                 portCfg.channelMask(),
+                                                 portCfg.format(),
+                                                 gainCfg);
+    }
+
+    private OnAmPortUpdateListener mPortListener = null;
+
+    /**
+     * The message sent to apps when the contents of the device list changes if they provide
+     * a {@link Handler} object to addOnAudioDeviceConnectionListener().
+     */
+    private final static int MSG_DEVICES_CALLBACK_REGISTERED = 0;
+    private final static int MSG_DEVICES_DEVICES_ADDED = 1;
+    private final static int MSG_DEVICES_DEVICES_REMOVED = 2;
+
+    /**
+     * The list of {@link AudioDeviceCallback} objects to receive add/remove notifications.
+     */
+    private final ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate> mDeviceCallbacks =
+            new ArrayMap<AudioDeviceCallback, NativeEventHandlerDelegate>();
+
+    /**
+     * The following are flags to allow users of {@link AudioManager#getDevices(int)} to filter
+     * the results list to only those device types they are interested in.
+     */
+    /**
+     * Specifies to the {@link AudioManager#getDevices(int)} method to include
+     * source (i.e. input) audio devices.
+     */
+    public static final int GET_DEVICES_INPUTS    = 0x0001;
+
+    /**
+     * Specifies to the {@link AudioManager#getDevices(int)} method to include
+     * sink (i.e. output) audio devices.
+     */
+    public static final int GET_DEVICES_OUTPUTS   = 0x0002;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = "GET_DEVICES", value = {
+            GET_DEVICES_INPUTS,
+            GET_DEVICES_OUTPUTS }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioDeviceRole {}
+
+    /**
+     * Specifies to the {@link AudioManager#getDevices(int)} method to include both
+     * source and sink devices.
+     */
+    public static final int GET_DEVICES_ALL = GET_DEVICES_OUTPUTS | GET_DEVICES_INPUTS;
+
+    /**
+     * Determines if a given AudioDevicePort meets the specified filter criteria.
+     * @param port  The port to test.
+     * @param flags A set of bitflags specifying the criteria to test.
+     * @see {@link GET_DEVICES_OUTPUTS} and {@link GET_DEVICES_INPUTS}
+     **/
+    private static boolean checkFlags(AudioDevicePort port, int flags) {
+        return port.role() == AudioPort.ROLE_SINK && (flags & GET_DEVICES_OUTPUTS) != 0 ||
+               port.role() == AudioPort.ROLE_SOURCE && (flags & GET_DEVICES_INPUTS) != 0;
+    }
+
+    private static boolean checkTypes(AudioDevicePort port) {
+        return AudioDeviceInfo.convertInternalDeviceToDeviceType(port.type()) !=
+                    AudioDeviceInfo.TYPE_UNKNOWN;
+    }
+
+    /**
+     * Returns an array of {@link AudioDeviceInfo} objects corresponding to the audio devices
+     * currently connected to the system and meeting the criteria specified in the
+     * <code>flags</code> parameter.
+     * @param flags A set of bitflags specifying the criteria to test.
+     * @see #GET_DEVICES_OUTPUTS
+     * @see #GET_DEVICES_INPUTS
+     * @see #GET_DEVICES_ALL
+     * @return A (possibly zero-length) array of AudioDeviceInfo objects.
+     */
+    public AudioDeviceInfo[] getDevices(@AudioDeviceRole int flags) {
+        return getDevicesStatic(flags);
+    }
+
+    /**
+     * Does the actual computation to generate an array of (externally-visible) AudioDeviceInfo
+     * objects from the current (internal) AudioDevicePort list.
+     */
+    private static AudioDeviceInfo[]
+        infoListFromPortList(ArrayList<AudioDevicePort> ports, int flags) {
+
+        // figure out how many AudioDeviceInfo we need space for...
+        int numRecs = 0;
+        for (AudioDevicePort port : ports) {
+            if (checkTypes(port) && checkFlags(port, flags)) {
+                numRecs++;
+            }
+        }
+
+        // Now load them up...
+        AudioDeviceInfo[] deviceList = new AudioDeviceInfo[numRecs];
+        int slot = 0;
+        for (AudioDevicePort port : ports) {
+            if (checkTypes(port) && checkFlags(port, flags)) {
+                deviceList[slot++] = new AudioDeviceInfo(port);
+            }
+        }
+
+        return deviceList;
+    }
+
+    /*
+     * Calculate the list of ports that are in ports_B, but not in ports_A. This is used by
+     * the add/remove callback mechanism to provide a list of the newly added or removed devices
+     * rather than the whole list and make the app figure it out.
+     * Note that calling this method with:
+     *  ports_A == PREVIOUS_ports and ports_B == CURRENT_ports will calculated ADDED ports.
+     *  ports_A == CURRENT_ports and ports_B == PREVIOUS_ports will calculated REMOVED ports.
+     */
+    private static AudioDeviceInfo[] calcListDeltas(
+            ArrayList<AudioDevicePort> ports_A, ArrayList<AudioDevicePort> ports_B, int flags) {
+
+        ArrayList<AudioDevicePort> delta_ports = new ArrayList<AudioDevicePort>();
+
+        AudioDevicePort cur_port = null;
+        for (int cur_index = 0; cur_index < ports_B.size(); cur_index++) {
+            boolean cur_port_found = false;
+            cur_port = ports_B.get(cur_index);
+            for (int prev_index = 0;
+                 prev_index < ports_A.size() && !cur_port_found;
+                 prev_index++) {
+                cur_port_found = (cur_port.id() == ports_A.get(prev_index).id());
+            }
+
+            if (!cur_port_found) {
+                delta_ports.add(cur_port);
+            }
+        }
+
+        return infoListFromPortList(delta_ports, flags);
+    }
+
+    /**
+     * Generates a list of AudioDeviceInfo objects corresponding to the audio devices currently
+     * connected to the system and meeting the criteria specified in the <code>flags</code>
+     * parameter.
+     * This is an internal function. The public API front is getDevices(int).
+     * @param flags A set of bitflags specifying the criteria to test.
+     * @see #GET_DEVICES_OUTPUTS
+     * @see #GET_DEVICES_INPUTS
+     * @see #GET_DEVICES_ALL
+     * @return A (possibly zero-length) array of AudioDeviceInfo objects.
+     * @hide
+     */
+    public static AudioDeviceInfo[] getDevicesStatic(int flags) {
+        ArrayList<AudioDevicePort> ports = new ArrayList<AudioDevicePort>();
+        int status = AudioManager.listAudioDevicePorts(ports);
+        if (status != AudioManager.SUCCESS) {
+            // fail and bail!
+            return new AudioDeviceInfo[0];  // Always return an array.
+        }
+
+        return infoListFromPortList(ports, flags);
+    }
+
+    /**
+     * Returns an {@link AudioDeviceInfo} corresponding to the specified {@link AudioPort} ID.
+     * @param portId The audio port ID to look up for.
+     * @param flags A set of bitflags specifying the criteria to test.
+     * @see #GET_DEVICES_OUTPUTS
+     * @see #GET_DEVICES_INPUTS
+     * @see #GET_DEVICES_ALL
+     * @return An AudioDeviceInfo or null if no device with matching port ID is found.
+     * @hide
+     */
+    public static AudioDeviceInfo getDeviceForPortId(int portId, int flags) {
+        if (portId == 0) {
+            return null;
+        }
+        AudioDeviceInfo[] devices = getDevicesStatic(flags);
+        for (AudioDeviceInfo device : devices) {
+            if (device.getId() == portId) {
+                return device;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Registers an {@link AudioDeviceCallback} object to receive notifications of changes
+     * to the set of connected audio devices.
+     * @param callback The {@link AudioDeviceCallback} object to receive connect/disconnect
+     * notifications.
+     * @param handler Specifies the {@link Handler} object for the thread on which to execute
+     * the callback. If <code>null</code>, the {@link Handler} associated with the main
+     * {@link Looper} will be used.
+     */
+    public void registerAudioDeviceCallback(AudioDeviceCallback callback,
+            @Nullable Handler handler) {
+        synchronized (mDeviceCallbacks) {
+            if (callback != null && !mDeviceCallbacks.containsKey(callback)) {
+                if (mDeviceCallbacks.size() == 0) {
+                    if (mPortListener == null) {
+                        mPortListener = new OnAmPortUpdateListener();
+                    }
+                    registerAudioPortUpdateListener(mPortListener);
+                }
+                NativeEventHandlerDelegate delegate =
+                        new NativeEventHandlerDelegate(callback, handler);
+                mDeviceCallbacks.put(callback, delegate);
+                broadcastDeviceListChange_sync(delegate.getHandler());
+            }
+        }
+    }
+
+    /**
+     * Unregisters an {@link AudioDeviceCallback} object which has been previously registered
+     * to receive notifications of changes to the set of connected audio devices.
+     * @param callback The {@link AudioDeviceCallback} object that was previously registered
+     * with {@link AudioManager#registerAudioDeviceCallback} to be unregistered.
+     */
+    public void unregisterAudioDeviceCallback(AudioDeviceCallback callback) {
+        synchronized (mDeviceCallbacks) {
+            if (mDeviceCallbacks.containsKey(callback)) {
+                mDeviceCallbacks.remove(callback);
+                if (mDeviceCallbacks.size() == 0) {
+                    unregisterAudioPortUpdateListener(mPortListener);
+                }
+            }
+        }
+    }
+
+    /**
+     * Set port id for microphones by matching device type and address.
+     * @hide
+     */
+    public static void setPortIdForMicrophones(ArrayList<MicrophoneInfo> microphones) {
+        AudioDeviceInfo[] devices = getDevicesStatic(AudioManager.GET_DEVICES_INPUTS);
+        for (int i = microphones.size() - 1; i >= 0; i--) {
+            boolean foundPortId = false;
+            for (AudioDeviceInfo device : devices) {
+                if (device.getPort().type() == microphones.get(i).getInternalDeviceType()
+                        && TextUtils.equals(device.getAddress(), microphones.get(i).getAddress())) {
+                    microphones.get(i).setId(device.getId());
+                    foundPortId = true;
+                    break;
+                }
+            }
+            if (!foundPortId) {
+                Log.i(TAG, "Failed to find port id for device with type:"
+                        + microphones.get(i).getType() + " address:"
+                        + microphones.get(i).getAddress());
+                microphones.remove(i);
+            }
+        }
+    }
+
+    /**
+     * Convert {@link AudioDeviceInfo} to {@link MicrophoneInfo}.
+     * @hide
+     */
+    public static MicrophoneInfo microphoneInfoFromAudioDeviceInfo(AudioDeviceInfo deviceInfo) {
+        int deviceType = deviceInfo.getType();
+        int micLocation = (deviceType == AudioDeviceInfo.TYPE_BUILTIN_MIC
+                || deviceType == AudioDeviceInfo.TYPE_TELEPHONY) ? MicrophoneInfo.LOCATION_MAINBODY
+                : deviceType == AudioDeviceInfo.TYPE_UNKNOWN ? MicrophoneInfo.LOCATION_UNKNOWN
+                        : MicrophoneInfo.LOCATION_PERIPHERAL;
+        MicrophoneInfo microphone = new MicrophoneInfo(
+                deviceInfo.getPort().name() + deviceInfo.getId(),
+                deviceInfo.getPort().type(), deviceInfo.getAddress(), micLocation,
+                MicrophoneInfo.GROUP_UNKNOWN, MicrophoneInfo.INDEX_IN_THE_GROUP_UNKNOWN,
+                MicrophoneInfo.POSITION_UNKNOWN, MicrophoneInfo.ORIENTATION_UNKNOWN,
+                new ArrayList<Pair<Float, Float>>(), new ArrayList<Pair<Integer, Integer>>(),
+                MicrophoneInfo.SENSITIVITY_UNKNOWN, MicrophoneInfo.SPL_UNKNOWN,
+                MicrophoneInfo.SPL_UNKNOWN, MicrophoneInfo.DIRECTIONALITY_UNKNOWN);
+        microphone.setId(deviceInfo.getId());
+        return microphone;
+    }
+
+    /**
+     * Add {@link MicrophoneInfo} by device information while filtering certain types.
+     */
+    private void addMicrophonesFromAudioDeviceInfo(ArrayList<MicrophoneInfo> microphones,
+                    HashSet<Integer> filterTypes) {
+        AudioDeviceInfo[] devices = getDevicesStatic(GET_DEVICES_INPUTS);
+        for (AudioDeviceInfo device : devices) {
+            if (filterTypes.contains(device.getType())) {
+                continue;
+            }
+            MicrophoneInfo microphone = microphoneInfoFromAudioDeviceInfo(device);
+            microphones.add(microphone);
+        }
+    }
+
+    /**
+     * Returns a list of {@link MicrophoneInfo} that corresponds to the characteristics
+     * of all available microphones. The list is empty when no microphones are available
+     * on the device. An error during the query will result in an IOException being thrown.
+     *
+     * @return a list that contains all microphones' characteristics
+     * @throws IOException if an error occurs.
+     */
+    public List<MicrophoneInfo> getMicrophones() throws IOException {
+        ArrayList<MicrophoneInfo> microphones = new ArrayList<MicrophoneInfo>();
+        int status = AudioSystem.getMicrophones(microphones);
+        HashSet<Integer> filterTypes = new HashSet<>();
+        filterTypes.add(AudioDeviceInfo.TYPE_TELEPHONY);
+        if (status != AudioManager.SUCCESS) {
+            // fail and populate microphones with unknown characteristics by device information.
+            if (status != AudioManager.ERROR_INVALID_OPERATION) {
+                Log.e(TAG, "getMicrophones failed:" + status);
+            }
+            Log.i(TAG, "fallback on device info");
+            addMicrophonesFromAudioDeviceInfo(microphones, filterTypes);
+            return microphones;
+        }
+        setPortIdForMicrophones(microphones);
+        filterTypes.add(AudioDeviceInfo.TYPE_BUILTIN_MIC);
+        addMicrophonesFromAudioDeviceInfo(microphones, filterTypes);
+        return microphones;
+    }
+
+    /**
+     * Returns a list of audio formats that corresponds to encoding formats
+     * supported on offload path for A2DP playback.
+     *
+     * @return a list of {@link BluetoothCodecConfig} objects containing encoding formats
+     * supported for offload A2DP playback
+     * @hide
+     */
+    public List<BluetoothCodecConfig> getHwOffloadEncodingFormatsSupportedForA2DP() {
+        ArrayList<Integer> formatsList = new ArrayList<Integer>();
+        ArrayList<BluetoothCodecConfig> codecConfigList = new ArrayList<BluetoothCodecConfig>();
+
+        int status = AudioSystem.getHwOffloadEncodingFormatsSupportedForA2DP(formatsList);
+        if (status != AudioManager.SUCCESS) {
+            Log.e(TAG, "getHwOffloadEncodingFormatsSupportedForA2DP failed:" + status);
+            return codecConfigList;
+        }
+
+        for (Integer format : formatsList) {
+            int btSourceCodec = AudioSystem.audioFormatToBluetoothSourceCodec(format);
+            if (btSourceCodec
+                    != BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID) {
+                codecConfigList.add(new BluetoothCodecConfig(btSourceCodec));
+            }
+        }
+        return codecConfigList;
+    }
+
+    // Since we need to calculate the changes since THE LAST NOTIFICATION, and not since the
+    // (unpredictable) last time updateAudioPortCache() was called by someone, keep a list
+    // of the ports that exist at the time of the last notification.
+    private ArrayList<AudioDevicePort> mPreviousPorts = new ArrayList<AudioDevicePort>();
+
+    /**
+     * Internal method to compute and generate add/remove messages and then send to any
+     * registered callbacks. Must be called synchronized on mDeviceCallbacks.
+     */
+    private void broadcastDeviceListChange_sync(Handler handler) {
+        int status;
+
+        // Get the new current set of ports
+        ArrayList<AudioDevicePort> current_ports = new ArrayList<AudioDevicePort>();
+        status = AudioManager.listAudioDevicePorts(current_ports);
+        if (status != AudioManager.SUCCESS) {
+            return;
+        }
+
+        if (handler != null) {
+            // This is the callback for the registration, so send the current list
+            AudioDeviceInfo[] deviceList =
+                    infoListFromPortList(current_ports, GET_DEVICES_ALL);
+            handler.sendMessage(
+                    Message.obtain(handler, MSG_DEVICES_CALLBACK_REGISTERED, deviceList));
+        } else {
+            AudioDeviceInfo[] added_devices =
+                    calcListDeltas(mPreviousPorts, current_ports, GET_DEVICES_ALL);
+            AudioDeviceInfo[] removed_devices =
+                    calcListDeltas(current_ports, mPreviousPorts, GET_DEVICES_ALL);
+            if (added_devices.length != 0 || removed_devices.length != 0) {
+                for (int i = 0; i < mDeviceCallbacks.size(); i++) {
+                    handler = mDeviceCallbacks.valueAt(i).getHandler();
+                    if (handler != null) {
+                        if (removed_devices.length != 0) {
+                            handler.sendMessage(Message.obtain(handler,
+                                    MSG_DEVICES_DEVICES_REMOVED,
+                                    removed_devices));
+                        }
+                        if (added_devices.length != 0) {
+                            handler.sendMessage(Message.obtain(handler,
+                                    MSG_DEVICES_DEVICES_ADDED,
+                                    added_devices));
+                        }
+                    }
+                }
+            }
+        }
+
+        mPreviousPorts = current_ports;
+    }
+
+    /**
+     * Handles Port list update notifications from the AudioManager
+     */
+    private class OnAmPortUpdateListener implements AudioManager.OnAudioPortUpdateListener {
+        static final String TAG = "OnAmPortUpdateListener";
+        public void onAudioPortListUpdate(AudioPort[] portList) {
+            synchronized (mDeviceCallbacks) {
+                broadcastDeviceListChange_sync(null);
+            }
+        }
+
+        /**
+         * Callback method called upon audio patch list update.
+         * Note: We don't do anything with Patches at this time, so ignore this notification.
+         * @param patchList the updated list of audio patches.
+         */
+        public void onAudioPatchListUpdate(AudioPatch[] patchList) {}
+
+        /**
+         * Callback method called when the mediaserver dies
+         */
+        public void onServiceDied() {
+            synchronized (mDeviceCallbacks) {
+                broadcastDeviceListChange_sync(null);
+            }
+        }
+    }
+
+
+    /**
+     * @hide
+     * Abstract class to receive event notification about audioserver process state.
+     */
+    @SystemApi
+    public abstract static class AudioServerStateCallback {
+        public void onAudioServerDown() { }
+        public void onAudioServerUp() { }
+    }
+
+    private Executor mAudioServerStateExec;
+    private AudioServerStateCallback mAudioServerStateCb;
+    private final Object mAudioServerStateCbLock = new Object();
+
+    private final IAudioServerStateDispatcher mAudioServerStateDispatcher =
+            new IAudioServerStateDispatcher.Stub() {
+        @Override
+        public void dispatchAudioServerStateChange(boolean state) {
+            Executor exec;
+            AudioServerStateCallback cb;
+
+            synchronized (mAudioServerStateCbLock) {
+                exec = mAudioServerStateExec;
+                cb = mAudioServerStateCb;
+            }
+
+            if ((exec == null) || (cb == null)) {
+                return;
+            }
+            if (state) {
+                exec.execute(() -> cb.onAudioServerUp());
+            } else {
+                exec.execute(() -> cb.onAudioServerDown());
+            }
+        }
+    };
+
+    /**
+     * @hide
+     * Registers a callback for notification of audio server state changes.
+     * @param executor {@link Executor} to handle the callbacks
+     * @param stateCallback the callback to receive the audio server state changes
+     *        To remove the callabck, pass a null reference for both executor and stateCallback.
+     */
+    @SystemApi
+    public void setAudioServerStateCallback(@NonNull Executor executor,
+            @NonNull AudioServerStateCallback stateCallback) {
+        if (stateCallback == null) {
+            throw new IllegalArgumentException("Illegal null AudioServerStateCallback");
+        }
+        if (executor == null) {
+            throw new IllegalArgumentException(
+                    "Illegal null Executor for the AudioServerStateCallback");
+        }
+
+        synchronized (mAudioServerStateCbLock) {
+            if (mAudioServerStateCb != null) {
+                throw new IllegalStateException(
+                    "setAudioServerStateCallback called with already registered callabck");
+            }
+            final IAudioService service = getService();
+            try {
+                service.registerAudioServerStateDispatcher(mAudioServerStateDispatcher);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            mAudioServerStateExec = executor;
+            mAudioServerStateCb = stateCallback;
+        }
+    }
+
+    /**
+     * @hide
+     * Unregisters the callback for notification of audio server state changes.
+     */
+    @SystemApi
+    public void clearAudioServerStateCallback() {
+        synchronized (mAudioServerStateCbLock) {
+            if (mAudioServerStateCb != null) {
+                final IAudioService service = getService();
+                try {
+                    service.unregisterAudioServerStateDispatcher(
+                            mAudioServerStateDispatcher);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
+            }
+            mAudioServerStateExec = null;
+            mAudioServerStateCb = null;
+        }
+    }
+
+    /**
+     * @hide
+     * Checks if native audioservice is running or not.
+     * @return true if native audioservice runs, false otherwise.
+     */
+    @SystemApi
+    public boolean isAudioServerRunning() {
+        final IAudioService service = getService();
+        try {
+            return service.isAudioServerRunning();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sets the surround sound mode.
+     *
+     * @return true if successful, otherwise false
+     */
+    @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS)
+    public boolean setEncodedSurroundMode(@EncodedSurroundOutputMode int mode) {
+        try {
+            return getService().setEncodedSurroundMode(mode);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Gets the surround sound mode.
+     *
+     * @return true if successful, otherwise false
+     */
+    public @EncodedSurroundOutputMode int getEncodedSurroundMode() {
+        try {
+            return getService().getEncodedSurroundMode(
+                    getContext().getApplicationInfo().targetSdkVersion);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Returns all surround formats.
+     * @return a map where the key is a surround format and
+     * the value indicates the surround format is enabled or not
+     */
+    @TestApi
+    @NonNull
+    public Map<Integer, Boolean> getSurroundFormats() {
+        try {
+            return getService().getSurroundFormats();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sets and persists a certain surround format as enabled or not.
+     * <p>
+     * This API is called by TvSettings surround sound menu when user enables or disables a
+     * surround sound format. This setting is persisted as global user setting.
+     * Applications should revert their changes to surround sound settings unless they intend to
+     * modify the global user settings across all apps. The framework does not auto-revert an
+     * application's settings after a lifecycle event. Audio focus is not required to apply these
+     * settings.
+     *
+     * @param enabled the required surround format state, true for enabled, false for disabled
+     * @return true if successful, otherwise false
+     */
+    @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS)
+    public boolean setSurroundFormatEnabled(
+            @AudioFormat.SurroundSoundEncoding int audioFormat, boolean enabled) {
+        try {
+            return getService().setSurroundFormatEnabled(audioFormat, enabled);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Gets whether a certain surround format is enabled or not.
+     * @param audioFormat a surround format
+     *
+     * @return whether the required surround format is enabled
+     */
+    public boolean isSurroundFormatEnabled(@AudioFormat.SurroundSoundEncoding int audioFormat) {
+        try {
+            return getService().isSurroundFormatEnabled(audioFormat);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Returns all surround formats that are reported by the connected HDMI device.
+     * The return values are not affected by calling setSurroundFormatEnabled.
+     *
+     * @return a list of surround formats
+     */
+    @TestApi
+    @NonNull
+    public List<Integer> getReportedSurroundFormats() {
+        try {
+            return getService().getReportedSurroundFormats();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Return if audio haptic coupled playback is supported or not.
+     *
+     * @return whether audio haptic playback supported.
+     */
+    public static boolean isHapticPlaybackSupported() {
+        return AudioSystem.isHapticPlaybackSupported();
+    }
+
+    /**
+     * @hide
+     * Introspection API to retrieve audio product strategies.
+     * When implementing {Car|Oem}AudioManager, use this method  to retrieve the collection of
+     * audio product strategies, which is indexed by a weakly typed index in order to be extended
+     * by OEM without any needs of AOSP patches.
+     * The {Car|Oem}AudioManager can expose API to build {@link AudioAttributes} for a given product
+     * strategy refered either by its index or human readable string. It will allow clients
+     * application to start streaming data using these {@link AudioAttributes} on the selected
+     * device by Audio Policy Engine.
+     * @return a (possibly zero-length) array of
+     *         {@see android.media.audiopolicy.AudioProductStrategy} objects.
+     */
+    @SystemApi
+    @NonNull
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public static List<AudioProductStrategy> getAudioProductStrategies() {
+        final IAudioService service = getService();
+        try {
+            return service.getAudioProductStrategies();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Introspection API to retrieve audio volume groups.
+     * When implementing {Car|Oem}AudioManager, use this method  to retrieve the collection of
+     * audio volume groups.
+     * @return a (possibly zero-length) List of
+     *         {@see android.media.audiopolicy.AudioVolumeGroup} objects.
+     */
+    @SystemApi
+    @NonNull
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public static List<AudioVolumeGroup> getAudioVolumeGroups() {
+        final IAudioService service = getService();
+        try {
+            return service.getAudioVolumeGroups();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Callback registered by client to be notified upon volume group change.
+     */
+    @SystemApi
+    public abstract static class VolumeGroupCallback {
+        /**
+         * Callback method called upon audio volume group change.
+         * @param group the group for which the volume has changed
+         */
+        public void onAudioVolumeGroupChanged(int group, int flags) {}
+    }
+
+   /**
+    * @hide
+    * Register an audio volume group change listener.
+    * @param callback the {@link VolumeGroupCallback} to register
+    */
+    @SystemApi
+    public void registerVolumeGroupCallback(
+            @NonNull Executor executor,
+            @NonNull VolumeGroupCallback callback) {
+        Preconditions.checkNotNull(executor, "executor must not be null");
+        Preconditions.checkNotNull(callback, "volume group change cb must not be null");
+        sAudioAudioVolumeGroupChangedHandler.init();
+        // TODO: make use of executor
+        sAudioAudioVolumeGroupChangedHandler.registerListener(callback);
+    }
+
+   /**
+    * @hide
+    * Unregister an audio volume group change listener.
+    * @param callback the {@link VolumeGroupCallback} to unregister
+    */
+    @SystemApi
+    public void unregisterVolumeGroupCallback(
+            @NonNull VolumeGroupCallback callback) {
+        Preconditions.checkNotNull(callback, "volume group change cb must not be null");
+        sAudioAudioVolumeGroupChangedHandler.unregisterListener(callback);
+    }
+
+    /**
+     * Return if an asset contains haptic channels or not.
+     *
+     * @param context the {@link Context} to resolve the uri.
+     * @param uri the {@link Uri} of the asset.
+     * @return true if the assert contains haptic channels.
+     * @hide
+     */
+    public static boolean hasHapticChannelsImpl(@NonNull Context context, @NonNull Uri uri) {
+        MediaExtractor extractor = new MediaExtractor();
+        try {
+            extractor.setDataSource(context, uri, null);
+            for (int i = 0; i < extractor.getTrackCount(); i++) {
+                MediaFormat format = extractor.getTrackFormat(i);
+                if (format.containsKey(MediaFormat.KEY_HAPTIC_CHANNEL_COUNT)
+                        && format.getInteger(MediaFormat.KEY_HAPTIC_CHANNEL_COUNT) > 0) {
+                    return true;
+                }
+            }
+        } catch (IOException e) {
+            Log.e(TAG, "hasHapticChannels failure:" + e);
+        }
+        return false;
+    }
+
+    /**
+     * Return if an asset contains haptic channels or not.
+     *
+     * @param context the {@link Context} to resolve the uri.
+     * @param uri the {@link Uri} of the asset.
+     * @return true if the assert contains haptic channels.
+     * @hide
+     */
+    public static boolean hasHapticChannels(@Nullable Context context, @NonNull Uri uri) {
+        Objects.requireNonNull(uri);
+
+        if (context != null) {
+            return hasHapticChannelsImpl(context, uri);
+        }
+
+        Context cachedContext = sContext.get();
+        if (cachedContext != null) {
+            if (DEBUG) {
+                Log.d(TAG, "Try to use static context to query if having haptic channels");
+            }
+            return hasHapticChannelsImpl(cachedContext, uri);
+        }
+
+        // Try with audio service context, this may fail to get correct result.
+        if (DEBUG) {
+            Log.d(TAG, "Try to use audio service context to query if having haptic channels");
+        }
+        try {
+            return getService().hasHapticChannels(uri);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set whether or not there is an active RTT call.
+     * This method should be called by Telecom service.
+     * @hide
+     * TODO: make this a @SystemApi
+     */
+    public static void setRttEnabled(boolean rttEnabled) {
+        try {
+            getService().setRttEnabled(rttEnabled);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Adjusts the volume of the most relevant stream, or the given fallback
+     * stream.
+     * <p>
+     * This method should only be used by applications that replace the
+     * platform-wide management of audio settings or the main telephony
+     * application.
+     * <p>
+     * This method has no effect if the device implements a fixed volume policy
+     * as indicated by {@link #isVolumeFixed()}.
+     * <p>This API checks if the caller has the necessary permissions based on the provided
+     * component name, uid, and pid values.
+     * See {@link #adjustSuggestedStreamVolume(int, int, int)}.
+     *
+     * @param suggestedStreamType The stream type that will be used if there
+     *         isn't a relevant stream. {@link #USE_DEFAULT_STREAM_TYPE} is
+     *         valid here.
+     * @param direction The direction to adjust the volume. One of
+     *         {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE},
+     *         {@link #ADJUST_SAME}, {@link #ADJUST_MUTE},
+     *         {@link #ADJUST_UNMUTE}, or {@link #ADJUST_TOGGLE_MUTE}.
+     * @param flags One or more flags.
+     * @param packageName the package name of client application
+     * @param uid the uid of client application
+     * @param pid the pid of client application
+     * @param targetSdkVersion the target sdk version of client application
+     * @see #adjustVolume(int, int)
+     * @see #adjustStreamVolume(int, int, int)
+     * @see #setStreamVolume(int, int, int)
+     * @see #isVolumeFixed()
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void adjustSuggestedStreamVolumeForUid(int suggestedStreamType, int direction, int flags,
+            @NonNull String packageName, int uid, int pid, int targetSdkVersion) {
+        try {
+            getService().adjustSuggestedStreamVolumeForUid(suggestedStreamType, direction, flags,
+                    packageName, uid, pid, UserHandle.getUserHandleForUid(uid), targetSdkVersion);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Adjusts the volume of a particular stream by one step in a direction.
+     * <p>
+     * This method should only be used by applications that replace the platform-wide
+     * management of audio settings or the main telephony application.
+     * <p>This method has no effect if the device implements a fixed volume policy
+     * as indicated by {@link #isVolumeFixed()}.
+     * <p>From N onward, ringer mode adjustments that would toggle Do Not Disturb are not allowed
+     * unless the app has been granted Do Not Disturb Access.
+     * See {@link NotificationManager#isNotificationPolicyAccessGranted()}.
+     * <p>This API checks if the caller has the necessary permissions based on the provided
+     * component name, uid, and pid values.
+     * See {@link #adjustStreamVolume(int, int, int)}.
+     *
+     * @param streamType The stream type to adjust. One of {@link #STREAM_VOICE_CALL},
+     *         {@link #STREAM_SYSTEM}, {@link #STREAM_RING}, {@link #STREAM_MUSIC},
+     *         {@link #STREAM_ALARM} or {@link #STREAM_ACCESSIBILITY}.
+     * @param direction The direction to adjust the volume. One of
+     *         {@link #ADJUST_LOWER}, {@link #ADJUST_RAISE}, or
+     *         {@link #ADJUST_SAME}.
+     * @param flags One or more flags.
+     * @param packageName the package name of client application
+     * @param uid the uid of client application
+     * @param pid the pid of client application
+     * @param targetSdkVersion the target sdk version of client application
+     * @see #adjustVolume(int, int)
+     * @see #setStreamVolume(int, int, int)
+     * @throws SecurityException if the adjustment triggers a Do Not Disturb change
+     *         and the caller is not granted notification policy access.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void adjustStreamVolumeForUid(int streamType, int direction, int flags,
+            @NonNull String packageName, int uid, int pid, int targetSdkVersion) {
+        try {
+            getService().adjustStreamVolumeForUid(streamType, direction, flags, packageName, uid,
+                    pid, UserHandle.getUserHandleForUid(uid), targetSdkVersion);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sets the volume index for a particular stream.
+     * <p>This method has no effect if the device implements a fixed volume policy
+     * as indicated by {@link #isVolumeFixed()}.
+     * <p>From N onward, volume adjustments that would toggle Do Not Disturb are not allowed unless
+     * the app has been granted Do Not Disturb Access.
+     * See {@link NotificationManager#isNotificationPolicyAccessGranted()}.
+     * <p>This API checks if the caller has the necessary permissions based on the provided
+     * component name, uid, and pid values.
+     * See {@link #setStreamVolume(int, int, int)}.
+     *
+     * @param streamType The stream whose volume index should be set.
+     * @param index The volume index to set. See
+     *         {@link #getStreamMaxVolume(int)} for the largest valid value.
+     * @param flags One or more flags.
+     * @param packageName the package name of client application
+     * @param uid the uid of client application
+     * @param pid the pid of client application
+     * @param targetSdkVersion the target sdk version of client application
+     * @see #getStreamMaxVolume(int)
+     * @see #getStreamVolume(int)
+     * @see #isVolumeFixed()
+     * @throws SecurityException if the volume change triggers a Do Not Disturb change
+     *         and the caller is not granted notification policy access.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void setStreamVolumeForUid(int streamType, int index, int flags,
+            @NonNull String packageName, int uid, int pid, int targetSdkVersion) {
+        try {
+            getService().setStreamVolumeForUid(streamType, index, flags, packageName, uid, pid,
+                    UserHandle.getUserHandleForUid(uid), targetSdkVersion);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+
+    /** @hide
+     * TODO: make this a @SystemApi */
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public void setMultiAudioFocusEnabled(boolean enabled) {
+        try {
+            getService().setMultiAudioFocusEnabled(enabled);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+
+    /**
+     * Retrieves the Hardware A/V synchronization ID corresponding to the given audio session ID.
+     * For more details on Hardware A/V synchronization please refer to
+     *  <a href="https://source.android.com/devices/tv/multimedia-tunneling/">
+     * media tunneling documentation</a>.
+     * @param sessionId the audio session ID for which the HW A/V sync ID is retrieved.
+     * @return the HW A/V sync ID for this audio session (an integer different from 0).
+     * @throws UnsupportedOperationException if HW A/V synchronization is not supported.
+     */
+    public int getAudioHwSyncForSession(int sessionId) {
+        int hwSyncId = AudioSystem.getAudioHwSyncForSession(sessionId);
+        if (hwSyncId == AudioSystem.AUDIO_HW_SYNC_INVALID) {
+            throw new UnsupportedOperationException("HW A/V synchronization is not supported.");
+        }
+        return hwSyncId;
+    }
+
+    /**
+     * Selects the audio device that should be used for communication use cases, for instance voice
+     * or video calls. This method can be used by voice or video chat applications to select a
+     * different audio device than the one selected by default by the platform.
+     * <p>The device selection is expressed as an {@link AudioDeviceInfo} among devices returned by
+     * {@link #getAvailableCommunicationDevices()}.
+     * The selection is active as long as the requesting application process lives, until
+     * {@link #clearCommunicationDevice} is called or until the device is disconnected.
+     * It is therefore important for applications to clear the request when a call ends or the
+     * the requesting activity or service is stopped or destroyed.
+     * <p>In case of simultaneous requests by multiple applications the priority is given to the
+     * application currently controlling the audio mode (see {@link #setMode(int)}). This is the
+     * latest application having selected mode {@link #MODE_IN_COMMUNICATION} or mode
+     * {@link #MODE_IN_CALL}. Note that <code>MODE_IN_CALL</code> can only be selected by the main
+     * telephony application with permission
+     * {@link android.Manifest.permission#MODIFY_PHONE_STATE}.
+     * <p> If the requested devices is not currently available, the request will be rejected and
+     * the method will return false.
+     * <p>This API replaces the following deprecated APIs:
+     * <ul>
+     *   <li> {@link #startBluetoothSco()}
+     *   <li> {@link #stopBluetoothSco()}
+     *   <li> {@link #setSpeakerphoneOn(boolean)}
+     * </ul>
+     * <h4>Example</h4>
+     * <p>The example below shows how to enable and disable speakerphone mode.
+     * <pre class="prettyprint">
+     * // Get an AudioManager instance
+     * AudioManager audioManager = Context.getSystemService(AudioManager.class);
+     * AudioDeviceInfo speakerDevice = null;
+     * List<AudioDeviceInfo> devices = audioManager.getAvailableCommunicationDevices();
+     * for (AudioDeviceInfo device : devices) {
+     *     if (device.getType() == AudioDeviceInfo.TYPE_BUILTIN_SPEAKER) {
+     *         speakerDevice = device;
+     *         break;
+     *     }
+     * }
+     * if (speakerDevice != null) {
+     *     // Turn speakerphone ON.
+     *     boolean result = audioManager.setCommunicationDevice(speakerDevice);
+     *     if (!result) {
+     *         // Handle error.
+     *     }
+     *     // Turn speakerphone OFF.
+     *     audioManager.clearCommunicationDevice();
+     * }
+     * </pre>
+     * @param device the requested audio device.
+     * @return <code>true</code> if the request was accepted, <code>false</code> otherwise.
+     * @throws IllegalArgumentException If an invalid device is specified.
+     */
+    public boolean setCommunicationDevice(@NonNull AudioDeviceInfo device) {
+        Objects.requireNonNull(device);
+        try {
+            if (device.getId() == 0) {
+                throw new IllegalArgumentException("In valid device: " + device);
+            }
+            return getService().setCommunicationDevice(mICallBack, device.getId());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Cancels previous communication device selection made with
+     * {@link #setCommunicationDevice(AudioDeviceInfo)}.
+     */
+    public void clearCommunicationDevice() {
+        try {
+            getService().setCommunicationDevice(mICallBack, 0);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns currently selected audio device for communication.
+     * <p>This API replaces the following deprecated APIs:
+     * <ul>
+     *   <li> {@link #isBluetoothScoOn()}
+     *   <li> {@link #isSpeakerphoneOn()}
+     * </ul>
+     * @return an {@link AudioDeviceInfo} indicating which audio device is
+     * currently selected for communication use cases. Can be null on platforms
+     * not supporting {@link android.content.pm.PackageManager#FEATURE_TELEPHONY}.
+     * is used.
+     */
+    @Nullable
+    public AudioDeviceInfo getCommunicationDevice() {
+        try {
+            return getDeviceForPortId(
+                    getService().getCommunicationDevice(), GET_DEVICES_OUTPUTS);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns a list of audio devices that can be selected for communication use cases via
+     * {@link #setCommunicationDevice(AudioDeviceInfo)}.
+     * @return a list of {@link AudioDeviceInfo} suitable for use with setCommunicationDevice().
+     */
+    @NonNull
+    public List<AudioDeviceInfo> getAvailableCommunicationDevices() {
+        try {
+            ArrayList<AudioDeviceInfo> devices = new ArrayList<>();
+            int[] portIds = getService().getAvailableCommunicationDeviceIds();
+            for (int portId : portIds) {
+                AudioDeviceInfo device = getDeviceForPortId(portId, GET_DEVICES_OUTPUTS);
+                if (device == null) {
+                    continue;
+                }
+                devices.add(device);
+            }
+            return devices;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * @hide
+     * Returns an {@link AudioDeviceInfo} corresponding to a connected device of the type provided.
+     * The type must be a valid output type defined in <code>AudioDeviceInfo</code> class,
+     * for instance {@link AudioDeviceInfo#TYPE_BUILTIN_SPEAKER}.
+     * The method will return null if no device of the provided type is connected.
+     * If more than one device of the provided type is connected, an object corresponding to the
+     * first device encountered in the enumeration list will be returned.
+     * @param deviceType The device device for which an <code>AudioDeviceInfo</code>
+     *                   object is queried.
+     * @return An AudioDeviceInfo object or null if no device with the requested type is connected.
+     * @throws IllegalArgumentException If an invalid device type is specified.
+     */
+    @TestApi
+    @Nullable
+    public static AudioDeviceInfo getDeviceInfoFromType(
+            @AudioDeviceInfo.AudioDeviceTypeOut int deviceType) {
+        return getDeviceInfoFromTypeAndAddress(deviceType, null);
+    }
+
+        /**
+     * @hide
+     * Returns an {@link AudioDeviceInfo} corresponding to a connected device of the type and
+     * address provided.
+     * The type must be a valid output type defined in <code>AudioDeviceInfo</code> class,
+     * for instance {@link AudioDeviceInfo#TYPE_BUILTIN_SPEAKER}.
+     * If a null address is provided, the matching will happen on the type only.
+     * The method will return null if no device of the provided type and address is connected.
+     * If more than one device of the provided type is connected, an object corresponding to the
+     * first device encountered in the enumeration list will be returned.
+     * @param type The device device for which an <code>AudioDeviceInfo</code>
+     *             object is queried.
+     * @param address The device address for which an <code>AudioDeviceInfo</code>
+     *                object is queried or null if requesting match on type only.
+     * @return An AudioDeviceInfo object or null if no matching device is connected.
+     * @throws IllegalArgumentException If an invalid device type is specified.
+     */
+    @Nullable
+    public static AudioDeviceInfo getDeviceInfoFromTypeAndAddress(
+            @AudioDeviceInfo.AudioDeviceTypeOut int type, @Nullable String address) {
+        AudioDeviceInfo[] devices = getDevicesStatic(GET_DEVICES_OUTPUTS);
+        AudioDeviceInfo deviceForType = null;
+        for (AudioDeviceInfo device : devices) {
+            if (device.getType() == type) {
+                deviceForType = device;
+                if (address == null || address.equals(device.getAddress())) {
+                    return device;
+                }
+            }
+        }
+        return deviceForType;
+    }
+
+    /**
+     * Listener registered by client to be notified upon communication audio device change.
+     * See {@link #setCommunicationDevice(AudioDeviceInfo)}.
+     */
+    public interface OnCommunicationDeviceChangedListener {
+        /**
+         * Callback method called upon communication audio device change.
+         * @param device the audio device requested for communication use cases.
+         *               Can be null on platforms not supporting
+         *               {@link android.content.pm.PackageManager#FEATURE_TELEPHONY}.
+         */
+        void onCommunicationDeviceChanged(@Nullable AudioDeviceInfo device);
+    }
+
+    /**
+     * Adds a listener for being notified of changes to the communication audio device.
+     * See {@link #setCommunicationDevice(AudioDeviceInfo)}.
+     * @param executor
+     * @param listener
+     */
+    public void addOnCommunicationDeviceChangedListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnCommunicationDeviceChangedListener listener) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(listener);
+        synchronized (mCommDevListenerLock) {
+            if (hasCommDevListener(listener)) {
+                throw new IllegalArgumentException(
+                        "attempt to call addOnCommunicationDeviceChangedListener() "
+                                + "on a previously registered listener");
+            }
+            // lazy initialization of the list of strategy-preferred device listener
+            if (mCommDevListeners == null) {
+                mCommDevListeners = new ArrayList<>();
+            }
+            final int oldCbCount = mCommDevListeners.size();
+            mCommDevListeners.add(new CommDevListenerInfo(listener, executor));
+            if (oldCbCount == 0 && mCommDevListeners.size() > 0) {
+                // register binder for callbacks
+                if (mCommDevDispatcherStub == null) {
+                    mCommDevDispatcherStub = new CommunicationDeviceDispatcherStub();
+                }
+                try {
+                    getService().registerCommunicationDeviceDispatcher(mCommDevDispatcherStub);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
+            }
+        }
+    }
+
+    /**
+     * Removes a previously added listener of changes to the communication audio device.
+     * See {@link #setCommunicationDevice(AudioDeviceInfo)}.
+     * @param listener
+     */
+    public void removeOnCommunicationDeviceChangedListener(
+            @NonNull OnCommunicationDeviceChangedListener listener) {
+        Objects.requireNonNull(listener);
+        synchronized (mCommDevListenerLock) {
+            if (!removeCommDevListener(listener)) {
+                throw new IllegalArgumentException(
+                        "attempt to call removeOnCommunicationDeviceChangedListener() "
+                                + "on an unregistered listener");
+            }
+            if (mCommDevListeners.size() == 0) {
+                // unregister binder for callbacks
+                try {
+                    getService().unregisterCommunicationDeviceDispatcher(
+                            mCommDevDispatcherStub);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                } finally {
+                    mCommDevDispatcherStub = null;
+                    mCommDevListeners = null;
+                }
+            }
+        }
+    }
+
+    private final Object mCommDevListenerLock = new Object();
+    /**
+     * List of listeners for preferred device for strategy and their associated Executor.
+     * List is lazy-initialized on first registration
+     */
+    @GuardedBy("mCommDevListenerLock")
+    private @Nullable ArrayList<CommDevListenerInfo> mCommDevListeners;
+
+    private static class CommDevListenerInfo {
+        final @NonNull OnCommunicationDeviceChangedListener mListener;
+        final @NonNull Executor mExecutor;
+
+        CommDevListenerInfo(OnCommunicationDeviceChangedListener listener, Executor exe) {
+            mListener = listener;
+            mExecutor = exe;
+        }
+    }
+
+    @GuardedBy("mCommDevListenerLock")
+    private CommunicationDeviceDispatcherStub mCommDevDispatcherStub;
+
+    private final class CommunicationDeviceDispatcherStub
+            extends ICommunicationDeviceDispatcher.Stub {
+
+        @Override
+        public void dispatchCommunicationDeviceChanged(int portId) {
+            // make a shallow copy of listeners so callback is not executed under lock
+            final ArrayList<CommDevListenerInfo> commDevListeners;
+            synchronized (mCommDevListenerLock) {
+                if (mCommDevListeners == null || mCommDevListeners.size() == 0) {
+                    return;
+                }
+                commDevListeners = (ArrayList<CommDevListenerInfo>) mCommDevListeners.clone();
+            }
+            AudioDeviceInfo device = getDeviceForPortId(portId, GET_DEVICES_OUTPUTS);
+            final long ident = Binder.clearCallingIdentity();
+            try {
+                for (CommDevListenerInfo info : commDevListeners) {
+                    info.mExecutor.execute(() ->
+                            info.mListener.onCommunicationDeviceChanged(device));
+                }
+            } finally {
+                Binder.restoreCallingIdentity(ident);
+            }
+        }
+    }
+
+    @GuardedBy("mCommDevListenerLock")
+    private @Nullable CommDevListenerInfo getCommDevListenerInfo(
+            OnCommunicationDeviceChangedListener listener) {
+        if (mCommDevListeners == null) {
+            return null;
+        }
+        for (CommDevListenerInfo info : mCommDevListeners) {
+            if (info.mListener == listener) {
+                return info;
+            }
+        }
+        return null;
+    }
+
+    @GuardedBy("mCommDevListenerLock")
+    private boolean hasCommDevListener(OnCommunicationDeviceChangedListener listener) {
+        return getCommDevListenerInfo(listener) != null;
+    }
+
+    @GuardedBy("mCommDevListenerLock")
+    /**
+     * @return true if the listener was removed from the list
+     */
+    private boolean removeCommDevListener(OnCommunicationDeviceChangedListener listener) {
+        final CommDevListenerInfo infoToRemove = getCommDevListenerInfo(listener);
+        if (infoToRemove != null) {
+            mCommDevListeners.remove(infoToRemove);
+            return true;
+        }
+        return false;
+    }
+
+    //---------------------------------------------------------
+    // Inner classes
+    //--------------------
+    /**
+     * Helper class to handle the forwarding of native events to the appropriate listener
+     * (potentially) handled in a different thread.
+     */
+    private class NativeEventHandlerDelegate {
+        private final Handler mHandler;
+
+        NativeEventHandlerDelegate(final AudioDeviceCallback callback,
+                                   Handler handler) {
+            // find the looper for our new event handler
+            Looper looper;
+            if (handler != null) {
+                looper = handler.getLooper();
+            } else {
+                // no given handler, use the looper the addListener call was called in
+                looper = Looper.getMainLooper();
+            }
+
+            // construct the event handler with this looper
+            if (looper != null) {
+                // implement the event handler delegate
+                mHandler = new Handler(looper) {
+                    @Override
+                    public void handleMessage(Message msg) {
+                        switch(msg.what) {
+                        case MSG_DEVICES_CALLBACK_REGISTERED:
+                        case MSG_DEVICES_DEVICES_ADDED:
+                            if (callback != null) {
+                                callback.onAudioDevicesAdded((AudioDeviceInfo[])msg.obj);
+                            }
+                            break;
+
+                        case MSG_DEVICES_DEVICES_REMOVED:
+                            if (callback != null) {
+                                callback.onAudioDevicesRemoved((AudioDeviceInfo[])msg.obj);
+                            }
+                           break;
+
+                        default:
+                            Log.e(TAG, "Unknown native event type: " + msg.what);
+                            break;
+                        }
+                    }
+                };
+            } else {
+                mHandler = null;
+            }
+        }
+
+        Handler getHandler() {
+            return mHandler;
+        }
+    }
+}
diff --git a/android/media/AudioManagerInternal.java b/android/media/AudioManagerInternal.java
new file mode 100644
index 0000000..cb887f2
--- /dev/null
+++ b/android/media/AudioManagerInternal.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2014 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.util.IntArray;
+
+import com.android.server.LocalServices;
+
+/**
+ * Class for system services to access extra AudioManager functionality. The
+ * AudioService is responsible for registering an implementation with
+ * {@link LocalServices}.
+ *
+ * @hide
+ */
+public abstract class AudioManagerInternal {
+
+    public abstract void setRingerModeDelegate(RingerModeDelegate delegate);
+
+    public abstract int getRingerModeInternal();
+
+    public abstract void setRingerModeInternal(int ringerMode, String caller);
+
+    public abstract void silenceRingerModeInternal(String caller);
+
+    public abstract void updateRingerModeAffectedStreamsInternal();
+
+    /**
+     * Notify the UID of the currently active {@link android.service.voice.HotwordDetectionService}.
+     *
+     * <p>The caller is expected to take care of any performance implications, e.g. by using a
+     * background thread to call this method.</p>
+     *
+     * @param uid UID of the currently active service or {@link android.os.Process#INVALID_UID} if
+     *            none.
+     */
+    public abstract void setHotwordDetectionServiceUid(int uid);
+
+    public abstract void setAccessibilityServiceUids(IntArray uids);
+
+    /**
+     * Called by {@link com.android.server.inputmethod.InputMethodManagerService} to notify the UID
+     * of the currently used {@link android.inputmethodservice.InputMethodService}.
+     *
+     * <p>The caller is expected to take care of any performance implications, e.g. by using a
+     * background thread to call this method.</p>
+     *
+     * @param uid UID of the currently used {@link android.inputmethodservice.InputMethodService}.
+     *            {@link android.os.Process#INVALID_UID} if no IME is active.
+     */
+    public abstract void setInputMethodServiceUid(int uid);
+
+    public interface RingerModeDelegate {
+        /** Called when external ringer mode is evaluated, returns the new internal ringer mode */
+        int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew, String caller,
+                int ringerModeInternal, VolumePolicy policy);
+
+        /** Called when internal ringer mode is evaluated, returns the new external ringer mode */
+        int onSetRingerModeInternal(int ringerModeOld, int ringerModeNew, String caller,
+                int ringerModeExternal, VolumePolicy policy);
+
+        boolean canVolumeDownEnterSilent();
+
+        int getRingerModeAffectedStreams(int streams);
+    }
+}
diff --git a/android/media/AudioMetadata.java b/android/media/AudioMetadata.java
new file mode 100644
index 0000000..ca175b4
--- /dev/null
+++ b/android/media/AudioMetadata.java
@@ -0,0 +1,896 @@
+/*
+ * Copyright (C) 2020 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.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.Log;
+import android.util.Pair;
+
+import java.lang.reflect.ParameterizedType;
+import java.nio.BufferUnderflowException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * AudioMetadata class is used to manage typed key-value pairs for
+ * configuration and capability requests within the Audio Framework.
+ */
+public final class AudioMetadata {
+    private static final String TAG = "AudioMetadata";
+
+    /**
+     * Key interface for the {@code AudioMetadata} map.
+     *
+     * <p>The presence of this {@code Key} interface on an object allows
+     * it to reference metadata in the Audio Framework.</p>
+     *
+     * <p>Vendors are allowed to implement this {@code Key} interface for their debugging or
+     * private application use. To avoid name conflicts, vendor key names should be qualified by
+     * the vendor company name followed by a dot; for example, "vendorCompany.someVolume".</p>
+     *
+     * @param <T> type of value associated with {@code Key}.
+     */
+    /*
+     * Internal details:
+     * Conceivably metadata keys exposing multiple interfaces
+     * could be eligible to work in multiple framework domains.
+     */
+    public interface Key<T> {
+        /**
+         * Returns the internal name of the key.  The name should be unique in the
+         * {@code AudioMetadata} namespace.  Vendors should prefix their keys with
+         * the company name followed by a dot.
+         */
+        @NonNull
+        String getName();
+
+        /**
+         * Returns the class type {@code T} of the associated value.  Valid class types for
+         * {@link android.os.Build.VERSION_CODES#R} are
+         * {@code Integer.class}, {@code Long.class}, {@code Float.class}, {@code Double.class},
+         * {@code String.class}.
+         */
+        @NonNull
+        Class<T> getValueClass();
+
+        // TODO: consider adding bool isValid(@NonNull T value)
+    }
+
+    /**
+     * Creates a {@link AudioMetadataMap} suitable for adding keys.
+     * @return an empty {@link AudioMetadataMap} instance.
+     */
+    @NonNull
+    public static AudioMetadataMap createMap() {
+        return new BaseMap();
+    }
+
+    /**
+     * A container class for AudioMetadata Format keys.
+     *
+     * @see AudioTrack.OnCodecFormatChangedListener
+     */
+    public static class Format {
+        // The key name strings used here must match that of the native framework, but are
+        // allowed to change between API releases.  This due to the Java specification
+        // on what is a compile time constant.
+        //
+        // Key<?> are final variables but not constant variables (per Java spec 4.12.4) because
+        // the keys are not a primitive type nor a String initialized by a constant expression.
+        // Hence (per Java spec 13.1.3), they are not resolved at compile time,
+        // rather are picked up by applications at run time.
+        //
+        // So the contractual API behavior of AudioMetadata.Key<> are different than Strings
+        // initialized by a constant expression (for example MediaFormat.KEY_*).
+
+        // See MediaFormat
+        /**
+         * A key representing the bitrate of the encoded stream used in
+         *
+         * If the stream is variable bitrate, this is the average bitrate of the stream.
+         * The unit is bits per second.
+         *
+         * An Integer value.
+         *
+         * @see MediaFormat#KEY_BIT_RATE
+         */
+        @NonNull public static final Key<Integer> KEY_BIT_RATE =
+                createKey("bitrate", Integer.class);
+
+        /**
+         * A key representing the audio channel mask of the stream.
+         *
+         * An Integer value.
+         *
+         * @see AudioTrack#getChannelConfiguration()
+         * @see MediaFormat#KEY_CHANNEL_MASK
+         */
+        @NonNull public static final Key<Integer> KEY_CHANNEL_MASK =
+                createKey("channel-mask", Integer.class);
+
+
+        /**
+         * A key representing the codec mime string.
+         *
+         * A String value.
+         *
+         * @see MediaFormat#KEY_MIME
+         */
+        @NonNull public static final Key<String> KEY_MIME = createKey("mime", String.class);
+
+        /**
+         * A key representing the audio sample rate in Hz of the stream.
+         *
+         * An Integer value.
+         *
+         * @see AudioFormat#getSampleRate()
+         * @see MediaFormat#KEY_SAMPLE_RATE
+         */
+        @NonNull public static final Key<Integer> KEY_SAMPLE_RATE =
+                createKey("sample-rate", Integer.class);
+
+        // Unique to Audio
+
+        /**
+         * A key representing the bit width of an element of decoded data.
+         *
+         * An Integer value.
+         */
+        @NonNull public static final Key<Integer> KEY_BIT_WIDTH =
+                createKey("bit-width", Integer.class);
+
+        /**
+         * A key representing the presence of Atmos in an E-AC3 stream.
+         *
+         * A Boolean value which is true if Atmos is present in an E-AC3 stream.
+         */
+
+        // Since Boolean isn't handled by Parceling, we translate
+        // internally to KEY_HAS_ATMOS when sending through JNI.
+        // Consider deprecating this key for KEY_HAS_ATMOS in the future.
+        //
+        @NonNull public static final Key<Boolean> KEY_ATMOS_PRESENT =
+                createKey("atmos-present", Boolean.class);
+
+        /**
+         * A key representing the presence of Atmos in an E-AC3 stream.
+         *
+         * An Integer value which is nonzero if Atmos is present in an E-AC3 stream.
+         * The integer representation is used for communication to the native side.
+         * @hide
+         */
+        @NonNull public static final Key<Integer> KEY_HAS_ATMOS =
+                createKey("has-atmos", Integer.class);
+
+        /**
+         * A key representing the audio encoding used for the stream.
+         * This is the same encoding used in {@link AudioFormat#getEncoding()}.
+         *
+         * An Integer value.
+         *
+         * @see AudioFormat#getEncoding()
+         */
+        @NonNull public static final Key<Integer> KEY_AUDIO_ENCODING =
+                createKey("audio-encoding", Integer.class);
+
+
+        /**
+         * A key representing the audio presentation id being decoded by a next generation
+         * audio decoder.
+         *
+         * An Integer value representing presentation id.
+         *
+         * @see AudioPresentation#getPresentationId()
+         */
+        @NonNull public static final Key<Integer> KEY_PRESENTATION_ID =
+                createKey("presentation-id", Integer.class);
+
+         /**
+         * A key representing the audio program id being decoded by a next generation
+         * audio decoder.
+         *
+         * An Integer value representing program id.
+         *
+         * @see AudioPresentation#getProgramId()
+         */
+        @NonNull public static final Key<Integer> KEY_PROGRAM_ID =
+                createKey("program-id", Integer.class);
+
+
+         /**
+         * A key representing the audio presentation content classifier being rendered
+         * by a next generation audio decoder.
+         *
+         * An Integer value representing presentation content classifier.
+         *
+         * @see AudioPresentation.ContentClassifier
+         * One of {@link AudioPresentation#CONTENT_UNKNOWN},
+         *     {@link AudioPresentation#CONTENT_MAIN},
+         *     {@link AudioPresentation#CONTENT_MUSIC_AND_EFFECTS},
+         *     {@link AudioPresentation#CONTENT_VISUALLY_IMPAIRED},
+         *     {@link AudioPresentation#CONTENT_HEARING_IMPAIRED},
+         *     {@link AudioPresentation#CONTENT_DIALOG},
+         *     {@link AudioPresentation#CONTENT_COMMENTARY},
+         *     {@link AudioPresentation#CONTENT_EMERGENCY},
+         *     {@link AudioPresentation#CONTENT_VOICEOVER}.
+         */
+        @NonNull public static final Key<Integer> KEY_PRESENTATION_CONTENT_CLASSIFIER =
+                createKey("presentation-content-classifier", Integer.class);
+
+        /**
+         * A key representing the audio presentation language being rendered by a next
+         * generation audio decoder.
+         *
+         * A String value representing ISO 639-2 (three letter code).
+         *
+         * @see AudioPresentation#getLocale()
+         */
+        @NonNull public static final Key<String> KEY_PRESENTATION_LANGUAGE =
+                createKey("presentation-language", String.class);
+
+        private Format() {} // delete constructor
+    }
+
+    /////////////////////////////////////////////////////////////////////////
+    // Hidden methods and functions.
+
+    /**
+     * Returns a Key object with the correct interface for the AudioMetadata.
+     *
+     * An interface with the same name and type will be treated as
+     * identical for the purposes of value storage, even though
+     * other methods or hidden parameters may return different values.
+     *
+     * @param name The name of the key.
+     * @param type The class type of the value represented by the key.
+     * @param <T> The type of value.
+     * @return a new key interface.
+     *
+     * Creating keys is currently only allowed by the Framework.
+     * @hide
+     */
+    @NonNull
+    public static <T> Key<T> createKey(@NonNull String name, @NonNull Class<T> type) {
+        // Implementation specific.
+        return new Key<T>() {
+            private final String mName = name;
+            private final Class<T> mType = type;
+
+            @Override
+            @NonNull
+            public String getName() {
+                return mName;
+            }
+
+            @Override
+            @NonNull
+            public Class<T> getValueClass() {
+                return mType;
+            }
+
+            /**
+             * Return true if the name and the type of two objects are the same.
+             */
+            @Override
+            public boolean equals(Object obj) {
+                if (obj == this) {
+                    return true;
+                }
+                if (!(obj instanceof Key)) {
+                    return false;
+                }
+                Key<?> other = (Key<?>) obj;
+                return mName.equals(other.getName()) && mType.equals(other.getValueClass());
+            }
+
+            @Override
+            public int hashCode() {
+                return Objects.hash(mName, mType);
+            }
+        };
+    }
+
+    /**
+     * @hide
+     *
+     * AudioMetadata is based on interfaces in order to allow multiple inheritance
+     * and maximum flexibility in implementation.
+     *
+     * Here, we provide a simple implementation of {@link Map} interface;
+     * Note that the Keys are not specific to this Map implementation.
+     *
+     * It is possible to require the keys to be of a certain class
+     * before allowing a set or get operation.
+     */
+    public static class BaseMap implements AudioMetadataMap {
+        @Override
+        public <T> boolean containsKey(@NonNull Key<T> key) {
+            Pair<Key<?>, Object> valuePair = mHashMap.get(pairFromKey(key));
+            return valuePair != null;
+        }
+
+        @Override
+        @NonNull
+        public AudioMetadataMap dup() {
+            BaseMap map = new BaseMap();
+            map.mHashMap.putAll(this.mHashMap);
+            return map;
+        }
+
+        @Override
+        @Nullable
+        public <T> T get(@NonNull Key<T> key) {
+            Pair<Key<?>, Object> valuePair = mHashMap.get(pairFromKey(key));
+            return (T) getValueFromValuePair(valuePair);
+        }
+
+        @Override
+        @NonNull
+        public Set<Key<?>> keySet() {
+            HashSet<Key<?>> set = new HashSet();
+            for (Pair<Key<?>, Object> pair : mHashMap.values()) {
+                set.add(pair.first);
+            }
+            return set;
+        }
+
+        @Override
+        @Nullable
+        public <T> T remove(@NonNull Key<T> key) {
+            Pair<Key<?>, Object> valuePair = mHashMap.remove(pairFromKey(key));
+            return (T) getValueFromValuePair(valuePair);
+        }
+
+        @Override
+        @Nullable
+        public <T> T set(@NonNull Key<T> key, @NonNull T value) {
+            Objects.requireNonNull(value);
+            Pair<Key<?>, Object> valuePair = mHashMap
+                    .put(pairFromKey(key), new Pair<Key<?>, Object>(key, value));
+            return (T) getValueFromValuePair(valuePair);
+        }
+
+        @Override
+        public int size() {
+            return mHashMap.size();
+        }
+
+        /**
+         * Return true if the object is a BaseMap and the content from two BaseMap are the same.
+         * Note: Need to override the equals functions of Key<T> for HashMap comparison.
+         */
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == this) {
+                return true;
+            }
+            if (!(obj instanceof BaseMap)) {
+                return false;
+            }
+            BaseMap other = (BaseMap) obj;
+            return mHashMap.equals(other.mHashMap);
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mHashMap);
+        }
+
+        /*
+         * Implementation specific.
+         *
+         * To store the value in the HashMap we need to convert the Key interface
+         * to a hashcode() / equals() compliant Pair.
+         */
+        @NonNull
+        private static <T> Pair<String, Class<?>> pairFromKey(@NonNull Key<T> key) {
+            Objects.requireNonNull(key);
+            return new Pair<String, Class<?>>(key.getName(), key.getValueClass());
+        }
+
+        /*
+         * Implementation specific.
+         *
+         * We store in a Pair (valuePair) the key along with the Object value.
+         * This helper returns the Object value from the value pair.
+         */
+        @Nullable
+        private static Object getValueFromValuePair(@Nullable Pair<Key<?>, Object> valuePair) {
+            if (valuePair == null) {
+                return null;
+            }
+            return valuePair.second;
+        }
+
+        /*
+         * Implementation specific.
+         *
+         * We use a HashMap to back the AudioMetadata BaseMap object.
+         * This is not locked, so concurrent reads are permitted if all threads
+         * have a ReadMap; this is risky with a Map.
+         */
+        private final HashMap<Pair<String, Class<?>>, Pair<Key<?>, Object>> mHashMap =
+                new HashMap();
+    }
+
+    // The audio metadata object type index should be kept the same as
+    // the ones in audio_utils::metadata::metadata_types
+    private static final int AUDIO_METADATA_OBJ_TYPE_NONE = 0;
+    private static final int AUDIO_METADATA_OBJ_TYPE_INT = 1;
+    private static final int AUDIO_METADATA_OBJ_TYPE_LONG = 2;
+    private static final int AUDIO_METADATA_OBJ_TYPE_FLOAT = 3;
+    private static final int AUDIO_METADATA_OBJ_TYPE_DOUBLE = 4;
+    private static final int AUDIO_METADATA_OBJ_TYPE_STRING = 5;
+    // BaseMap is corresponding to audio_utils::metadata::Data
+    private static final int AUDIO_METADATA_OBJ_TYPE_BASEMAP = 6;
+
+    private static final HashMap<Class, Integer> AUDIO_METADATA_OBJ_TYPES = new HashMap<>() {{
+            put(Integer.class, AUDIO_METADATA_OBJ_TYPE_INT);
+            put(Long.class, AUDIO_METADATA_OBJ_TYPE_LONG);
+            put(Float.class, AUDIO_METADATA_OBJ_TYPE_FLOAT);
+            put(Double.class, AUDIO_METADATA_OBJ_TYPE_DOUBLE);
+            put(String.class, AUDIO_METADATA_OBJ_TYPE_STRING);
+            put(BaseMap.class, AUDIO_METADATA_OBJ_TYPE_BASEMAP);
+        }};
+
+    private static final Charset AUDIO_METADATA_CHARSET = StandardCharsets.UTF_8;
+
+    /**
+     * An auto growing byte buffer
+     */
+    private static class AutoGrowByteBuffer {
+        private static final int INTEGER_BYTE_COUNT = Integer.SIZE / Byte.SIZE;
+        private static final int LONG_BYTE_COUNT = Long.SIZE / Byte.SIZE;
+        private static final int FLOAT_BYTE_COUNT = Float.SIZE / Byte.SIZE;
+        private static final int DOUBLE_BYTE_COUNT = Double.SIZE / Byte.SIZE;
+
+        private ByteBuffer mBuffer;
+
+        AutoGrowByteBuffer() {
+            this(1024);
+        }
+
+        AutoGrowByteBuffer(@IntRange(from = 0) int initialCapacity) {
+            mBuffer = ByteBuffer.allocateDirect(initialCapacity);
+        }
+
+        public ByteBuffer getRawByteBuffer() {
+            // Slice the buffer from 0 to position.
+            int limit = mBuffer.limit();
+            int position = mBuffer.position();
+            mBuffer.limit(position);
+            mBuffer.position(0);
+            ByteBuffer buffer = mBuffer.slice();
+
+            // Restore position and limit.
+            mBuffer.limit(limit);
+            mBuffer.position(position);
+            return buffer;
+        }
+
+        public ByteOrder order() {
+            return mBuffer.order();
+        }
+
+        public int position() {
+            return mBuffer.position();
+        }
+
+        public AutoGrowByteBuffer position(int newPosition) {
+            mBuffer.position(newPosition);
+            return this;
+        }
+
+        public AutoGrowByteBuffer order(ByteOrder order) {
+            mBuffer.order(order);
+            return this;
+        }
+
+        public AutoGrowByteBuffer putInt(int value) {
+            ensureCapacity(INTEGER_BYTE_COUNT);
+            mBuffer.putInt(value);
+            return this;
+        }
+
+        public AutoGrowByteBuffer putLong(long value) {
+            ensureCapacity(LONG_BYTE_COUNT);
+            mBuffer.putLong(value);
+            return this;
+        }
+
+        public AutoGrowByteBuffer putFloat(float value) {
+            ensureCapacity(FLOAT_BYTE_COUNT);
+            mBuffer.putFloat(value);
+            return this;
+        }
+
+        public AutoGrowByteBuffer putDouble(double value) {
+            ensureCapacity(DOUBLE_BYTE_COUNT);
+            mBuffer.putDouble(value);
+            return this;
+        }
+
+        public AutoGrowByteBuffer put(byte[] src) {
+            ensureCapacity(src.length);
+            mBuffer.put(src);
+            return this;
+        }
+
+        /**
+         * Ensures capacity to append at least <code>count</code> values.
+         */
+        private void ensureCapacity(@IntRange int count) {
+            if (mBuffer.remaining() < count) {
+                int newCapacity = mBuffer.position() + count;
+                if (newCapacity > Integer.MAX_VALUE >> 1) {
+                    throw new IllegalStateException(
+                            "Item memory requirements too large: " + newCapacity);
+                }
+                newCapacity <<= 1;
+                ByteBuffer buffer = ByteBuffer.allocateDirect(newCapacity);
+                buffer.order(mBuffer.order());
+
+                // Copy data from old buffer to new buffer
+                mBuffer.flip();
+                buffer.put(mBuffer);
+
+                // Set buffer to new buffer
+                mBuffer = buffer;
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Describes a unpacking/packing contract of type {@code T} out of a {@link ByteBuffer}
+     *
+     * @param <T> the type being unpack
+     */
+    private interface DataPackage<T> {
+        /**
+         * Read an item from a {@link ByteBuffer}.
+         *
+         * The parceling format is assumed the same as the one described in
+         * audio_utils::Metadata.h. Copied here as a reference.
+         * All values are native endian order.
+         *
+         * Datum = { (type_size_t)  Type (the type index from type_as_value<T>.)
+         *           (datum_size_t) Size (size of datum, including the size field)
+         *           (byte string)  Payload<Type>
+         *         }
+         *
+         * Primitive types:
+         * Payload<Type> = { bytes in native endian order }
+         *
+         * Vector, Map, Container types:
+         * Payload<Type> = { (index_size_t) number of elements
+         *                   (byte string)  Payload<Element_Type> * number
+         *                 }
+         *
+         * Pair container types:
+         * Payload<Type> = { (byte string) Payload<first>,
+         *                   (byte string) Payload<second>
+         *                 }
+         *
+         * @param buffer the byte buffer to read from
+         * @return an object, which types is given type for {@link DataPackage}
+         * @throws BufferUnderflowException when there is no enough data remaining
+         *      in the buffer for unpacking.
+         */
+        @Nullable
+        T unpack(ByteBuffer buffer);
+
+        /**
+         * Pack the item into a byte array. This is the reversed way of unpacking.
+         *
+         * @param output is the stream to which to write the data
+         * @param obj the item to pack
+         * @return true if packing successfully. Otherwise, return false.
+         */
+        boolean pack(AutoGrowByteBuffer output, T obj);
+
+        /**
+         * Return what kind of data is contained in the package.
+         */
+        default Class getMyType() {
+            return (Class) ((ParameterizedType) getClass().getGenericInterfaces()[0])
+                    .getActualTypeArguments()[0];
+        }
+    }
+
+    /*****************************************************************************************
+     * Following class are common {@link DataPackage} implementations, which include types
+     * that are defined in audio_utils::metadata::metadata_types
+     *
+     * For Java
+     *     int32_t corresponds to Integer
+     *     int64_t corresponds to Long
+     *     float corresponds to Float
+     *     double corresponds to Double
+     *     std::string corresponds to String
+     *     Data corresponds to BaseMap
+     *     Datum corresponds to Object
+     ****************************************************************************************/
+
+    private static final HashMap<Integer, DataPackage<?>> DATA_PACKAGES = new HashMap<>() {{
+            put(AUDIO_METADATA_OBJ_TYPE_INT, new DataPackage<Integer>() {
+                @Override
+                @Nullable
+                public Integer unpack(ByteBuffer buffer) {
+                    return buffer.getInt();
+                }
+
+                @Override
+                public boolean pack(AutoGrowByteBuffer output, Integer obj) {
+                    output.putInt(obj);
+                    return true;
+                }
+            });
+            put(AUDIO_METADATA_OBJ_TYPE_LONG, new DataPackage<Long>() {
+                @Override
+                @Nullable
+                public Long unpack(ByteBuffer buffer) {
+                    return buffer.getLong();
+                }
+
+                @Override
+                public boolean pack(AutoGrowByteBuffer output, Long obj) {
+                    output.putLong(obj);
+                    return true;
+                }
+            });
+            put(AUDIO_METADATA_OBJ_TYPE_FLOAT, new DataPackage<Float>() {
+                @Override
+                @Nullable
+                public Float unpack(ByteBuffer buffer) {
+                    return buffer.getFloat();
+                }
+
+                @Override
+                public boolean pack(AutoGrowByteBuffer output, Float obj) {
+                    output.putFloat(obj);
+                    return true;
+                }
+            });
+            put(AUDIO_METADATA_OBJ_TYPE_DOUBLE, new DataPackage<Double>() {
+                @Override
+                @Nullable
+                public Double unpack(ByteBuffer buffer) {
+                    return buffer.getDouble();
+                }
+
+                @Override
+                public boolean pack(AutoGrowByteBuffer output, Double obj) {
+                    output.putDouble(obj);
+                    return true;
+                }
+            });
+            put(AUDIO_METADATA_OBJ_TYPE_STRING, new DataPackage<String>() {
+                @Override
+                @Nullable
+                public String unpack(ByteBuffer buffer) {
+                    int dataSize = buffer.getInt();
+                    if (buffer.position() + dataSize > buffer.limit()) {
+                        return null;
+                    }
+                    byte[] valueArr = new byte[dataSize];
+                    buffer.get(valueArr);
+                    String value = new String(valueArr, AUDIO_METADATA_CHARSET);
+                    return value;
+                }
+
+                /**
+                 * This is a reversed operation of unpack. It is needed to write the String
+                 * at bytes encoded with AUDIO_METADATA_CHARSET. There should be an integer
+                 * value representing the length of the bytes written before the bytes.
+                 */
+                @Override
+                public boolean pack(AutoGrowByteBuffer output, String obj) {
+                    byte[] valueArr = obj.getBytes(AUDIO_METADATA_CHARSET);
+                    output.putInt(valueArr.length);
+                    output.put(valueArr);
+                    return true;
+                }
+            });
+            put(AUDIO_METADATA_OBJ_TYPE_BASEMAP, new BaseMapPackage());
+        }};
+    // ObjectPackage is a special case that it is expected to unpack audio_utils::metadata::Datum,
+    // which contains data type and data size besides the payload for the data.
+    private static final ObjectPackage OBJECT_PACKAGE = new ObjectPackage();
+
+    private static class ObjectPackage implements DataPackage<Pair<Class, Object>> {
+        /**
+         * The {@link ObjectPackage} will unpack byte string for audio_utils::metadata::Datum.
+         * Since the Datum is a std::any, {@link Object} is used to carrying the data. The
+         * data type is stored in the data package header. In that case, a {@link Class}
+         * will also be returned to indicate the actual type for the object.
+         */
+        @Override
+        @Nullable
+        public Pair<Class, Object> unpack(ByteBuffer buffer) {
+            int dataType = buffer.getInt();
+            DataPackage dataPackage = DATA_PACKAGES.get(dataType);
+            if (dataPackage == null) {
+                Log.e(TAG, "Cannot find DataPackage for type:" + dataType);
+                return null;
+            }
+            int dataSize = buffer.getInt();
+            int position = buffer.position();
+            Object obj = dataPackage.unpack(buffer);
+            if (buffer.position() - position != dataSize) {
+                Log.e(TAG, "Broken data package");
+                return null;
+            }
+            return new Pair<Class, Object>(dataPackage.getMyType(), obj);
+        }
+
+        @Override
+        public boolean pack(AutoGrowByteBuffer output, Pair<Class, Object> obj) {
+            final Integer dataType = AUDIO_METADATA_OBJ_TYPES.get(obj.first);
+            if (dataType == null) {
+                Log.e(TAG, "Cannot find data type for " + obj.first);
+                return false;
+            }
+            DataPackage dataPackage = DATA_PACKAGES.get(dataType);
+            if (dataPackage == null) {
+                Log.e(TAG, "Cannot find DataPackage for type:" + dataType);
+                return false;
+            }
+            output.putInt(dataType);
+            int position = output.position(); // Keep current position.
+            output.putInt(0); // Keep a place for the size of payload.
+            int payloadIdx = output.position();
+            if (!dataPackage.pack(output, obj.second)) {
+                Log.i(TAG, "Failed to pack object: " + obj.second);
+                return false;
+            }
+            // Put the actual payload size.
+            int currentPosition = output.position();
+            output.position(position);
+            output.putInt(currentPosition - payloadIdx);
+            output.position(currentPosition);
+            return true;
+        }
+    }
+
+    /**
+     * BaseMap will be corresponding to audio_utils::metadata::Data.
+     */
+    private static class BaseMapPackage implements DataPackage<BaseMap> {
+        @Override
+        @Nullable
+        public BaseMap unpack(ByteBuffer buffer) {
+            BaseMap ret = new BaseMap();
+            int mapSize = buffer.getInt();
+            DataPackage<String> strDataPackage =
+                    (DataPackage<String>) DATA_PACKAGES.get(AUDIO_METADATA_OBJ_TYPE_STRING);
+            if (strDataPackage == null) {
+                Log.e(TAG, "Cannot find DataPackage for String");
+                return null;
+            }
+            for (int i = 0; i < mapSize; i++) {
+                String key = strDataPackage.unpack(buffer);
+                if (key == null) {
+                    Log.e(TAG, "Failed to unpack key for map");
+                    return null;
+                }
+                Pair<Class, Object> value = OBJECT_PACKAGE.unpack(buffer);
+                if (value == null) {
+                    Log.e(TAG, "Failed to unpack value for map");
+                    return null;
+                }
+
+                // Special handling of KEY_ATMOS_PRESENT.
+                if (key.equals(Format.KEY_HAS_ATMOS.getName())
+                        && value.first == Format.KEY_HAS_ATMOS.getValueClass()) {
+                    ret.set(Format.KEY_ATMOS_PRESENT,
+                            (Boolean) ((int) value.second != 0));  // Translate Integer to Boolean
+                    continue; // Should we store both keys in the java table?
+                }
+
+                ret.set(createKey(key, value.first), value.first.cast(value.second));
+            }
+            return ret;
+        }
+
+        @Override
+        public boolean pack(AutoGrowByteBuffer output, BaseMap obj) {
+            output.putInt(obj.size());
+            DataPackage<String> strDataPackage =
+                    (DataPackage<String>) DATA_PACKAGES.get(AUDIO_METADATA_OBJ_TYPE_STRING);
+            if (strDataPackage == null) {
+                Log.e(TAG, "Cannot find DataPackage for String");
+                return false;
+            }
+            for (Key<?> key : obj.keySet()) {
+                Object value = obj.get(key);
+
+                // Special handling of KEY_ATMOS_PRESENT.
+                if (key == Format.KEY_ATMOS_PRESENT) {
+                    key = Format.KEY_HAS_ATMOS;
+                    value = (Integer) ((boolean) value ? 1 : 0); // Translate Boolean to Integer
+                }
+
+                if (!strDataPackage.pack(output, key.getName())) {
+                    Log.i(TAG, "Failed to pack key: " + key.getName());
+                    return false;
+                }
+                if (!OBJECT_PACKAGE.pack(output, new Pair<>(key.getValueClass(), value))) {
+                    Log.i(TAG, "Failed to pack value: " + obj.get(key));
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    /**
+     * @hide
+     * Extract a {@link BaseMap} from a given {@link ByteBuffer}
+     * @param buffer is a byte string that contains information to unpack.
+     * @return a {@link BaseMap} object if extracting successfully from given byte buffer.
+     *     Otherwise, returns {@code null}.
+     */
+    @Nullable
+    public static BaseMap fromByteBuffer(ByteBuffer buffer) {
+        DataPackage dataPackage = DATA_PACKAGES.get(AUDIO_METADATA_OBJ_TYPE_BASEMAP);
+        if (dataPackage == null) {
+            Log.e(TAG, "Cannot find DataPackage for BaseMap");
+            return null;
+        }
+        try {
+            return (BaseMap) dataPackage.unpack(buffer);
+        } catch (BufferUnderflowException e) {
+            Log.e(TAG, "No enough data to unpack");
+        }
+        return null;
+    }
+
+    /**
+     * @hide
+     * Pack a {link BaseMap} to a {@link ByteBuffer}
+     * @param data is the object for packing
+     * @param order is the byte order
+     * @return a {@link ByteBuffer} if successfully packing the data.
+     *     Otherwise, returns {@code null};
+     */
+    @Nullable
+    public static ByteBuffer toByteBuffer(BaseMap data, ByteOrder order) {
+        DataPackage dataPackage = DATA_PACKAGES.get(AUDIO_METADATA_OBJ_TYPE_BASEMAP);
+        if (dataPackage == null) {
+            Log.e(TAG, "Cannot find DataPackage for BaseMap");
+            return null;
+        }
+        AutoGrowByteBuffer output = new AutoGrowByteBuffer();
+        output.order(order);
+        if (dataPackage.pack(output, data)) {
+            return output.getRawByteBuffer();
+        }
+        return null;
+    }
+
+    // Delete the constructor as there is nothing to implement here.
+    private AudioMetadata() {}
+}
diff --git a/android/media/AudioMetadataMap.java b/android/media/AudioMetadataMap.java
new file mode 100644
index 0000000..1961931
--- /dev/null
+++ b/android/media/AudioMetadataMap.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2020 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.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * AudioMetadataMap is a writeable {@code Map}-style
+ * interface of {@link AudioMetadata.Key} value pairs.
+ * This interface is not guaranteed to be thread-safe
+ * unless the underlying implementation for the {@code AudioMetadataMap}
+ * states it as thread safe.
+ *
+ * {@see AudioMetadataReadMap}
+ */
+// TODO: Create a wrapper like java.util.Collections.synchronizedMap?
+
+public interface AudioMetadataMap extends AudioMetadataReadMap {
+    /**
+     * Removes the value associated with the key.
+     * @param key interface for storing the value.
+     * @param <T> type of value.
+     * @return the value of the key, null if it doesn't exist.
+     */
+    @Nullable
+    <T> T remove(@NonNull AudioMetadata.Key<T> key);
+
+    /**
+     * Sets a value for the key.
+     *
+     * @param key interface for storing the value.
+     * @param <T> type of value.
+     * @param value a non-null value of type T.
+     * @return the previous value associated with key or null if it doesn't exist.
+     */
+    // See automatic Kotlin overloading for Java interoperability.
+    // https://kotlinlang.org/docs/reference/java-interop.html#operators
+    // See also Kotlin set for overloaded operator indexing.
+    // https://kotlinlang.org/docs/reference/operator-overloading.html#indexed
+    // Also the Kotlin mutable-list set.
+    // https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-mutable-list/set.html
+    @Nullable
+    <T> T set(@NonNull AudioMetadata.Key<T> key, @NonNull T value);
+}
diff --git a/android/media/AudioMetadataReadMap.java b/android/media/AudioMetadataReadMap.java
new file mode 100644
index 0000000..e74242a
--- /dev/null
+++ b/android/media/AudioMetadataReadMap.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 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.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.Set;
+
+/**
+ * A read only {@code Map}-style interface of {@link AudioMetadata.Key} value pairs used
+ * for {@link AudioMetadata}.
+ *
+ * <p>Using a {@link AudioMetadata.Key} interface,
+ * this map looks up the corresponding value.
+ * Read-only maps are thread-safe for lookup, but the underlying object
+ * values may need their own thread protection if mutable.</p>
+ *
+ * {@see AudioMetadataMap}
+ */
+public interface AudioMetadataReadMap {
+    /**
+     * Returns true if the key exists in the map.
+     *
+     * @param key interface for requesting the value.
+     * @param <T> type of value.
+     * @return true if key exists in the Map.
+     */
+    <T> boolean containsKey(@NonNull AudioMetadata.Key<T> key);
+
+    /**
+     * Returns a copy of the map.
+     *
+     * This is intended for safe conversion between a {@link AudioMetadataReadMap}
+     * interface and a {@link AudioMetadataMap} interface.
+     * Currently only simple objects are used for key values which
+     * means a shallow copy is sufficient.
+     *
+     * @return a Map copied from the existing map.
+     */
+    @NonNull
+    AudioMetadataMap dup(); // lint checker doesn't like clone().
+
+    /**
+     * Returns the value associated with the key.
+     *
+     * @param key interface for requesting the value.
+     * @param <T> type of value.
+     * @return returns the value of associated with key or null if it doesn't exist.
+     */
+    @Nullable
+    <T> T get(@NonNull AudioMetadata.Key<T> key);
+
+    /**
+     * Returns a {@code Set} of keys associated with the map.
+     * @hide
+     */
+    @NonNull
+    Set<AudioMetadata.Key<?>> keySet();
+
+    /**
+     * Returns the number of elements in the map.
+     */
+    @IntRange(from = 0)
+    int size();
+}
diff --git a/android/media/AudioMixPort.java b/android/media/AudioMixPort.java
new file mode 100644
index 0000000..b24268a
--- /dev/null
+++ b/android/media/AudioMixPort.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2014 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.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+
+import java.util.List;
+
+/**
+ * The AudioMixPort is a specialized type of AudioPort
+ * describing an audio mix or stream at an input or output stream of the audio
+ * framework.
+ * In addition to base audio port attributes, the mix descriptor contains:
+ * - the unique audio I/O handle assigned by AudioFlinger to this mix.
+ * @see AudioPort
+ * @hide
+ */
+
+public class AudioMixPort extends AudioPort {
+
+    private final int mIoHandle;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    AudioMixPort(AudioHandle handle, int ioHandle, int role, String deviceName,
+            int[] samplingRates, int[] channelMasks, int[] channelIndexMasks,
+            int[] formats, AudioGain[] gains) {
+        super(handle, role, deviceName, samplingRates, channelMasks, channelIndexMasks,
+                formats, gains);
+        mIoHandle = ioHandle;
+    }
+
+    AudioMixPort(AudioHandle handle, int ioHandle, int role, String deviceName,
+            List<AudioProfile> profiles, AudioGain[] gains) {
+        super(handle, role, deviceName, profiles, gains, null);
+        mIoHandle = ioHandle;
+    }
+
+    /**
+     * Build a specific configuration of this audio mix port for use by methods
+     * like AudioManager.connectAudioPatch().
+     */
+    public AudioMixPortConfig buildConfig(int samplingRate, int channelMask, int format,
+                                       AudioGainConfig gain) {
+        return new AudioMixPortConfig(this, samplingRate, channelMask, format, gain);
+    }
+
+    /**
+     * Get the device type (e.g AudioManager.DEVICE_OUT_SPEAKER)
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public int ioHandle() {
+        return mIoHandle;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || !(o instanceof AudioMixPort)) {
+            return false;
+        }
+        AudioMixPort other = (AudioMixPort)o;
+        if (mIoHandle != other.ioHandle()) {
+            return false;
+        }
+
+        return super.equals(o);
+    }
+
+}
diff --git a/android/media/AudioMixPortConfig.java b/android/media/AudioMixPortConfig.java
new file mode 100644
index 0000000..483524a
--- /dev/null
+++ b/android/media/AudioMixPortConfig.java
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2014 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.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+
+/**
+ * An AudioMixPortConfig describes a possible configuration of an output or input mixer.
+ * It is used to specify a sink or source when creating a connection with
+ * AudioManager.connectAudioPatch().
+ * An AudioMixPortConfig is obtained from AudioMixPort.buildConfig().
+ * @hide
+ */
+
+public class AudioMixPortConfig extends AudioPortConfig {
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    AudioMixPortConfig(AudioMixPort mixPort, int samplingRate, int channelMask, int format,
+                AudioGainConfig gain) {
+        super((AudioPort)mixPort, samplingRate, channelMask, format, gain);
+    }
+
+    /**
+     * Returns the audio mix port this AudioMixPortConfig is issued from.
+     */
+    public AudioMixPort port() {
+        return (AudioMixPort)mPort;
+    }
+}
+
diff --git a/android/media/AudioPatch.java b/android/media/AudioPatch.java
new file mode 100644
index 0000000..99663bf
--- /dev/null
+++ b/android/media/AudioPatch.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 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.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+
+
+/**
+ * An AudioPatch describes a connection between audio sources and audio sinks.
+ * An audio source can be an output mix (playback AudioBus) or an input device (microphone).
+ * An audio sink can be an output device (speaker) or an input mix (capture AudioBus).
+ * An AudioPatch is created by AudioManager.createAudioPatch() and released by
+ * AudioManager.releaseAudioPatch()
+ * It contains the list of source and sink AudioPortConfig showing audio port configurations
+ * being connected.
+ * @hide
+ */
+public class AudioPatch {
+
+    @UnsupportedAppUsage
+    private final AudioHandle mHandle;
+    private final AudioPortConfig[] mSources;
+    private final AudioPortConfig[] mSinks;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    AudioPatch(AudioHandle patchHandle, AudioPortConfig[] sources, AudioPortConfig[] sinks) {
+        mHandle = patchHandle;
+        mSources = sources;
+        mSinks = sinks;
+    }
+
+    /**
+     * Retrieve the list of sources of this audio patch.
+     */
+    @UnsupportedAppUsage
+    public AudioPortConfig[] sources() {
+        return mSources;
+    }
+
+    /**
+     * Retreive the list of sinks of this audio patch.
+     */
+    @UnsupportedAppUsage
+    public AudioPortConfig[] sinks() {
+        return mSinks;
+    }
+
+    /**
+     * Get the system unique patch ID.
+     */
+    public int id() {
+        return mHandle.id();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder();
+        s.append("mHandle: ");
+        s.append(mHandle.toString());
+
+        s.append(" mSources: {");
+        for (AudioPortConfig source : mSources) {
+            s.append(source.toString());
+            s.append(", ");
+        }
+        s.append("} mSinks: {");
+        for (AudioPortConfig sink : mSinks) {
+            s.append(sink.toString());
+            s.append(", ");
+        }
+        s.append("}");
+
+        return s.toString();
+    }
+}
diff --git a/android/media/AudioPlaybackCaptureConfiguration.java b/android/media/AudioPlaybackCaptureConfiguration.java
new file mode 100644
index 0000000..453704e
--- /dev/null
+++ b/android/media/AudioPlaybackCaptureConfiguration.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 2019 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.annotation.NonNull;
+import android.media.AudioAttributes.AttributeUsage;
+import android.media.audiopolicy.AudioMix;
+import android.media.audiopolicy.AudioMixingRule;
+import android.media.audiopolicy.AudioMixingRule.AudioMixMatchCriterion;
+import android.media.projection.MediaProjection;
+import android.os.RemoteException;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.function.ToIntFunction;
+
+/**
+ * Configuration for capturing audio played by other apps.
+ *
+ *  When capturing audio signals played by other apps (and yours),
+ *  you will only capture a mix of the audio signals played by players
+ *  (such as AudioTrack or MediaPlayer) which present the following characteristics:
+ *  <ul>
+ *  <li> the usage value MUST be {@link AudioAttributes#USAGE_UNKNOWN} or
+ *       {@link AudioAttributes#USAGE_GAME}
+ *       or {@link AudioAttributes#USAGE_MEDIA}. All other usages CAN NOT be captured. </li>
+ *  <li> AND the capture policy set by their app (with {@link AudioManager#setAllowedCapturePolicy})
+ *       or on each player (with {@link AudioAttributes.Builder#setAllowedCapturePolicy}) is
+ *       {@link AudioAttributes#ALLOW_CAPTURE_BY_ALL}, whichever is the most strict. </li>
+ *  <li> AND their app attribute allowAudioPlaybackCapture in their manifest
+ *       MUST either be: <ul>
+ *       <li> set to "true" </li>
+ *       <li> not set, and their {@code targetSdkVersion} MUST be equal to or greater than
+ *            {@link android.os.Build.VERSION_CODES#Q}.
+ *            Ie. Apps that do not target at least Android Q must explicitly opt-in to be captured
+ *            by a MediaProjection. </li></ul>
+ *  <li> AND their apps MUST be in the same user profile as your app
+ *       (eg work profile cannot capture user profile apps and vice-versa). </li>
+ *  </ul>
+ *
+ * <p>An example for creating a capture configuration for capturing all media playback:
+ *
+ * <pre>
+ *     MediaProjection mediaProjection;
+ *     // Retrieve a audio capable projection from the MediaProjectionManager
+ *     AudioPlaybackCaptureConfiguration config =
+ *         new AudioPlaybackCaptureConfiguration.Builder(mediaProjection)
+ *         .addMatchingUsage(AudioAttributes.USAGE_MEDIA)
+ *         .build();
+ *     AudioRecord record = new AudioRecord.Builder()
+ *         .setAudioPlaybackCaptureConfig(config)
+ *         .build();
+ * </pre>
+ *
+ * @see Builder
+ * @see android.media.projection.MediaProjectionManager#getMediaProjection(int, Intent)
+ * @see AudioRecord.Builder#setAudioPlaybackCaptureConfig(AudioPlaybackCaptureConfiguration)
+ */
+public final class AudioPlaybackCaptureConfiguration {
+
+    private final AudioMixingRule mAudioMixingRule;
+    private final MediaProjection mProjection;
+
+    private AudioPlaybackCaptureConfiguration(AudioMixingRule audioMixingRule,
+                                              MediaProjection projection) {
+        mAudioMixingRule = audioMixingRule;
+        mProjection = projection;
+    }
+
+    /**
+     * @return the {@code MediaProjection} used to build this object.
+     * @see Builder#Builder(MediaProjection)
+     */
+    public @NonNull MediaProjection getMediaProjection() {
+        return mProjection;
+    }
+
+    /** @return the usages passed to {@link Builder#addMatchingUsage(int)}. */
+    @AttributeUsage
+    public @NonNull int[] getMatchingUsages() {
+        return getIntPredicates(AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE,
+                                criterion -> criterion.getAudioAttributes().getUsage());
+    }
+
+    /** @return the UIDs passed to {@link Builder#addMatchingUid(int)}. */
+    public @NonNull int[] getMatchingUids() {
+        return getIntPredicates(AudioMixingRule.RULE_MATCH_UID,
+                                criterion -> criterion.getIntProp());
+    }
+
+    /** @return the usages passed to {@link Builder#excludeUsage(int)}. */
+    @AttributeUsage
+    public @NonNull int[] getExcludeUsages() {
+        return getIntPredicates(AudioMixingRule.RULE_EXCLUDE_ATTRIBUTE_USAGE,
+                                criterion -> criterion.getAudioAttributes().getUsage());
+    }
+
+    /** @return the UIDs passed to {@link Builder#excludeUid(int)}.  */
+    public @NonNull int[] getExcludeUids() {
+        return getIntPredicates(AudioMixingRule.RULE_EXCLUDE_UID,
+                                criterion -> criterion.getIntProp());
+    }
+
+    private int[] getIntPredicates(int rule,
+                                   ToIntFunction<AudioMixMatchCriterion> getPredicate) {
+        return mAudioMixingRule.getCriteria().stream()
+            .filter(criterion -> criterion.getRule() == rule)
+            .mapToInt(getPredicate)
+            .toArray();
+    }
+
+    /**
+     * Returns a mix that routes audio back into the app while still playing it from the speakers.
+     *
+     * @param audioFormat The format in which to capture the audio.
+     */
+    @NonNull AudioMix createAudioMix(@NonNull AudioFormat audioFormat) {
+        return new AudioMix.Builder(mAudioMixingRule)
+                .setFormat(audioFormat)
+                .setRouteFlags(AudioMix.ROUTE_FLAG_LOOP_BACK | AudioMix.ROUTE_FLAG_RENDER)
+                .build();
+    }
+
+    /** Builder for creating {@link AudioPlaybackCaptureConfiguration} instances. */
+    public static final class Builder {
+
+        private static final int MATCH_TYPE_UNSPECIFIED = 0;
+        private static final int MATCH_TYPE_INCLUSIVE = 1;
+        private static final int MATCH_TYPE_EXCLUSIVE = 2;
+
+        private static final String ERROR_MESSAGE_MISMATCHED_RULES =
+                "Inclusive and exclusive usage rules cannot be combined";
+        private static final String ERROR_MESSAGE_START_ACTIVITY_FAILED =
+                "startActivityForResult failed";
+        private static final String ERROR_MESSAGE_NON_AUDIO_PROJECTION =
+                "MediaProjection can not project audio";
+
+        private final AudioMixingRule.Builder mAudioMixingRuleBuilder;
+        private final MediaProjection mProjection;
+        private int mUsageMatchType = MATCH_TYPE_UNSPECIFIED;
+        private int mUidMatchType = MATCH_TYPE_UNSPECIFIED;
+
+        /** @param projection A MediaProjection that supports audio projection. */
+        public Builder(@NonNull MediaProjection projection) {
+            Preconditions.checkNotNull(projection);
+            try {
+                Preconditions.checkArgument(projection.getProjection().canProjectAudio(),
+                                            ERROR_MESSAGE_NON_AUDIO_PROJECTION);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            mProjection = projection;
+            mAudioMixingRuleBuilder = new AudioMixingRule.Builder();
+        }
+
+        /**
+         * Only capture audio output with the given {@link AudioAttributes}.
+         *
+         * <p>If called multiple times, will capture audio output that matches any of the given
+         * attributes.
+         *
+         * @throws IllegalStateException if called in conjunction with
+         *     {@link #excludeUsage(int)}.
+         */
+        public @NonNull Builder addMatchingUsage(@AttributeUsage int usage) {
+            Preconditions.checkState(
+                    mUsageMatchType != MATCH_TYPE_EXCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES);
+            mAudioMixingRuleBuilder.addRule(new AudioAttributes.Builder().setUsage(usage).build(),
+                                            AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE);
+            mUsageMatchType = MATCH_TYPE_INCLUSIVE;
+            return this;
+        }
+
+        /**
+         * Only capture audio output by app with the matching {@code uid}.
+         *
+         * <p>If called multiple times, will capture audio output by apps whose uid is any of the
+         * given uids.
+         *
+         * @throws IllegalStateException if called in conjunction with {@link #excludeUid(int)}.
+         */
+        public @NonNull Builder addMatchingUid(int uid) {
+            Preconditions.checkState(
+                    mUidMatchType != MATCH_TYPE_EXCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES);
+            mAudioMixingRuleBuilder.addMixRule(AudioMixingRule.RULE_MATCH_UID, uid);
+            mUidMatchType = MATCH_TYPE_INCLUSIVE;
+            return this;
+        }
+
+        /**
+         * Only capture audio output that does not match the given {@link AudioAttributes}.
+         *
+         * <p>If called multiple times, will capture audio output that does not match any of the
+         * given attributes.
+         *
+         * @throws IllegalStateException if called in conjunction with
+         *     {@link #addMatchingUsage(int)}.
+         */
+        public @NonNull Builder excludeUsage(@AttributeUsage int usage) {
+            Preconditions.checkState(
+                    mUsageMatchType != MATCH_TYPE_INCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES);
+            mAudioMixingRuleBuilder.excludeRule(new AudioAttributes.Builder()
+                                                    .setUsage(usage)
+                                                    .build(),
+                                                AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE);
+            mUsageMatchType = MATCH_TYPE_EXCLUSIVE;
+            return this;
+        }
+
+        /**
+         * Only capture audio output by apps that do not have the matching {@code uid}.
+         *
+         * <p>If called multiple times, will capture audio output by apps whose uid is not any of
+         * the given uids.
+         *
+         * @throws IllegalStateException if called in conjunction with {@link #addMatchingUid(int)}.
+         */
+        public @NonNull Builder excludeUid(int uid) {
+            Preconditions.checkState(
+                    mUidMatchType != MATCH_TYPE_INCLUSIVE, ERROR_MESSAGE_MISMATCHED_RULES);
+            mAudioMixingRuleBuilder.excludeMixRule(AudioMixingRule.RULE_MATCH_UID, uid);
+            mUidMatchType = MATCH_TYPE_EXCLUSIVE;
+            return this;
+        }
+
+        /**
+         * Builds the configuration instance.
+         *
+         * @throws UnsupportedOperationException if the parameters set are incompatible.
+         */
+        public @NonNull AudioPlaybackCaptureConfiguration build() {
+            return new AudioPlaybackCaptureConfiguration(mAudioMixingRuleBuilder.build(),
+                                                         mProjection);
+        }
+    }
+}
diff --git a/android/media/AudioPlaybackConfiguration.java b/android/media/AudioPlaybackConfiguration.java
new file mode 100644
index 0000000..d18d7e4
--- /dev/null
+++ b/android/media/AudioPlaybackConfiguration.java
@@ -0,0 +1,677 @@
+/*
+ * Copyright (C) 2016 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.ALLOW_CAPTURE_BY_ALL;
+import static android.media.AudioAttributes.ALLOW_CAPTURE_BY_NONE;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * The AudioPlaybackConfiguration class collects the information describing an audio playback
+ * session.
+ */
+public final class AudioPlaybackConfiguration implements Parcelable {
+    private static final String TAG = new String("AudioPlaybackConfiguration");
+
+    private static final boolean DEBUG = false;
+
+    /** @hide */
+    public static final int PLAYER_PIID_INVALID = -1;
+    /** @hide */
+    public static final int PLAYER_UPID_INVALID = -1;
+    /** @hide */
+    public static final int PLAYER_DEVICEID_INVALID = 0;
+
+    // information about the implementation
+    /**
+     * @hide
+     * An unknown type of player
+     */
+    @SystemApi
+    public static final int PLAYER_TYPE_UNKNOWN = -1;
+    /**
+     * @hide
+     * Player backed by a java android.media.AudioTrack player
+     */
+    @SystemApi
+    public static final int PLAYER_TYPE_JAM_AUDIOTRACK = 1;
+    /**
+     * @hide
+     * Player backed by a java android.media.MediaPlayer player
+     */
+    @SystemApi
+    public static final int PLAYER_TYPE_JAM_MEDIAPLAYER = 2;
+    /**
+     * @hide
+     * Player backed by a java android.media.SoundPool player
+     */
+    @SystemApi
+    public static final int PLAYER_TYPE_JAM_SOUNDPOOL = 3;
+    /**
+     * @hide
+     * Player backed by a C OpenSL ES AudioPlayer player with a BufferQueue source
+     */
+    @SystemApi
+    public static final int PLAYER_TYPE_SLES_AUDIOPLAYER_BUFFERQUEUE = 11;
+    /**
+     * @hide
+     * Player backed by a C OpenSL ES AudioPlayer player with a URI or FD source
+     */
+    @SystemApi
+    public static final int PLAYER_TYPE_SLES_AUDIOPLAYER_URI_FD = 12;
+
+    /**
+     * @hide
+     * Player backed an AAudio player.
+     */
+    @SystemApi
+    public static final int PLAYER_TYPE_AAUDIO = 13;
+
+    /**
+     * @hide
+     * Player backed a hardware source, whose state is visible in the Android audio policy manager.
+     * Note this type is not in System API so it will not be returned in public API calls
+     */
+    // TODO unhide for SystemApi, update getPlayerType()
+    public static final int PLAYER_TYPE_HW_SOURCE = 14;
+
+    /**
+     * @hide
+     * Player is a proxy for an audio player whose audio and state doesn't go through the Android
+     * audio framework.
+     * Note this type is not in System API so it will not be returned in public API calls
+     */
+    // TODO unhide for SystemApi, update getPlayerType()
+    public static final int PLAYER_TYPE_EXTERNAL_PROXY = 15;
+
+    /** @hide */
+    @IntDef({
+        PLAYER_TYPE_UNKNOWN,
+        PLAYER_TYPE_JAM_AUDIOTRACK,
+        PLAYER_TYPE_JAM_MEDIAPLAYER,
+        PLAYER_TYPE_JAM_SOUNDPOOL,
+        PLAYER_TYPE_SLES_AUDIOPLAYER_BUFFERQUEUE,
+        PLAYER_TYPE_SLES_AUDIOPLAYER_URI_FD,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PlayerType {}
+
+    /**
+     * @hide
+     * An unknown player state
+     */
+    @SystemApi
+    public static final int PLAYER_STATE_UNKNOWN = -1;
+    /**
+     * @hide
+     * The resources of the player have been released, it cannot play anymore
+     */
+    @SystemApi
+    public static final int PLAYER_STATE_RELEASED = 0;
+    /**
+     * @hide
+     * The state of a player when it's created
+     */
+    @SystemApi
+    public static final int PLAYER_STATE_IDLE = 1;
+    /**
+     * @hide
+     * The state of a player that is actively playing
+     */
+    @SystemApi
+    public static final int PLAYER_STATE_STARTED = 2;
+    /**
+     * @hide
+     * The state of a player where playback is paused
+     */
+    @SystemApi
+    public static final int PLAYER_STATE_PAUSED = 3;
+    /**
+     * @hide
+     * The state of a player where playback is stopped
+     */
+    @SystemApi
+    public static final int PLAYER_STATE_STOPPED = 4;
+    /**
+     * @hide
+     * The state used to update device id, does not actually change the state of the player
+     */
+    public static final int PLAYER_UPDATE_DEVICE_ID = 5;
+
+    /** @hide */
+    @IntDef({
+        PLAYER_STATE_UNKNOWN,
+        PLAYER_STATE_RELEASED,
+        PLAYER_STATE_IDLE,
+        PLAYER_STATE_STARTED,
+        PLAYER_STATE_PAUSED,
+        PLAYER_STATE_STOPPED,
+        PLAYER_UPDATE_DEVICE_ID
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PlayerState {}
+
+    /** @hide */
+    public static String playerStateToString(@PlayerState int state) {
+        switch (state) {
+            case PLAYER_STATE_UNKNOWN: return "PLAYER_STATE_UNKNOWN";
+            case PLAYER_STATE_RELEASED: return "PLAYER_STATE_RELEASED";
+            case PLAYER_STATE_IDLE: return "PLAYER_STATE_IDLE";
+            case PLAYER_STATE_STARTED: return "PLAYER_STATE_STARTED";
+            case PLAYER_STATE_PAUSED: return "PLAYER_STATE_PAUSED";
+            case PLAYER_STATE_STOPPED: return "PLAYER_STATE_STOPPED";
+            case PLAYER_UPDATE_DEVICE_ID: return "PLAYER_UPDATE_DEVICE_ID";
+            default:
+                return "invalid state " + state;
+        }
+    }
+
+    // immutable data
+    private final int mPlayerIId;
+
+    // not final due to anonymization step
+    private int mPlayerType;
+    private int mClientUid;
+    private int mClientPid;
+    // the IPlayer reference and death monitor
+    private IPlayerShell mIPlayerShell;
+
+    private int mPlayerState;
+    private AudioAttributes mPlayerAttr; // never null
+
+    private int mDeviceId;
+
+    private int mSessionId;
+
+    /**
+     * Never use without initializing parameters afterwards
+     */
+    private AudioPlaybackConfiguration(int piid) {
+        mPlayerIId = piid;
+        mIPlayerShell = null;
+    }
+
+    /**
+     * @hide
+     */
+    public AudioPlaybackConfiguration(PlayerBase.PlayerIdCard pic, int piid, int uid, int pid) {
+        if (DEBUG) {
+            Log.d(TAG, "new: piid=" + piid + " iplayer=" + pic.mIPlayer
+                    + " sessionId=" + pic.mSessionId);
+        }
+        mPlayerIId = piid;
+        mPlayerType = pic.mPlayerType;
+        mClientUid = uid;
+        mClientPid = pid;
+        mDeviceId = PLAYER_DEVICEID_INVALID;
+        mPlayerState = PLAYER_STATE_IDLE;
+        mPlayerAttr = pic.mAttributes;
+        if ((sPlayerDeathMonitor != null) && (pic.mIPlayer != null)) {
+            mIPlayerShell = new IPlayerShell(this, pic.mIPlayer);
+        } else {
+            mIPlayerShell = null;
+        }
+        mSessionId = pic.mSessionId;
+    }
+
+    /**
+     * @hide
+     */
+    public void init() {
+        synchronized (this) {
+            if (mIPlayerShell != null) {
+                mIPlayerShell.monitorDeath();
+            }
+        }
+    }
+
+    // Note that this method is called server side, so no "privileged" information is ever sent
+    // to a client that is not supposed to have access to it.
+    /**
+     * @hide
+     * Creates a copy of the playback configuration that is stripped of any data enabling
+     * identification of which application it is associated with ("anonymized").
+     * @param toSanitize
+     */
+    public static AudioPlaybackConfiguration anonymizedCopy(AudioPlaybackConfiguration in) {
+        final AudioPlaybackConfiguration anonymCopy = new AudioPlaybackConfiguration(in.mPlayerIId);
+        anonymCopy.mPlayerState = in.mPlayerState;
+        // do not reuse the full attributes: only usage, content type and public flags are allowed
+        AudioAttributes.Builder builder = new AudioAttributes.Builder()
+                .setContentType(in.mPlayerAttr.getContentType())
+                .setFlags(in.mPlayerAttr.getFlags())
+                .setAllowedCapturePolicy(
+                        in.mPlayerAttr.getAllowedCapturePolicy() == ALLOW_CAPTURE_BY_ALL
+                                ? ALLOW_CAPTURE_BY_ALL : ALLOW_CAPTURE_BY_NONE);
+        if (AudioAttributes.isSystemUsage(in.mPlayerAttr.getSystemUsage())) {
+            builder.setSystemUsage(in.mPlayerAttr.getSystemUsage());
+        } else {
+            builder.setUsage(in.mPlayerAttr.getUsage());
+        }
+        anonymCopy.mPlayerAttr = builder.build();
+        anonymCopy.mDeviceId = in.mDeviceId;
+        // anonymized data
+        anonymCopy.mPlayerType = PLAYER_TYPE_UNKNOWN;
+        anonymCopy.mClientUid = PLAYER_UPID_INVALID;
+        anonymCopy.mClientPid = PLAYER_UPID_INVALID;
+        anonymCopy.mIPlayerShell = null;
+        anonymCopy.mSessionId = AudioSystem.AUDIO_SESSION_ALLOCATE;
+        return anonymCopy;
+    }
+
+    /**
+     * Return the {@link AudioAttributes} of the corresponding player.
+     * @return the audio attributes of the player
+     */
+    public AudioAttributes getAudioAttributes() {
+        return mPlayerAttr;
+    }
+
+    /**
+     * @hide
+     * Return the uid of the client application that created this player.
+     * @return the uid of the client
+     */
+    @SystemApi
+    public int getClientUid() {
+        return mClientUid;
+    }
+
+    /**
+     * @hide
+     * Return the pid of the client application that created this player.
+     * @return the pid of the client
+     */
+    @SystemApi
+    public int getClientPid() {
+        return mClientPid;
+    }
+
+    /**
+     * Returns information about the {@link AudioDeviceInfo} used for this playback.
+     * @return the audio playback device or null if the device is not available at the time of query
+     */
+    public @Nullable AudioDeviceInfo getAudioDeviceInfo() {
+        if (mDeviceId == PLAYER_DEVICEID_INVALID) {
+            return null;
+        }
+        return AudioManager.getDeviceForPortId(mDeviceId, AudioManager.GET_DEVICES_OUTPUTS);
+    }
+
+    /**
+     * @hide
+     * Return the audio session ID associated with this player.
+     * See {@link AudioManager#generateAudioSessionId()}.
+     * @return an audio session ID
+     */
+    @SystemApi
+    public @IntRange(from = 0) int getSessionId() {
+        return mSessionId;
+    }
+
+    /**
+     * @hide
+     * Return the type of player linked to this configuration.
+     * <br>Note that player types not exposed in the system API will be represented as
+     * {@link #PLAYER_TYPE_UNKNOWN}.
+     * @return the type of the player.
+     */
+    @SystemApi
+    public @PlayerType int getPlayerType() {
+        switch (mPlayerType) {
+            case PLAYER_TYPE_HW_SOURCE:
+            case PLAYER_TYPE_EXTERNAL_PROXY:
+                return PLAYER_TYPE_UNKNOWN;
+            default:
+                return mPlayerType;
+        }
+    }
+
+    /**
+     * @hide
+     * Return the current state of the player linked to this configuration. The return value is one
+     * of {@link #PLAYER_STATE_IDLE}, {@link #PLAYER_STATE_PAUSED}, {@link #PLAYER_STATE_STARTED},
+     * {@link #PLAYER_STATE_STOPPED}, {@link #PLAYER_STATE_RELEASED} or
+     * {@link #PLAYER_STATE_UNKNOWN}.
+     * @return the state of the player.
+     */
+    @SystemApi
+    public @PlayerState int getPlayerState() {
+        return mPlayerState;
+    }
+
+    /**
+     * @hide
+     * Return an identifier unique for the lifetime of the player.
+     * @return a player interface identifier
+     */
+    @SystemApi
+    public int getPlayerInterfaceId() {
+        return mPlayerIId;
+    }
+
+    /**
+     * @hide
+     * Return a proxy for the player associated with this playback configuration
+     * @return a proxy player
+     */
+    @SystemApi
+    public PlayerProxy getPlayerProxy() {
+        final IPlayerShell ips;
+        synchronized (this) {
+            ips = mIPlayerShell;
+        }
+        return ips == null ? null : new PlayerProxy(this);
+    }
+
+    /**
+     * @hide
+     * @return the IPlayer interface for the associated player
+     */
+    IPlayer getIPlayer() {
+        final IPlayerShell ips;
+        synchronized (this) {
+            ips = mIPlayerShell;
+        }
+        return ips == null ? null : ips.getIPlayer();
+    }
+
+    /**
+     * @hide
+     * Handle a change of audio attributes
+     * @param attr
+     */
+    public boolean handleAudioAttributesEvent(@NonNull AudioAttributes attr) {
+        final boolean changed = !attr.equals(mPlayerAttr);
+        mPlayerAttr = attr;
+        return changed;
+    }
+
+    /**
+     * @hide
+     * Handle a change of audio session Id
+     * @param sessionId the audio session ID
+     */
+    public boolean handleSessionIdEvent(int sessionId) {
+        final boolean changed = sessionId != mSessionId;
+        mSessionId = sessionId;
+        return changed;
+    }
+
+    /**
+     * @hide
+     * Handle a player state change
+     * @param event
+     * @param deviceId active device id or {@Code PLAYER_DEVICEID_INVALID}
+     * <br>Note device id is valid for {@code PLAYER_UPDATE_DEVICE_ID} or
+     * <br>{@code PLAYER_STATE_STARTED} events, as the device id will be reset to none when
+     * <br>pausing or stopping playback. It will be set to active device when playback starts or
+     * <br>it will be changed when PLAYER_UPDATE_DEVICE_ID is sent. The latter can happen if the
+     * <br>device changes in the middle of playback.
+     * @return true if the state changed, false otherwise
+     */
+    public boolean handleStateEvent(int event, int deviceId) {
+        boolean changed = false;
+        synchronized (this) {
+
+            // Do not update if it is only device id update
+            if (event != PLAYER_UPDATE_DEVICE_ID) {
+                changed = (mPlayerState != event);
+                mPlayerState = event;
+            }
+
+            if (event == PLAYER_STATE_STARTED || event == PLAYER_UPDATE_DEVICE_ID) {
+                changed = changed || (mDeviceId != deviceId);
+                mDeviceId = deviceId;
+            }
+
+            if (changed && (event == PLAYER_STATE_RELEASED) && (mIPlayerShell != null)) {
+                mIPlayerShell.release();
+                mIPlayerShell = null;
+            }
+        }
+        return changed;
+    }
+
+    // To report IPlayer death from death recipient
+    /** @hide */
+    public interface PlayerDeathMonitor {
+        public void playerDeath(int piid);
+    }
+    /** @hide */
+    public static PlayerDeathMonitor sPlayerDeathMonitor;
+
+    private void playerDied() {
+        if (sPlayerDeathMonitor != null) {
+            sPlayerDeathMonitor.playerDeath(mPlayerIId);
+        }
+    }
+
+    /**
+     * @hide
+     * Returns true if the player is considered "active", i.e. actively playing, and thus
+     * in a state that should make it considered for the list public (sanitized) active playback
+     * configurations
+     * @return true if active
+     */
+    @SystemApi
+    public boolean isActive() {
+        switch (mPlayerState) {
+            case PLAYER_STATE_STARTED:
+                return true;
+            case PLAYER_STATE_UNKNOWN:
+            case PLAYER_STATE_RELEASED:
+            case PLAYER_STATE_IDLE:
+            case PLAYER_STATE_PAUSED:
+            case PLAYER_STATE_STOPPED:
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * @hide
+     * For AudioService dump
+     * @param pw
+     */
+    public void dump(PrintWriter pw) {
+        pw.println("  " + this);
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<AudioPlaybackConfiguration> CREATOR
+            = new Parcelable.Creator<AudioPlaybackConfiguration>() {
+        /**
+         * Rebuilds an AudioPlaybackConfiguration previously stored with writeToParcel().
+         * @param p Parcel object to read the AudioPlaybackConfiguration from
+         * @return a new AudioPlaybackConfiguration created from the data in the parcel
+         */
+        public AudioPlaybackConfiguration createFromParcel(Parcel p) {
+            return new AudioPlaybackConfiguration(p);
+        }
+        public AudioPlaybackConfiguration[] newArray(int size) {
+            return new AudioPlaybackConfiguration[size];
+        }
+    };
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mPlayerIId, mDeviceId, mPlayerType, mClientUid, mClientPid,
+                mSessionId);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mPlayerIId);
+        dest.writeInt(mDeviceId);
+        dest.writeInt(mPlayerType);
+        dest.writeInt(mClientUid);
+        dest.writeInt(mClientPid);
+        dest.writeInt(mPlayerState);
+        mPlayerAttr.writeToParcel(dest, 0);
+        final IPlayerShell ips;
+        synchronized (this) {
+            ips = mIPlayerShell;
+        }
+        dest.writeStrongInterface(ips == null ? null : ips.getIPlayer());
+        dest.writeInt(mSessionId);
+    }
+
+    private AudioPlaybackConfiguration(Parcel in) {
+        mPlayerIId = in.readInt();
+        mDeviceId = in.readInt();
+        mPlayerType = in.readInt();
+        mClientUid = in.readInt();
+        mClientPid = in.readInt();
+        mPlayerState = in.readInt();
+        mPlayerAttr = AudioAttributes.CREATOR.createFromParcel(in);
+        final IPlayer p = IPlayer.Stub.asInterface(in.readStrongBinder());
+        mIPlayerShell = (p == null) ? null : new IPlayerShell(null, p);
+        mSessionId = in.readInt();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || !(o instanceof AudioPlaybackConfiguration)) return false;
+
+        AudioPlaybackConfiguration that = (AudioPlaybackConfiguration) o;
+
+        return ((mPlayerIId == that.mPlayerIId)
+                && (mDeviceId == that.mDeviceId)
+                && (mPlayerType == that.mPlayerType)
+                && (mClientUid == that.mClientUid)
+                && (mClientPid == that.mClientPid))
+                && (mSessionId == that.mSessionId);
+    }
+
+    @Override
+    public String toString() {
+        return "AudioPlaybackConfiguration piid:" + mPlayerIId
+                + " deviceId:" + mDeviceId
+                + " type:" + toLogFriendlyPlayerType(mPlayerType)
+                + " u/pid:" + mClientUid + "/" + mClientPid
+                + " state:" + toLogFriendlyPlayerState(mPlayerState)
+                + " attr:" + mPlayerAttr
+                + " sessionId:" + mSessionId;
+    }
+
+    //=====================================================================
+    // Inner class for corresponding IPlayer and its death monitoring
+    static final class IPlayerShell implements IBinder.DeathRecipient {
+
+        final AudioPlaybackConfiguration mMonitor; // never null
+        private volatile IPlayer mIPlayer;
+
+        IPlayerShell(@NonNull AudioPlaybackConfiguration monitor, @NonNull IPlayer iplayer) {
+            mMonitor = monitor;
+            mIPlayer = iplayer;
+        }
+
+        synchronized void monitorDeath() {
+            if (mIPlayer == null) {
+                return;
+            }
+            try {
+                mIPlayer.asBinder().linkToDeath(this, 0);
+            } catch (RemoteException e) {
+                if (mMonitor != null) {
+                    Log.w(TAG, "Could not link to client death for piid=" + mMonitor.mPlayerIId, e);
+                } else {
+                    Log.w(TAG, "Could not link to client death", e);
+                }
+            }
+        }
+
+        IPlayer getIPlayer() {
+            return mIPlayer;
+        }
+
+        public void binderDied() {
+            if (mMonitor != null) {
+                if (DEBUG) { Log.i(TAG, "IPlayerShell binderDied for piid=" + mMonitor.mPlayerIId);}
+                mMonitor.playerDied();
+            } else if (DEBUG) { Log.i(TAG, "IPlayerShell binderDied"); }
+        }
+
+        synchronized void release() {
+            if (mIPlayer == null) {
+                return;
+            }
+            mIPlayer.asBinder().unlinkToDeath(this, 0);
+            mIPlayer = null;
+            Binder.flushPendingCommands();
+        }
+    }
+
+    //=====================================================================
+    // Utilities
+
+    /** @hide */
+    public static String toLogFriendlyPlayerType(int type) {
+        switch (type) {
+            case PLAYER_TYPE_UNKNOWN: return "unknown";
+            case PLAYER_TYPE_JAM_AUDIOTRACK: return "android.media.AudioTrack";
+            case PLAYER_TYPE_JAM_MEDIAPLAYER: return "android.media.MediaPlayer";
+            case PLAYER_TYPE_JAM_SOUNDPOOL:   return "android.media.SoundPool";
+            case PLAYER_TYPE_SLES_AUDIOPLAYER_BUFFERQUEUE:
+                return "OpenSL ES AudioPlayer (Buffer Queue)";
+            case PLAYER_TYPE_SLES_AUDIOPLAYER_URI_FD:
+                return "OpenSL ES AudioPlayer (URI/FD)";
+            case PLAYER_TYPE_AAUDIO: return "AAudio";
+            case PLAYER_TYPE_HW_SOURCE: return "hardware source";
+            case PLAYER_TYPE_EXTERNAL_PROXY: return "external proxy";
+            default:
+                return "unknown player type " + type + " - FIXME";
+        }
+    }
+
+    /** @hide */
+    public static String toLogFriendlyPlayerState(int state) {
+        switch (state) {
+            case PLAYER_STATE_UNKNOWN: return "unknown";
+            case PLAYER_STATE_RELEASED: return "released";
+            case PLAYER_STATE_IDLE: return "idle";
+            case PLAYER_STATE_STARTED: return "started";
+            case PLAYER_STATE_PAUSED: return "paused";
+            case PLAYER_STATE_STOPPED: return "stopped";
+            case PLAYER_UPDATE_DEVICE_ID: return "device";
+            default:
+                return "unknown player state - FIXME";
+        }
+    }
+}
diff --git a/android/media/AudioPort.java b/android/media/AudioPort.java
new file mode 100644
index 0000000..8a2d096
--- /dev/null
+++ b/android/media/AudioPort.java
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2014 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.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * An audio port is a node of the audio framework or hardware that can be connected to or
+ * disconnect from another audio node to create a specific audio routing configuration.
+ * Examples of audio ports are an output device (speaker) or an output mix (see AudioMixPort).
+ * All attributes that are relevant for applications to make routing selection are described
+ * in an AudioPort,  in particular:
+ * - possible channel mask configurations.
+ * - audio format (PCM 16bit, PCM 24bit...)
+ * - gain: a port can be associated with one or more gain controllers (see AudioGain).
+ *
+ * This object is always created by the framework and read only by applications.
+ * A list of all audio port descriptors currently available for applications to control
+ * is obtained by AudioManager.listAudioPorts().
+ * An application can obtain an AudioPortConfig for a valid configuration of this port
+ * by calling AudioPort.buildConfig() and use this configuration
+ * to create a connection between audio sinks and sources with AudioManager.connectAudioPatch()
+ *
+ * @hide
+ */
+public class AudioPort {
+    private static final String TAG = "AudioPort";
+
+    /**
+     * For use by the audio framework.
+     */
+    public static final int ROLE_NONE = 0;
+    /**
+     * The audio port is a source (produces audio)
+     */
+    public static final int ROLE_SOURCE = 1;
+    /**
+     * The audio port is a sink (consumes audio)
+     */
+    public static final int ROLE_SINK = 2;
+
+    /**
+     * audio port type for use by audio framework implementation
+     */
+    public static final int TYPE_NONE = 0;
+    /**
+     */
+    public static final int TYPE_DEVICE = 1;
+    /**
+     */
+    public static final int TYPE_SUBMIX = 2;
+    /**
+     */
+    public static final int TYPE_SESSION = 3;
+
+
+    @UnsupportedAppUsage
+    AudioHandle mHandle;
+    @UnsupportedAppUsage
+    protected final int mRole;
+    private final String mName;
+    private final int[] mSamplingRates;
+    private final int[] mChannelMasks;
+    private final int[] mChannelIndexMasks;
+    private final int[] mFormats;
+    private final List<AudioProfile> mProfiles;
+    private final List<AudioDescriptor> mDescriptors;
+    @UnsupportedAppUsage
+    private final AudioGain[] mGains;
+    @UnsupportedAppUsage
+    private AudioPortConfig mActiveConfig;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    AudioPort(AudioHandle handle, int role, String name,
+            int[] samplingRates, int[] channelMasks, int[] channelIndexMasks,
+            int[] formats, AudioGain[] gains) {
+        mHandle = handle;
+        mRole = role;
+        mName = name;
+        mSamplingRates = samplingRates;
+        mChannelMasks = channelMasks;
+        mChannelIndexMasks = channelIndexMasks;
+        mFormats = formats;
+        mGains = gains;
+        mProfiles = new ArrayList<>();
+        if (mFormats != null) {
+            for (int format : mFormats) {
+                mProfiles.add(new AudioProfile(
+                        format, samplingRates, channelMasks, channelIndexMasks,
+                        AudioProfile.AUDIO_ENCAPSULATION_TYPE_NONE));
+            }
+        }
+        mDescriptors = new ArrayList<>();
+    }
+
+    AudioPort(AudioHandle handle, int role, String name,
+              List<AudioProfile> profiles, AudioGain[] gains,
+              List<AudioDescriptor> descriptors) {
+        mHandle = handle;
+        mRole = role;
+        mName = name;
+        mProfiles = profiles;
+        mDescriptors = descriptors;
+        mGains = gains;
+        Set<Integer> formats = new HashSet<>();
+        Set<Integer> samplingRates = new HashSet<>();
+        Set<Integer> channelMasks = new HashSet<>();
+        Set<Integer> channelIndexMasks = new HashSet<>();
+        for (AudioProfile profile : profiles) {
+            formats.add(profile.getFormat());
+            samplingRates.addAll(Arrays.stream(profile.getSampleRates()).boxed()
+                    .collect(Collectors.toList()));
+            channelMasks.addAll(Arrays.stream(profile.getChannelMasks()).boxed()
+                    .collect(Collectors.toList()));
+            channelIndexMasks.addAll(Arrays.stream(profile.getChannelIndexMasks()).boxed()
+                    .collect(Collectors.toList()));
+        }
+        mSamplingRates = samplingRates.stream().mapToInt(Number::intValue).toArray();
+        mChannelMasks = channelMasks.stream().mapToInt(Number::intValue).toArray();
+        mChannelIndexMasks = channelIndexMasks.stream().mapToInt(Number::intValue).toArray();
+        mFormats = formats.stream().mapToInt(Number::intValue).toArray();
+    }
+
+    AudioHandle handle() {
+        return mHandle;
+    }
+
+    /**
+     * Get the system unique device ID.
+     */
+    @UnsupportedAppUsage
+    public int id() {
+        return mHandle.id();
+    }
+
+
+    /**
+     * Get the audio port role
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public int role() {
+        return mRole;
+    }
+
+    /**
+     * Get the human-readable name of this port. Perhaps an internal
+     * designation or an physical device.
+     */
+    public String name() {
+        return mName;
+    }
+
+    /**
+     * Get the list of supported sampling rates
+     * Empty array if sampling rate is not relevant for this audio port
+     */
+    public int[] samplingRates() {
+        return mSamplingRates;
+    }
+
+    /**
+     * Get the list of supported channel mask configurations
+     * (e.g AudioFormat.CHANNEL_OUT_STEREO)
+     * Empty array if channel mask is not relevant for this audio port
+     */
+    public int[] channelMasks() {
+        return mChannelMasks;
+    }
+
+    /**
+     * Get the list of supported channel index mask configurations
+     * (e.g 0x0003 means 2 channel, 0x000F means 4 channel....)
+     * Empty array if channel index mask is not relevant for this audio port
+     */
+    public int[] channelIndexMasks() {
+        return mChannelIndexMasks;
+    }
+
+    /**
+     * Get the list of supported audio format configurations
+     * (e.g AudioFormat.ENCODING_PCM_16BIT)
+     * Empty array if format is not relevant for this audio port
+     */
+    public int[] formats() {
+        return mFormats;
+    }
+
+    /**
+     * Get the list of supported audio profiles
+     */
+    public List<AudioProfile> profiles() {
+        return mProfiles;
+    }
+
+    /**
+     * Get the list of audio descriptor
+     */
+    public List<AudioDescriptor> audioDescriptors() {
+        return mDescriptors;
+    }
+
+    /**
+     * Get the list of gain descriptors
+     * Empty array if this port does not have gain control
+     */
+    public AudioGain[] gains() {
+        return mGains;
+    }
+
+    /**
+     * Get the gain descriptor at a given index
+     */
+    AudioGain gain(int index) {
+        if (index < 0 || index >= mGains.length) {
+            return null;
+        }
+        return mGains[index];
+    }
+
+    /**
+     * Build a specific configuration of this audio port for use by methods
+     * like AudioManager.connectAudioPatch().
+     * @param samplingRate
+     * @param channelMask The desired channel mask. AudioFormat.CHANNEL_OUT_DEFAULT if no change
+     * from active configuration requested.
+     * @param format The desired audio format. AudioFormat.ENCODING_DEFAULT if no change
+     * from active configuration requested.
+     * @param gain The desired gain. null if no gain changed requested.
+     */
+    public AudioPortConfig buildConfig(int samplingRate, int channelMask, int format,
+                                        AudioGainConfig gain) {
+        return new AudioPortConfig(this, samplingRate, channelMask, format, gain);
+    }
+
+    /**
+     * Get currently active configuration of this audio port.
+     */
+    public AudioPortConfig activeConfig() {
+        return mActiveConfig;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null || !(o instanceof AudioPort)) {
+            return false;
+        }
+        AudioPort ap = (AudioPort)o;
+        return mHandle.equals(ap.handle());
+    }
+
+    @Override
+    public int hashCode() {
+        return mHandle.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        String role = Integer.toString(mRole);
+        switch (mRole) {
+            case ROLE_NONE:
+                role = "NONE";
+                break;
+            case ROLE_SOURCE:
+                role = "SOURCE";
+                break;
+            case ROLE_SINK:
+                role = "SINK";
+                break;
+        }
+        return "{mHandle: " + mHandle
+                + ", mRole: " + role
+                + "}";
+    }
+}
diff --git a/android/media/AudioPortConfig.java b/android/media/AudioPortConfig.java
new file mode 100644
index 0000000..4dd3cb6
--- /dev/null
+++ b/android/media/AudioPortConfig.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2014 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.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+
+/**
+ * An AudioPortConfig contains a possible configuration of an audio port chosen
+ * among all possible attributes described by an AudioPort.
+ * An AudioPortConfig is created by AudioPort.buildConfiguration().
+ * AudioPorts are used to specify the sources and sinks of a patch created
+ * with AudioManager.connectAudioPatch().
+ * Several specialized versions of AudioPortConfig exist to handle different categories of
+ * audio ports and their specific attributes:
+ * - AudioDevicePortConfig for input (e.g micropohone) and output devices (e.g speaker)
+ * - AudioMixPortConfig for input or output streams of the audio framework.
+ * @hide
+ */
+
+public class AudioPortConfig {
+    @UnsupportedAppUsage
+    final AudioPort mPort;
+    @UnsupportedAppUsage
+    private final int mSamplingRate;
+    @UnsupportedAppUsage
+    private final int mChannelMask;
+    @UnsupportedAppUsage
+    private final int mFormat;
+    @UnsupportedAppUsage
+    private final AudioGainConfig mGain;
+
+    // mConfigMask indicates which fields in this configuration should be
+    // taken into account. Used with AudioSystem.setAudioPortConfig()
+    // framework use only.
+    static final int SAMPLE_RATE  = 0x1;
+    static final int CHANNEL_MASK = 0x2;
+    static final int FORMAT       = 0x4;
+    static final int GAIN         = 0x8;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    int mConfigMask;
+
+    @UnsupportedAppUsage
+    AudioPortConfig(AudioPort port, int samplingRate, int channelMask, int format,
+            AudioGainConfig gain) {
+        mPort = port;
+        mSamplingRate = samplingRate;
+        mChannelMask = channelMask;
+        mFormat = format;
+        mGain = gain;
+        mConfigMask = 0;
+    }
+
+    /**
+     * Returns the audio port this AudioPortConfig is issued from.
+     */
+    @UnsupportedAppUsage
+    public AudioPort port() {
+        return mPort;
+    }
+
+    /**
+     * Sampling rate configured for this AudioPortConfig.
+     */
+    public int samplingRate() {
+        return mSamplingRate;
+    }
+
+    /**
+     * Channel mask configuration (e.g AudioFormat.CHANNEL_CONFIGURATION_STEREO).
+     */
+    public int channelMask() {
+        return mChannelMask;
+    }
+
+    /**
+     * Audio format configuration (e.g AudioFormat.ENCODING_PCM_16BIT).
+     */
+    public int format() {
+        return mFormat;
+    }
+
+    /**
+     * The gain configuration if this port supports gain control, null otherwise
+     */
+    public AudioGainConfig gain() {
+        return mGain;
+    }
+
+    @Override
+    public String toString() {
+        return "{mPort:" + mPort
+                + ", mSamplingRate:" + mSamplingRate
+                + ", mChannelMask: " + mChannelMask
+                + ", mFormat:" + mFormat
+                + ", mGain:" + mGain
+                + "}";
+    }
+}
diff --git a/android/media/AudioPortEventHandler.java b/android/media/AudioPortEventHandler.java
new file mode 100644
index 0000000..763eb29
--- /dev/null
+++ b/android/media/AudioPortEventHandler.java
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2014 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.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+/**
+ * The AudioPortEventHandler handles AudioManager.OnAudioPortUpdateListener callbacks
+ * posted from JNI
+ * @hide
+ */
+
+class AudioPortEventHandler {
+    private Handler mHandler;
+    private HandlerThread mHandlerThread;
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private final ArrayList<AudioManager.OnAudioPortUpdateListener> mListeners =
+            new ArrayList<AudioManager.OnAudioPortUpdateListener>();
+
+    private static final String TAG = "AudioPortEventHandler";
+
+    private static final int AUDIOPORT_EVENT_PORT_LIST_UPDATED = 1;
+    private static final int AUDIOPORT_EVENT_PATCH_LIST_UPDATED = 2;
+    private static final int AUDIOPORT_EVENT_SERVICE_DIED = 3;
+    private static final int AUDIOPORT_EVENT_NEW_LISTENER = 4;
+
+    private static final long RESCHEDULE_MESSAGE_DELAY_MS = 100;
+
+    /**
+     * Accessed by native methods: JNI Callback context.
+     */
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private long mJniCallback;
+
+    void init() {
+        synchronized (mLock) {
+            if (mHandler != null) {
+                return;
+            }
+            // create a new thread for our new event handler
+            mHandlerThread = new HandlerThread(TAG);
+            mHandlerThread.start();
+
+            if (mHandlerThread.getLooper() != null) {
+                mHandler = new Handler(mHandlerThread.getLooper()) {
+                    @Override
+                    public void handleMessage(Message msg) {
+                        ArrayList<AudioManager.OnAudioPortUpdateListener> listeners;
+                        synchronized (mLock) {
+                            if (msg.what == AUDIOPORT_EVENT_NEW_LISTENER) {
+                                listeners = new ArrayList<AudioManager.OnAudioPortUpdateListener>();
+                                if (mListeners.contains(msg.obj)) {
+                                    listeners.add((AudioManager.OnAudioPortUpdateListener)msg.obj);
+                                }
+                            } else {
+                                listeners = (ArrayList<AudioManager.OnAudioPortUpdateListener>)
+                                        mListeners.clone();
+                            }
+                        }
+                        // reset audio port cache if the event corresponds to a change coming
+                        // from audio policy service or if mediaserver process died.
+                        if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED ||
+                                msg.what == AUDIOPORT_EVENT_PATCH_LIST_UPDATED ||
+                                msg.what == AUDIOPORT_EVENT_SERVICE_DIED) {
+                            AudioManager.resetAudioPortGeneration();
+                        }
+
+                        if (listeners.isEmpty()) {
+                            return;
+                        }
+
+                        ArrayList<AudioPort> ports = new ArrayList<AudioPort>();
+                        ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>();
+                        if (msg.what != AUDIOPORT_EVENT_SERVICE_DIED) {
+                            int status = AudioManager.updateAudioPortCache(ports, patches, null);
+                            if (status != AudioManager.SUCCESS) {
+                                // Since audio ports and audio patches are not null, the return
+                                // value could be ERROR due to inconsistency between port generation
+                                // and patch generation. In this case, we need to reschedule the
+                                // message to make sure the native callback is done.
+                                sendMessageDelayed(obtainMessage(msg.what, msg.obj),
+                                        RESCHEDULE_MESSAGE_DELAY_MS);
+                                return;
+                            }
+                        }
+
+                        switch (msg.what) {
+                        case AUDIOPORT_EVENT_NEW_LISTENER:
+                        case AUDIOPORT_EVENT_PORT_LIST_UPDATED:
+                            AudioPort[] portList = ports.toArray(new AudioPort[0]);
+                            for (int i = 0; i < listeners.size(); i++) {
+                                listeners.get(i).onAudioPortListUpdate(portList);
+                            }
+                            if (msg.what == AUDIOPORT_EVENT_PORT_LIST_UPDATED) {
+                                break;
+                            }
+                            // FALL THROUGH
+
+                        case AUDIOPORT_EVENT_PATCH_LIST_UPDATED:
+                            AudioPatch[] patchList = patches.toArray(new AudioPatch[0]);
+                            for (int i = 0; i < listeners.size(); i++) {
+                                listeners.get(i).onAudioPatchListUpdate(patchList);
+                            }
+                            break;
+
+                        case AUDIOPORT_EVENT_SERVICE_DIED:
+                            for (int i = 0; i < listeners.size(); i++) {
+                                listeners.get(i).onServiceDied();
+                            }
+                            break;
+
+                        default:
+                            break;
+                        }
+                    }
+                };
+                native_setup(new WeakReference<AudioPortEventHandler>(this));
+            } else {
+                mHandler = null;
+            }
+        }
+    }
+
+    private native void native_setup(Object module_this);
+
+    @Override
+    protected void finalize() {
+        native_finalize();
+        if (mHandlerThread.isAlive()) {
+            mHandlerThread.quit();
+        }
+    }
+    private native void native_finalize();
+
+    void registerListener(AudioManager.OnAudioPortUpdateListener l) {
+        synchronized (mLock) {
+            mListeners.add(l);
+        }
+        if (mHandler != null) {
+            Message m = mHandler.obtainMessage(AUDIOPORT_EVENT_NEW_LISTENER, 0, 0, l);
+            mHandler.sendMessage(m);
+        }
+    }
+
+    void unregisterListener(AudioManager.OnAudioPortUpdateListener l) {
+        synchronized (mLock) {
+            mListeners.remove(l);
+        }
+    }
+
+    Handler handler() {
+        return mHandler;
+    }
+
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static void postEventFromNative(Object module_ref,
+                                            int what, int arg1, int arg2, Object obj) {
+        AudioPortEventHandler eventHandler =
+                (AudioPortEventHandler)((WeakReference)module_ref).get();
+        if (eventHandler == null) {
+            return;
+        }
+
+        if (eventHandler != null) {
+            Handler handler = eventHandler.handler();
+            if (handler != null) {
+                Message m = handler.obtainMessage(what, arg1, arg2, obj);
+                if (what != AUDIOPORT_EVENT_NEW_LISTENER) {
+                    // Except AUDIOPORT_EVENT_NEW_LISTENER, we can only respect the last message.
+                    handler.removeMessages(what);
+                }
+                handler.sendMessage(m);
+            }
+        }
+    }
+
+}
diff --git a/android/media/AudioPresentation.java b/android/media/AudioPresentation.java
new file mode 100644
index 0000000..47358be
--- /dev/null
+++ b/android/media/AudioPresentation.java
@@ -0,0 +1,452 @@
+/*
+ * Copyright (C) 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.icu.util.ULocale;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.HashMap;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+
+
+/**
+ * The AudioPresentation class encapsulates the information that describes an audio presentation
+ * which is available in next generation audio content.
+ *
+ * Used by {@link MediaExtractor} {@link MediaExtractor#getAudioPresentations(int)} and
+ * {@link AudioTrack} {@link AudioTrack#setPresentation(AudioPresentation)} to query available
+ * presentations and to select one, respectively.
+ *
+ * A list of available audio presentations in a media source can be queried using
+ * {@link MediaExtractor#getAudioPresentations(int)}. This list can be presented to a user for
+ * selection.
+ * An AudioPresentation can be passed to an offloaded audio decoder via
+ * {@link AudioTrack#setPresentation(AudioPresentation)} to request decoding of the selected
+ * presentation. An audio stream may contain multiple presentations that differ by language,
+ * accessibility, end point mastering and dialogue enhancement. An audio presentation may also have
+ * a set of description labels in different languages to help the user to make an informed
+ * selection.
+ *
+ * Applications that parse media streams and extract presentation information on their own
+ * can create instances of AudioPresentation by using {@link AudioPresentation.Builder} class.
+ */
+public final class AudioPresentation {
+    private final int mPresentationId;
+    private final int mProgramId;
+    private final ULocale mLanguage;
+
+    /** @hide */
+    @IntDef(
+        value = {
+        CONTENT_UNKNOWN,
+        CONTENT_MAIN,
+        CONTENT_MUSIC_AND_EFFECTS,
+        CONTENT_VISUALLY_IMPAIRED,
+        CONTENT_HEARING_IMPAIRED,
+        CONTENT_DIALOG,
+        CONTENT_COMMENTARY,
+        CONTENT_EMERGENCY,
+        CONTENT_VOICEOVER,
+    })
+
+    /**
+     * The ContentClassifier int definitions represent the AudioPresentation content
+     * classifier (as per TS 103 190-1 v1.2.1 4.3.3.8.1)
+    */
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ContentClassifier {}
+
+    /**
+     * Audio presentation classifier: Unknown.
+     */
+    public static final int CONTENT_UNKNOWN                 = -1;
+    /**
+     * Audio presentation classifier: Complete main.
+     */
+    public static final int CONTENT_MAIN                    = 0;
+    /**
+     * Audio presentation content classifier: Music and effects.
+     */
+    public static final int CONTENT_MUSIC_AND_EFFECTS       = 1;
+    /**
+     * Audio presentation content classifier: Visually impaired.
+     */
+    public static final int CONTENT_VISUALLY_IMPAIRED       = 2;
+    /**
+     * Audio presentation content classifier: Hearing impaired.
+     */
+    public static final int CONTENT_HEARING_IMPAIRED        = 3;
+    /**
+     * Audio presentation content classifier: Dialog.
+     */
+    public static final int CONTENT_DIALOG                  = 4;
+    /**
+     * Audio presentation content classifier: Commentary.
+     */
+    public static final int CONTENT_COMMENTARY              = 5;
+    /**
+     * Audio presentation content classifier: Emergency.
+     */
+    public static final int CONTENT_EMERGENCY               = 6;
+    /**
+     * Audio presentation content classifier: Voice over.
+     */
+    public static final int CONTENT_VOICEOVER               = 7;
+
+    /** @hide */
+    @IntDef(
+        value = {
+            MASTERING_NOT_INDICATED,
+            MASTERED_FOR_STEREO,
+            MASTERED_FOR_SURROUND,
+            MASTERED_FOR_3D,
+            MASTERED_FOR_HEADPHONE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MasteringIndicationType {}
+    private final @MasteringIndicationType int mMasteringIndication;
+    private final boolean mAudioDescriptionAvailable;
+    private final boolean mSpokenSubtitlesAvailable;
+    private final boolean mDialogueEnhancementAvailable;
+    private final Map<ULocale, CharSequence> mLabels;
+
+    /**
+     * No preferred reproduction channel layout.
+     *
+     * @see Builder#setMasteringIndication(int)
+     */
+    public static final int MASTERING_NOT_INDICATED         = 0;
+    /**
+     * Stereo speaker layout.
+     *
+     * @see Builder#setMasteringIndication(int)
+     */
+    public static final int MASTERED_FOR_STEREO             = 1;
+    /**
+     * Two-dimensional (e.g. 5.1) speaker layout.
+     *
+     * @see Builder#setMasteringIndication(int)
+     */
+    public static final int MASTERED_FOR_SURROUND           = 2;
+    /**
+     * Three-dimensional (e.g. 5.1.2) speaker layout.
+     *
+     * @see Builder#setMasteringIndication(int)
+     */
+    public static final int MASTERED_FOR_3D                 = 3;
+    /**
+     * Prerendered for headphone playback.
+     *
+     * @see Builder#setMasteringIndication(int)
+     */
+    public static final int MASTERED_FOR_HEADPHONE          = 4;
+
+    /**
+     * This ID is reserved. No items can be explicitly assigned this ID.
+     */
+    private static final int UNKNOWN_ID = -1;
+
+    /**
+     * This allows an application developer to construct an AudioPresentation object with all the
+     * parameters.
+     * The IDs are all that is required for an
+     * {@link AudioTrack#setPresentation(AudioPresentation)} to be successful.
+     * The rest of the metadata is informative only so as to distinguish features
+     * of different presentations.
+     * @param presentationId Presentation ID to be decoded by a next generation audio decoder.
+     * @param programId Program ID to be decoded by a next generation audio decoder.
+     * @param language Locale corresponding to ISO 639-1/639-2 language code.
+     * @param masteringIndication One of {@link AudioPresentation#MASTERING_NOT_INDICATED},
+     *     {@link AudioPresentation#MASTERED_FOR_STEREO},
+     *     {@link AudioPresentation#MASTERED_FOR_SURROUND},
+     *     {@link AudioPresentation#MASTERED_FOR_3D},
+     *     {@link AudioPresentation#MASTERED_FOR_HEADPHONE}.
+     * @param audioDescriptionAvailable Audio description for the visually impaired.
+     * @param spokenSubtitlesAvailable Spoken subtitles for the visually impaired.
+     * @param dialogueEnhancementAvailable Dialogue enhancement.
+     * @param labels Text label indexed by its locale corresponding to the language code.
+     */
+    private AudioPresentation(int presentationId,
+                             int programId,
+                             @NonNull ULocale language,
+                             @MasteringIndicationType int masteringIndication,
+                             boolean audioDescriptionAvailable,
+                             boolean spokenSubtitlesAvailable,
+                             boolean dialogueEnhancementAvailable,
+                             @NonNull Map<ULocale, CharSequence> labels) {
+        mPresentationId = presentationId;
+        mProgramId = programId;
+        mLanguage = language;
+        mMasteringIndication = masteringIndication;
+        mAudioDescriptionAvailable = audioDescriptionAvailable;
+        mSpokenSubtitlesAvailable = spokenSubtitlesAvailable;
+        mDialogueEnhancementAvailable = dialogueEnhancementAvailable;
+        mLabels = new HashMap<ULocale, CharSequence>(labels);
+    }
+
+    /**
+     * Returns presentation ID used by the framework to select an audio presentation rendered by a
+     * decoder. Presentation ID is typically sequential, but does not have to be.
+     */
+    public int getPresentationId() {
+        return mPresentationId;
+    }
+
+    /**
+     * Returns program ID used by the framework to select an audio presentation rendered by a
+     * decoder. Program ID can be used to further uniquely identify the presentation to a decoder.
+     */
+    public int getProgramId() {
+        return mProgramId;
+    }
+
+    /**
+     * @return a map of available text labels for this presentation. Each label is indexed by its
+     * locale corresponding to the language code as specified by ISO 639-2. Either ISO 639-2/B
+     * or ISO 639-2/T could be used.
+     */
+    public Map<Locale, String> getLabels() {
+        Map<Locale, String> localeLabels = new HashMap<Locale, String>(mLabels.size());
+        for (Map.Entry<ULocale, CharSequence> entry : mLabels.entrySet()) {
+            localeLabels.put(entry.getKey().toLocale(), entry.getValue().toString());
+        }
+        return localeLabels;
+    }
+
+    private Map<ULocale, CharSequence> getULabels() {
+        return mLabels;
+    }
+
+    /**
+     * @return the locale corresponding to audio presentation's ISO 639-1/639-2 language code.
+     */
+    public Locale getLocale() {
+        return mLanguage.toLocale();
+    }
+
+    private ULocale getULocale() {
+        return mLanguage;
+    }
+
+    /**
+     * @return the mastering indication of the audio presentation.
+     * See {@link AudioPresentation#MASTERING_NOT_INDICATED},
+     *     {@link AudioPresentation#MASTERED_FOR_STEREO},
+     *     {@link AudioPresentation#MASTERED_FOR_SURROUND},
+     *     {@link AudioPresentation#MASTERED_FOR_3D},
+     *     {@link AudioPresentation#MASTERED_FOR_HEADPHONE}
+     */
+    @MasteringIndicationType
+    public int getMasteringIndication() {
+        return mMasteringIndication;
+    }
+
+    /**
+     * Indicates whether an audio description for the visually impaired is available.
+     * @return {@code true} if audio description is available.
+     */
+    public boolean hasAudioDescription() {
+        return mAudioDescriptionAvailable;
+    }
+
+    /**
+     * Indicates whether spoken subtitles for the visually impaired are available.
+     * @return {@code true} if spoken subtitles are available.
+     */
+    public boolean hasSpokenSubtitles() {
+        return mSpokenSubtitlesAvailable;
+    }
+
+    /**
+     * Indicates whether dialogue enhancement is available.
+     * @return {@code true} if dialogue enhancement is available.
+     */
+    public boolean hasDialogueEnhancement() {
+        return mDialogueEnhancementAvailable;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof AudioPresentation)) {
+            return false;
+        }
+        AudioPresentation obj = (AudioPresentation) o;
+        return mPresentationId == obj.getPresentationId()
+                && mProgramId == obj.getProgramId()
+                && mLanguage.equals(obj.getULocale())
+                && mMasteringIndication == obj.getMasteringIndication()
+                && mAudioDescriptionAvailable == obj.hasAudioDescription()
+                && mSpokenSubtitlesAvailable == obj.hasSpokenSubtitles()
+                && mDialogueEnhancementAvailable == obj.hasDialogueEnhancement()
+                && mLabels.equals(obj.getULabels());
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mPresentationId,
+                mProgramId,
+                mLanguage.hashCode(),
+                mMasteringIndication,
+                mAudioDescriptionAvailable,
+                mSpokenSubtitlesAvailable,
+                mDialogueEnhancementAvailable,
+                mLabels.hashCode());
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getClass().getSimpleName() + " ");
+        sb.append("{ presentation id=" + mPresentationId);
+        sb.append(", program id=" + mProgramId);
+        sb.append(", language=" + mLanguage);
+        sb.append(", labels=" + mLabels);
+        sb.append(", mastering indication=" + mMasteringIndication);
+        sb.append(", audio description=" + mAudioDescriptionAvailable);
+        sb.append(", spoken subtitles=" + mSpokenSubtitlesAvailable);
+        sb.append(", dialogue enhancement=" + mDialogueEnhancementAvailable);
+        sb.append(" }");
+        return sb.toString();
+    }
+
+    /**
+     * A builder class for creating {@link AudioPresentation} objects.
+     */
+    public static final class Builder {
+        private final int mPresentationId;
+        private int mProgramId = UNKNOWN_ID;
+        private ULocale mLanguage = new ULocale("");
+        private int mMasteringIndication = MASTERING_NOT_INDICATED;
+        private boolean mAudioDescriptionAvailable = false;
+        private boolean mSpokenSubtitlesAvailable = false;
+        private boolean mDialogueEnhancementAvailable = false;
+        private Map<ULocale, CharSequence> mLabels = new HashMap<ULocale, CharSequence>();
+
+        /**
+         * Create a {@link Builder}. Any field that should be included in the
+         * {@link AudioPresentation} must be added.
+         *
+         * @param presentationId The presentation ID of this audio presentation.
+         */
+        public Builder(int presentationId) {
+            mPresentationId = presentationId;
+        }
+        /**
+         * Sets the ProgramId to which this audio presentation refers.
+         *
+         * @param programId The program ID to be decoded.
+         */
+        public @NonNull Builder setProgramId(int programId) {
+            mProgramId = programId;
+            return this;
+        }
+        /**
+         * Sets the language information of the audio presentation.
+         *
+         * @param language Locale corresponding to ISO 639-1/639-2 language code.
+         */
+        public @NonNull Builder setLocale(@NonNull ULocale language) {
+            mLanguage = language;
+            return this;
+        }
+
+        /**
+         * Sets the mastering indication.
+         *
+         * @param masteringIndication Input to set mastering indication.
+         * @throws IllegalArgumentException if the mastering indication is not any of
+         * {@link AudioPresentation#MASTERING_NOT_INDICATED},
+         * {@link AudioPresentation#MASTERED_FOR_STEREO},
+         * {@link AudioPresentation#MASTERED_FOR_SURROUND},
+         * {@link AudioPresentation#MASTERED_FOR_3D},
+         * and {@link AudioPresentation#MASTERED_FOR_HEADPHONE}
+         */
+        public @NonNull Builder setMasteringIndication(
+                @MasteringIndicationType int masteringIndication) {
+            if (masteringIndication != MASTERING_NOT_INDICATED
+                    && masteringIndication != MASTERED_FOR_STEREO
+                    && masteringIndication != MASTERED_FOR_SURROUND
+                    && masteringIndication != MASTERED_FOR_3D
+                    && masteringIndication != MASTERED_FOR_HEADPHONE) {
+                throw new IllegalArgumentException("Unknown mastering indication: "
+                                                        + masteringIndication);
+            }
+            mMasteringIndication = masteringIndication;
+            return this;
+        }
+
+        /**
+         * Sets locale / text label pairs describing the presentation.
+         *
+         * @param labels Text label indexed by its locale corresponding to the language code.
+         */
+        public @NonNull Builder setLabels(@NonNull Map<ULocale, CharSequence> labels) {
+            mLabels = new HashMap<ULocale, CharSequence>(labels);
+            return this;
+        }
+
+        /**
+         * Indicate whether the presentation contains audio description for the visually impaired.
+         *
+         * @param audioDescriptionAvailable Audio description for the visually impaired.
+         */
+        public @NonNull Builder setHasAudioDescription(boolean audioDescriptionAvailable) {
+            mAudioDescriptionAvailable = audioDescriptionAvailable;
+            return this;
+        }
+
+        /**
+         * Indicate whether the presentation contains spoken subtitles for the visually impaired.
+         *
+         * @param spokenSubtitlesAvailable Spoken subtitles for the visually impaired.
+         */
+        public @NonNull Builder setHasSpokenSubtitles(boolean spokenSubtitlesAvailable) {
+            mSpokenSubtitlesAvailable = spokenSubtitlesAvailable;
+            return this;
+        }
+
+        /**
+         * Indicate whether the presentation supports dialogue enhancement.
+         *
+         * @param dialogueEnhancementAvailable Dialogue enhancement.
+         */
+        public @NonNull Builder setHasDialogueEnhancement(boolean dialogueEnhancementAvailable) {
+            mDialogueEnhancementAvailable = dialogueEnhancementAvailable;
+            return this;
+        }
+
+        /**
+         * Creates a {@link AudioPresentation} instance with the specified fields.
+         *
+         * @return The new {@link AudioPresentation} instance
+         */
+        public @NonNull AudioPresentation build() {
+            return new AudioPresentation(mPresentationId, mProgramId,
+                                           mLanguage, mMasteringIndication,
+                                           mAudioDescriptionAvailable, mSpokenSubtitlesAvailable,
+                                           mDialogueEnhancementAvailable, mLabels);
+        }
+    }
+}
diff --git a/android/media/AudioProfile.java b/android/media/AudioProfile.java
new file mode 100644
index 0000000..ae8d0a5
--- /dev/null
+++ b/android/media/AudioProfile.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2020 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.annotation.IntDef;
+import android.annotation.NonNull;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Arrays;
+import java.util.stream.Collectors;
+
+/**
+ * An AudioProfile is specific to an audio format and lists supported sampling rates and
+ * channel masks for that format.  An {@link AudioDeviceInfo} has a list of supported AudioProfiles.
+ * There can be multiple profiles whose encoding format is the same. This usually happens when
+ * an encoding format is only supported when it is encapsulated by some particular encapsulation
+ * types. If there are multiple encapsulation types that can carry this encoding format, they will
+ * be reported in different audio profiles. The application can choose any of the encapsulation
+ * types.
+ */
+public class AudioProfile {
+    /**
+     * No encapsulation type is specified.
+     */
+    public static final int AUDIO_ENCAPSULATION_TYPE_NONE = 0;
+    /**
+     * Encapsulation format is defined in standard IEC 61937.
+     */
+    public static final int AUDIO_ENCAPSULATION_TYPE_IEC61937 = 1;
+
+    /** @hide */
+    @IntDef({
+            AUDIO_ENCAPSULATION_TYPE_NONE,
+            AUDIO_ENCAPSULATION_TYPE_IEC61937,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EncapsulationType {}
+
+    private final int mFormat;
+    private final int[] mSamplingRates;
+    private final int[] mChannelMasks;
+    private final int[] mChannelIndexMasks;
+    private final int mEncapsulationType;
+
+    AudioProfile(int format, @NonNull int[] samplingRates, @NonNull int[] channelMasks,
+                 @NonNull int[] channelIndexMasks,
+                 int encapsulationType) {
+        mFormat = format;
+        mSamplingRates = samplingRates;
+        mChannelMasks = channelMasks;
+        mChannelIndexMasks = channelIndexMasks;
+        mEncapsulationType = encapsulationType;
+    }
+
+    /**
+     * @return the encoding format for this AudioProfile.
+     */
+    public @AudioFormat.Encoding int getFormat() {
+        return mFormat;
+    }
+
+    /**
+     * @return an array of channel position masks that are associated with the encoding format.
+     */
+    public @NonNull int[] getChannelMasks() {
+        return mChannelMasks;
+    }
+
+    /**
+     * @return an array of channel index masks that are associated with the encoding format.
+     */
+    public @NonNull int[] getChannelIndexMasks() {
+        return mChannelIndexMasks;
+    }
+
+    /**
+     * @return an array of sample rates that are associated with the encoding format.
+     */
+    public @NonNull int[] getSampleRates() {
+        return mSamplingRates;
+    }
+
+    /**
+     * The encapsulation type indicates what encapsulation type is required when the framework is
+     * using this format when playing to a device exposing this audio profile.
+     * When encapsulation is required, only playback with {@link android.media.AudioTrack} API is
+     * supported. But playback with {@link android.media.MediaPlayer} is not.
+     * When an encapsulation type is required, the {@link AudioFormat} encoding selected when
+     * creating the {@link AudioTrack} must match the encapsulation type, e.g
+     * AudioFormat.ENCODING_IEC61937 for AUDIO_ENCAPSULATION_TYPE_IEC61937.
+     *
+     * @return an integer representing the encapsulation type
+     *
+     * @see #AUDIO_ENCAPSULATION_TYPE_NONE
+     * @see #AUDIO_ENCAPSULATION_TYPE_IEC61937
+     */
+    public @EncapsulationType int getEncapsulationType() {
+        return mEncapsulationType;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder("{");
+        sb.append(AudioFormat.toLogFriendlyEncoding(mFormat));
+        if (mSamplingRates != null && mSamplingRates.length > 0) {
+            sb.append(", sampling rates=").append(Arrays.toString(mSamplingRates));
+        }
+        if (mChannelMasks != null && mChannelMasks.length > 0) {
+            sb.append(", channel masks=").append(toHexString(mChannelMasks));
+        }
+        if (mChannelIndexMasks != null && mChannelIndexMasks.length > 0) {
+            sb.append(", channel index masks=").append(Arrays.toString(mChannelIndexMasks));
+        }
+        sb.append("}");
+        return sb.toString();
+    }
+
+    private static String toHexString(int[] ints) {
+        if (ints == null || ints.length == 0) {
+            return "";
+        }
+        return Arrays.stream(ints).mapToObj(anInt -> String.format("0x%02X", anInt))
+                .collect(Collectors.joining(", "));
+    }
+}
diff --git a/android/media/AudioRecord.java b/android/media/AudioRecord.java
new file mode 100644
index 0000000..7c6ae28
--- /dev/null
+++ b/android/media/AudioRecord.java
@@ -0,0 +1,2423 @@
+/*
+ * Copyright (C) 2008 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.annotation.CallbackExecutor;
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.app.ActivityThread;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
+import android.content.AttributionSource.ScopedParcelState;
+import android.content.Context;
+import android.media.MediaRecorder.Source;
+import android.media.audiopolicy.AudioMix;
+import android.media.audiopolicy.AudioPolicy;
+import android.media.metrics.LogSessionId;
+import android.media.projection.MediaProjection;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.PersistableBundle;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * The AudioRecord class manages the audio resources for Java applications
+ * to record audio from the audio input hardware of the platform. This is
+ * achieved by "pulling" (reading) the data from the AudioRecord object. The
+ * application is responsible for polling the AudioRecord object in time using one of
+ * the following three methods:  {@link #read(byte[],int, int)}, {@link #read(short[], int, int)}
+ * or {@link #read(ByteBuffer, int)}. The choice of which method to use will be based
+ * on the audio data storage format that is the most convenient for the user of AudioRecord.
+ * <p>Upon creation, an AudioRecord object initializes its associated audio buffer that it will
+ * fill with the new audio data. The size of this buffer, specified during the construction,
+ * determines how long an AudioRecord can record before "over-running" data that has not
+ * been read yet. Data should be read from the audio hardware in chunks of sizes inferior to
+ * the total recording buffer size.</p>
+ * <p>
+ * Applications creating an AudioRecord instance need
+ * {@link android.Manifest.permission#RECORD_AUDIO} or the Builder will throw
+ * {@link java.lang.UnsupportedOperationException} on
+ * {@link android.media.AudioRecord.Builder#build build()},
+ * and the constructor will return an instance in state
+ * {@link #STATE_UNINITIALIZED}.</p>
+ */
+public class AudioRecord implements AudioRouting, MicrophoneDirection,
+        AudioRecordingMonitor, AudioRecordingMonitorClient
+{
+    //---------------------------------------------------------
+    // Constants
+    //--------------------
+
+
+    /**
+     *  indicates AudioRecord state is not successfully initialized.
+     */
+    public static final int STATE_UNINITIALIZED = 0;
+    /**
+     *  indicates AudioRecord state is ready to be used
+     */
+    public static final int STATE_INITIALIZED   = 1;
+
+    /**
+     * indicates AudioRecord recording state is not recording
+     */
+    public static final int RECORDSTATE_STOPPED = 1;  // matches SL_RECORDSTATE_STOPPED
+    /**
+     * indicates AudioRecord recording state is recording
+     */
+    public static final int RECORDSTATE_RECORDING = 3;// matches SL_RECORDSTATE_RECORDING
+
+    /**
+     * Denotes a successful operation.
+     */
+    public  static final int SUCCESS                               = AudioSystem.SUCCESS;
+    /**
+     * Denotes a generic operation failure.
+     */
+    public  static final int ERROR                                 = AudioSystem.ERROR;
+    /**
+     * Denotes a failure due to the use of an invalid value.
+     */
+    public  static final int ERROR_BAD_VALUE                       = AudioSystem.BAD_VALUE;
+    /**
+     * Denotes a failure due to the improper use of a method.
+     */
+    public  static final int ERROR_INVALID_OPERATION               = AudioSystem.INVALID_OPERATION;
+    /**
+     * An error code indicating that the object reporting it is no longer valid and needs to
+     * be recreated.
+     */
+    public  static final int ERROR_DEAD_OBJECT                     = AudioSystem.DEAD_OBJECT;
+
+    // Error codes:
+    // to keep in sync with frameworks/base/core/jni/android_media_AudioRecord.cpp
+    private static final int AUDIORECORD_ERROR_SETUP_ZEROFRAMECOUNT      = -16;
+    private static final int AUDIORECORD_ERROR_SETUP_INVALIDCHANNELMASK  = -17;
+    private static final int AUDIORECORD_ERROR_SETUP_INVALIDFORMAT       = -18;
+    private static final int AUDIORECORD_ERROR_SETUP_INVALIDSOURCE       = -19;
+    private static final int AUDIORECORD_ERROR_SETUP_NATIVEINITFAILED    = -20;
+
+    // Events:
+    // to keep in sync with frameworks/av/include/media/AudioRecord.h
+    /**
+     * Event id denotes when record head has reached a previously set marker.
+     */
+    private static final int NATIVE_EVENT_MARKER  = 2;
+    /**
+     * Event id denotes when previously set update period has elapsed during recording.
+     */
+    private static final int NATIVE_EVENT_NEW_POS = 3;
+
+    private final static String TAG = "android.media.AudioRecord";
+
+    /** @hide */
+    public final static String SUBMIX_FIXED_VOLUME = "fixedVolume";
+
+    /** @hide */
+    @IntDef({
+        READ_BLOCKING,
+        READ_NON_BLOCKING
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ReadMode {}
+
+    /**
+     * The read mode indicating the read operation will block until all data
+     * requested has been read.
+     */
+    public final static int READ_BLOCKING = 0;
+
+    /**
+     * The read mode indicating the read operation will return immediately after
+     * reading as much audio data as possible without blocking.
+     */
+    public final static int READ_NON_BLOCKING = 1;
+
+    //---------------------------------------------------------
+    // Used exclusively by native code
+    //--------------------
+    /**
+     * Accessed by native methods: provides access to C++ AudioRecord object
+     * Is 0 after release()
+     */
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage
+    private long mNativeRecorderInJavaObj;
+
+    /**
+     * Accessed by native methods: provides access to the callback data.
+     */
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private long mNativeCallbackCookie;
+
+    /**
+     * Accessed by native methods: provides access to the JNIDeviceCallback instance.
+     */
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private long mNativeDeviceCallback;
+
+
+    //---------------------------------------------------------
+    // Member variables
+    //--------------------
+    private AudioPolicy mAudioCapturePolicy;
+
+    /**
+     * The audio data sampling rate in Hz.
+     * Never {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED}.
+     */
+    private int mSampleRate; // initialized by all constructors via audioParamCheck()
+    /**
+     * The number of input audio channels (1 is mono, 2 is stereo)
+     */
+    private int mChannelCount;
+    /**
+     * The audio channel position mask
+     */
+    private int mChannelMask;
+    /**
+     * The audio channel index mask
+     */
+    private int mChannelIndexMask;
+    /**
+     * The encoding of the audio samples.
+     * @see AudioFormat#ENCODING_PCM_8BIT
+     * @see AudioFormat#ENCODING_PCM_16BIT
+     * @see AudioFormat#ENCODING_PCM_FLOAT
+     */
+    private int mAudioFormat;
+    /**
+     * Where the audio data is recorded from.
+     */
+    private int mRecordSource;
+    /**
+     * Indicates the state of the AudioRecord instance.
+     */
+    private int mState = STATE_UNINITIALIZED;
+    /**
+     * Indicates the recording state of the AudioRecord instance.
+     */
+    private int mRecordingState = RECORDSTATE_STOPPED;
+    /**
+     * Lock to make sure mRecordingState updates are reflecting the actual state of the object.
+     */
+    private final Object mRecordingStateLock = new Object();
+    /**
+     * The listener the AudioRecord notifies when the record position reaches a marker
+     * or for periodic updates during the progression of the record head.
+     *  @see #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)
+     *  @see #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)
+     */
+    private OnRecordPositionUpdateListener mPositionListener = null;
+    /**
+     * Lock to protect position listener updates against event notifications
+     */
+    private final Object mPositionListenerLock = new Object();
+    /**
+     * Handler for marker events coming from the native code
+     */
+    private NativeEventHandler mEventHandler = null;
+    /**
+     * Looper associated with the thread that creates the AudioRecord instance
+     */
+    @UnsupportedAppUsage
+    private Looper mInitializationLooper = null;
+    /**
+     * Size of the native audio buffer.
+     */
+    private int mNativeBufferSizeInBytes = 0;
+    /**
+     * Audio session ID
+     */
+    private int mSessionId = AudioManager.AUDIO_SESSION_ID_GENERATE;
+    /**
+     * AudioAttributes
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private AudioAttributes mAudioAttributes;
+    private boolean mIsSubmixFullVolume = false;
+
+    /**
+     * The log session id used for metrics.
+     * {@link LogSessionId#LOG_SESSION_ID_NONE} here means it is not set.
+     */
+    @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;
+
+    //---------------------------------------------------------
+    // Constructor, Finalize
+    //--------------------
+    /**
+     * Class constructor.
+     * Though some invalid parameters will result in an {@link IllegalArgumentException} exception,
+     * other errors do not.  Thus you should call {@link #getState()} immediately after construction
+     * to confirm that the object is usable.
+     * @param audioSource the recording source.
+     *   See {@link MediaRecorder.AudioSource} for the recording source definitions.
+     * @param sampleRateInHz the sample rate expressed in Hertz. 44100Hz is currently the only
+     *   rate that is guaranteed to work on all devices, but other rates such as 22050,
+     *   16000, and 11025 may work on some devices.
+     *   {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED} means to use a route-dependent value
+     *   which is usually the sample rate of the source.
+     *   {@link #getSampleRate()} can be used to retrieve the actual sample rate chosen.
+     * @param channelConfig describes the configuration of the audio channels.
+     *   See {@link AudioFormat#CHANNEL_IN_MONO} and
+     *   {@link AudioFormat#CHANNEL_IN_STEREO}.  {@link AudioFormat#CHANNEL_IN_MONO} is guaranteed
+     *   to work on all devices.
+     * @param audioFormat the format in which the audio data is to be returned.
+     *   See {@link AudioFormat#ENCODING_PCM_8BIT}, {@link AudioFormat#ENCODING_PCM_16BIT},
+     *   and {@link AudioFormat#ENCODING_PCM_FLOAT}.
+     * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is written
+     *   to during the recording. New audio data can be read from this buffer in smaller chunks
+     *   than this size. See {@link #getMinBufferSize(int, int, int)} to determine the minimum
+     *   required buffer size for the successful creation of an AudioRecord instance. Using values
+     *   smaller than getMinBufferSize() will result in an initialization failure.
+     * @throws java.lang.IllegalArgumentException
+     */
+    @RequiresPermission(android.Manifest.permission.RECORD_AUDIO)
+    public AudioRecord(int audioSource, int sampleRateInHz, int channelConfig, int audioFormat,
+            int bufferSizeInBytes)
+    throws IllegalArgumentException {
+        this((new AudioAttributes.Builder())
+                    .setInternalCapturePreset(audioSource)
+                    .build(),
+                (new AudioFormat.Builder())
+                    .setChannelMask(getChannelMaskFromLegacyConfig(channelConfig,
+                                        true/*allow legacy configurations*/))
+                    .setEncoding(audioFormat)
+                    .setSampleRate(sampleRateInHz)
+                    .build(),
+                bufferSizeInBytes,
+                AudioManager.AUDIO_SESSION_ID_GENERATE);
+    }
+
+    /**
+     * @hide
+     * Class constructor with {@link AudioAttributes} and {@link AudioFormat}.
+     * @param attributes a non-null {@link AudioAttributes} instance. Use
+     *     {@link AudioAttributes.Builder#setCapturePreset(int)} for configuring the audio
+     *     source for this instance.
+     * @param format a non-null {@link AudioFormat} instance describing the format of the data
+     *     that will be recorded through this AudioRecord. See {@link AudioFormat.Builder} for
+     *     configuring the audio format parameters such as encoding, channel mask and sample rate.
+     * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is written
+     *   to during the recording. New audio data can be read from this buffer in smaller chunks
+     *   than this size. See {@link #getMinBufferSize(int, int, int)} to determine the minimum
+     *   required buffer size for the successful creation of an AudioRecord instance. Using values
+     *   smaller than getMinBufferSize() will result in an initialization failure.
+     * @param sessionId ID of audio session the AudioRecord must be attached to, or
+     *   {@link AudioManager#AUDIO_SESSION_ID_GENERATE} if the session isn't known at construction
+     *   time. See also {@link AudioManager#generateAudioSessionId()} to obtain a session ID before
+     *   construction.
+     * @throws IllegalArgumentException
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.RECORD_AUDIO)
+    public AudioRecord(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
+            int sessionId) throws IllegalArgumentException {
+        this(attributes, format, bufferSizeInBytes, sessionId,
+                ActivityThread.currentApplication(), 0 /*maxSharedAudioHistoryMs*/);
+    }
+
+    /**
+     * @hide
+     * Class constructor with {@link AudioAttributes} and {@link AudioFormat}.
+     * @param attributes a non-null {@link AudioAttributes} instance. Use
+     *     {@link AudioAttributes.Builder#setCapturePreset(int)} for configuring the audio
+     *     source for this instance.
+     * @param format a non-null {@link AudioFormat} instance describing the format of the data
+     *     that will be recorded through this AudioRecord. See {@link AudioFormat.Builder} for
+     *     configuring the audio format parameters such as encoding, channel mask and sample rate.
+     * @param bufferSizeInBytes the total size (in bytes) of the buffer where audio data is written
+     *   to during the recording. New audio data can be read from this buffer in smaller chunks
+     *   than this size. See {@link #getMinBufferSize(int, int, int)} to determine the minimum
+     *   required buffer size for the successful creation of an AudioRecord instance. Using values
+     *   smaller than getMinBufferSize() will result in an initialization failure.
+     * @param sessionId ID of audio session the AudioRecord must be attached to, or
+     *   {@link AudioManager#AUDIO_SESSION_ID_GENERATE} if the session isn't known at construction
+     *   time. See also {@link AudioManager#generateAudioSessionId()} to obtain a session ID before
+     *   construction.
+     * @param context An optional context on whose behalf the recoding is performed.
+     *
+     * @throws IllegalArgumentException
+     */
+    private AudioRecord(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
+            int sessionId, @Nullable Context context,
+            int maxSharedAudioHistoryMs) throws IllegalArgumentException {
+        mRecordingState = RECORDSTATE_STOPPED;
+
+        if (attributes == null) {
+            throw new IllegalArgumentException("Illegal null AudioAttributes");
+        }
+        if (format == null) {
+            throw new IllegalArgumentException("Illegal null AudioFormat");
+        }
+
+        // remember which looper is associated with the AudioRecord instanciation
+        if ((mInitializationLooper = Looper.myLooper()) == null) {
+            mInitializationLooper = Looper.getMainLooper();
+        }
+
+        // is this AudioRecord using REMOTE_SUBMIX at full volume?
+        if (attributes.getCapturePreset() == MediaRecorder.AudioSource.REMOTE_SUBMIX) {
+            final AudioAttributes.Builder filteredAttr = new AudioAttributes.Builder();
+            final Iterator<String> tagsIter = attributes.getTags().iterator();
+            while (tagsIter.hasNext()) {
+                final String tag = tagsIter.next();
+                if (tag.equalsIgnoreCase(SUBMIX_FIXED_VOLUME)) {
+                    mIsSubmixFullVolume = true;
+                    Log.v(TAG, "Will record from REMOTE_SUBMIX at full fixed volume");
+                } else { // SUBMIX_FIXED_VOLUME: is not to be propagated to the native layers
+                    filteredAttr.addTag(tag);
+                }
+            }
+            filteredAttr.setInternalCapturePreset(attributes.getCapturePreset());
+            mAudioAttributes = filteredAttr.build();
+        } else {
+            mAudioAttributes = attributes;
+        }
+
+        int rate = format.getSampleRate();
+        if (rate == AudioFormat.SAMPLE_RATE_UNSPECIFIED) {
+            rate = 0;
+        }
+
+        int encoding = AudioFormat.ENCODING_DEFAULT;
+        if ((format.getPropertySetMask() & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_ENCODING) != 0)
+        {
+            encoding = format.getEncoding();
+        }
+
+        audioParamCheck(attributes.getCapturePreset(), rate, encoding);
+
+        if ((format.getPropertySetMask()
+                & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK) != 0) {
+            mChannelIndexMask = format.getChannelIndexMask();
+            mChannelCount = format.getChannelCount();
+        }
+        if ((format.getPropertySetMask()
+                & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) != 0) {
+            mChannelMask = getChannelMaskFromLegacyConfig(format.getChannelMask(), false);
+            mChannelCount = format.getChannelCount();
+        } else if (mChannelIndexMask == 0) {
+            mChannelMask = getChannelMaskFromLegacyConfig(AudioFormat.CHANNEL_IN_DEFAULT, false);
+            mChannelCount =  AudioFormat.channelCountFromInChannelMask(mChannelMask);
+        }
+
+        audioBuffSizeCheck(bufferSizeInBytes);
+
+        AttributionSource attributionSource = (context != null)
+                ? context.getAttributionSource() : AttributionSource.myAttributionSource();
+        if (attributionSource.getPackageName() == null) {
+            // Command line utility
+            attributionSource = attributionSource.withPackageName("uid:" + Binder.getCallingUid());
+        }
+
+        int[] sampleRate = new int[] {mSampleRate};
+        int[] session = new int[1];
+        session[0] = sessionId;
+
+        //TODO: update native initialization when information about hardware init failure
+        //      due to capture device already open is available.
+        try (ScopedParcelState attributionSourceState = attributionSource.asScopedParcelState()) {
+            int initResult = native_setup(new WeakReference<AudioRecord>(this), mAudioAttributes,
+                    sampleRate, mChannelMask, mChannelIndexMask, mAudioFormat,
+                    mNativeBufferSizeInBytes, session, attributionSourceState.getParcel(),
+                    0 /*nativeRecordInJavaObj*/, maxSharedAudioHistoryMs);
+            if (initResult != SUCCESS) {
+                loge("Error code " + initResult + " when initializing native AudioRecord object.");
+                return; // with mState == STATE_UNINITIALIZED
+            }
+        }
+
+        mSampleRate = sampleRate[0];
+        mSessionId = session[0];
+
+        mState = STATE_INITIALIZED;
+    }
+
+    /**
+     * A constructor which explicitly connects a Native (C++) AudioRecord. For use by
+     * the AudioRecordRoutingProxy subclass.
+     * @param nativeRecordInJavaObj A C/C++ pointer to a native AudioRecord
+     * (associated with an OpenSL ES recorder). Note: the caller must ensure a correct
+     * value here as no error checking is or can be done.
+     */
+    /*package*/ AudioRecord(long nativeRecordInJavaObj) {
+        mNativeRecorderInJavaObj = 0;
+        mNativeCallbackCookie = 0;
+        mNativeDeviceCallback = 0;
+
+        // other initialization...
+        if (nativeRecordInJavaObj != 0) {
+            deferred_connect(nativeRecordInJavaObj);
+        } else {
+            mState = STATE_UNINITIALIZED;
+        }
+    }
+
+    /**
+     * Sets an {@link AudioPolicy} to automatically unregister when the record is released.
+     *
+     * <p>This is to prevent users of the audio capture API from having to manually unregister the
+     * policy that was used to create the record.
+     */
+    private void unregisterAudioPolicyOnRelease(AudioPolicy audioPolicy) {
+        mAudioCapturePolicy = audioPolicy;
+    }
+
+    /**
+     * @hide
+     */
+    /* package */ void deferred_connect(long  nativeRecordInJavaObj) {
+        if (mState != STATE_INITIALIZED) {
+            int[] session = {0};
+            int[] rates = {0};
+            //TODO: update native initialization when information about hardware init failure
+            //      due to capture device already open is available.
+            // Note that for this native_setup, we are providing an already created/initialized
+            // *Native* AudioRecord, so the attributes parameters to native_setup() are ignored.
+            final int initResult;
+            try (ScopedParcelState attributionSourceState = AttributionSource.myAttributionSource()
+                    .asScopedParcelState()) {
+                initResult = native_setup(new WeakReference<>(this),
+                        null /*mAudioAttributes*/,
+                        rates /*mSampleRates*/,
+                        0 /*mChannelMask*/,
+                        0 /*mChannelIndexMask*/,
+                        0 /*mAudioFormat*/,
+                        0 /*mNativeBufferSizeInBytes*/,
+                        session,
+                        attributionSourceState.getParcel(),
+                        nativeRecordInJavaObj,
+                        0);
+            }
+            if (initResult != SUCCESS) {
+                loge("Error code "+initResult+" when initializing native AudioRecord object.");
+                return; // with mState == STATE_UNINITIALIZED
+            }
+
+            mSessionId = session[0];
+
+            mState = STATE_INITIALIZED;
+        }
+    }
+
+    /** @hide */
+    public AudioAttributes getAudioAttributes() {
+        return mAudioAttributes;
+    }
+
+    /**
+     * Builder class for {@link AudioRecord} objects.
+     * Use this class to configure and create an <code>AudioRecord</code> instance. By setting the
+     * recording source and audio format parameters, you indicate which of
+     * those vary from the default behavior on the device.
+     * <p> Here is an example where <code>Builder</code> is used to specify all {@link AudioFormat}
+     * parameters, to be used by a new <code>AudioRecord</code> instance:
+     *
+     * <pre class="prettyprint">
+     * AudioRecord recorder = new AudioRecord.Builder()
+     *         .setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION)
+     *         .setAudioFormat(new AudioFormat.Builder()
+     *                 .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
+     *                 .setSampleRate(32000)
+     *                 .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
+     *                 .build())
+     *         .setBufferSizeInBytes(2*minBuffSize)
+     *         .build();
+     * </pre>
+     * <p>
+     * If the audio source is not set with {@link #setAudioSource(int)},
+     * {@link MediaRecorder.AudioSource#DEFAULT} is used.
+     * <br>If the audio format is not specified or is incomplete, its channel configuration will be
+     * {@link AudioFormat#CHANNEL_IN_MONO}, and the encoding will be
+     * {@link AudioFormat#ENCODING_PCM_16BIT}.
+     * The sample rate will depend on the device actually selected for capture and can be queried
+     * with {@link #getSampleRate()} method.
+     * <br>If the buffer size is not specified with {@link #setBufferSizeInBytes(int)},
+     * the minimum buffer size for the source is used.
+     */
+    public static class Builder {
+
+        private static final String ERROR_MESSAGE_SOURCE_MISMATCH =
+                "Cannot both set audio source and set playback capture config";
+
+        private AudioPlaybackCaptureConfiguration mAudioPlaybackCaptureConfiguration;
+        private AudioAttributes mAttributes;
+        private AudioFormat mFormat;
+        private Context mContext;
+        private int mBufferSizeInBytes;
+        private int mSessionId = AudioManager.AUDIO_SESSION_ID_GENERATE;
+        private int mPrivacySensitive = PRIVACY_SENSITIVE_DEFAULT;
+        private int mMaxSharedAudioHistoryMs = 0;
+        private static final int PRIVACY_SENSITIVE_DEFAULT = -1;
+        private static final int PRIVACY_SENSITIVE_DISABLED = 0;
+        private static final int PRIVACY_SENSITIVE_ENABLED = 1;
+
+        /**
+         * Constructs a new Builder with the default values as described above.
+         */
+        public Builder() {
+        }
+
+        /**
+         * @param source the audio source.
+         * See {@link MediaRecorder.AudioSource} for the supported audio source definitions.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        public Builder setAudioSource(@Source int source) throws IllegalArgumentException {
+            Preconditions.checkState(
+                    mAudioPlaybackCaptureConfiguration == null,
+                    ERROR_MESSAGE_SOURCE_MISMATCH);
+            if ( (source < MediaRecorder.AudioSource.DEFAULT) ||
+                    (source > MediaRecorder.getAudioSourceMax()) ) {
+                throw new IllegalArgumentException("Invalid audio source " + source);
+            }
+            mAttributes = new AudioAttributes.Builder()
+                    .setInternalCapturePreset(source)
+                    .build();
+            return this;
+        }
+
+        /**
+         * Sets the context the record belongs to. This context will be used to pull information,
+         * such as {@link android.content.AttributionSource}, which will be associated with
+         * the AudioRecord. However, the context itself will not be retained by the AudioRecord.
+         * @param context a non-null {@link Context} instance
+         * @return the same Builder instance.
+         */
+        public @NonNull Builder setContext(@NonNull Context context) {
+            Objects.requireNonNull(context);
+            // keep reference, we only copy the data when building
+            mContext = context;
+            return this;
+        }
+
+        /**
+         * @hide
+         * To be only used by system components. Allows specifying non-public capture presets
+         * @param attributes a non-null {@link AudioAttributes} instance that contains the capture
+         *     preset to be used.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        @SystemApi
+        public Builder setAudioAttributes(@NonNull AudioAttributes attributes)
+                throws IllegalArgumentException {
+            if (attributes == null) {
+                throw new IllegalArgumentException("Illegal null AudioAttributes argument");
+            }
+            if (attributes.getCapturePreset() == MediaRecorder.AudioSource.AUDIO_SOURCE_INVALID) {
+                throw new IllegalArgumentException(
+                        "No valid capture preset in AudioAttributes argument");
+            }
+            // keep reference, we only copy the data when building
+            mAttributes = attributes;
+            return this;
+        }
+
+        /**
+         * Sets the format of the audio data to be captured.
+         * @param format a non-null {@link AudioFormat} instance
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        public Builder setAudioFormat(@NonNull AudioFormat format) throws IllegalArgumentException {
+            if (format == null) {
+                throw new IllegalArgumentException("Illegal null AudioFormat argument");
+            }
+            // keep reference, we only copy the data when building
+            mFormat = format;
+            return this;
+        }
+
+        /**
+         * Sets the total size (in bytes) of the buffer where audio data is written
+         * during the recording. New audio data can be read from this buffer in smaller chunks
+         * than this size. See {@link #getMinBufferSize(int, int, int)} to determine the minimum
+         * required buffer size for the successful creation of an AudioRecord instance.
+         * Since bufferSizeInBytes may be internally increased to accommodate the source
+         * requirements, use {@link #getBufferSizeInFrames()} to determine the actual buffer size
+         * in frames.
+         * @param bufferSizeInBytes a value strictly greater than 0
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        public Builder setBufferSizeInBytes(int bufferSizeInBytes) throws IllegalArgumentException {
+            if (bufferSizeInBytes <= 0) {
+                throw new IllegalArgumentException("Invalid buffer size " + bufferSizeInBytes);
+            }
+            mBufferSizeInBytes = bufferSizeInBytes;
+            return this;
+        }
+
+        /**
+         * Sets the {@link AudioRecord} to record audio played by other apps.
+         *
+         * @param config Defines what apps to record audio from (i.e., via either their uid or
+         *               the type of audio).
+         * @throws IllegalStateException if called in conjunction with {@link #setAudioSource(int)}.
+         * @throws NullPointerException if {@code config} is null.
+         */
+        public @NonNull Builder setAudioPlaybackCaptureConfig(
+                @NonNull AudioPlaybackCaptureConfiguration config) {
+            Preconditions.checkNotNull(
+                    config, "Illegal null AudioPlaybackCaptureConfiguration argument");
+            Preconditions.checkState(
+                    mAttributes == null,
+                    ERROR_MESSAGE_SOURCE_MISMATCH);
+            mAudioPlaybackCaptureConfiguration = config;
+            return this;
+        }
+
+        /**
+         * Indicates that this capture request is privacy sensitive and that
+         * any concurrent capture is not permitted.
+         * <p>
+         * The default is not privacy sensitive except when the audio source set with
+         * {@link #setAudioSource(int)} is {@link MediaRecorder.AudioSource#VOICE_COMMUNICATION} or
+         * {@link MediaRecorder.AudioSource#CAMCORDER}.
+         * <p>
+         * Always takes precedence over default from audio source when set explicitly.
+         * <p>
+         * Using this API is only permitted when the audio source is one of:
+         * <ul>
+         * <li>{@link MediaRecorder.AudioSource#MIC}</li>
+         * <li>{@link MediaRecorder.AudioSource#CAMCORDER}</li>
+         * <li>{@link MediaRecorder.AudioSource#VOICE_RECOGNITION}</li>
+         * <li>{@link MediaRecorder.AudioSource#VOICE_COMMUNICATION}</li>
+         * <li>{@link MediaRecorder.AudioSource#UNPROCESSED}</li>
+         * <li>{@link MediaRecorder.AudioSource#VOICE_PERFORMANCE}</li>
+         * </ul>
+         * Invoking {@link #build()} will throw an UnsupportedOperationException if this
+         * condition is not met.
+         * @param privacySensitive True if capture from this AudioRecord must be marked as privacy
+         * sensitive, false otherwise.
+         */
+        public @NonNull Builder setPrivacySensitive(boolean privacySensitive) {
+            mPrivacySensitive =
+                privacySensitive ? PRIVACY_SENSITIVE_ENABLED : PRIVACY_SENSITIVE_DISABLED;
+            return this;
+        }
+
+        /**
+         * @hide
+         * To be only used by system components.
+         * @param sessionId ID of audio session the AudioRecord must be attached to, or
+         *     {@link AudioManager#AUDIO_SESSION_ID_GENERATE} if the session isn't known at
+         *     construction time.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        @SystemApi
+        public Builder setSessionId(int sessionId) throws IllegalArgumentException {
+            if (sessionId < 0) {
+                throw new IllegalArgumentException("Invalid session ID " + sessionId);
+            }
+            // Do not override a session ID previously set with setSharedAudioEvent()
+            if (mSessionId == AudioManager.AUDIO_SESSION_ID_GENERATE) {
+                mSessionId = sessionId;
+            } else {
+                Log.e(TAG, "setSessionId() called twice or after setSharedAudioEvent()");
+            }
+            return this;
+        }
+
+        private @NonNull AudioRecord buildAudioPlaybackCaptureRecord() {
+            AudioMix audioMix = mAudioPlaybackCaptureConfiguration.createAudioMix(mFormat);
+            MediaProjection projection = mAudioPlaybackCaptureConfiguration.getMediaProjection();
+            AudioPolicy audioPolicy = new AudioPolicy.Builder(/*context=*/ null)
+                    .setMediaProjection(projection)
+                    .addMix(audioMix).build();
+
+            int error = AudioManager.registerAudioPolicyStatic(audioPolicy);
+            if (error != 0) {
+                throw new UnsupportedOperationException("Error: could not register audio policy");
+            }
+
+            AudioRecord record = audioPolicy.createAudioRecordSink(audioMix);
+            if (record == null) {
+                throw new UnsupportedOperationException("Cannot create AudioRecord");
+            }
+            record.unregisterAudioPolicyOnRelease(audioPolicy);
+            return record;
+        }
+
+        /**
+         * @hide
+         * Specifies the maximum duration in the past of the this AudioRecord's capture buffer
+         * that can be shared with another app by calling
+         * {@link AudioRecord#shareAudioHistory(String, long)}.
+         * @param maxSharedAudioHistoryMillis the maximum duration that will be available
+         *                                    in milliseconds.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         *
+         */
+        @SystemApi
+        @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD)
+        public @NonNull Builder setMaxSharedAudioHistoryMillis(long maxSharedAudioHistoryMillis)
+                throws IllegalArgumentException {
+            if (maxSharedAudioHistoryMillis <= 0
+                    || maxSharedAudioHistoryMillis > MAX_SHARED_AUDIO_HISTORY_MS) {
+                throw new IllegalArgumentException("Illegal maxSharedAudioHistoryMillis argument");
+            }
+            mMaxSharedAudioHistoryMs = (int) maxSharedAudioHistoryMillis;
+            return this;
+        }
+
+        /**
+         * @hide
+         * Indicates that this AudioRecord will use the audio history shared by another app's
+         * AudioRecord. See {@link AudioRecord#shareAudioHistory(String, long)}.
+         * The audio session ID set with {@link AudioRecord.Builder#setSessionId(int)} will be
+         * ignored if this method is used.
+         * @param event The {@link MediaSyncEvent} provided by the app sharing its audio history
+         *              with this AudioRecord.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        @SystemApi
+        public @NonNull Builder setSharedAudioEvent(@NonNull MediaSyncEvent event)
+                throws IllegalArgumentException {
+            Objects.requireNonNull(event);
+            if (event.getType() != MediaSyncEvent.SYNC_EVENT_SHARE_AUDIO_HISTORY) {
+                throw new IllegalArgumentException(
+                        "Invalid event type " + event.getType());
+            }
+            if (event.getAudioSessionId() == AudioSystem.AUDIO_SESSION_ALLOCATE) {
+                throw new IllegalArgumentException(
+                        "Invalid session ID " + event.getAudioSessionId());
+            }
+            // This prevails over a session ID set with setSessionId()
+            mSessionId = event.getAudioSessionId();
+            return this;
+        }
+
+        /**
+         * @return a new {@link AudioRecord} instance successfully initialized with all
+         *     the parameters set on this <code>Builder</code>.
+         * @throws UnsupportedOperationException if the parameters set on the <code>Builder</code>
+         *     were incompatible, or if they are not supported by the device,
+         *     or if the device was not available.
+         */
+        @RequiresPermission(android.Manifest.permission.RECORD_AUDIO)
+        public AudioRecord build() throws UnsupportedOperationException {
+            if (mAudioPlaybackCaptureConfiguration != null) {
+                return buildAudioPlaybackCaptureRecord();
+            }
+
+            if (mFormat == null) {
+                mFormat = new AudioFormat.Builder()
+                        .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
+                        .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
+                        .build();
+            } else {
+                if (mFormat.getEncoding() == AudioFormat.ENCODING_INVALID) {
+                    mFormat = new AudioFormat.Builder(mFormat)
+                            .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
+                            .build();
+                }
+                if (mFormat.getChannelMask() == AudioFormat.CHANNEL_INVALID
+                        && mFormat.getChannelIndexMask() == AudioFormat.CHANNEL_INVALID) {
+                    mFormat = new AudioFormat.Builder(mFormat)
+                            .setChannelMask(AudioFormat.CHANNEL_IN_MONO)
+                            .build();
+                }
+            }
+            if (mAttributes == null) {
+                mAttributes = new AudioAttributes.Builder()
+                        .setInternalCapturePreset(MediaRecorder.AudioSource.DEFAULT)
+                        .build();
+            }
+
+            // If mPrivacySensitive is default, the privacy flag is already set
+            // according to audio source in audio attributes.
+            if (mPrivacySensitive != PRIVACY_SENSITIVE_DEFAULT) {
+                int source = mAttributes.getCapturePreset();
+                if (source == MediaRecorder.AudioSource.REMOTE_SUBMIX
+                        || source == MediaRecorder.AudioSource.RADIO_TUNER
+                        || source == MediaRecorder.AudioSource.VOICE_DOWNLINK
+                        || source == MediaRecorder.AudioSource.VOICE_UPLINK
+                        || source == MediaRecorder.AudioSource.VOICE_CALL
+                        || source == MediaRecorder.AudioSource.ECHO_REFERENCE) {
+                    throw new UnsupportedOperationException(
+                            "Cannot request private capture with source: " + source);
+                }
+
+                mAttributes = new AudioAttributes.Builder(mAttributes)
+                        .setInternalCapturePreset(source)
+                        .setPrivacySensitive(mPrivacySensitive == PRIVACY_SENSITIVE_ENABLED)
+                        .build();
+            }
+
+            try {
+                // If the buffer size is not specified,
+                // use a single frame for the buffer size and let the
+                // native code figure out the minimum buffer size.
+                if (mBufferSizeInBytes == 0) {
+                    mBufferSizeInBytes = mFormat.getChannelCount()
+                            * mFormat.getBytesPerSample(mFormat.getEncoding());
+                }
+                final AudioRecord record = new AudioRecord(
+                        mAttributes, mFormat, mBufferSizeInBytes, mSessionId, mContext,
+                                    mMaxSharedAudioHistoryMs);
+                if (record.getState() == STATE_UNINITIALIZED) {
+                    // release is not necessary
+                    throw new UnsupportedOperationException("Cannot create AudioRecord");
+                }
+                return record;
+            } catch (IllegalArgumentException e) {
+                throw new UnsupportedOperationException(e.getMessage());
+            }
+        }
+    }
+
+    // Convenience method for the constructor's parameter checks.
+    // This, getChannelMaskFromLegacyConfig and audioBuffSizeCheck are where constructor
+    // IllegalArgumentException-s are thrown
+    private static int getChannelMaskFromLegacyConfig(int inChannelConfig,
+            boolean allowLegacyConfig) {
+        int mask;
+        switch (inChannelConfig) {
+        case AudioFormat.CHANNEL_IN_DEFAULT: // AudioFormat.CHANNEL_CONFIGURATION_DEFAULT
+        case AudioFormat.CHANNEL_IN_MONO:
+        case AudioFormat.CHANNEL_CONFIGURATION_MONO:
+            mask = AudioFormat.CHANNEL_IN_MONO;
+            break;
+        case AudioFormat.CHANNEL_IN_STEREO:
+        case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
+            mask = AudioFormat.CHANNEL_IN_STEREO;
+            break;
+        case (AudioFormat.CHANNEL_IN_FRONT | AudioFormat.CHANNEL_IN_BACK):
+            mask = inChannelConfig;
+            break;
+        default:
+            throw new IllegalArgumentException("Unsupported channel configuration.");
+        }
+
+        if (!allowLegacyConfig && ((inChannelConfig == AudioFormat.CHANNEL_CONFIGURATION_MONO)
+                || (inChannelConfig == AudioFormat.CHANNEL_CONFIGURATION_STEREO))) {
+            // only happens with the constructor that uses AudioAttributes and AudioFormat
+            throw new IllegalArgumentException("Unsupported deprecated configuration.");
+        }
+
+        return mask;
+    }
+
+    // postconditions:
+    //    mRecordSource is valid
+    //    mAudioFormat is valid
+    //    mSampleRate is valid
+    private void audioParamCheck(int audioSource, int sampleRateInHz, int audioFormat)
+            throws IllegalArgumentException {
+
+        //--------------
+        // audio source
+        if ( (audioSource < MediaRecorder.AudioSource.DEFAULT) ||
+             ((audioSource > MediaRecorder.getAudioSourceMax()) &&
+              (audioSource != MediaRecorder.AudioSource.RADIO_TUNER) &&
+              (audioSource != MediaRecorder.AudioSource.ECHO_REFERENCE) &&
+              (audioSource != MediaRecorder.AudioSource.HOTWORD)) )  {
+            throw new IllegalArgumentException("Invalid audio source " + audioSource);
+        }
+        mRecordSource = audioSource;
+
+        //--------------
+        // sample rate
+        if ((sampleRateInHz < AudioFormat.SAMPLE_RATE_HZ_MIN ||
+                sampleRateInHz > AudioFormat.SAMPLE_RATE_HZ_MAX) &&
+                sampleRateInHz != AudioFormat.SAMPLE_RATE_UNSPECIFIED) {
+            throw new IllegalArgumentException(sampleRateInHz
+                    + "Hz is not a supported sample rate.");
+        }
+        mSampleRate = sampleRateInHz;
+
+        //--------------
+        // audio format
+        switch (audioFormat) {
+            case AudioFormat.ENCODING_DEFAULT:
+                mAudioFormat = AudioFormat.ENCODING_PCM_16BIT;
+                break;
+            case AudioFormat.ENCODING_PCM_24BIT_PACKED:
+            case AudioFormat.ENCODING_PCM_32BIT:
+            case AudioFormat.ENCODING_PCM_FLOAT:
+            case AudioFormat.ENCODING_PCM_16BIT:
+            case AudioFormat.ENCODING_PCM_8BIT:
+                mAudioFormat = audioFormat;
+                break;
+            default:
+                throw new IllegalArgumentException("Unsupported sample encoding " + audioFormat
+                        + ". Should be ENCODING_PCM_8BIT, ENCODING_PCM_16BIT,"
+                        + " ENCODING_PCM_24BIT_PACKED, ENCODING_PCM_32BIT,"
+                        + " or ENCODING_PCM_FLOAT.");
+        }
+    }
+
+
+    // Convenience method for the contructor's audio buffer size check.
+    // preconditions:
+    //    mChannelCount is valid
+    //    mAudioFormat is AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT,
+    //                 or AudioFormat.ENCODING_PCM_FLOAT
+    // postcondition:
+    //    mNativeBufferSizeInBytes is valid (multiple of frame size, positive)
+    private void audioBuffSizeCheck(int audioBufferSize) throws IllegalArgumentException {
+        // NB: this section is only valid with PCM data.
+        // To update when supporting compressed formats
+        int frameSizeInBytes = mChannelCount
+            * (AudioFormat.getBytesPerSample(mAudioFormat));
+        if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) {
+            throw new IllegalArgumentException("Invalid audio buffer size " + audioBufferSize
+                    + " (frame size " + frameSizeInBytes + ")");
+        }
+
+        mNativeBufferSizeInBytes = audioBufferSize;
+    }
+
+
+
+    /**
+     * Releases the native AudioRecord resources.
+     * The object can no longer be used and the reference should be set to null
+     * after a call to release()
+     */
+    public void release() {
+        try {
+            stop();
+        } catch(IllegalStateException ise) {
+            // don't raise an exception, we're releasing the resources.
+        }
+        if (mAudioCapturePolicy != null) {
+            AudioManager.unregisterAudioPolicyAsyncStatic(mAudioCapturePolicy);
+            mAudioCapturePolicy = null;
+        }
+        native_release();
+        mState = STATE_UNINITIALIZED;
+    }
+
+
+    @Override
+    protected void finalize() {
+        // will cause stop() to be called, and if appropriate, will handle fixed volume recording
+        release();
+    }
+
+
+    //--------------------------------------------------------------------------
+    // Getters
+    //--------------------
+    /**
+     * Returns the configured audio sink sample rate in Hz.
+     * The sink sample rate never changes after construction.
+     * If the constructor had a specific sample rate, then the sink sample rate is that value.
+     * If the constructor had {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED},
+     * then the sink sample rate is a route-dependent default value based on the source [sic].
+     */
+    public int getSampleRate() {
+        return mSampleRate;
+    }
+
+    /**
+     * Returns the audio recording source.
+     * @see MediaRecorder.AudioSource
+     */
+    public int getAudioSource() {
+        return mRecordSource;
+    }
+
+    /**
+     * Returns the configured audio data encoding. See {@link AudioFormat#ENCODING_PCM_8BIT},
+     * {@link AudioFormat#ENCODING_PCM_16BIT}, and {@link AudioFormat#ENCODING_PCM_FLOAT}.
+     */
+    public int getAudioFormat() {
+        return mAudioFormat;
+    }
+
+    /**
+     * Returns the configured channel position mask.
+     * <p> See {@link AudioFormat#CHANNEL_IN_MONO}
+     * and {@link AudioFormat#CHANNEL_IN_STEREO}.
+     * This method may return {@link AudioFormat#CHANNEL_INVALID} if
+     * a channel index mask is used.
+     * Consider {@link #getFormat()} instead, to obtain an {@link AudioFormat},
+     * which contains both the channel position mask and the channel index mask.
+     */
+    public int getChannelConfiguration() {
+        return mChannelMask;
+    }
+
+    /**
+     * Returns the configured <code>AudioRecord</code> format.
+     * @return an {@link AudioFormat} containing the
+     * <code>AudioRecord</code> parameters at the time of configuration.
+     */
+    public @NonNull AudioFormat getFormat() {
+        AudioFormat.Builder builder = new AudioFormat.Builder()
+            .setSampleRate(mSampleRate)
+            .setEncoding(mAudioFormat);
+        if (mChannelMask != AudioFormat.CHANNEL_INVALID) {
+            builder.setChannelMask(mChannelMask);
+        }
+        if (mChannelIndexMask != AudioFormat.CHANNEL_INVALID  /* 0 */) {
+            builder.setChannelIndexMask(mChannelIndexMask);
+        }
+        return builder.build();
+    }
+
+    /**
+     * Returns the configured number of channels.
+     */
+    public int getChannelCount() {
+        return mChannelCount;
+    }
+
+    /**
+     * Returns the state of the AudioRecord instance. This is useful after the
+     * AudioRecord instance has been created to check if it was initialized
+     * properly. This ensures that the appropriate hardware resources have been
+     * acquired.
+     * @see AudioRecord#STATE_INITIALIZED
+     * @see AudioRecord#STATE_UNINITIALIZED
+     */
+    public int getState() {
+        return mState;
+    }
+
+    /**
+     * Returns the recording state of the AudioRecord instance.
+     * @see AudioRecord#RECORDSTATE_STOPPED
+     * @see AudioRecord#RECORDSTATE_RECORDING
+     */
+    public int getRecordingState() {
+        synchronized (mRecordingStateLock) {
+            return mRecordingState;
+        }
+    }
+
+    /**
+     *  Returns the frame count of the native <code>AudioRecord</code> buffer.
+     *  This is greater than or equal to the bufferSizeInBytes converted to frame units
+     *  specified in the <code>AudioRecord</code> constructor or Builder.
+     *  The native frame count may be enlarged to accommodate the requirements of the
+     *  source on creation or if the <code>AudioRecord</code>
+     *  is subsequently rerouted.
+     *  @return current size in frames of the <code>AudioRecord</code> buffer.
+     *  @throws IllegalStateException
+     */
+    public int getBufferSizeInFrames() {
+        return native_get_buffer_size_in_frames();
+    }
+
+    /**
+     * Returns the notification marker position expressed in frames.
+     */
+    public int getNotificationMarkerPosition() {
+        return native_get_marker_pos();
+    }
+
+    /**
+     * Returns the notification update period expressed in frames.
+     */
+    public int getPositionNotificationPeriod() {
+        return native_get_pos_update_period();
+    }
+
+    /**
+     * Poll for an {@link AudioTimestamp} on demand.
+     * <p>
+     * The AudioTimestamp reflects the frame delivery information at
+     * the earliest point available in the capture pipeline.
+     * <p>
+     * Calling {@link #startRecording()} following a {@link #stop()} will reset
+     * the frame count to 0.
+     *
+     * @param outTimestamp a caller provided non-null AudioTimestamp instance,
+     *        which is updated with the AudioRecord frame delivery information upon success.
+     * @param timebase one of
+     *        {@link AudioTimestamp#TIMEBASE_BOOTTIME AudioTimestamp.TIMEBASE_BOOTTIME} or
+     *        {@link AudioTimestamp#TIMEBASE_MONOTONIC AudioTimestamp.TIMEBASE_MONOTONIC},
+     *        used to select the clock for the AudioTimestamp time.
+     * @return {@link #SUCCESS} if a timestamp is available,
+     *         or {@link #ERROR_INVALID_OPERATION} if a timestamp not available.
+     */
+     public int getTimestamp(@NonNull AudioTimestamp outTimestamp,
+             @AudioTimestamp.Timebase int timebase)
+     {
+         if (outTimestamp == null ||
+                 (timebase != AudioTimestamp.TIMEBASE_BOOTTIME
+                 && timebase != AudioTimestamp.TIMEBASE_MONOTONIC)) {
+             throw new IllegalArgumentException();
+         }
+         return native_get_timestamp(outTimestamp, timebase);
+     }
+
+    /**
+     * Returns the minimum buffer size required for the successful creation of an AudioRecord
+     * object, in byte units.
+     * Note that this size doesn't guarantee a smooth recording under load, and higher values
+     * should be chosen according to the expected frequency at which the AudioRecord instance
+     * will be polled for new data.
+     * See {@link #AudioRecord(int, int, int, int, int)} for more information on valid
+     * configuration values.
+     * @param sampleRateInHz the sample rate expressed in Hertz.
+     *   {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED} is not permitted.
+     * @param channelConfig describes the configuration of the audio channels.
+     *   See {@link AudioFormat#CHANNEL_IN_MONO} and
+     *   {@link AudioFormat#CHANNEL_IN_STEREO}
+     * @param audioFormat the format in which the audio data is represented.
+     *   See {@link AudioFormat#ENCODING_PCM_16BIT}.
+     * @return {@link #ERROR_BAD_VALUE} if the recording parameters are not supported by the
+     *  hardware, or an invalid parameter was passed,
+     *  or {@link #ERROR} if the implementation was unable to query the hardware for its
+     *  input properties,
+     *   or the minimum buffer size expressed in bytes.
+     * @see #AudioRecord(int, int, int, int, int)
+     */
+    static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
+        int channelCount = 0;
+        switch (channelConfig) {
+        case AudioFormat.CHANNEL_IN_DEFAULT: // AudioFormat.CHANNEL_CONFIGURATION_DEFAULT
+        case AudioFormat.CHANNEL_IN_MONO:
+        case AudioFormat.CHANNEL_CONFIGURATION_MONO:
+            channelCount = 1;
+            break;
+        case AudioFormat.CHANNEL_IN_STEREO:
+        case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
+        case (AudioFormat.CHANNEL_IN_FRONT | AudioFormat.CHANNEL_IN_BACK):
+            channelCount = 2;
+            break;
+        case AudioFormat.CHANNEL_INVALID:
+        default:
+            loge("getMinBufferSize(): Invalid channel configuration.");
+            return ERROR_BAD_VALUE;
+        }
+
+        int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);
+        if (size == 0) {
+            return ERROR_BAD_VALUE;
+        }
+        else if (size == -1) {
+            return ERROR;
+        }
+        else {
+            return size;
+        }
+    }
+
+    /**
+     * Returns the audio session ID.
+     *
+     * @return the ID of the audio session this AudioRecord belongs to.
+     */
+    public int getAudioSessionId() {
+        return mSessionId;
+    }
+
+    /**
+     * Returns whether this AudioRecord is marked as privacy sensitive or not.
+     * <p>
+     * See {@link Builder#setPrivacySensitive(boolean)}
+     * <p>
+     * @return true if privacy sensitive, false otherwise
+     */
+    public boolean isPrivacySensitive() {
+        return (mAudioAttributes.getAllFlags() & AudioAttributes.FLAG_CAPTURE_PRIVATE) != 0;
+    }
+
+    //---------------------------------------------------------
+    // Transport control methods
+    //--------------------
+    /**
+     * Starts recording from the AudioRecord instance.
+     * @throws IllegalStateException
+     */
+    public void startRecording()
+    throws IllegalStateException {
+        if (mState != STATE_INITIALIZED) {
+            throw new IllegalStateException("startRecording() called on an "
+                    + "uninitialized AudioRecord.");
+        }
+
+        // start recording
+        synchronized(mRecordingStateLock) {
+            if (native_start(MediaSyncEvent.SYNC_EVENT_NONE, 0) == SUCCESS) {
+                handleFullVolumeRec(true);
+                mRecordingState = RECORDSTATE_RECORDING;
+            }
+        }
+    }
+
+    /**
+     * Starts recording from the AudioRecord instance when the specified synchronization event
+     * occurs on the specified audio session.
+     * @throws IllegalStateException
+     * @param syncEvent event that triggers the capture.
+     * @see MediaSyncEvent
+     */
+    public void startRecording(MediaSyncEvent syncEvent)
+    throws IllegalStateException {
+        if (mState != STATE_INITIALIZED) {
+            throw new IllegalStateException("startRecording() called on an "
+                    + "uninitialized AudioRecord.");
+        }
+
+        // start recording
+        synchronized(mRecordingStateLock) {
+            if (native_start(syncEvent.getType(), syncEvent.getAudioSessionId()) == SUCCESS) {
+                handleFullVolumeRec(true);
+                mRecordingState = RECORDSTATE_RECORDING;
+            }
+        }
+    }
+
+    /**
+     * Stops recording.
+     * @throws IllegalStateException
+     */
+    public void stop()
+    throws IllegalStateException {
+        if (mState != STATE_INITIALIZED) {
+            throw new IllegalStateException("stop() called on an uninitialized AudioRecord.");
+        }
+
+        // stop recording
+        synchronized(mRecordingStateLock) {
+            handleFullVolumeRec(false);
+            native_stop();
+            mRecordingState = RECORDSTATE_STOPPED;
+        }
+    }
+
+    private final IBinder mICallBack = new Binder();
+    private void handleFullVolumeRec(boolean starting) {
+        if (!mIsSubmixFullVolume) {
+            return;
+        }
+        final IBinder b = ServiceManager.getService(android.content.Context.AUDIO_SERVICE);
+        final IAudioService ias = IAudioService.Stub.asInterface(b);
+        try {
+            ias.forceRemoteSubmixFullVolume(starting, mICallBack);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error talking to AudioService when handling full submix volume", e);
+        }
+    }
+
+    //---------------------------------------------------------
+    // Audio data supply
+    //--------------------
+    /**
+     * Reads audio data from the audio hardware for recording into a byte array.
+     * The format specified in the AudioRecord constructor should be
+     * {@link AudioFormat#ENCODING_PCM_8BIT} to correspond to the data in the array.
+     * @param audioData the array to which the recorded audio data is written.
+     * @param offsetInBytes index in audioData from which the data is written expressed in bytes.
+     * @param sizeInBytes the number of requested bytes.
+     * @return zero or the positive number of bytes that were read, or one of the following
+     *    error codes. The number of bytes will not exceed sizeInBytes.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the object isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the object is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next read()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     */
+    public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes) {
+        return read(audioData, offsetInBytes, sizeInBytes, READ_BLOCKING);
+    }
+
+    /**
+     * Reads audio data from the audio hardware for recording into a byte array.
+     * The format specified in the AudioRecord constructor should be
+     * {@link AudioFormat#ENCODING_PCM_8BIT} to correspond to the data in the array.
+     * The format can be {@link AudioFormat#ENCODING_PCM_16BIT}, but this is deprecated.
+     * @param audioData the array to which the recorded audio data is written.
+     * @param offsetInBytes index in audioData to which the data is written expressed in bytes.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param sizeInBytes the number of requested bytes.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param readMode one of {@link #READ_BLOCKING}, {@link #READ_NON_BLOCKING}.
+     *     <br>With {@link #READ_BLOCKING}, the read will block until all the requested data
+     *     is read.
+     *     <br>With {@link #READ_NON_BLOCKING}, the read will return immediately after
+     *     reading as much audio data as possible without blocking.
+     * @return zero or the positive number of bytes that were read, or one of the following
+     *    error codes. The number of bytes will be a multiple of the frame size in bytes
+     *    not to exceed sizeInBytes.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the object isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the object is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next read()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     */
+    public int read(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
+            @ReadMode int readMode) {
+        // Note: we allow reads of extended integers into a byte array.
+        if (mState != STATE_INITIALIZED  || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
+            return ERROR_INVALID_OPERATION;
+        }
+
+        if ((readMode != READ_BLOCKING) && (readMode != READ_NON_BLOCKING)) {
+            Log.e(TAG, "AudioRecord.read() called with invalid blocking mode");
+            return ERROR_BAD_VALUE;
+        }
+
+        if ( (audioData == null) || (offsetInBytes < 0 ) || (sizeInBytes < 0)
+                || (offsetInBytes + sizeInBytes < 0)  // detect integer overflow
+                || (offsetInBytes + sizeInBytes > audioData.length)) {
+            return ERROR_BAD_VALUE;
+        }
+
+        return native_read_in_byte_array(audioData, offsetInBytes, sizeInBytes,
+                readMode == READ_BLOCKING);
+    }
+
+    /**
+     * Reads audio data from the audio hardware for recording into a short array.
+     * The format specified in the AudioRecord constructor should be
+     * {@link AudioFormat#ENCODING_PCM_16BIT} to correspond to the data in the array.
+     * @param audioData the array to which the recorded audio data is written.
+     * @param offsetInShorts index in audioData to which the data is written expressed in shorts.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param sizeInShorts the number of requested shorts.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
+     * @return zero or the positive number of shorts that were read, or one of the following
+     *    error codes. The number of shorts will be a multiple of the channel count not to exceed
+     *    sizeInShorts.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the object isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the object is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next read()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     */
+    public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts) {
+        return read(audioData, offsetInShorts, sizeInShorts, READ_BLOCKING);
+    }
+
+    /**
+     * Reads audio data from the audio hardware for recording into a short array.
+     * The format specified in the AudioRecord constructor should be
+     * {@link AudioFormat#ENCODING_PCM_16BIT} to correspond to the data in the array.
+     * @param audioData the array to which the recorded audio data is written.
+     * @param offsetInShorts index in audioData from which the data is written expressed in shorts.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param sizeInShorts the number of requested shorts.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param readMode one of {@link #READ_BLOCKING}, {@link #READ_NON_BLOCKING}.
+     *     <br>With {@link #READ_BLOCKING}, the read will block until all the requested data
+     *     is read.
+     *     <br>With {@link #READ_NON_BLOCKING}, the read will return immediately after
+     *     reading as much audio data as possible without blocking.
+     * @return zero or the positive number of shorts that were read, or one of the following
+     *    error codes. The number of shorts will be a multiple of the channel count not to exceed
+     *    sizeInShorts.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the object isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the object is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next read()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     */
+    public int read(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
+            @ReadMode int readMode) {
+        if (mState != STATE_INITIALIZED
+                || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT
+                // use ByteBuffer instead for later encodings
+                || mAudioFormat > AudioFormat.ENCODING_LEGACY_SHORT_ARRAY_THRESHOLD) {
+            return ERROR_INVALID_OPERATION;
+        }
+
+        if ((readMode != READ_BLOCKING) && (readMode != READ_NON_BLOCKING)) {
+            Log.e(TAG, "AudioRecord.read() called with invalid blocking mode");
+            return ERROR_BAD_VALUE;
+        }
+
+        if ( (audioData == null) || (offsetInShorts < 0 ) || (sizeInShorts < 0)
+                || (offsetInShorts + sizeInShorts < 0)  // detect integer overflow
+                || (offsetInShorts + sizeInShorts > audioData.length)) {
+            return ERROR_BAD_VALUE;
+        }
+        return native_read_in_short_array(audioData, offsetInShorts, sizeInShorts,
+                readMode == READ_BLOCKING);
+    }
+
+    /**
+     * Reads audio data from the audio hardware for recording into a float array.
+     * The format specified in the AudioRecord constructor should be
+     * {@link AudioFormat#ENCODING_PCM_FLOAT} to correspond to the data in the array.
+     * @param audioData the array to which the recorded audio data is written.
+     * @param offsetInFloats index in audioData from which the data is written.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param sizeInFloats the number of requested floats.
+     *        Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param readMode one of {@link #READ_BLOCKING}, {@link #READ_NON_BLOCKING}.
+     *     <br>With {@link #READ_BLOCKING}, the read will block until all the requested data
+     *     is read.
+     *     <br>With {@link #READ_NON_BLOCKING}, the read will return immediately after
+     *     reading as much audio data as possible without blocking.
+     * @return zero or the positive number of floats that were read, or one of the following
+     *    error codes. The number of floats will be a multiple of the channel count not to exceed
+     *    sizeInFloats.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the object isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the object is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next read()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     */
+    public int read(@NonNull float[] audioData, int offsetInFloats, int sizeInFloats,
+            @ReadMode int readMode) {
+        if (mState == STATE_UNINITIALIZED) {
+            Log.e(TAG, "AudioRecord.read() called in invalid state STATE_UNINITIALIZED");
+            return ERROR_INVALID_OPERATION;
+        }
+
+        if (mAudioFormat != AudioFormat.ENCODING_PCM_FLOAT) {
+            Log.e(TAG, "AudioRecord.read(float[] ...) requires format ENCODING_PCM_FLOAT");
+            return ERROR_INVALID_OPERATION;
+        }
+
+        if ((readMode != READ_BLOCKING) && (readMode != READ_NON_BLOCKING)) {
+            Log.e(TAG, "AudioRecord.read() called with invalid blocking mode");
+            return ERROR_BAD_VALUE;
+        }
+
+        if ((audioData == null) || (offsetInFloats < 0) || (sizeInFloats < 0)
+                || (offsetInFloats + sizeInFloats < 0)  // detect integer overflow
+                || (offsetInFloats + sizeInFloats > audioData.length)) {
+            return ERROR_BAD_VALUE;
+        }
+
+        return native_read_in_float_array(audioData, offsetInFloats, sizeInFloats,
+                readMode == READ_BLOCKING);
+    }
+
+    /**
+     * Reads audio data from the audio hardware for recording into a direct buffer. If this buffer
+     * is not a direct buffer, this method will always return 0.
+     * Note that the value returned by {@link java.nio.Buffer#position()} on this buffer is
+     * unchanged after a call to this method.
+     * The representation of the data in the buffer will depend on the format specified in
+     * the AudioRecord constructor, and will be native endian.
+     * @param audioBuffer the direct buffer to which the recorded audio data is written.
+     * Data is written to audioBuffer.position().
+     * @param sizeInBytes the number of requested bytes. It is recommended but not enforced
+     *    that the number of bytes requested be a multiple of the frame size (sample size in
+     *    bytes multiplied by the channel count).
+     * @return zero or the positive number of bytes that were read, or one of the following
+     *    error codes. The number of bytes will not exceed sizeInBytes and will be truncated to be
+     *    a multiple of the frame size.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the object isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the object is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next read()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     */
+    public int read(@NonNull ByteBuffer audioBuffer, int sizeInBytes) {
+        return read(audioBuffer, sizeInBytes, READ_BLOCKING);
+    }
+
+    /**
+     * Reads audio data from the audio hardware for recording into a direct buffer. If this buffer
+     * is not a direct buffer, this method will always return 0.
+     * Note that the value returned by {@link java.nio.Buffer#position()} on this buffer is
+     * unchanged after a call to this method.
+     * The representation of the data in the buffer will depend on the format specified in
+     * the AudioRecord constructor, and will be native endian.
+     * @param audioBuffer the direct buffer to which the recorded audio data is written.
+     * Data is written to audioBuffer.position().
+     * @param sizeInBytes the number of requested bytes. It is recommended but not enforced
+     *    that the number of bytes requested be a multiple of the frame size (sample size in
+     *    bytes multiplied by the channel count).
+     * @param readMode one of {@link #READ_BLOCKING}, {@link #READ_NON_BLOCKING}.
+     *     <br>With {@link #READ_BLOCKING}, the read will block until all the requested data
+     *     is read.
+     *     <br>With {@link #READ_NON_BLOCKING}, the read will return immediately after
+     *     reading as much audio data as possible without blocking.
+     * @return zero or the positive number of bytes that were read, or one of the following
+     *    error codes. The number of bytes will not exceed sizeInBytes and will be truncated to be
+     *    a multiple of the frame size.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the object isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the object is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next read()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     */
+    public int read(@NonNull ByteBuffer audioBuffer, int sizeInBytes, @ReadMode int readMode) {
+        if (mState != STATE_INITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
+
+        if ((readMode != READ_BLOCKING) && (readMode != READ_NON_BLOCKING)) {
+            Log.e(TAG, "AudioRecord.read() called with invalid blocking mode");
+            return ERROR_BAD_VALUE;
+        }
+
+        if ( (audioBuffer == null) || (sizeInBytes < 0) ) {
+            return ERROR_BAD_VALUE;
+        }
+
+        return native_read_in_direct_buffer(audioBuffer, sizeInBytes, readMode == READ_BLOCKING);
+    }
+
+    /**
+     *  Return Metrics data about the current AudioTrack instance.
+     *
+     * @return a {@link PersistableBundle} containing the set of attributes and values
+     * available for the media being handled by this instance of AudioRecord
+     * The attributes are descibed in {@link MetricsConstants}.
+     *
+     * Additional vendor-specific fields may also be present in
+     * the return value.
+     */
+    public PersistableBundle getMetrics() {
+        PersistableBundle bundle = native_getMetrics();
+        return bundle;
+    }
+
+    private native PersistableBundle native_getMetrics();
+
+    //--------------------------------------------------------------------------
+    // Initialization / configuration
+    //--------------------
+    /**
+     * Sets the listener the AudioRecord notifies when a previously set marker is reached or
+     * for each periodic record head position update.
+     * @param listener
+     */
+    public void setRecordPositionUpdateListener(OnRecordPositionUpdateListener listener) {
+        setRecordPositionUpdateListener(listener, null);
+    }
+
+    /**
+     * Sets the listener the AudioRecord notifies when a previously set marker is reached or
+     * for each periodic record head position update.
+     * Use this method to receive AudioRecord events in the Handler associated with another
+     * thread than the one in which you created the AudioRecord instance.
+     * @param listener
+     * @param handler the Handler that will receive the event notification messages.
+     */
+    public void setRecordPositionUpdateListener(OnRecordPositionUpdateListener listener,
+                                                    Handler handler) {
+        synchronized (mPositionListenerLock) {
+
+            mPositionListener = listener;
+
+            if (listener != null) {
+                if (handler != null) {
+                    mEventHandler = new NativeEventHandler(this, handler.getLooper());
+                } else {
+                    // no given handler, use the looper the AudioRecord was created in
+                    mEventHandler = new NativeEventHandler(this, mInitializationLooper);
+                }
+            } else {
+                mEventHandler = null;
+            }
+        }
+
+    }
+
+
+    /**
+     * Sets the marker position at which the listener is called, if set with
+     * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or
+     * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)}.
+     * @param markerInFrames marker position expressed in frames
+     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
+     *  {@link #ERROR_INVALID_OPERATION}
+     */
+    public int setNotificationMarkerPosition(int markerInFrames) {
+        if (mState == STATE_UNINITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
+        return native_set_marker_pos(markerInFrames);
+    }
+
+    /**
+     * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioRecord.
+     * Note: The query is only valid if the AudioRecord is currently recording. If it is not,
+     * <code>getRoutedDevice()</code> will return null.
+     */
+    @Override
+    public AudioDeviceInfo getRoutedDevice() {
+        int deviceId = native_getRoutedDeviceId();
+        if (deviceId == 0) {
+            return null;
+        }
+        return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_INPUTS);
+    }
+
+    /**
+     * Must match the native definition in frameworks/av/service/audioflinger/Audioflinger.h.
+     */
+    private static final long MAX_SHARED_AUDIO_HISTORY_MS = 5000;
+
+    /**
+     * @hide
+     * returns the maximum duration in milliseconds of the audio history that can be requested
+     * to be made available to other clients using the same session with
+     * {@Link Builder#setMaxSharedAudioHistory(long)}.
+     */
+    @SystemApi
+    public static long getMaxSharedAudioHistoryMillis() {
+        return MAX_SHARED_AUDIO_HISTORY_MS;
+    }
+
+    /**
+     * @hide
+     *
+     * A privileged app with permission CAPTURE_AUDIO_HOTWORD can share part of its recent
+     * capture history on a given AudioRecord with the following steps:
+     * 1) Specify the maximum time in the past that will be available for other apps by calling
+     * {@link Builder#setMaxSharedAudioHistoryMillis(long)} when creating the AudioRecord.
+     * 2) Start recording and determine where the other app should start capturing in the past.
+     * 3) Call this method with the package name of the app the history will be shared with and
+     * the intended start time for this app's capture relative to this AudioRecord's start time.
+     * 4) Communicate the {@link MediaSyncEvent} returned by this method to the other app.
+     * 5) The other app will use the MediaSyncEvent when creating its AudioRecord with
+     * {@link Builder#setSharedAudioEvent(MediaSyncEvent).
+     * 6) Only after the other app has started capturing can this app stop capturing and
+     * release its AudioRecord.
+     * This method is intended to be called only once: if called multiple times, only the last
+     * request will be honored.
+     * The implementation is "best effort": if the specified start time if too far in the past
+     * compared to the max available history specified, the start time will be adjusted to the
+     * start of the available history.
+     * @param sharedPackage the package the history will be shared with
+     * @param startFromMillis the start time, relative to the initial start time of this
+     *        AudioRecord, at which the other AudioRecord will start.
+     * @return a {@link MediaSyncEvent} to be communicated to the app this AudioRecord's audio
+     *         history will be shared with.
+     * @throws IllegalArgumentException
+     * @throws SecurityException
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD)
+    @NonNull public MediaSyncEvent shareAudioHistory(@NonNull String sharedPackage,
+                                  @IntRange(from = 0) long startFromMillis) {
+        Objects.requireNonNull(sharedPackage);
+        if (startFromMillis < 0) {
+            throw new IllegalArgumentException("Illegal negative sharedAudioHistoryMs argument");
+        }
+        int status = native_shareAudioHistory(sharedPackage, startFromMillis);
+        if (status == AudioSystem.BAD_VALUE) {
+            throw new IllegalArgumentException("Illegal sharedAudioHistoryMs argument");
+        } else if (status == AudioSystem.PERMISSION_DENIED) {
+            throw new SecurityException("permission CAPTURE_AUDIO_HOTWORD required");
+        }
+        MediaSyncEvent event =
+                MediaSyncEvent.createEvent(MediaSyncEvent.SYNC_EVENT_SHARE_AUDIO_HISTORY);
+        event.setAudioSessionId(mSessionId);
+        return event;
+    }
+
+    /*
+     * Call BEFORE adding a routing callback handler.
+     */
+    @GuardedBy("mRoutingChangeListeners")
+    private void testEnableNativeRoutingCallbacksLocked() {
+        if (mRoutingChangeListeners.size() == 0) {
+            native_enableDeviceCallback();
+        }
+    }
+
+    /*
+     * Call AFTER removing a routing callback handler.
+     */
+    @GuardedBy("mRoutingChangeListeners")
+    private void testDisableNativeRoutingCallbacksLocked() {
+        if (mRoutingChangeListeners.size() == 0) {
+            native_disableDeviceCallback();
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // (Re)Routing Info
+    //--------------------
+    /**
+     * The list of AudioRouting.OnRoutingChangedListener interfaces added (with
+     * {@link AudioRecord#addOnRoutingChangedListener} by an app to receive
+     * (re)routing notifications.
+     */
+    @GuardedBy("mRoutingChangeListeners")
+    private ArrayMap<AudioRouting.OnRoutingChangedListener,
+            NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<>();
+
+    /**
+     * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of
+     * routing changes on this AudioRecord.
+     * @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive
+     * notifications of rerouting events.
+     * @param handler  Specifies the {@link Handler} object for the thread on which to execute
+     * the callback. If <code>null</code>, the {@link Handler} associated with the main
+     * {@link Looper} will be used.
+     */
+    @Override
+    public void addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener,
+            android.os.Handler handler) {
+        synchronized (mRoutingChangeListeners) {
+            if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
+                testEnableNativeRoutingCallbacksLocked();
+                mRoutingChangeListeners.put(
+                        listener, new NativeRoutingEventHandlerDelegate(this, listener,
+                                handler != null ? handler : new Handler(mInitializationLooper)));
+            }
+        }
+    }
+
+    /**
+     * Removes an {@link AudioRouting.OnRoutingChangedListener} which has been previously added
+    * to receive rerouting notifications.
+    * @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
+    * to remove.
+    */
+    @Override
+    public void removeOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener) {
+        synchronized (mRoutingChangeListeners) {
+            if (mRoutingChangeListeners.containsKey(listener)) {
+                mRoutingChangeListeners.remove(listener);
+                testDisableNativeRoutingCallbacksLocked();
+            }
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // (Re)Routing Info
+    //--------------------
+    /**
+     * Defines the interface by which applications can receive notifications of
+     * routing changes for the associated {@link AudioRecord}.
+     *
+     * @deprecated users should switch to the general purpose
+     *             {@link AudioRouting.OnRoutingChangedListener} class instead.
+     */
+    @Deprecated
+    public interface OnRoutingChangedListener extends AudioRouting.OnRoutingChangedListener {
+        /**
+         * Called when the routing of an AudioRecord changes from either and
+         * explicit or policy rerouting. Use {@link #getRoutedDevice()} to
+         * retrieve the newly routed-from device.
+         */
+        public void onRoutingChanged(AudioRecord audioRecord);
+
+        @Override
+        default public void onRoutingChanged(AudioRouting router) {
+            if (router instanceof AudioRecord) {
+                onRoutingChanged((AudioRecord) router);
+            }
+        }
+    }
+
+    /**
+     * Adds an {@link OnRoutingChangedListener} to receive notifications of routing changes
+     * on this AudioRecord.
+     * @param listener The {@link OnRoutingChangedListener} interface to receive notifications
+     * of rerouting events.
+     * @param handler  Specifies the {@link Handler} object for the thread on which to execute
+     * the callback. If <code>null</code>, the {@link Handler} associated with the main
+     * {@link Looper} will be used.
+     * @deprecated users should switch to the general purpose
+     *             {@link AudioRouting.OnRoutingChangedListener} class instead.
+     */
+    @Deprecated
+    public void addOnRoutingChangedListener(OnRoutingChangedListener listener,
+            android.os.Handler handler) {
+        addOnRoutingChangedListener((AudioRouting.OnRoutingChangedListener) listener, handler);
+    }
+
+    /**
+      * Removes an {@link OnRoutingChangedListener} which has been previously added
+     * to receive rerouting notifications.
+     * @param listener The previously added {@link OnRoutingChangedListener} interface to remove.
+     * @deprecated users should switch to the general purpose
+     *             {@link AudioRouting.OnRoutingChangedListener} class instead.
+     */
+    @Deprecated
+    public void removeOnRoutingChangedListener(OnRoutingChangedListener listener) {
+        removeOnRoutingChangedListener((AudioRouting.OnRoutingChangedListener) listener);
+    }
+
+    /**
+     * Sends device list change notification to all listeners.
+     */
+    private void broadcastRoutingChange() {
+        AudioManager.resetAudioPortGeneration();
+        synchronized (mRoutingChangeListeners) {
+            for (NativeRoutingEventHandlerDelegate delegate : mRoutingChangeListeners.values()) {
+                delegate.notifyClient();
+            }
+        }
+    }
+
+    /**
+     * Sets the period at which the listener is called, if set with
+     * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener)} or
+     * {@link #setRecordPositionUpdateListener(OnRecordPositionUpdateListener, Handler)}.
+     * It is possible for notifications to be lost if the period is too small.
+     * @param periodInFrames update period expressed in frames
+     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_INVALID_OPERATION}
+     */
+    public int setPositionNotificationPeriod(int periodInFrames) {
+        if (mState == STATE_UNINITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
+        return native_set_pos_update_period(periodInFrames);
+    }
+
+    //--------------------------------------------------------------------------
+    // Explicit Routing
+    //--------------------
+    private AudioDeviceInfo mPreferredDevice = null;
+
+    /**
+     * Specifies an audio device (via an {@link AudioDeviceInfo} object) to route
+     * the input to this AudioRecord.
+     * @param deviceInfo The {@link AudioDeviceInfo} specifying the audio source.
+     *  If deviceInfo is null, default routing is restored.
+     * @return true if successful, false if the specified {@link AudioDeviceInfo} is non-null and
+     * does not correspond to a valid audio input device.
+     */
+    @Override
+    public boolean setPreferredDevice(AudioDeviceInfo deviceInfo) {
+        // Do some validation....
+        if (deviceInfo != null && !deviceInfo.isSource()) {
+            return false;
+        }
+
+        int preferredDeviceId = deviceInfo != null ? deviceInfo.getId() : 0;
+        boolean status = native_setInputDevice(preferredDeviceId);
+        if (status == true) {
+            synchronized (this) {
+                mPreferredDevice = deviceInfo;
+            }
+        }
+        return status;
+    }
+
+    /**
+     * Returns the selected input specified by {@link #setPreferredDevice}. Note that this
+     * is not guarenteed to correspond to the actual device being used for recording.
+     */
+    @Override
+    public AudioDeviceInfo getPreferredDevice() {
+        synchronized (this) {
+            return mPreferredDevice;
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Microphone information
+    //--------------------
+    /**
+     * Returns a lists of {@link MicrophoneInfo} representing the active microphones.
+     * By querying channel mapping for each active microphone, developer can know how
+     * the microphone is used by each channels or a capture stream.
+     * Note that the information about the active microphones may change during a recording.
+     * See {@link AudioManager#registerAudioDeviceCallback} to be notified of changes
+     * in the audio devices, querying the active microphones then will return the latest
+     * information.
+     *
+     * @return a lists of {@link MicrophoneInfo} representing the active microphones.
+     * @throws IOException if an error occurs
+     */
+    public List<MicrophoneInfo> getActiveMicrophones() throws IOException {
+        ArrayList<MicrophoneInfo> activeMicrophones = new ArrayList<>();
+        int status = native_get_active_microphones(activeMicrophones);
+        if (status != AudioManager.SUCCESS) {
+            if (status != AudioManager.ERROR_INVALID_OPERATION) {
+                Log.e(TAG, "getActiveMicrophones failed:" + status);
+            }
+            Log.i(TAG, "getActiveMicrophones failed, fallback on routed device info");
+        }
+        AudioManager.setPortIdForMicrophones(activeMicrophones);
+
+        // Use routed device when there is not information returned by hal.
+        if (activeMicrophones.size() == 0) {
+            AudioDeviceInfo device = getRoutedDevice();
+            if (device != null) {
+                MicrophoneInfo microphone = AudioManager.microphoneInfoFromAudioDeviceInfo(device);
+                ArrayList<Pair<Integer, Integer>> channelMapping = new ArrayList<>();
+                for (int i = 0; i < mChannelCount; i++) {
+                    channelMapping.add(new Pair(i, MicrophoneInfo.CHANNEL_MAPPING_DIRECT));
+                }
+                microphone.setChannelMapping(channelMapping);
+                activeMicrophones.add(microphone);
+            }
+        }
+        return activeMicrophones;
+    }
+
+    //--------------------------------------------------------------------------
+    // Implementation of AudioRecordingMonitor interface
+    //--------------------
+
+    AudioRecordingMonitorImpl mRecordingInfoImpl =
+            new AudioRecordingMonitorImpl((AudioRecordingMonitorClient) this);
+
+    /**
+     * Register a callback to be notified of audio capture changes via a
+     * {@link AudioManager.AudioRecordingCallback}. A callback is received when the capture path
+     * configuration changes (pre-processing, format, sampling rate...) or capture is
+     * silenced/unsilenced by the system.
+     * @param executor {@link Executor} to handle the callbacks.
+     * @param cb non-null callback to register
+     */
+    public void registerAudioRecordingCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull AudioManager.AudioRecordingCallback cb) {
+        mRecordingInfoImpl.registerAudioRecordingCallback(executor, cb);
+    }
+
+    /**
+     * Unregister an audio recording callback previously registered with
+     * {@link #registerAudioRecordingCallback(Executor, AudioManager.AudioRecordingCallback)}.
+     * @param cb non-null callback to unregister
+     */
+    public void unregisterAudioRecordingCallback(@NonNull AudioManager.AudioRecordingCallback cb) {
+        mRecordingInfoImpl.unregisterAudioRecordingCallback(cb);
+    }
+
+    /**
+     * Returns the current active audio recording for this audio recorder.
+     * @return a valid {@link AudioRecordingConfiguration} if this recorder is active
+     * or null otherwise.
+     * @see AudioRecordingConfiguration
+     */
+    public @Nullable AudioRecordingConfiguration getActiveRecordingConfiguration() {
+        return mRecordingInfoImpl.getActiveRecordingConfiguration();
+    }
+
+    //---------------------------------------------------------
+    // Implementation of AudioRecordingMonitorClient interface
+    //--------------------
+    /**
+     * @hide
+     */
+    public int getPortId() {
+        if (mNativeRecorderInJavaObj == 0) {
+            return 0;
+        }
+        try {
+            return native_getPortId();
+        } catch (IllegalStateException e) {
+            return 0;
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // MicrophoneDirection
+    //--------------------
+    /**
+     * Specifies the logical microphone (for processing). Applications can use this to specify
+     * which side of the device to optimize capture from. Typically used in conjunction with
+     * the camera capturing video.
+     *
+     * @return true if sucessful.
+     */
+    public boolean setPreferredMicrophoneDirection(@DirectionMode int direction) {
+        return native_set_preferred_microphone_direction(direction) == AudioSystem.SUCCESS;
+    }
+
+    /**
+     * Specifies the zoom factor (i.e. the field dimension) for the selected microphone
+     * (for processing). The selected microphone is determined by the use-case for the stream.
+     *
+     * @param zoom the desired field dimension of microphone capture. Range is from -1 (wide angle),
+     * though 0 (no zoom) to 1 (maximum zoom).
+     * @return true if sucessful.
+     */
+    public boolean setPreferredMicrophoneFieldDimension(
+                            @FloatRange(from = -1.0, to = 1.0) float zoom) {
+        Preconditions.checkArgument(
+                zoom >= -1 && zoom <= 1, "Argument must fall between -1 & 1 (inclusive)");
+        return native_set_preferred_microphone_field_dimension(zoom) == AudioSystem.SUCCESS;
+    }
+
+    /**
+     * Sets a {@link LogSessionId} instance to this AudioRecord for metrics collection.
+     *
+     * @param logSessionId a {@link LogSessionId} instance which is used to
+     *        identify this object to the metrics service. Proper generated
+     *        Ids must be obtained from the Java metrics service and should
+     *        be considered opaque. Use
+     *        {@link LogSessionId#LOG_SESSION_ID_NONE} to remove the
+     *        logSessionId association.
+     * @throws IllegalStateException if AudioRecord not initialized.
+     */
+    public void setLogSessionId(@NonNull LogSessionId logSessionId) {
+        Objects.requireNonNull(logSessionId);
+        if (mState == STATE_UNINITIALIZED) {
+            throw new IllegalStateException("AudioRecord not initialized");
+        }
+        String stringId = logSessionId.getStringId();
+        native_setLogSessionId(stringId);
+        mLogSessionId = logSessionId;
+    }
+
+    /**
+     * Returns the {@link LogSessionId}.
+     */
+    @NonNull
+    public LogSessionId getLogSessionId() {
+        return mLogSessionId;
+    }
+
+    //---------------------------------------------------------
+    // Interface definitions
+    //--------------------
+    /**
+     * Interface definition for a callback to be invoked when an AudioRecord has
+     * reached a notification marker set by {@link AudioRecord#setNotificationMarkerPosition(int)}
+     * or for periodic updates on the progress of the record head, as set by
+     * {@link AudioRecord#setPositionNotificationPeriod(int)}.
+     */
+    public interface OnRecordPositionUpdateListener  {
+        /**
+         * Called on the listener to notify it that the previously set marker has been reached
+         * by the recording head.
+         */
+        void onMarkerReached(AudioRecord recorder);
+
+        /**
+         * Called on the listener to periodically notify it that the record head has reached
+         * a multiple of the notification period.
+         */
+        void onPeriodicNotification(AudioRecord recorder);
+    }
+
+
+
+    //---------------------------------------------------------
+    // Inner classes
+    //--------------------
+
+    /**
+     * Helper class to handle the forwarding of native events to the appropriate listener
+     * (potentially) handled in a different thread
+     */
+    private class NativeEventHandler extends Handler {
+        private final AudioRecord mAudioRecord;
+
+        NativeEventHandler(AudioRecord recorder, Looper looper) {
+            super(looper);
+            mAudioRecord = recorder;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            OnRecordPositionUpdateListener listener = null;
+            synchronized (mPositionListenerLock) {
+                listener = mAudioRecord.mPositionListener;
+            }
+
+            switch (msg.what) {
+            case NATIVE_EVENT_MARKER:
+                if (listener != null) {
+                    listener.onMarkerReached(mAudioRecord);
+                }
+                break;
+            case NATIVE_EVENT_NEW_POS:
+                if (listener != null) {
+                    listener.onPeriodicNotification(mAudioRecord);
+                }
+                break;
+            default:
+                loge("Unknown native event type: " + msg.what);
+                break;
+            }
+        }
+    }
+
+    //---------------------------------------------------------
+    // Java methods called from the native side
+    //--------------------
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static void postEventFromNative(Object audiorecord_ref,
+            int what, int arg1, int arg2, Object obj) {
+        //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2);
+        AudioRecord recorder = (AudioRecord)((WeakReference)audiorecord_ref).get();
+        if (recorder == null) {
+            return;
+        }
+
+        if (what == AudioSystem.NATIVE_EVENT_ROUTING_CHANGE) {
+            recorder.broadcastRoutingChange();
+            return;
+        }
+
+        if (recorder.mEventHandler != null) {
+            Message m =
+                recorder.mEventHandler.obtainMessage(what, arg1, arg2, obj);
+            recorder.mEventHandler.sendMessage(m);
+        }
+
+    }
+
+
+    //---------------------------------------------------------
+    // Native methods called from the Java side
+    //--------------------
+
+    /**
+     * @deprecated Use native_setup that takes an {@link AttributionSource} object
+     * @return
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R,
+            publicAlternatives = "{@code AudioRecord.Builder}")
+    @Deprecated
+    private int native_setup(Object audiorecordThis,
+            Object /*AudioAttributes*/ attributes,
+            int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
+            int buffSizeInBytes, int[] sessionId, String opPackageName,
+            long nativeRecordInJavaObj) {
+        AttributionSource attributionSource = AttributionSource.myAttributionSource()
+                .withPackageName(opPackageName);
+        try (ScopedParcelState attributionSourceState = attributionSource.asScopedParcelState()) {
+            return native_setup(audiorecordThis, attributes, sampleRate, channelMask,
+                    channelIndexMask, audioFormat, buffSizeInBytes, sessionId,
+                    attributionSourceState.getParcel(), nativeRecordInJavaObj, 0);
+        }
+    }
+
+    private native int native_setup(Object audiorecordThis,
+            Object /*AudioAttributes*/ attributes,
+            int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
+            int buffSizeInBytes, int[] sessionId, @NonNull Parcel attributionSource,
+            long nativeRecordInJavaObj, int maxSharedAudioHistoryMs);
+
+    // TODO remove: implementation calls directly into implementation of native_release()
+    private native void native_finalize();
+
+    /**
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public native final void native_release();
+
+    private native final int native_start(int syncEvent, int sessionId);
+
+    private native final void native_stop();
+
+    private native final int native_read_in_byte_array(byte[] audioData,
+            int offsetInBytes, int sizeInBytes, boolean isBlocking);
+
+    private native final int native_read_in_short_array(short[] audioData,
+            int offsetInShorts, int sizeInShorts, boolean isBlocking);
+
+    private native final int native_read_in_float_array(float[] audioData,
+            int offsetInFloats, int sizeInFloats, boolean isBlocking);
+
+    private native final int native_read_in_direct_buffer(Object jBuffer,
+            int sizeInBytes, boolean isBlocking);
+
+    private native final int native_get_buffer_size_in_frames();
+
+    private native final int native_set_marker_pos(int marker);
+    private native final int native_get_marker_pos();
+
+    private native final int native_set_pos_update_period(int updatePeriod);
+    private native final int native_get_pos_update_period();
+
+    static private native final int native_get_min_buff_size(
+            int sampleRateInHz, int channelCount, int audioFormat);
+
+    private native final boolean native_setInputDevice(int deviceId);
+    private native final int native_getRoutedDeviceId();
+    private native final void native_enableDeviceCallback();
+    private native final void native_disableDeviceCallback();
+
+    private native final int native_get_timestamp(@NonNull AudioTimestamp outTimestamp,
+            @AudioTimestamp.Timebase int timebase);
+
+    private native final int native_get_active_microphones(
+            ArrayList<MicrophoneInfo> activeMicrophones);
+
+    /**
+     * @throws IllegalStateException
+     */
+    private native int native_getPortId();
+
+    private native int native_set_preferred_microphone_direction(int direction);
+    private native int native_set_preferred_microphone_field_dimension(float zoom);
+
+    private native void native_setLogSessionId(@Nullable String logSessionId);
+
+    private native int native_shareAudioHistory(@NonNull String sharedPackage, long startFromMs);
+
+    //---------------------------------------------------------
+    // Utility methods
+    //------------------
+
+    private static void logd(String msg) {
+        Log.d(TAG, msg);
+    }
+
+    private static void loge(String msg) {
+        Log.e(TAG, msg);
+    }
+
+    public static final class MetricsConstants
+    {
+        private MetricsConstants() {}
+
+        // MM_PREFIX is slightly different than TAG, used to avoid cut-n-paste errors.
+        private static final String MM_PREFIX = "android.media.audiorecord.";
+
+        /**
+         * Key to extract the audio data encoding for this track
+         * from the {@link AudioRecord#getMetrics} return value.
+         * The value is a {@code String}.
+         */
+        public static final String ENCODING = MM_PREFIX + "encoding";
+
+        /**
+         * Key to extract the source type for this track
+         * from the {@link AudioRecord#getMetrics} return value.
+         * The value is a {@code String}.
+         */
+        public static final String SOURCE = MM_PREFIX + "source";
+
+        /**
+         * Key to extract the estimated latency through the recording pipeline
+         * from the {@link AudioRecord#getMetrics} return value.
+         * This is in units of milliseconds.
+         * The value is an {@code int}.
+         * @deprecated Not properly supported in the past.
+         */
+        @Deprecated
+        public static final String LATENCY = MM_PREFIX + "latency";
+
+        /**
+         * Key to extract the sink sample rate for this record track in Hz
+         * from the {@link AudioRecord#getMetrics} return value.
+         * The value is an {@code int}.
+         */
+        public static final String SAMPLERATE = MM_PREFIX + "samplerate";
+
+        /**
+         * Key to extract the number of channels being recorded in this record track
+         * from the {@link AudioRecord#getMetrics} return value.
+         * The value is an {@code int}.
+         */
+        public static final String CHANNELS = MM_PREFIX + "channels";
+
+        /**
+         * Use for testing only. Do not expose.
+         * The native channel mask.
+         * The value is a {@code long}.
+         * @hide
+         */
+        @TestApi
+        public static final String CHANNEL_MASK = MM_PREFIX + "channelMask";
+
+
+        /**
+         * Use for testing only. Do not expose.
+         * The port id of this input port in audioserver.
+         * The value is an {@code int}.
+         * @hide
+         */
+        @TestApi
+        public static final String PORT_ID = MM_PREFIX + "portId";
+
+        /**
+         * Use for testing only. Do not expose.
+         * The buffer frameCount.
+         * The value is an {@code int}.
+         * @hide
+         */
+        @TestApi
+        public static final String FRAME_COUNT = MM_PREFIX + "frameCount";
+
+        /**
+         * Use for testing only. Do not expose.
+         * The actual record track attributes used.
+         * The value is a {@code String}.
+         * @hide
+         */
+        @TestApi
+        public static final String ATTRIBUTES = MM_PREFIX + "attributes";
+
+        /**
+         * Use for testing only. Do not expose.
+         * The buffer frameCount
+         * The value is a {@code double}.
+         * @hide
+         */
+        @TestApi
+        public static final String DURATION_MS = MM_PREFIX + "durationMs";
+
+        /**
+         * Use for testing only. Do not expose.
+         * The number of times the record track has started
+         * The value is a {@code long}.
+         * @hide
+         */
+        @TestApi
+        public static final String START_COUNT = MM_PREFIX + "startCount";
+    }
+}
diff --git a/android/media/AudioRecordRoutingProxy.java b/android/media/AudioRecordRoutingProxy.java
new file mode 100644
index 0000000..b0c19e4
--- /dev/null
+++ b/android/media/AudioRecordRoutingProxy.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2008 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;
+
+/**
+ * An AudioRecord connected to a native (C/C++) which allows access only to routing methods.
+ */
+class AudioRecordRoutingProxy extends AudioRecord {
+    /**
+     * A constructor which explicitly connects a Native (C++) AudioRecord. For use by
+     * the AudioRecordRoutingProxy subclass.
+     * @param nativeRecordInJavaObj A C/C++ pointer to a native AudioRecord
+     * (associated with an OpenSL ES recorder).
+     */
+    public AudioRecordRoutingProxy(long nativeRecordInJavaObj) {
+        super(nativeRecordInJavaObj);
+    }
+}
diff --git a/android/media/AudioRecordingConfiguration.java b/android/media/AudioRecordingConfiguration.java
new file mode 100644
index 0000000..7908c96
--- /dev/null
+++ b/android/media/AudioRecordingConfiguration.java
@@ -0,0 +1,413 @@
+/*
+ * Copyright (C) 2016 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.media.audiofx.AudioEffect;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * The AudioRecordingConfiguration class collects the information describing an audio recording
+ * session.
+ * <p>Direct polling (see {@link AudioManager#getActiveRecordingConfigurations()}) or callback
+ * (see {@link AudioManager#registerAudioRecordingCallback(android.media.AudioManager.AudioRecordingCallback, android.os.Handler)}
+ * methods are ways to receive information about the current recording configuration of the device.
+ * <p>An audio recording configuration contains information about the recording format as used by
+ * the application ({@link #getClientFormat()}, as well as the recording format actually used by
+ * the device ({@link #getFormat()}). The two recording formats may, for instance, be at different
+ * sampling rates due to hardware limitations (e.g. application recording at 44.1kHz whereas the
+ * device always records at 48kHz, and the Android framework resamples for the application).
+ * <p>The configuration also contains the use case for which audio is recorded
+ * ({@link #getClientAudioSource()}), enabling the ability to distinguish between different
+ * activities such as ongoing voice recognition or camcorder recording.
+ *
+ */
+public final class AudioRecordingConfiguration implements Parcelable {
+    private final static String TAG = new String("AudioRecordingConfiguration");
+
+    private final int mClientSessionId;
+
+    private final int mClientSource;
+
+    private final AudioFormat mDeviceFormat;
+    private final AudioFormat mClientFormat;
+
+    @NonNull private final String mClientPackageName;
+    private final int mClientUid;
+
+    private final int mPatchHandle;
+
+    private final int mClientPortId;
+
+    private boolean mClientSilenced;
+
+    private final int mDeviceSource;
+
+    private final AudioEffect.Descriptor[] mClientEffects;
+
+    private final AudioEffect.Descriptor[] mDeviceEffects;
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public AudioRecordingConfiguration(int uid, int session, int source, AudioFormat clientFormat,
+            AudioFormat devFormat, int patchHandle, String packageName, int clientPortId,
+            boolean clientSilenced, int deviceSource,
+            AudioEffect.Descriptor[] clientEffects, AudioEffect.Descriptor[] deviceEffects) {
+        mClientUid = uid;
+        mClientSessionId = session;
+        mClientSource = source;
+        mClientFormat = clientFormat;
+        mDeviceFormat = devFormat;
+        mPatchHandle = patchHandle;
+        mClientPackageName = packageName;
+        mClientPortId = clientPortId;
+        mClientSilenced = clientSilenced;
+        mDeviceSource = deviceSource;
+        mClientEffects = clientEffects;
+        mDeviceEffects = deviceEffects;
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public AudioRecordingConfiguration(int uid, int session, int source,
+                                       AudioFormat clientFormat, AudioFormat devFormat,
+                                       int patchHandle, String packageName) {
+        this(uid, session, source, clientFormat,
+                   devFormat, patchHandle, packageName, 0 /*clientPortId*/,
+                   false /*clientSilenced*/, MediaRecorder.AudioSource.DEFAULT /*deviceSource*/,
+                   new AudioEffect.Descriptor[0] /*clientEffects*/,
+                   new AudioEffect.Descriptor[0] /*deviceEffects*/);
+    }
+
+    /**
+     * @hide
+     * For AudioService dump
+     * @param pw
+     */
+    public void dump(PrintWriter pw) {
+        pw.println("  " + toLogFriendlyString(this));
+    }
+
+    /**
+     * @hide
+     */
+    public static String toLogFriendlyString(AudioRecordingConfiguration arc) {
+        String clientEffects = new String();
+        for (AudioEffect.Descriptor desc : arc.mClientEffects) {
+            clientEffects += "'" + desc.name + "' ";
+        }
+        String deviceEffects = new String();
+        for (AudioEffect.Descriptor desc : arc.mDeviceEffects) {
+            deviceEffects += "'" + desc.name + "' ";
+        }
+
+        return new String("session:" + arc.mClientSessionId
+                + " -- source client=" + MediaRecorder.toLogFriendlyAudioSource(arc.mClientSource)
+                + ", dev=" + arc.mDeviceFormat.toLogFriendlyString()
+                + " -- uid:" + arc.mClientUid
+                + " -- patch:" + arc.mPatchHandle
+                + " -- pack:" + arc.mClientPackageName
+                + " -- format client=" + arc.mClientFormat.toLogFriendlyString()
+                + ", dev=" + arc.mDeviceFormat.toLogFriendlyString()
+                + " -- silenced:" + arc.mClientSilenced
+                + " -- effects client=" + clientEffects
+                + ", dev=" + deviceEffects);
+    }
+
+    // Note that this method is called server side, so no "privileged" information is ever sent
+    // to a client that is not supposed to have access to it.
+    /**
+     * @hide
+     * Creates a copy of the recording configuration that is stripped of any data enabling
+     * identification of which application it is associated with ("anonymized").
+     * @param in
+     */
+    public static AudioRecordingConfiguration anonymizedCopy(AudioRecordingConfiguration in) {
+        return new AudioRecordingConfiguration( /*anonymized uid*/ -1,
+                in.mClientSessionId, in.mClientSource, in.mClientFormat,
+                in.mDeviceFormat, in.mPatchHandle, "" /*empty package name*/,
+                in.mClientPortId, in.mClientSilenced, in.mDeviceSource, in.mClientEffects,
+                in.mDeviceEffects);
+    }
+
+    // matches the sources that return false in MediaRecorder.isSystemOnlyAudioSource(source)
+    /** @hide */
+    @IntDef({
+        MediaRecorder.AudioSource.DEFAULT,
+        MediaRecorder.AudioSource.MIC,
+        MediaRecorder.AudioSource.VOICE_UPLINK,
+        MediaRecorder.AudioSource.VOICE_DOWNLINK,
+        MediaRecorder.AudioSource.VOICE_CALL,
+        MediaRecorder.AudioSource.CAMCORDER,
+        MediaRecorder.AudioSource.VOICE_RECOGNITION,
+        MediaRecorder.AudioSource.VOICE_COMMUNICATION,
+        MediaRecorder.AudioSource.UNPROCESSED,
+        MediaRecorder.AudioSource.VOICE_PERFORMANCE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioSource {}
+
+    // documented return values match the sources that return false
+    //   in MediaRecorder.isSystemOnlyAudioSource(source)
+    /**
+     * Returns the audio source selected by the client.
+     * @return the audio source selected by the client.
+     */
+    public @AudioSource int getClientAudioSource() { return mClientSource; }
+
+    /**
+     * Returns the session number of the recording, see {@link AudioRecord#getAudioSessionId()}.
+     * @return the session number.
+     */
+    public int getClientAudioSessionId() {
+        return mClientSessionId;
+    }
+
+    /**
+     * Returns the audio format at which audio is recorded on this Android device.
+     * Note that it may differ from the client application recording format
+     * (see {@link #getClientFormat()}).
+     * @return the device recording format
+     */
+    public AudioFormat getFormat() { return mDeviceFormat; }
+
+    /**
+     * Returns the audio format at which the client application is recording audio.
+     * Note that it may differ from the actual recording format (see {@link #getFormat()}).
+     * @return the recording format
+     */
+    public AudioFormat getClientFormat() { return mClientFormat; }
+
+    /**
+     * @pending for SystemApi
+     * Returns the package name of the application performing the recording.
+     * Where there are multiple packages sharing the same user id through the "sharedUserId"
+     * mechanism, only the first one with that id will be returned
+     * (see {@link PackageManager#getPackagesForUid(int)}).
+     * <p>This information is only available if the caller has the
+     * {@link android.Manifest.permission.MODIFY_AUDIO_ROUTING} permission.
+     * <br>When called without the permission, the result is an empty string.
+     * @return the package name
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public String getClientPackageName() { return mClientPackageName; }
+
+    /**
+     * Returns the user id of the application performing the recording.
+     * <p>This information is only available if the caller has the
+     * {@link android.Manifest.permission.MODIFY_AUDIO_ROUTING}
+     * permission.
+     * @return the user id
+     * @throws SecurityException Thrown if the caller is missing the MODIFY_AUDIO_ROUTING permission
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public int getClientUid() {
+        if (mClientUid == -1) {
+            throw new SecurityException("MODIFY_AUDIO_ROUTING permission is missing");
+        }
+        return mClientUid;
+    }
+
+    /**
+     * Returns information about the audio input device used for this recording.
+     * @return the audio recording device or null if this information cannot be retrieved
+     */
+    public AudioDeviceInfo getAudioDevice() {
+        // build the AudioDeviceInfo from the patch handle
+        ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>();
+        if (AudioManager.listAudioPatches(patches) != AudioManager.SUCCESS) {
+            Log.e(TAG, "Error retrieving list of audio patches");
+            return null;
+        }
+        for (int i = 0 ; i < patches.size() ; i++) {
+            final AudioPatch patch = patches.get(i);
+            if (patch.id() == mPatchHandle) {
+                final AudioPortConfig[] sources = patch.sources();
+                if ((sources != null) && (sources.length > 0)) {
+                    // not supporting multiple sources, so just look at the first source
+                    int devId = sources[0].port().id();
+                    return AudioManager.getDeviceForPortId(devId, AudioManager.GET_DEVICES_INPUTS);
+                }
+                // patch handle is unique, there won't be another with the same handle
+                break;
+            }
+        }
+        Log.e(TAG, "Couldn't find device for recording, did recording end already?");
+        return null;
+    }
+
+    /**
+     * @hide
+     * Returns the system unique ID assigned for the AudioRecord object corresponding to this
+     * AudioRecordingConfiguration client.
+     * @return the port ID.
+     */
+    public int getClientPortId() {
+        return mClientPortId;
+    }
+
+    /**
+     * Returns true if the audio returned to the client is currently being silenced by the
+     * audio framework due to concurrent capture policy (e.g the capturing application does not have
+     * an active foreground process or service anymore).
+     * @return true if captured audio is silenced, false otherwise .
+     */
+    public boolean isClientSilenced() {
+        return mClientSilenced;
+    }
+
+    /**
+     * Returns the audio source currently used to configure the capture path. It can be different
+     * from the source returned by {@link #getClientAudioSource()} if another capture is active.
+     * @return the audio source active on the capture path.
+     */
+    public @AudioSource int getAudioSource() {
+        return mDeviceSource;
+    }
+
+    /**
+     * Returns the list of {@link AudioEffect.Descriptor} for all effects currently enabled on
+     * the audio capture client (e.g. {@link AudioRecord} or {@link MediaRecorder}).
+     * @return List of {@link AudioEffect.Descriptor} containing all effects enabled for the client.
+     */
+    public @NonNull List<AudioEffect.Descriptor> getClientEffects() {
+        return new ArrayList<AudioEffect.Descriptor>(Arrays.asList(mClientEffects));
+    }
+
+    /**
+     * Returns the list of {@link AudioEffect.Descriptor} for all effects currently enabled on
+     * the capture stream.
+     * @return List of {@link AudioEffect.Descriptor} containing all effects enabled on the
+     * capture stream. This can be different from the list returned by {@link #getClientEffects()}
+     * if another capture is active.
+     */
+    public @NonNull List<AudioEffect.Descriptor> getEffects() {
+        return new ArrayList<AudioEffect.Descriptor>(Arrays.asList(mDeviceEffects));
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<AudioRecordingConfiguration> CREATOR
+            = new Parcelable.Creator<AudioRecordingConfiguration>() {
+        /**
+         * Rebuilds an AudioRecordingConfiguration previously stored with writeToParcel().
+         * @param p Parcel object to read the AudioRecordingConfiguration from
+         * @return a new AudioRecordingConfiguration created from the data in the parcel
+         */
+        public AudioRecordingConfiguration createFromParcel(Parcel p) {
+            return new AudioRecordingConfiguration(p);
+        }
+        public AudioRecordingConfiguration[] newArray(int size) {
+            return new AudioRecordingConfiguration[size];
+        }
+    };
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mClientSessionId, mClientSource);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mClientSessionId);
+        dest.writeInt(mClientSource);
+        mClientFormat.writeToParcel(dest, 0);
+        mDeviceFormat.writeToParcel(dest, 0);
+        dest.writeInt(mPatchHandle);
+        dest.writeString(mClientPackageName);
+        dest.writeInt(mClientUid);
+        dest.writeInt(mClientPortId);
+        dest.writeBoolean(mClientSilenced);
+        dest.writeInt(mDeviceSource);
+        dest.writeInt(mClientEffects.length);
+        for (int i = 0; i < mClientEffects.length; i++) {
+            mClientEffects[i].writeToParcel(dest);
+        }
+        dest.writeInt(mDeviceEffects.length);
+        for (int i = 0; i < mDeviceEffects.length; i++) {
+            mDeviceEffects[i].writeToParcel(dest);
+        }
+    }
+
+    private AudioRecordingConfiguration(Parcel in) {
+        mClientSessionId = in.readInt();
+        mClientSource = in.readInt();
+        mClientFormat = AudioFormat.CREATOR.createFromParcel(in);
+        mDeviceFormat = AudioFormat.CREATOR.createFromParcel(in);
+        mPatchHandle = in.readInt();
+        mClientPackageName = in.readString();
+        mClientUid = in.readInt();
+        mClientPortId = in.readInt();
+        mClientSilenced = in.readBoolean();
+        mDeviceSource = in.readInt();
+        mClientEffects = new AudioEffect.Descriptor[in.readInt()];
+        for (int i = 0; i < mClientEffects.length; i++) {
+            mClientEffects[i] = new AudioEffect.Descriptor(in);
+        }
+        mDeviceEffects = new AudioEffect.Descriptor[in.readInt()];
+        for (int i = 0; i < mDeviceEffects.length; i++) {
+            mDeviceEffects[i] = new AudioEffect.Descriptor(in);
+        }
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || !(o instanceof AudioRecordingConfiguration)) return false;
+
+        AudioRecordingConfiguration that = (AudioRecordingConfiguration) o;
+
+        return ((mClientUid == that.mClientUid)
+                && (mClientSessionId == that.mClientSessionId)
+                && (mClientSource == that.mClientSource)
+                && (mPatchHandle == that.mPatchHandle)
+                && (mClientFormat.equals(that.mClientFormat))
+                && (mDeviceFormat.equals(that.mDeviceFormat))
+                && (mClientPackageName.equals(that.mClientPackageName))
+                && (mClientPortId == that.mClientPortId)
+                && (mClientSilenced == that.mClientSilenced)
+                && (mDeviceSource == that.mDeviceSource)
+                && (Arrays.equals(mClientEffects, that.mClientEffects))
+                && (Arrays.equals(mDeviceEffects, that.mDeviceEffects)));
+    }
+}
diff --git a/android/media/AudioRecordingMonitor.java b/android/media/AudioRecordingMonitor.java
new file mode 100644
index 0000000..e2605d0
--- /dev/null
+++ b/android/media/AudioRecordingMonitor.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 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.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import java.util.concurrent.Executor;
+
+/**
+ * AudioRecordingMonitor defines an interface implemented by {@link AudioRecord} and
+ * {@link MediaRecorder} allowing applications to install a callback and be notified of changes
+ * in the capture path while recoding is active.
+ */
+public interface AudioRecordingMonitor {
+    /**
+     * Register a callback to be notified of audio capture changes via a
+     * {@link AudioManager.AudioRecordingCallback}. A callback is received when the capture path
+     * configuration changes (pre-processing, format, sampling rate...) or capture is
+     * silenced/unsilenced by the system.
+     * @param executor {@link Executor} to handle the callbacks.
+     * @param cb non-null callback to register
+     */
+    void registerAudioRecordingCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull AudioManager.AudioRecordingCallback cb);
+
+    /**
+     * Unregister an audio recording callback previously registered with
+     * {@link #registerAudioRecordingCallback(Executor, AudioManager.AudioRecordingCallback)}.
+     * @param cb non-null callback to unregister
+     */
+    void unregisterAudioRecordingCallback(@NonNull AudioManager.AudioRecordingCallback cb);
+
+    /**
+     * Returns the current active audio recording for this audio recorder.
+     * @return a valid {@link AudioRecordingConfiguration} if this recorder is active
+     * or null otherwise.
+     * @see AudioRecordingConfiguration
+     */
+    @Nullable AudioRecordingConfiguration getActiveRecordingConfiguration();
+}
diff --git a/android/media/AudioRecordingMonitorClient.java b/android/media/AudioRecordingMonitorClient.java
new file mode 100644
index 0000000..7578d9b
--- /dev/null
+++ b/android/media/AudioRecordingMonitorClient.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 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;
+
+/**
+ * Interface implemented by classes using { @link AudioRecordingMonitor} interface.
+ * @hide
+ */
+public interface AudioRecordingMonitorClient {
+    /**
+     * @return the unique port ID allocated by audio framework to this recorder
+     */
+    int getPortId();
+}
diff --git a/android/media/AudioRecordingMonitorImpl.java b/android/media/AudioRecordingMonitorImpl.java
new file mode 100644
index 0000000..c2cd4bc
--- /dev/null
+++ b/android/media/AudioRecordingMonitorImpl.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright (C) 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.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.Executor;
+
+/**
+ * Implementation of AudioRecordingMonitor interface.
+ * @hide
+ */
+public class AudioRecordingMonitorImpl implements AudioRecordingMonitor {
+
+    private static final String TAG = "android.media.AudioRecordingMonitor";
+
+    private static IAudioService sService; //lazy initialization, use getService()
+
+    private final AudioRecordingMonitorClient mClient;
+
+    AudioRecordingMonitorImpl(@NonNull AudioRecordingMonitorClient client) {
+        mClient = client;
+    }
+
+    /**
+     * Register a callback to be notified of audio capture changes via a
+     * {@link AudioManager.AudioRecordingCallback}. A callback is received when the capture path
+     * configuration changes (pre-processing, format, sampling rate...) or capture is
+     * silenced/unsilenced by the system.
+     * @param executor {@link Executor} to handle the callbacks.
+     * @param cb non-null callback to register
+     */
+    public void registerAudioRecordingCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull AudioManager.AudioRecordingCallback cb) {
+        if (cb == null) {
+            throw new IllegalArgumentException("Illegal null AudioRecordingCallback");
+        }
+        if (executor == null) {
+            throw new IllegalArgumentException("Illegal null Executor");
+        }
+        synchronized (mRecordCallbackLock) {
+            // check if eventCallback already in list
+            for (AudioRecordingCallbackInfo arci : mRecordCallbackList) {
+                if (arci.mCb == cb) {
+                    throw new IllegalArgumentException(
+                            "AudioRecordingCallback already registered");
+                }
+            }
+            beginRecordingCallbackHandling();
+            mRecordCallbackList.add(new AudioRecordingCallbackInfo(executor, cb));
+        }
+    }
+
+    /**
+     * Unregister an audio recording callback previously registered with
+     * {@link #registerAudioRecordingCallback(Executor, AudioManager.AudioRecordingCallback)}.
+     * @param cb non-null callback to unregister
+     */
+    public void unregisterAudioRecordingCallback(@NonNull AudioManager.AudioRecordingCallback cb) {
+        if (cb == null) {
+            throw new IllegalArgumentException("Illegal null AudioRecordingCallback argument");
+        }
+
+        synchronized (mRecordCallbackLock) {
+            for (AudioRecordingCallbackInfo arci : mRecordCallbackList) {
+                if (arci.mCb == cb) {
+                    // ok to remove while iterating over list as we exit iteration
+                    mRecordCallbackList.remove(arci);
+                    if (mRecordCallbackList.size() == 0) {
+                        endRecordingCallbackHandling();
+                    }
+                    return;
+                }
+            }
+            throw new IllegalArgumentException("AudioRecordingCallback was not registered");
+        }
+    }
+
+    /**
+     * Returns the current active audio recording for this audio recorder.
+     * @return a valid {@link AudioRecordingConfiguration} if this recorder is active
+     * or null otherwise.
+     * @see AudioRecordingConfiguration
+     */
+    public @Nullable AudioRecordingConfiguration getActiveRecordingConfiguration() {
+        final IAudioService service = getService();
+        try {
+            List<AudioRecordingConfiguration> configs = service.getActiveRecordingConfigurations();
+            return getMyConfig(configs);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    private static class AudioRecordingCallbackInfo {
+        final AudioManager.AudioRecordingCallback mCb;
+        final Executor mExecutor;
+        AudioRecordingCallbackInfo(Executor e, AudioManager.AudioRecordingCallback cb) {
+            mExecutor = e;
+            mCb = cb;
+        }
+    }
+
+    private static final int MSG_RECORDING_CONFIG_CHANGE = 1;
+
+    private final Object mRecordCallbackLock = new Object();
+    @GuardedBy("mRecordCallbackLock")
+    @NonNull private LinkedList<AudioRecordingCallbackInfo> mRecordCallbackList =
+            new LinkedList<AudioRecordingCallbackInfo>();
+    @GuardedBy("mRecordCallbackLock")
+    private @Nullable HandlerThread mRecordingCallbackHandlerThread;
+    @GuardedBy("mRecordCallbackLock")
+    private @Nullable volatile Handler mRecordingCallbackHandler;
+
+    @GuardedBy("mRecordCallbackLock")
+    private final IRecordingConfigDispatcher mRecordingCallback =
+            new IRecordingConfigDispatcher.Stub() {
+        @Override
+        public void dispatchRecordingConfigChange(List<AudioRecordingConfiguration> configs) {
+            AudioRecordingConfiguration config = getMyConfig(configs);
+            if (config != null) {
+                synchronized (mRecordCallbackLock) {
+                    if (mRecordingCallbackHandler != null) {
+                        final Message m = mRecordingCallbackHandler.obtainMessage(
+                                              MSG_RECORDING_CONFIG_CHANGE/*what*/, config /*obj*/);
+                        mRecordingCallbackHandler.sendMessage(m);
+                    }
+                }
+            }
+        }
+    };
+
+    @GuardedBy("mRecordCallbackLock")
+    private void beginRecordingCallbackHandling() {
+        if (mRecordingCallbackHandlerThread == null) {
+            mRecordingCallbackHandlerThread = new HandlerThread(TAG + ".RecordingCallback");
+            mRecordingCallbackHandlerThread.start();
+            final Looper looper = mRecordingCallbackHandlerThread.getLooper();
+            if (looper != null) {
+                mRecordingCallbackHandler = new Handler(looper) {
+                    @Override
+                    public void handleMessage(Message msg) {
+                        switch (msg.what) {
+                            case MSG_RECORDING_CONFIG_CHANGE: {
+                                if (msg.obj == null) {
+                                    return;
+                                }
+                                ArrayList<AudioRecordingConfiguration> configs =
+                                        new ArrayList<AudioRecordingConfiguration>();
+                                configs.add((AudioRecordingConfiguration) msg.obj);
+
+                                final LinkedList<AudioRecordingCallbackInfo> cbInfoList;
+                                synchronized (mRecordCallbackLock) {
+                                    if (mRecordCallbackList.size() == 0) {
+                                        return;
+                                    }
+                                    cbInfoList = new LinkedList<AudioRecordingCallbackInfo>(
+                                        mRecordCallbackList);
+                                }
+
+                                final long identity = Binder.clearCallingIdentity();
+                                try {
+                                    for (AudioRecordingCallbackInfo cbi : cbInfoList) {
+                                        cbi.mExecutor.execute(() ->
+                                                cbi.mCb.onRecordingConfigChanged(configs));
+                                    }
+                                } finally {
+                                    Binder.restoreCallingIdentity(identity);
+                                }
+                            } break;
+                            default:
+                                Log.e(TAG, "Unknown event " + msg.what);
+                                break;
+                        }
+                    }
+                };
+                final IAudioService service = getService();
+                try {
+                    service.registerRecordingCallback(mRecordingCallback);
+                } catch (RemoteException e) {
+                    throw e.rethrowFromSystemServer();
+                }
+            }
+        }
+    }
+
+    @GuardedBy("mRecordCallbackLock")
+    private void endRecordingCallbackHandling() {
+        if (mRecordingCallbackHandlerThread != null) {
+            final IAudioService service = getService();
+            try {
+                service.unregisterRecordingCallback(mRecordingCallback);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+            mRecordingCallbackHandlerThread.quit();
+            mRecordingCallbackHandlerThread = null;
+        }
+    }
+
+    AudioRecordingConfiguration getMyConfig(List<AudioRecordingConfiguration> configs) {
+        int portId = mClient.getPortId();
+        for (AudioRecordingConfiguration config : configs) {
+            if (config.getClientPortId() == portId) {
+                return config;
+            }
+        }
+        return null;
+    }
+
+    private static IAudioService getService() {
+        if (sService != null) {
+            return sService;
+        }
+        IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
+        sService = IAudioService.Stub.asInterface(b);
+        return sService;
+    }
+}
diff --git a/android/media/AudioRoutesInfo.java b/android/media/AudioRoutesInfo.java
new file mode 100644
index 0000000..46df388
--- /dev/null
+++ b/android/media/AudioRoutesInfo.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2012 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.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * Information available from AudioService about the current routes.
+ * @hide
+ */
+public class AudioRoutesInfo implements Parcelable {
+    public static final int MAIN_SPEAKER = 0;
+    public static final int MAIN_HEADSET = 1<<0;
+    public static final int MAIN_HEADPHONES = 1<<1;
+    public static final int MAIN_DOCK_SPEAKERS = 1<<2;
+    public static final int MAIN_HDMI = 1<<3;
+    public static final int MAIN_USB = 1<<4;
+
+    public CharSequence bluetoothName;
+    public int mainType = MAIN_SPEAKER;
+
+    public AudioRoutesInfo() {
+    }
+
+    public AudioRoutesInfo(AudioRoutesInfo o) {
+        bluetoothName = o.bluetoothName;
+        mainType = o.mainType;
+    }
+
+    AudioRoutesInfo(Parcel src) {
+        bluetoothName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(src);
+        mainType = src.readInt();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + "{ type=" + typeToString(mainType)
+                + (TextUtils.isEmpty(bluetoothName) ? "" : ", bluetoothName=" + bluetoothName)
+                + " }";
+    }
+
+    private static String typeToString(int type) {
+        if (type == MAIN_SPEAKER) return "SPEAKER";
+        if ((type & MAIN_HEADSET) != 0) return "HEADSET";
+        if ((type & MAIN_HEADPHONES) != 0) return "HEADPHONES";
+        if ((type & MAIN_DOCK_SPEAKERS) != 0) return "DOCK_SPEAKERS";
+        if ((type & MAIN_HDMI) != 0) return "HDMI";
+        if ((type & MAIN_USB) != 0) return "USB";
+        return Integer.toHexString(type);
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        TextUtils.writeToParcel(bluetoothName, dest, flags);
+        dest.writeInt(mainType);
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<AudioRoutesInfo> CREATOR
+            = new Parcelable.Creator<AudioRoutesInfo>() {
+        public AudioRoutesInfo createFromParcel(Parcel in) {
+            return new AudioRoutesInfo(in);
+        }
+
+        public AudioRoutesInfo[] newArray(int size) {
+            return new AudioRoutesInfo[size];
+        }
+    };
+}
diff --git a/android/media/AudioRouting.java b/android/media/AudioRouting.java
new file mode 100644
index 0000000..26fa631
--- /dev/null
+++ b/android/media/AudioRouting.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 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.os.Handler;
+import android.os.Looper;
+
+/**
+ * AudioRouting defines an interface for controlling routing and routing notifications in
+ * AudioTrack and AudioRecord objects.
+ */
+public interface AudioRouting {
+    /**
+     * Specifies an audio device (via an {@link AudioDeviceInfo} object) to route
+     * the output/input to/from.
+     * @param deviceInfo The {@link AudioDeviceInfo} specifying the audio sink or source.
+     *  If deviceInfo is null, default routing is restored.
+     * @return true if succesful, false if the specified {@link AudioDeviceInfo} is non-null and
+     * does not correspond to a valid audio device.
+     */
+    public boolean setPreferredDevice(AudioDeviceInfo deviceInfo);
+
+    /**
+     * Returns the selected output/input specified by {@link #setPreferredDevice}. Note that this
+     * is not guaranteed to correspond to the actual device being used for playback/recording.
+     */
+    public AudioDeviceInfo getPreferredDevice();
+
+    /**
+     * Returns an {@link AudioDeviceInfo} identifying the current routing of this
+     * AudioTrack/AudioRecord.
+     * Note: The query is only valid if the AudioTrack/AudioRecord is currently playing.
+     * If it is not, <code>getRoutedDevice()</code> will return null.
+     */
+    public AudioDeviceInfo getRoutedDevice();
+
+    /**
+     * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
+     * changes on this AudioTrack/AudioRecord.
+     * @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive
+     * notifications of rerouting events.
+     * @param handler  Specifies the {@link Handler} object for the thread on which to execute
+     * the callback. If <code>null</code>, the {@link Handler} associated with the main
+     * {@link Looper} will be used.
+     */
+    public void addOnRoutingChangedListener(OnRoutingChangedListener listener,
+            Handler handler);
+
+    /**
+     * Removes an {@link AudioRouting.OnRoutingChangedListener} which has been previously added
+     * to receive rerouting notifications.
+     * @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
+     * to remove.
+     */
+    public void removeOnRoutingChangedListener(OnRoutingChangedListener listener);
+
+    /**
+     * Defines the interface by which applications can receive notifications of routing
+     * changes for the associated {@link AudioRouting}.
+     */
+    public interface OnRoutingChangedListener {
+        public void onRoutingChanged(AudioRouting router);
+    }
+}
diff --git a/android/media/AudioSystem.java b/android/media/AudioSystem.java
new file mode 100644
index 0000000..69d1889
--- /dev/null
+++ b/android/media/AudioSystem.java
@@ -0,0 +1,2157 @@
+/*
+ * Copyright (C) 2006 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.TestApi;
+import android.bluetooth.BluetoothCodecConfig;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.media.audiofx.AudioEffect;
+import android.media.audiopolicy.AudioMix;
+import android.os.Build;
+import android.os.IBinder;
+import android.os.Vibrator;
+import android.telephony.TelephonyManager;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/* IF YOU CHANGE ANY OF THE CONSTANTS IN THIS FILE, DO NOT FORGET
+ * TO UPDATE THE CORRESPONDING NATIVE GLUE AND AudioManager.java.
+ * THANK YOU FOR YOUR COOPERATION.
+ */
+
+/**
+ * @hide
+ */
+@TestApi
+public class AudioSystem
+{
+    private static final boolean DEBUG_VOLUME = false;
+
+    private static final String TAG = "AudioSystem";
+
+    // private constructor to prevent instantiating AudioSystem
+    private AudioSystem() {
+        throw new UnsupportedOperationException("Trying to instantiate AudioSystem");
+    }
+
+    /* These values must be kept in sync with system/audio.h */
+    /*
+     * If these are modified, please also update Settings.System.VOLUME_SETTINGS
+     * and attrs.xml and AudioManager.java.
+     */
+    /** @hide Used to identify the default audio stream volume */
+    @TestApi
+    public static final int STREAM_DEFAULT = -1;
+    /** @hide Used to identify the volume of audio streams for phone calls */
+    public static final int STREAM_VOICE_CALL = 0;
+    /** @hide Used to identify the volume of audio streams for system sounds */
+    public static final int STREAM_SYSTEM = 1;
+    /** @hide Used to identify the volume of audio streams for the phone ring and message alerts */
+    public static final int STREAM_RING = 2;
+    /** @hide Used to identify the volume of audio streams for music playback */
+    public static final int STREAM_MUSIC = 3;
+    /** @hide Used to identify the volume of audio streams for alarms */
+    public static final int STREAM_ALARM = 4;
+    /** @hide Used to identify the volume of audio streams for notifications */
+    public static final int STREAM_NOTIFICATION = 5;
+    /** @hide
+     *  Used to identify the volume of audio streams for phone calls when connected on bluetooth */
+    public static final int STREAM_BLUETOOTH_SCO = 6;
+    /** @hide Used to identify the volume of audio streams for enforced system sounds in certain
+     * countries (e.g camera in Japan) */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public static final int STREAM_SYSTEM_ENFORCED = 7;
+    /** @hide Used to identify the volume of audio streams for DTMF tones */
+    public static final int STREAM_DTMF = 8;
+    /** @hide Used to identify the volume of audio streams exclusively transmitted through the
+     *  speaker (TTS) of the device */
+    public static final int STREAM_TTS = 9;
+    /** @hide Used to identify the volume of audio streams for accessibility prompts */
+    public static final int STREAM_ACCESSIBILITY = 10;
+    /** @hide Used to identify the volume of audio streams for virtual assistant */
+    public static final int STREAM_ASSISTANT = 11;
+    /**
+     * @hide
+     * @deprecated Use {@link #numStreamTypes() instead}
+     */
+    public static final int NUM_STREAMS = 5;
+
+    /*
+     * Framework static final constants that are primitives or Strings
+     * accessed by CTS tests or internal applications must be set from methods
+     * (or in a static block) to prevent Java compile-time replacement.
+     * We set them from methods so they are read from the device framework.
+     * Do not un-hide or change to a numeric literal.
+     */
+
+    /** Maximum value for AudioTrack channel count
+     * @hide
+     */
+    public static final int OUT_CHANNEL_COUNT_MAX = native_getMaxChannelCount();
+    private static native int native_getMaxChannelCount();
+
+    /** Maximum value for sample rate, used by AudioFormat.
+     * @hide
+     */
+    public static final int SAMPLE_RATE_HZ_MAX = native_getMaxSampleRate();
+    private static native int native_getMaxSampleRate();
+
+    /** Minimum value for sample rate, used by AudioFormat.
+     * @hide
+     */
+    public static final int SAMPLE_RATE_HZ_MIN = native_getMinSampleRate();
+    private static native int native_getMinSampleRate();
+
+    /** @hide */
+    public static final int FCC_24 = 24; // fixed channel count 24; do not change.
+
+    // Expose only the getter method publicly so we can change it in the future
+    private static final int NUM_STREAM_TYPES = 12;
+
+    /**
+     * @hide
+     * @return total number of stream types
+     */
+    @UnsupportedAppUsage
+    @TestApi
+    public static final int getNumStreamTypes() { return NUM_STREAM_TYPES; }
+
+    /** @hide */
+    public static final String[] STREAM_NAMES = new String[] {
+        "STREAM_VOICE_CALL",
+        "STREAM_SYSTEM",
+        "STREAM_RING",
+        "STREAM_MUSIC",
+        "STREAM_ALARM",
+        "STREAM_NOTIFICATION",
+        "STREAM_BLUETOOTH_SCO",
+        "STREAM_SYSTEM_ENFORCED",
+        "STREAM_DTMF",
+        "STREAM_TTS",
+        "STREAM_ACCESSIBILITY",
+        "STREAM_ASSISTANT"
+    };
+
+    /**
+     * @hide
+     * Sets the microphone mute on or off.
+     *
+     * @param on set <var>true</var> to mute the microphone;
+     *           <var>false</var> to turn mute off
+     * @return command completion status see AUDIO_STATUS_OK, see AUDIO_STATUS_ERROR
+     */
+    @UnsupportedAppUsage
+    public static native int muteMicrophone(boolean on);
+
+    /**
+     * @hide
+     * Checks whether the microphone mute is on or off.
+     *
+     * @return true if microphone is muted, false if it's not
+     */
+    @UnsupportedAppUsage
+    public static native boolean isMicrophoneMuted();
+
+    /* modes for setPhoneState, must match AudioSystem.h audio_mode */
+    /** @hide */
+    public static final int MODE_INVALID            = -2;
+    /** @hide */
+    public static final int MODE_CURRENT            = -1;
+    /** @hide */
+    public static final int MODE_NORMAL             = 0;
+    /** @hide */
+    public static final int MODE_RINGTONE           = 1;
+    /** @hide */
+    public static final int MODE_IN_CALL            = 2;
+    /** @hide */
+    public static final int MODE_IN_COMMUNICATION   = 3;
+    /** @hide */
+    public static final int MODE_CALL_SCREENING     = 4;
+    /** @hide */
+    public static final int NUM_MODES               = 5;
+
+    /** @hide */
+    public static String modeToString(int mode) {
+        switch (mode) {
+            case MODE_CURRENT: return "MODE_CURRENT";
+            case MODE_IN_CALL: return "MODE_IN_CALL";
+            case MODE_IN_COMMUNICATION: return "MODE_IN_COMMUNICATION";
+            case MODE_INVALID: return "MODE_INVALID";
+            case MODE_NORMAL: return "MODE_NORMAL";
+            case MODE_RINGTONE: return "MODE_RINGTONE";
+            case MODE_CALL_SCREENING: return "MODE_CALL_SCREENING";
+            default: return "unknown mode (" + mode + ")";
+        }
+    }
+
+    /* Formats for A2DP codecs, must match system/audio-base.h audio_format_t */
+    /** @hide */
+    public static final int AUDIO_FORMAT_INVALID        = 0xFFFFFFFF;
+    /** @hide */
+    public static final int AUDIO_FORMAT_DEFAULT        = 0;
+    /** @hide */
+    public static final int AUDIO_FORMAT_AAC            = 0x04000000;
+    /** @hide */
+    public static final int AUDIO_FORMAT_SBC            = 0x1F000000;
+    /** @hide */
+    public static final int AUDIO_FORMAT_APTX           = 0x20000000;
+    /** @hide */
+    public static final int AUDIO_FORMAT_APTX_HD        = 0x21000000;
+    /** @hide */
+    public static final int AUDIO_FORMAT_LDAC           = 0x23000000;
+
+    /** @hide */
+    @IntDef(flag = false, prefix = "AUDIO_FORMAT_", value = {
+            AUDIO_FORMAT_INVALID,
+            AUDIO_FORMAT_DEFAULT,
+            AUDIO_FORMAT_AAC,
+            AUDIO_FORMAT_SBC,
+            AUDIO_FORMAT_APTX,
+            AUDIO_FORMAT_APTX_HD,
+            AUDIO_FORMAT_LDAC }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioFormatNativeEnumForBtCodec {}
+
+    /**
+     * @hide
+     * Convert audio format enum values to Bluetooth codec values
+     */
+    public static int audioFormatToBluetoothSourceCodec(
+            @AudioFormatNativeEnumForBtCodec int audioFormat) {
+        switch (audioFormat) {
+            case AUDIO_FORMAT_AAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC;
+            case AUDIO_FORMAT_SBC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC;
+            case AUDIO_FORMAT_APTX: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX;
+            case AUDIO_FORMAT_APTX_HD: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD;
+            case AUDIO_FORMAT_LDAC: return BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC;
+            default:
+                Log.e(TAG, "Unknown audio format 0x" + Integer.toHexString(audioFormat)
+                        + " for conversion to BT codec");
+                return BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID;
+        }
+    }
+
+    /**
+     * @hide
+     * Convert a Bluetooth codec to an audio format enum
+     * @param btCodec the codec to convert.
+     * @return the audio format, or {@link #AUDIO_FORMAT_DEFAULT} if unknown
+     */
+    public static @AudioFormatNativeEnumForBtCodec int bluetoothCodecToAudioFormat(int btCodec) {
+        switch (btCodec) {
+            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC:
+                return AudioSystem.AUDIO_FORMAT_SBC;
+            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC:
+                return AudioSystem.AUDIO_FORMAT_AAC;
+            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX:
+                return AudioSystem.AUDIO_FORMAT_APTX;
+            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD:
+                return AudioSystem.AUDIO_FORMAT_APTX_HD;
+            case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
+                return AudioSystem.AUDIO_FORMAT_LDAC;
+            default:
+                Log.e(TAG, "Unknown BT codec 0x" + Integer.toHexString(btCodec)
+                        + " for conversion to audio format");
+                // TODO returning DEFAULT is the current behavior, should this return INVALID?
+                return AudioSystem.AUDIO_FORMAT_DEFAULT;
+        }
+    }
+
+    /**
+     * @hide
+     * Convert a native audio format integer constant to a string.
+     */
+    public static String audioFormatToString(int audioFormat) {
+        switch (audioFormat) {
+            case /* AUDIO_FORMAT_INVALID         */ 0xFFFFFFFF:
+                return "AUDIO_FORMAT_INVALID";
+            case /* AUDIO_FORMAT_DEFAULT         */ 0:
+                return "AUDIO_FORMAT_DEFAULT";
+            case /* AUDIO_FORMAT_MP3             */ 0x01000000:
+                return "AUDIO_FORMAT_MP3";
+            case /* AUDIO_FORMAT_AMR_NB          */ 0x02000000:
+                return "AUDIO_FORMAT_AMR_NB";
+            case /* AUDIO_FORMAT_AMR_WB          */ 0x03000000:
+                return "AUDIO_FORMAT_AMR_WB";
+            case /* AUDIO_FORMAT_AAC             */ 0x04000000:
+                return "AUDIO_FORMAT_AAC";
+            case /* AUDIO_FORMAT_HE_AAC_V1       */ 0x05000000:
+                return "AUDIO_FORMAT_HE_AAC_V1";
+            case /* AUDIO_FORMAT_HE_AAC_V2       */ 0x06000000:
+                return "AUDIO_FORMAT_HE_AAC_V2";
+            case /* AUDIO_FORMAT_VORBIS          */ 0x07000000:
+                return "AUDIO_FORMAT_VORBIS";
+            case /* AUDIO_FORMAT_OPUS            */ 0x08000000:
+                return "AUDIO_FORMAT_OPUS";
+            case /* AUDIO_FORMAT_AC3             */ 0x09000000:
+                return "AUDIO_FORMAT_AC3";
+            case /* AUDIO_FORMAT_E_AC3           */ 0x0A000000:
+                return "AUDIO_FORMAT_E_AC3";
+            case /* AUDIO_FORMAT_DTS             */ 0x0B000000:
+                return "AUDIO_FORMAT_DTS";
+            case /* AUDIO_FORMAT_DTS_HD          */ 0x0C000000:
+                return "AUDIO_FORMAT_DTS_HD";
+            case /* AUDIO_FORMAT_IEC61937        */ 0x0D000000:
+                return "AUDIO_FORMAT_IEC61937";
+            case /* AUDIO_FORMAT_DOLBY_TRUEHD    */ 0x0E000000:
+                return "AUDIO_FORMAT_DOLBY_TRUEHD";
+            case /* AUDIO_FORMAT_EVRC            */ 0x10000000:
+                return "AUDIO_FORMAT_EVRC";
+            case /* AUDIO_FORMAT_EVRCB           */ 0x11000000:
+                return "AUDIO_FORMAT_EVRCB";
+            case /* AUDIO_FORMAT_EVRCWB          */ 0x12000000:
+                return "AUDIO_FORMAT_EVRCWB";
+            case /* AUDIO_FORMAT_EVRCNW          */ 0x13000000:
+                return "AUDIO_FORMAT_EVRCNW";
+            case /* AUDIO_FORMAT_AAC_ADIF        */ 0x14000000:
+                return "AUDIO_FORMAT_AAC_ADIF";
+            case /* AUDIO_FORMAT_WMA             */ 0x15000000:
+                return "AUDIO_FORMAT_WMA";
+            case /* AUDIO_FORMAT_WMA_PRO         */ 0x16000000:
+                return "AUDIO_FORMAT_WMA_PRO";
+            case /* AUDIO_FORMAT_AMR_WB_PLUS     */ 0x17000000:
+                return "AUDIO_FORMAT_AMR_WB_PLUS";
+            case /* AUDIO_FORMAT_MP2             */ 0x18000000:
+                return "AUDIO_FORMAT_MP2";
+            case /* AUDIO_FORMAT_QCELP           */ 0x19000000:
+                return "AUDIO_FORMAT_QCELP";
+            case /* AUDIO_FORMAT_DSD             */ 0x1A000000:
+                return "AUDIO_FORMAT_DSD";
+            case /* AUDIO_FORMAT_FLAC            */ 0x1B000000:
+                return "AUDIO_FORMAT_FLAC";
+            case /* AUDIO_FORMAT_ALAC            */ 0x1C000000:
+                return "AUDIO_FORMAT_ALAC";
+            case /* AUDIO_FORMAT_APE             */ 0x1D000000:
+                return "AUDIO_FORMAT_APE";
+            case /* AUDIO_FORMAT_AAC_ADTS        */ 0x1E000000:
+                return "AUDIO_FORMAT_AAC_ADTS";
+            case /* AUDIO_FORMAT_SBC             */ 0x1F000000:
+                return "AUDIO_FORMAT_SBC";
+            case /* AUDIO_FORMAT_APTX            */ 0x20000000:
+                return "AUDIO_FORMAT_APTX";
+            case /* AUDIO_FORMAT_APTX_HD         */ 0x21000000:
+                return "AUDIO_FORMAT_APTX_HD";
+            case /* AUDIO_FORMAT_AC4             */ 0x22000000:
+                return "AUDIO_FORMAT_AC4";
+            case /* AUDIO_FORMAT_LDAC            */ 0x23000000:
+                return "AUDIO_FORMAT_LDAC";
+            case /* AUDIO_FORMAT_MAT             */ 0x24000000:
+                return "AUDIO_FORMAT_MAT";
+            case /* AUDIO_FORMAT_AAC_LATM        */ 0x25000000:
+                return "AUDIO_FORMAT_AAC_LATM";
+            case /* AUDIO_FORMAT_CELT            */ 0x26000000:
+                return "AUDIO_FORMAT_CELT";
+            case /* AUDIO_FORMAT_APTX_ADAPTIVE   */ 0x27000000:
+                return "AUDIO_FORMAT_APTX_ADAPTIVE";
+            case /* AUDIO_FORMAT_LHDC            */ 0x28000000:
+                return "AUDIO_FORMAT_LHDC";
+            case /* AUDIO_FORMAT_LHDC_LL         */ 0x29000000:
+                return "AUDIO_FORMAT_LHDC_LL";
+            case /* AUDIO_FORMAT_APTX_TWSP       */ 0x2A000000:
+                return "AUDIO_FORMAT_APTX_TWSP";
+
+            /* Aliases */
+            case /* AUDIO_FORMAT_PCM_16_BIT        */ 0x1:
+                return "AUDIO_FORMAT_PCM_16_BIT";        // (PCM | PCM_SUB_16_BIT)
+            case /* AUDIO_FORMAT_PCM_8_BIT         */ 0x2:
+                return "AUDIO_FORMAT_PCM_8_BIT";        // (PCM | PCM_SUB_8_BIT)
+            case /* AUDIO_FORMAT_PCM_32_BIT        */ 0x3:
+                return "AUDIO_FORMAT_PCM_32_BIT";        // (PCM | PCM_SUB_32_BIT)
+            case /* AUDIO_FORMAT_PCM_8_24_BIT      */ 0x4:
+                return "AUDIO_FORMAT_PCM_8_24_BIT";        // (PCM | PCM_SUB_8_24_BIT)
+            case /* AUDIO_FORMAT_PCM_FLOAT         */ 0x5:
+                return "AUDIO_FORMAT_PCM_FLOAT";        // (PCM | PCM_SUB_FLOAT)
+            case /* AUDIO_FORMAT_PCM_24_BIT_PACKED */ 0x6:
+                return "AUDIO_FORMAT_PCM_24_BIT_PACKED";        // (PCM | PCM_SUB_24_BIT_PACKED)
+            case /* AUDIO_FORMAT_AAC_MAIN          */ 0x4000001:
+                return "AUDIO_FORMAT_AAC_MAIN";  // (AAC | AAC_SUB_MAIN)
+            case /* AUDIO_FORMAT_AAC_LC            */ 0x4000002:
+                return "AUDIO_FORMAT_AAC_LC";  // (AAC | AAC_SUB_LC)
+            case /* AUDIO_FORMAT_AAC_SSR           */ 0x4000004:
+                return "AUDIO_FORMAT_AAC_SSR";  // (AAC | AAC_SUB_SSR)
+            case /* AUDIO_FORMAT_AAC_LTP           */ 0x4000008:
+                return "AUDIO_FORMAT_AAC_LTP";  // (AAC | AAC_SUB_LTP)
+            case /* AUDIO_FORMAT_AAC_HE_V1         */ 0x4000010:
+                return "AUDIO_FORMAT_AAC_HE_V1";  // (AAC | AAC_SUB_HE_V1)
+            case /* AUDIO_FORMAT_AAC_SCALABLE      */ 0x4000020:
+                return "AUDIO_FORMAT_AAC_SCALABLE";  // (AAC | AAC_SUB_SCALABLE)
+            case /* AUDIO_FORMAT_AAC_ERLC          */ 0x4000040:
+                return "AUDIO_FORMAT_AAC_ERLC";  // (AAC | AAC_SUB_ERLC)
+            case /* AUDIO_FORMAT_AAC_LD            */ 0x4000080:
+                return "AUDIO_FORMAT_AAC_LD";  // (AAC | AAC_SUB_LD)
+            case /* AUDIO_FORMAT_AAC_HE_V2         */ 0x4000100:
+                return "AUDIO_FORMAT_AAC_HE_V2";  // (AAC | AAC_SUB_HE_V2)
+            case /* AUDIO_FORMAT_AAC_ELD           */ 0x4000200:
+                return "AUDIO_FORMAT_AAC_ELD";  // (AAC | AAC_SUB_ELD)
+            case /* AUDIO_FORMAT_AAC_XHE           */ 0x4000300:
+                return "AUDIO_FORMAT_AAC_XHE";  // (AAC | AAC_SUB_XHE)
+            case /* AUDIO_FORMAT_AAC_ADTS_MAIN     */ 0x1e000001:
+                return "AUDIO_FORMAT_AAC_ADTS_MAIN"; // (AAC_ADTS | AAC_SUB_MAIN)
+            case /* AUDIO_FORMAT_AAC_ADTS_LC       */ 0x1e000002:
+                return "AUDIO_FORMAT_AAC_ADTS_LC"; // (AAC_ADTS | AAC_SUB_LC)
+            case /* AUDIO_FORMAT_AAC_ADTS_SSR      */ 0x1e000004:
+                return "AUDIO_FORMAT_AAC_ADTS_SSR"; // (AAC_ADTS | AAC_SUB_SSR)
+            case /* AUDIO_FORMAT_AAC_ADTS_LTP      */ 0x1e000008:
+                return "AUDIO_FORMAT_AAC_ADTS_LTP"; // (AAC_ADTS | AAC_SUB_LTP)
+            case /* AUDIO_FORMAT_AAC_ADTS_HE_V1    */ 0x1e000010:
+                return "AUDIO_FORMAT_AAC_ADTS_HE_V1"; // (AAC_ADTS | AAC_SUB_HE_V1)
+            case /* AUDIO_FORMAT_AAC_ADTS_SCALABLE */ 0x1e000020:
+                return "AUDIO_FORMAT_AAC_ADTS_SCALABLE"; // (AAC_ADTS | AAC_SUB_SCALABLE)
+            case /* AUDIO_FORMAT_AAC_ADTS_ERLC     */ 0x1e000040:
+                return "AUDIO_FORMAT_AAC_ADTS_ERLC"; // (AAC_ADTS | AAC_SUB_ERLC)
+            case /* AUDIO_FORMAT_AAC_ADTS_LD       */ 0x1e000080:
+                return "AUDIO_FORMAT_AAC_ADTS_LD"; // (AAC_ADTS | AAC_SUB_LD)
+            case /* AUDIO_FORMAT_AAC_ADTS_HE_V2    */ 0x1e000100:
+                return "AUDIO_FORMAT_AAC_ADTS_HE_V2"; // (AAC_ADTS | AAC_SUB_HE_V2)
+            case /* AUDIO_FORMAT_AAC_ADTS_ELD      */ 0x1e000200:
+                return "AUDIO_FORMAT_AAC_ADTS_ELD"; // (AAC_ADTS | AAC_SUB_ELD)
+            case /* AUDIO_FORMAT_AAC_ADTS_XHE      */ 0x1e000300:
+                return "AUDIO_FORMAT_AAC_ADTS_XHE"; // (AAC_ADTS | AAC_SUB_XHE)
+            case /* AUDIO_FORMAT_AAC_LATM_LC       */ 0x25000002:
+                return "AUDIO_FORMAT_AAC_LATM_LC"; // (AAC_LATM | AAC_SUB_LC)
+            case /* AUDIO_FORMAT_AAC_LATM_HE_V1    */ 0x25000010:
+                return "AUDIO_FORMAT_AAC_LATM_HE_V1"; // (AAC_LATM | AAC_SUB_HE_V1)
+            case /* AUDIO_FORMAT_AAC_LATM_HE_V2    */ 0x25000100:
+                return "AUDIO_FORMAT_AAC_LATM_HE_V2"; // (AAC_LATM | AAC_SUB_HE_V2)
+            case /* AUDIO_FORMAT_E_AC3_JOC         */ 0xA000001:
+                return "AUDIO_FORMAT_E_AC3_JOC";  // (E_AC3 | E_AC3_SUB_JOC)
+            case /* AUDIO_FORMAT_MAT_1_0           */ 0x24000001:
+                return "AUDIO_FORMAT_MAT_1_0"; // (MAT | MAT_SUB_1_0)
+            case /* AUDIO_FORMAT_MAT_2_0           */ 0x24000002:
+                return "AUDIO_FORMAT_MAT_2_0"; // (MAT | MAT_SUB_2_0)
+            case /* AUDIO_FORMAT_MAT_2_1           */ 0x24000003:
+                return "AUDIO_FORMAT_MAT_2_1"; // (MAT | MAT_SUB_2_1)
+            case /* AUDIO_FORMAT_DTS_UHD */           0x2E000000:
+                return "AUDIO_FORMAT_DTS_UHD";
+            case /* AUDIO_FORMAT_DRA */           0x2F000000:
+                return "AUDIO_FORMAT_DRA";
+            default:
+                return "AUDIO_FORMAT_(" + audioFormat + ")";
+        }
+    }
+
+    /* Routing bits for the former setRouting/getRouting API */
+    /** @hide @deprecated */
+    @Deprecated public static final int ROUTE_EARPIECE          = (1 << 0);
+    /** @hide @deprecated */
+    @Deprecated public static final int ROUTE_SPEAKER           = (1 << 1);
+    /** @hide @deprecated use {@link #ROUTE_BLUETOOTH_SCO} */
+    @Deprecated public static final int ROUTE_BLUETOOTH = (1 << 2);
+    /** @hide @deprecated */
+    @Deprecated public static final int ROUTE_BLUETOOTH_SCO     = (1 << 2);
+    /** @hide @deprecated */
+    @Deprecated public static final int ROUTE_HEADSET           = (1 << 3);
+    /** @hide @deprecated */
+    @Deprecated public static final int ROUTE_BLUETOOTH_A2DP    = (1 << 4);
+    /** @hide @deprecated */
+    @Deprecated public static final int ROUTE_ALL               = 0xFFFFFFFF;
+
+    // Keep in sync with system/media/audio/include/system/audio.h
+    /**  @hide */
+    public static final int AUDIO_SESSION_ALLOCATE = 0;
+
+    /**
+     * @hide
+     * Checks whether the specified stream type is active.
+     *
+     * return true if any track playing on this stream is active.
+     */
+    @UnsupportedAppUsage
+    public static native boolean isStreamActive(int stream, int inPastMs);
+
+    /**
+     * @hide
+     * Checks whether the specified stream type is active on a remotely connected device. The notion
+     * of what constitutes a remote device is enforced by the audio policy manager of the platform.
+     *
+     * return true if any track playing on this stream is active on a remote device.
+     */
+    public static native boolean isStreamActiveRemotely(int stream, int inPastMs);
+
+    /**
+     * @hide
+     * Checks whether the specified audio source is active.
+     *
+     * return true if any recorder using this source is currently recording
+     */
+    @UnsupportedAppUsage
+    public static native boolean isSourceActive(int source);
+
+    /**
+     * @hide
+     * Returns a new unused audio session ID
+     */
+    public static native int newAudioSessionId();
+
+    /**
+     * @hide
+     * Returns a new unused audio player ID
+     */
+    public static native int newAudioPlayerId();
+
+    /**
+     * @hide
+     * Returns a new unused audio recorder ID
+     */
+    public static native int newAudioRecorderId();
+
+
+    /**
+     * @hide
+     * Sets a group generic audio configuration parameters. The use of these parameters
+     * are platform dependent, see libaudio
+     *
+     * param keyValuePairs  list of parameters key value pairs in the form:
+     *    key1=value1;key2=value2;...
+     */
+    @UnsupportedAppUsage
+    public static native int setParameters(String keyValuePairs);
+
+    /**
+     * @hide
+     * Gets a group generic audio configuration parameters. The use of these parameters
+     * are platform dependent, see libaudio
+     *
+     * param keys  list of parameters
+     * return value: list of parameters key value pairs in the form:
+     *    key1=value1;key2=value2;...
+     */
+    @UnsupportedAppUsage
+    public static native String getParameters(String keys);
+
+    // These match the enum AudioError in frameworks/base/core/jni/android_media_AudioSystem.cpp
+    /** @hide Command successful or Media server restarted. see ErrorCallback */
+    public static final int AUDIO_STATUS_OK = 0;
+    /** @hide Command failed or unspecified audio error.  see ErrorCallback */
+    public static final int AUDIO_STATUS_ERROR = 1;
+    /** @hide Media server died. see ErrorCallback */
+    public static final int AUDIO_STATUS_SERVER_DIED = 100;
+
+    // all accesses must be synchronized (AudioSystem.class)
+    private static ErrorCallback sErrorCallback;
+
+    /** @hide
+     * Handles the audio error callback.
+     */
+    public interface ErrorCallback
+    {
+        /*
+         * Callback for audio server errors.
+         * param error   error code:
+         * - AUDIO_STATUS_OK
+         * - AUDIO_STATUS_SERVER_DIED
+         * - AUDIO_STATUS_ERROR
+         */
+        void onError(int error);
+    };
+
+    /**
+     * @hide
+     * Registers a callback to be invoked when an error occurs.
+     * @param cb the callback to run
+     */
+    @UnsupportedAppUsage
+    public static void setErrorCallback(ErrorCallback cb)
+    {
+        synchronized (AudioSystem.class) {
+            sErrorCallback = cb;
+            if (cb != null) {
+                cb.onError(checkAudioFlinger());
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
+    private static void errorCallbackFromNative(int error)
+    {
+        ErrorCallback errorCallback;
+        synchronized (AudioSystem.class) {
+            errorCallback = sErrorCallback;
+        }
+        if (errorCallback != null) {
+            errorCallback.onError(error);
+        }
+    }
+
+    /**
+     * @hide
+     * Handles events from the audio policy manager about dynamic audio policies
+     * @see android.media.audiopolicy.AudioPolicy
+     */
+    public interface DynamicPolicyCallback
+    {
+        void onDynamicPolicyMixStateUpdate(String regId, int state);
+    }
+
+    //keep in sync with include/media/AudioPolicy.h
+    private final static int DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE = 0;
+
+    // all accesses must be synchronized (AudioSystem.class)
+    private static DynamicPolicyCallback sDynPolicyCallback;
+
+    /** @hide */
+    public static void setDynamicPolicyCallback(DynamicPolicyCallback cb)
+    {
+        synchronized (AudioSystem.class) {
+            sDynPolicyCallback = cb;
+            native_register_dynamic_policy_callback();
+        }
+    }
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static void dynamicPolicyCallbackFromNative(int event, String regId, int val)
+    {
+        DynamicPolicyCallback cb;
+        synchronized (AudioSystem.class) {
+            cb = sDynPolicyCallback;
+        }
+        if (cb != null) {
+            switch(event) {
+                case DYNAMIC_POLICY_EVENT_MIX_STATE_UPDATE:
+                    cb.onDynamicPolicyMixStateUpdate(regId, val);
+                    break;
+                default:
+                    Log.e(TAG, "dynamicPolicyCallbackFromNative: unknown event " + event);
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Handles events from the audio policy manager about recording events
+     * @see android.media.AudioManager.AudioRecordingCallback
+     */
+    public interface AudioRecordingCallback
+    {
+        /**
+         * Callback for recording activity notifications events
+         * @param event
+         * @param riid recording identifier
+         * @param uid uid of the client app performing the recording
+         * @param session
+         * @param source
+         * @param recordingFormat an array of ints containing respectively the client and device
+         *    recording configurations (2*3 ints), followed by the patch handle:
+         *    index 0: client format
+         *          1: client channel mask
+         *          2: client sample rate
+         *          3: device format
+         *          4: device channel mask
+         *          5: device sample rate
+         *          6: patch handle
+         * @param packName package name of the client app performing the recording. NOT SUPPORTED
+         */
+        void onRecordingConfigurationChanged(int event, int riid, int uid, int session, int source,
+                        int portId, boolean silenced, int[] recordingFormat,
+                        AudioEffect.Descriptor[] clienteffects, AudioEffect.Descriptor[] effects,
+                        int activeSource, String packName);
+    }
+
+    // all accesses must be synchronized (AudioSystem.class)
+    private static AudioRecordingCallback sRecordingCallback;
+
+    /** @hide */
+    public static void setRecordingCallback(AudioRecordingCallback cb) {
+        synchronized (AudioSystem.class) {
+            sRecordingCallback = cb;
+            native_register_recording_callback();
+        }
+    }
+
+    /**
+     * Callback from native for recording configuration updates.
+     * @param event
+     * @param riid
+     * @param uid
+     * @param session
+     * @param source
+     * @param portId
+     * @param silenced
+     * @param recordingFormat see
+     *     {@link AudioRecordingCallback#onRecordingConfigurationChanged(int, int, int, int, int, \
+     int, boolean, int[], AudioEffect.Descriptor[], AudioEffect.Descriptor[], int, String)}
+     *     for the description of the record format.
+     * @param cleintEffects
+     * @param effects
+     * @param activeSource
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static void recordingCallbackFromNative(int event, int riid, int uid, int session,
+                          int source, int portId, boolean silenced, int[] recordingFormat,
+                          AudioEffect.Descriptor[] clientEffects, AudioEffect.Descriptor[] effects,
+                          int activeSource) {
+        AudioRecordingCallback cb;
+        synchronized (AudioSystem.class) {
+            cb = sRecordingCallback;
+        }
+
+        String clientEffectName =  clientEffects.length == 0 ? "None" : clientEffects[0].name;
+        String effectName =  effects.length == 0 ? "None" : effects[0].name;
+
+        if (cb != null) {
+            ArrayList<AudioPatch> audioPatches = new ArrayList<>();
+            if (AudioManager.listAudioPatches(audioPatches) == AudioManager.SUCCESS) {
+                boolean patchFound = false;
+                int patchHandle = recordingFormat[6];
+                for (AudioPatch patch : audioPatches) {
+                    if (patch.id() == patchHandle) {
+                        patchFound = true;
+                        break;
+                    }
+                }
+                if (!patchFound) {
+                    // The cached audio patches in AudioManager is not up-to-date.
+                    // Reset audio port generation to ensure callback side can
+                    // get up-to-date audio port information.
+                    AudioManager.resetAudioPortGeneration();
+                }
+            }
+            // TODO receive package name from native
+            cb.onRecordingConfigurationChanged(event, riid, uid, session, source, portId, silenced,
+                                        recordingFormat, clientEffects, effects, activeSource, "");
+        }
+    }
+
+    /**
+     * @hide
+     * Handles events from the audio policy manager about routing events
+     */
+    public interface RoutingUpdateCallback {
+        /**
+         * Callback to notify a routing update event occurred
+         */
+        void onRoutingUpdated();
+    }
+
+    @GuardedBy("AudioSystem.class")
+    private static RoutingUpdateCallback sRoutingUpdateCallback;
+
+    /** @hide */
+    public static void setRoutingCallback(RoutingUpdateCallback cb) {
+        synchronized (AudioSystem.class) {
+            sRoutingUpdateCallback = cb;
+            native_register_routing_callback();
+        }
+    }
+
+    private static void routingCallbackFromNative() {
+        final RoutingUpdateCallback cb;
+        synchronized (AudioSystem.class) {
+            cb = sRoutingUpdateCallback;
+        }
+        if (cb == null) {
+            Log.e(TAG, "routing update from APM was not captured");
+            return;
+        }
+        cb.onRoutingUpdated();
+    }
+
+    /*
+     * Error codes used by public APIs (AudioTrack, AudioRecord, AudioManager ...)
+     * Must be kept in sync with frameworks/base/core/jni/android_media_AudioErrors.h
+     */
+    /** @hide */
+    public static final int SUCCESS            = 0;
+    /** @hide */
+    public static final int ERROR              = -1;
+    /** @hide */
+    public static final int BAD_VALUE          = -2;
+    /** @hide */
+    public static final int INVALID_OPERATION  = -3;
+    /** @hide */
+    public static final int PERMISSION_DENIED  = -4;
+    /** @hide */
+    public static final int NO_INIT            = -5;
+    /** @hide */
+    public static final int DEAD_OBJECT        = -6;
+    /** @hide */
+    public static final int WOULD_BLOCK        = -7;
+
+    /** @hide */
+    @IntDef({
+            SUCCESS,
+            ERROR,
+            BAD_VALUE,
+            INVALID_OPERATION,
+            PERMISSION_DENIED,
+            NO_INIT,
+            DEAD_OBJECT,
+            WOULD_BLOCK
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioSystemError {}
+
+    /**
+     * @hide
+     * Convert an int error value to its String value for readability.
+     * Accepted error values are the java AudioSystem errors, matching android_media_AudioErrors.h,
+     * which map onto the native status_t type.
+     * @param error one of the java AudioSystem errors
+     * @return a human-readable string
+     */
+    public static String audioSystemErrorToString(@AudioSystemError int error) {
+        switch(error) {
+            case SUCCESS:
+                return "SUCCESS";
+            case ERROR:
+                return "ERROR";
+            case BAD_VALUE:
+                return "BAD_VALUE";
+            case INVALID_OPERATION:
+                return "INVALID_OPERATION";
+            case PERMISSION_DENIED:
+                return "PERMISSION_DENIED";
+            case NO_INIT:
+                return "NO_INIT";
+            case DEAD_OBJECT:
+                return "DEAD_OBJECT";
+            case WOULD_BLOCK:
+                return "WOULD_BLOCK";
+            default:
+                return ("unknown error:" + error);
+        }
+    }
+
+    /*
+     * AudioPolicyService methods
+     */
+
+    //
+    // audio device definitions: must be kept in sync with values in system/core/audio.h
+    //
+    /** @hide */
+    public static final int DEVICE_NONE = 0x0;
+    // reserved bits
+    /** @hide */
+    public static final int DEVICE_BIT_IN = 0x80000000;
+    /** @hide */
+    public static final int DEVICE_BIT_DEFAULT = 0x40000000;
+    // output devices, be sure to update AudioManager.java also
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_EARPIECE = 0x1;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_SPEAKER = 0x2;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_WIRED_HEADSET = 0x4;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_WIRED_HEADPHONE = 0x8;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_BLUETOOTH_SCO = 0x10;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_BLUETOOTH_SCO_HEADSET = 0x20;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_BLUETOOTH_SCO_CARKIT = 0x40;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_BLUETOOTH_A2DP = 0x80;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES = 0x100;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER = 0x200;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_AUX_DIGITAL = 0x400;
+    /** @hide */
+    public static final int DEVICE_OUT_HDMI = DEVICE_OUT_AUX_DIGITAL;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_ANLG_DOCK_HEADSET = 0x800;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_DGTL_DOCK_HEADSET = 0x1000;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_USB_ACCESSORY = 0x2000;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_USB_DEVICE = 0x4000;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_REMOTE_SUBMIX = 0x8000;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_TELEPHONY_TX = 0x10000;
+    /** @hide */
+    public static final int DEVICE_OUT_LINE = 0x20000;
+    /** @hide */
+    public static final int DEVICE_OUT_HDMI_ARC = 0x40000;
+    /** @hide */
+    public static final int DEVICE_OUT_HDMI_EARC = 0x40001;
+    /** @hide */
+    public static final int DEVICE_OUT_SPDIF = 0x80000;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_FM = 0x100000;
+    /** @hide */
+    public static final int DEVICE_OUT_AUX_LINE = 0x200000;
+    /** @hide */
+    public static final int DEVICE_OUT_SPEAKER_SAFE = 0x400000;
+    /** @hide */
+    public static final int DEVICE_OUT_IP = 0x800000;
+    /** @hide */
+    public static final int DEVICE_OUT_BUS = 0x1000000;
+    /** @hide */
+    public static final int DEVICE_OUT_PROXY = 0x2000000;
+    /** @hide */
+    public static final int DEVICE_OUT_USB_HEADSET = 0x4000000;
+    /** @hide */
+    public static final int DEVICE_OUT_HEARING_AID = 0x8000000;
+    /** @hide */
+    public static final int DEVICE_OUT_ECHO_CANCELLER = 0x10000000;
+    /** @hide */
+    public static final int DEVICE_OUT_BLE_HEADSET = 0x20000000;
+    /** @hide */
+    public static final int DEVICE_OUT_BLE_SPEAKER = 0x20000001;
+
+    /** @hide */
+    public static final int DEVICE_OUT_DEFAULT = DEVICE_BIT_DEFAULT;
+
+    // Deprecated in R because multiple device types are no longer accessed as a bit mask.
+    // Removing this will get lint warning about changing hidden apis.
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_OUT_ALL_USB = (DEVICE_OUT_USB_ACCESSORY |
+                                                  DEVICE_OUT_USB_DEVICE |
+                                                  DEVICE_OUT_USB_HEADSET);
+
+    /** @hide */
+    public static final Set<Integer> DEVICE_OUT_ALL_SET;
+    /** @hide */
+    public static final Set<Integer> DEVICE_OUT_ALL_A2DP_SET;
+    /** @hide */
+    public static final Set<Integer> DEVICE_OUT_ALL_SCO_SET;
+    /** @hide */
+    public static final Set<Integer> DEVICE_OUT_ALL_USB_SET;
+    /** @hide */
+    public static final Set<Integer> DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET;
+    /** @hide */
+    public static final Set<Integer> DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET;
+    /** @hide */
+    public static final Set<Integer> DEVICE_OUT_ALL_BLE_SET;
+    static {
+        DEVICE_OUT_ALL_SET = new HashSet<>();
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_EARPIECE);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_SPEAKER);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_WIRED_HEADSET);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_WIRED_HEADPHONE);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLUETOOTH_SCO);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLUETOOTH_SCO_HEADSET);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLUETOOTH_SCO_CARKIT);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLUETOOTH_A2DP);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_HDMI);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_ANLG_DOCK_HEADSET);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_DGTL_DOCK_HEADSET);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_USB_ACCESSORY);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_USB_DEVICE);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_REMOTE_SUBMIX);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_TELEPHONY_TX);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_LINE);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_HDMI_ARC);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_HDMI_EARC);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_SPDIF);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_FM);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_AUX_LINE);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_SPEAKER_SAFE);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_IP);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BUS);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_PROXY);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_USB_HEADSET);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_HEARING_AID);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_ECHO_CANCELLER);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLE_HEADSET);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_BLE_SPEAKER);
+        DEVICE_OUT_ALL_SET.add(DEVICE_OUT_DEFAULT);
+
+        DEVICE_OUT_ALL_A2DP_SET = new HashSet<>();
+        DEVICE_OUT_ALL_A2DP_SET.add(DEVICE_OUT_BLUETOOTH_A2DP);
+        DEVICE_OUT_ALL_A2DP_SET.add(DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES);
+        DEVICE_OUT_ALL_A2DP_SET.add(DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER);
+
+        DEVICE_OUT_ALL_SCO_SET = new HashSet<>();
+        DEVICE_OUT_ALL_SCO_SET.add(DEVICE_OUT_BLUETOOTH_SCO);
+        DEVICE_OUT_ALL_SCO_SET.add(DEVICE_OUT_BLUETOOTH_SCO_HEADSET);
+        DEVICE_OUT_ALL_SCO_SET.add(DEVICE_OUT_BLUETOOTH_SCO_CARKIT);
+
+        DEVICE_OUT_ALL_USB_SET = new HashSet<>();
+        DEVICE_OUT_ALL_USB_SET.add(DEVICE_OUT_USB_ACCESSORY);
+        DEVICE_OUT_ALL_USB_SET.add(DEVICE_OUT_USB_DEVICE);
+        DEVICE_OUT_ALL_USB_SET.add(DEVICE_OUT_USB_HEADSET);
+
+        DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET = new HashSet<>();
+        DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET.add(DEVICE_OUT_AUX_LINE);
+        DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET.add(DEVICE_OUT_HDMI_ARC);
+        DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET.add(DEVICE_OUT_HDMI_EARC);
+        DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET.add(DEVICE_OUT_SPDIF);
+
+        DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET = new HashSet<>();
+        DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET.addAll(DEVICE_OUT_ALL_HDMI_SYSTEM_AUDIO_SET);
+        DEVICE_ALL_HDMI_SYSTEM_AUDIO_AND_SPEAKER_SET.add(DEVICE_OUT_SPEAKER);
+
+        DEVICE_OUT_ALL_BLE_SET = new HashSet<>();
+        DEVICE_OUT_ALL_BLE_SET.add(DEVICE_OUT_BLE_HEADSET);
+        DEVICE_OUT_ALL_BLE_SET.add(DEVICE_OUT_BLE_SPEAKER);
+    }
+
+    // input devices
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_COMMUNICATION = DEVICE_BIT_IN | 0x1;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_AMBIENT = DEVICE_BIT_IN | 0x2;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_BUILTIN_MIC = DEVICE_BIT_IN | 0x4;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_BLUETOOTH_SCO_HEADSET = DEVICE_BIT_IN | 0x8;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_WIRED_HEADSET = DEVICE_BIT_IN | 0x10;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_AUX_DIGITAL = DEVICE_BIT_IN | 0x20;
+    /** @hide */
+    public static final int DEVICE_IN_HDMI = DEVICE_IN_AUX_DIGITAL;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_VOICE_CALL = DEVICE_BIT_IN | 0x40;
+    /** @hide */
+    public static final int DEVICE_IN_TELEPHONY_RX = DEVICE_IN_VOICE_CALL;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_BACK_MIC = DEVICE_BIT_IN | 0x80;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_REMOTE_SUBMIX = DEVICE_BIT_IN | 0x100;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_ANLG_DOCK_HEADSET = DEVICE_BIT_IN | 0x200;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_DGTL_DOCK_HEADSET = DEVICE_BIT_IN | 0x400;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_USB_ACCESSORY = DEVICE_BIT_IN | 0x800;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_USB_DEVICE = DEVICE_BIT_IN | 0x1000;
+    /** @hide */
+    public static final int DEVICE_IN_FM_TUNER = DEVICE_BIT_IN | 0x2000;
+    /** @hide */
+    public static final int DEVICE_IN_TV_TUNER = DEVICE_BIT_IN | 0x4000;
+    /** @hide */
+    public static final int DEVICE_IN_LINE = DEVICE_BIT_IN | 0x8000;
+    /** @hide */
+    public static final int DEVICE_IN_SPDIF = DEVICE_BIT_IN | 0x10000;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_BLUETOOTH_A2DP = DEVICE_BIT_IN | 0x20000;
+    /** @hide */
+    public static final int DEVICE_IN_LOOPBACK = DEVICE_BIT_IN | 0x40000;
+    /** @hide */
+    public static final int DEVICE_IN_IP = DEVICE_BIT_IN | 0x80000;
+    /** @hide */
+    public static final int DEVICE_IN_BUS = DEVICE_BIT_IN | 0x100000;
+    /** @hide */
+    public static final int DEVICE_IN_PROXY = DEVICE_BIT_IN | 0x1000000;
+    /** @hide */
+    public static final int DEVICE_IN_USB_HEADSET = DEVICE_BIT_IN | 0x2000000;
+    /** @hide */
+    public static final int DEVICE_IN_BLUETOOTH_BLE = DEVICE_BIT_IN | 0x4000000;
+    /** @hide */
+    public static final int DEVICE_IN_HDMI_ARC = DEVICE_BIT_IN | 0x8000000;
+    /** @hide */
+    public static final int DEVICE_IN_HDMI_EARC = DEVICE_BIT_IN | 0x8000001;
+    /** @hide */
+    public static final int DEVICE_IN_ECHO_REFERENCE = DEVICE_BIT_IN | 0x10000000;
+    /** @hide */
+    public static final int DEVICE_IN_BLE_HEADSET = DEVICE_BIT_IN | 0x20000000;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_IN_DEFAULT = DEVICE_BIT_IN | DEVICE_BIT_DEFAULT;
+
+    /** @hide */
+    public static final Set<Integer> DEVICE_IN_ALL_SET;
+    /** @hide */
+    public static final Set<Integer> DEVICE_IN_ALL_SCO_SET;
+    /** @hide */
+    public static final Set<Integer> DEVICE_IN_ALL_USB_SET;
+    static {
+        DEVICE_IN_ALL_SET = new HashSet<>();
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_COMMUNICATION);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_AMBIENT);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_BUILTIN_MIC);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_BLUETOOTH_SCO_HEADSET);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_WIRED_HEADSET);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_HDMI);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_TELEPHONY_RX);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_BACK_MIC);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_REMOTE_SUBMIX);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_ANLG_DOCK_HEADSET);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_DGTL_DOCK_HEADSET);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_USB_ACCESSORY);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_USB_DEVICE);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_FM_TUNER);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_TV_TUNER);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_LINE);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_SPDIF);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_BLUETOOTH_A2DP);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_LOOPBACK);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_IP);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_BUS);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_PROXY);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_USB_HEADSET);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_BLUETOOTH_BLE);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_HDMI_ARC);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_HDMI_EARC);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_ECHO_REFERENCE);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_BLE_HEADSET);
+        DEVICE_IN_ALL_SET.add(DEVICE_IN_DEFAULT);
+
+        DEVICE_IN_ALL_SCO_SET = new HashSet<>();
+        DEVICE_IN_ALL_SCO_SET.add(DEVICE_IN_BLUETOOTH_SCO_HEADSET);
+
+        DEVICE_IN_ALL_USB_SET = new HashSet<>();
+        DEVICE_IN_ALL_USB_SET.add(DEVICE_IN_USB_ACCESSORY);
+        DEVICE_IN_ALL_USB_SET.add(DEVICE_IN_USB_DEVICE);
+        DEVICE_IN_ALL_USB_SET.add(DEVICE_IN_USB_HEADSET);
+    }
+
+    /** @hide */
+    public static final String LEGACY_REMOTE_SUBMIX_ADDRESS = "0";
+
+    // device states, must match AudioSystem::device_connection_state
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_STATE_UNAVAILABLE = 0;
+    /** @hide */
+    @UnsupportedAppUsage
+    public static final int DEVICE_STATE_AVAILABLE = 1;
+    private static final int NUM_DEVICE_STATES = 1;
+
+    /** @hide */
+    public static String deviceStateToString(int state) {
+        switch (state) {
+            case DEVICE_STATE_UNAVAILABLE: return "DEVICE_STATE_UNAVAILABLE";
+            case DEVICE_STATE_AVAILABLE: return "DEVICE_STATE_AVAILABLE";
+            default: return "unknown state (" + state + ")";
+        }
+    }
+
+    /** @hide */ public static final String DEVICE_OUT_EARPIECE_NAME = "earpiece";
+    /** @hide */ public static final String DEVICE_OUT_SPEAKER_NAME = "speaker";
+    /** @hide */ public static final String DEVICE_OUT_WIRED_HEADSET_NAME = "headset";
+    /** @hide */ public static final String DEVICE_OUT_WIRED_HEADPHONE_NAME = "headphone";
+    /** @hide */ public static final String DEVICE_OUT_BLUETOOTH_SCO_NAME = "bt_sco";
+    /** @hide */ public static final String DEVICE_OUT_BLUETOOTH_SCO_HEADSET_NAME = "bt_sco_hs";
+    /** @hide */ public static final String DEVICE_OUT_BLUETOOTH_SCO_CARKIT_NAME = "bt_sco_carkit";
+    /** @hide */ public static final String DEVICE_OUT_BLUETOOTH_A2DP_NAME = "bt_a2dp";
+    /** @hide */
+    public static final String DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES_NAME = "bt_a2dp_hp";
+    /** @hide */ public static final String DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER_NAME = "bt_a2dp_spk";
+    /** @hide */ public static final String DEVICE_OUT_AUX_DIGITAL_NAME = "aux_digital";
+    /** @hide */ public static final String DEVICE_OUT_HDMI_NAME = "hdmi";
+    /** @hide */ public static final String DEVICE_OUT_ANLG_DOCK_HEADSET_NAME = "analog_dock";
+    /** @hide */ public static final String DEVICE_OUT_DGTL_DOCK_HEADSET_NAME = "digital_dock";
+    /** @hide */ public static final String DEVICE_OUT_USB_ACCESSORY_NAME = "usb_accessory";
+    /** @hide */ public static final String DEVICE_OUT_USB_DEVICE_NAME = "usb_device";
+    /** @hide */ public static final String DEVICE_OUT_REMOTE_SUBMIX_NAME = "remote_submix";
+    /** @hide */ public static final String DEVICE_OUT_TELEPHONY_TX_NAME = "telephony_tx";
+    /** @hide */ public static final String DEVICE_OUT_LINE_NAME = "line";
+    /** @hide */ public static final String DEVICE_OUT_HDMI_ARC_NAME = "hmdi_arc";
+    /** @hide */ public static final String DEVICE_OUT_HDMI_EARC_NAME = "hmdi_earc";
+    /** @hide */ public static final String DEVICE_OUT_SPDIF_NAME = "spdif";
+    /** @hide */ public static final String DEVICE_OUT_FM_NAME = "fm_transmitter";
+    /** @hide */ public static final String DEVICE_OUT_AUX_LINE_NAME = "aux_line";
+    /** @hide */ public static final String DEVICE_OUT_SPEAKER_SAFE_NAME = "speaker_safe";
+    /** @hide */ public static final String DEVICE_OUT_IP_NAME = "ip";
+    /** @hide */ public static final String DEVICE_OUT_BUS_NAME = "bus";
+    /** @hide */ public static final String DEVICE_OUT_PROXY_NAME = "proxy";
+    /** @hide */ public static final String DEVICE_OUT_USB_HEADSET_NAME = "usb_headset";
+    /** @hide */ public static final String DEVICE_OUT_HEARING_AID_NAME = "hearing_aid_out";
+    /** @hide */ public static final String DEVICE_OUT_ECHO_CANCELLER_NAME = "echo_canceller";
+    /** @hide */ public static final String DEVICE_OUT_BLE_HEADSET_NAME = "ble_headset";
+    /** @hide */ public static final String DEVICE_OUT_BLE_SPEAKER_NAME = "ble_speaker";
+
+    /** @hide */ public static final String DEVICE_IN_COMMUNICATION_NAME = "communication";
+    /** @hide */ public static final String DEVICE_IN_AMBIENT_NAME = "ambient";
+    /** @hide */ public static final String DEVICE_IN_BUILTIN_MIC_NAME = "mic";
+    /** @hide */ public static final String DEVICE_IN_BLUETOOTH_SCO_HEADSET_NAME = "bt_sco_hs";
+    /** @hide */ public static final String DEVICE_IN_WIRED_HEADSET_NAME = "headset";
+    /** @hide */ public static final String DEVICE_IN_AUX_DIGITAL_NAME = "aux_digital";
+    /** @hide */ public static final String DEVICE_IN_TELEPHONY_RX_NAME = "telephony_rx";
+    /** @hide */ public static final String DEVICE_IN_BACK_MIC_NAME = "back_mic";
+    /** @hide */ public static final String DEVICE_IN_REMOTE_SUBMIX_NAME = "remote_submix";
+    /** @hide */ public static final String DEVICE_IN_ANLG_DOCK_HEADSET_NAME = "analog_dock";
+    /** @hide */ public static final String DEVICE_IN_DGTL_DOCK_HEADSET_NAME = "digital_dock";
+    /** @hide */ public static final String DEVICE_IN_USB_ACCESSORY_NAME = "usb_accessory";
+    /** @hide */ public static final String DEVICE_IN_USB_DEVICE_NAME = "usb_device";
+    /** @hide */ public static final String DEVICE_IN_FM_TUNER_NAME = "fm_tuner";
+    /** @hide */ public static final String DEVICE_IN_TV_TUNER_NAME = "tv_tuner";
+    /** @hide */ public static final String DEVICE_IN_LINE_NAME = "line";
+    /** @hide */ public static final String DEVICE_IN_SPDIF_NAME = "spdif";
+    /** @hide */ public static final String DEVICE_IN_BLUETOOTH_A2DP_NAME = "bt_a2dp";
+    /** @hide */ public static final String DEVICE_IN_LOOPBACK_NAME = "loopback";
+    /** @hide */ public static final String DEVICE_IN_IP_NAME = "ip";
+    /** @hide */ public static final String DEVICE_IN_BUS_NAME = "bus";
+    /** @hide */ public static final String DEVICE_IN_PROXY_NAME = "proxy";
+    /** @hide */ public static final String DEVICE_IN_USB_HEADSET_NAME = "usb_headset";
+    /** @hide */ public static final String DEVICE_IN_BLUETOOTH_BLE_NAME = "bt_ble";
+    /** @hide */ public static final String DEVICE_IN_ECHO_REFERENCE_NAME = "echo_reference";
+    /** @hide */ public static final String DEVICE_IN_HDMI_ARC_NAME = "hdmi_arc";
+    /** @hide */ public static final String DEVICE_IN_HDMI_EARC_NAME = "hdmi_earc";
+    /** @hide */ public static final String DEVICE_IN_BLE_HEADSET_NAME = "ble_headset";
+
+    /** @hide */
+    @UnsupportedAppUsage
+    public static String getOutputDeviceName(int device)
+    {
+        switch(device) {
+        case DEVICE_OUT_EARPIECE:
+            return DEVICE_OUT_EARPIECE_NAME;
+        case DEVICE_OUT_SPEAKER:
+            return DEVICE_OUT_SPEAKER_NAME;
+        case DEVICE_OUT_WIRED_HEADSET:
+            return DEVICE_OUT_WIRED_HEADSET_NAME;
+        case DEVICE_OUT_WIRED_HEADPHONE:
+            return DEVICE_OUT_WIRED_HEADPHONE_NAME;
+        case DEVICE_OUT_BLUETOOTH_SCO:
+            return DEVICE_OUT_BLUETOOTH_SCO_NAME;
+        case DEVICE_OUT_BLUETOOTH_SCO_HEADSET:
+            return DEVICE_OUT_BLUETOOTH_SCO_HEADSET_NAME;
+        case DEVICE_OUT_BLUETOOTH_SCO_CARKIT:
+            return DEVICE_OUT_BLUETOOTH_SCO_CARKIT_NAME;
+        case DEVICE_OUT_BLUETOOTH_A2DP:
+            return DEVICE_OUT_BLUETOOTH_A2DP_NAME;
+        case DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES:
+            return DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES_NAME;
+        case DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER:
+            return DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER_NAME;
+        case DEVICE_OUT_HDMI:
+            return DEVICE_OUT_HDMI_NAME;
+        case DEVICE_OUT_ANLG_DOCK_HEADSET:
+            return DEVICE_OUT_ANLG_DOCK_HEADSET_NAME;
+        case DEVICE_OUT_DGTL_DOCK_HEADSET:
+            return DEVICE_OUT_DGTL_DOCK_HEADSET_NAME;
+        case DEVICE_OUT_USB_ACCESSORY:
+            return DEVICE_OUT_USB_ACCESSORY_NAME;
+        case DEVICE_OUT_USB_DEVICE:
+            return DEVICE_OUT_USB_DEVICE_NAME;
+        case DEVICE_OUT_REMOTE_SUBMIX:
+            return DEVICE_OUT_REMOTE_SUBMIX_NAME;
+        case DEVICE_OUT_TELEPHONY_TX:
+            return DEVICE_OUT_TELEPHONY_TX_NAME;
+        case DEVICE_OUT_LINE:
+            return DEVICE_OUT_LINE_NAME;
+        case DEVICE_OUT_HDMI_ARC:
+            return DEVICE_OUT_HDMI_ARC_NAME;
+        case DEVICE_OUT_HDMI_EARC:
+            return DEVICE_OUT_HDMI_EARC_NAME;
+        case DEVICE_OUT_SPDIF:
+            return DEVICE_OUT_SPDIF_NAME;
+        case DEVICE_OUT_FM:
+            return DEVICE_OUT_FM_NAME;
+        case DEVICE_OUT_AUX_LINE:
+            return DEVICE_OUT_AUX_LINE_NAME;
+        case DEVICE_OUT_SPEAKER_SAFE:
+            return DEVICE_OUT_SPEAKER_SAFE_NAME;
+        case DEVICE_OUT_IP:
+            return DEVICE_OUT_IP_NAME;
+        case DEVICE_OUT_BUS:
+            return DEVICE_OUT_BUS_NAME;
+        case DEVICE_OUT_PROXY:
+            return DEVICE_OUT_PROXY_NAME;
+        case DEVICE_OUT_USB_HEADSET:
+            return DEVICE_OUT_USB_HEADSET_NAME;
+        case DEVICE_OUT_HEARING_AID:
+            return DEVICE_OUT_HEARING_AID_NAME;
+        case DEVICE_OUT_ECHO_CANCELLER:
+            return DEVICE_OUT_ECHO_CANCELLER_NAME;
+        case DEVICE_OUT_BLE_HEADSET:
+            return DEVICE_OUT_BLE_HEADSET_NAME;
+        case DEVICE_OUT_BLE_SPEAKER:
+            return DEVICE_OUT_BLE_SPEAKER_NAME;
+        case DEVICE_OUT_DEFAULT:
+        default:
+            return Integer.toString(device);
+        }
+    }
+
+    /** @hide */
+    public static String getInputDeviceName(int device)
+    {
+        switch(device) {
+        case DEVICE_IN_COMMUNICATION:
+            return DEVICE_IN_COMMUNICATION_NAME;
+        case DEVICE_IN_AMBIENT:
+            return DEVICE_IN_AMBIENT_NAME;
+        case DEVICE_IN_BUILTIN_MIC:
+            return DEVICE_IN_BUILTIN_MIC_NAME;
+        case DEVICE_IN_BLUETOOTH_SCO_HEADSET:
+            return DEVICE_IN_BLUETOOTH_SCO_HEADSET_NAME;
+        case DEVICE_IN_WIRED_HEADSET:
+            return DEVICE_IN_WIRED_HEADSET_NAME;
+        case DEVICE_IN_AUX_DIGITAL:
+            return DEVICE_IN_AUX_DIGITAL_NAME;
+        case DEVICE_IN_TELEPHONY_RX:
+            return DEVICE_IN_TELEPHONY_RX_NAME;
+        case DEVICE_IN_BACK_MIC:
+            return DEVICE_IN_BACK_MIC_NAME;
+        case DEVICE_IN_REMOTE_SUBMIX:
+            return DEVICE_IN_REMOTE_SUBMIX_NAME;
+        case DEVICE_IN_ANLG_DOCK_HEADSET:
+            return DEVICE_IN_ANLG_DOCK_HEADSET_NAME;
+        case DEVICE_IN_DGTL_DOCK_HEADSET:
+            return DEVICE_IN_DGTL_DOCK_HEADSET_NAME;
+        case DEVICE_IN_USB_ACCESSORY:
+            return DEVICE_IN_USB_ACCESSORY_NAME;
+        case DEVICE_IN_USB_DEVICE:
+            return DEVICE_IN_USB_DEVICE_NAME;
+        case DEVICE_IN_FM_TUNER:
+            return DEVICE_IN_FM_TUNER_NAME;
+        case DEVICE_IN_TV_TUNER:
+            return DEVICE_IN_TV_TUNER_NAME;
+        case DEVICE_IN_LINE:
+            return DEVICE_IN_LINE_NAME;
+        case DEVICE_IN_SPDIF:
+            return DEVICE_IN_SPDIF_NAME;
+        case DEVICE_IN_BLUETOOTH_A2DP:
+            return DEVICE_IN_BLUETOOTH_A2DP_NAME;
+        case DEVICE_IN_LOOPBACK:
+            return DEVICE_IN_LOOPBACK_NAME;
+        case DEVICE_IN_IP:
+            return DEVICE_IN_IP_NAME;
+        case DEVICE_IN_BUS:
+            return DEVICE_IN_BUS_NAME;
+        case DEVICE_IN_PROXY:
+            return DEVICE_IN_PROXY_NAME;
+        case DEVICE_IN_USB_HEADSET:
+            return DEVICE_IN_USB_HEADSET_NAME;
+        case DEVICE_IN_BLUETOOTH_BLE:
+            return DEVICE_IN_BLUETOOTH_BLE_NAME;
+        case DEVICE_IN_ECHO_REFERENCE:
+            return DEVICE_IN_ECHO_REFERENCE_NAME;
+        case DEVICE_IN_HDMI_ARC:
+            return DEVICE_IN_HDMI_ARC_NAME;
+        case DEVICE_IN_HDMI_EARC:
+            return DEVICE_IN_HDMI_EARC_NAME;
+        case DEVICE_IN_BLE_HEADSET:
+            return DEVICE_IN_BLE_HEADSET_NAME;
+        case DEVICE_IN_DEFAULT:
+        default:
+            return Integer.toString(device);
+        }
+    }
+
+    /**
+     * @hide
+     * Returns a human readable name for a given device type
+     * @param device a native device type, NOT an AudioDeviceInfo type
+     * @return a string describing the device type
+     */
+    public static @NonNull String getDeviceName(int device) {
+        if ((device & DEVICE_BIT_IN) != 0) {
+            return getInputDeviceName(device);
+        }
+        return getOutputDeviceName(device);
+    }
+
+    // phone state, match audio_mode???
+    /** @hide */ public static final int PHONE_STATE_OFFCALL = 0;
+    /** @hide */ public static final int PHONE_STATE_RINGING = 1;
+    /** @hide */ public static final int PHONE_STATE_INCALL = 2;
+
+    // device categories config for setForceUse, must match audio_policy_forced_cfg_t
+    /** @hide */ @UnsupportedAppUsage public static final int FORCE_NONE = 0;
+    /** @hide */ public static final int FORCE_SPEAKER = 1;
+    /** @hide */ public static final int FORCE_HEADPHONES = 2;
+    /** @hide */ public static final int FORCE_BT_SCO = 3;
+    /** @hide */ public static final int FORCE_BT_A2DP = 4;
+    /** @hide */ public static final int FORCE_WIRED_ACCESSORY = 5;
+    /** @hide */ @UnsupportedAppUsage public static final int FORCE_BT_CAR_DOCK = 6;
+    /** @hide */ @UnsupportedAppUsage public static final int FORCE_BT_DESK_DOCK = 7;
+    /** @hide */ @UnsupportedAppUsage public static final int FORCE_ANALOG_DOCK = 8;
+    /** @hide */ @UnsupportedAppUsage public static final int FORCE_DIGITAL_DOCK = 9;
+    /** @hide */ public static final int FORCE_NO_BT_A2DP = 10;
+    /** @hide */ public static final int FORCE_SYSTEM_ENFORCED = 11;
+    /** @hide */ public static final int FORCE_HDMI_SYSTEM_AUDIO_ENFORCED = 12;
+    /** @hide */ public static final int FORCE_ENCODED_SURROUND_NEVER = 13;
+    /** @hide */ public static final int FORCE_ENCODED_SURROUND_ALWAYS = 14;
+    /** @hide */ public static final int FORCE_ENCODED_SURROUND_MANUAL = 15;
+    /** @hide */ public static final int NUM_FORCE_CONFIG = 16;
+    /** @hide */ public static final int FORCE_DEFAULT = FORCE_NONE;
+
+    /** @hide */
+    public static String forceUseConfigToString(int config) {
+        switch (config) {
+            case FORCE_NONE: return "FORCE_NONE";
+            case FORCE_SPEAKER: return "FORCE_SPEAKER";
+            case FORCE_HEADPHONES: return "FORCE_HEADPHONES";
+            case FORCE_BT_SCO: return "FORCE_BT_SCO";
+            case FORCE_BT_A2DP: return "FORCE_BT_A2DP";
+            case FORCE_WIRED_ACCESSORY: return "FORCE_WIRED_ACCESSORY";
+            case FORCE_BT_CAR_DOCK: return "FORCE_BT_CAR_DOCK";
+            case FORCE_BT_DESK_DOCK: return "FORCE_BT_DESK_DOCK";
+            case FORCE_ANALOG_DOCK: return "FORCE_ANALOG_DOCK";
+            case FORCE_DIGITAL_DOCK: return "FORCE_DIGITAL_DOCK";
+            case FORCE_NO_BT_A2DP: return "FORCE_NO_BT_A2DP";
+            case FORCE_SYSTEM_ENFORCED: return "FORCE_SYSTEM_ENFORCED";
+            case FORCE_HDMI_SYSTEM_AUDIO_ENFORCED: return "FORCE_HDMI_SYSTEM_AUDIO_ENFORCED";
+            case FORCE_ENCODED_SURROUND_NEVER: return "FORCE_ENCODED_SURROUND_NEVER";
+            case FORCE_ENCODED_SURROUND_ALWAYS: return "FORCE_ENCODED_SURROUND_ALWAYS";
+            case FORCE_ENCODED_SURROUND_MANUAL: return "FORCE_ENCODED_SURROUND_MANUAL";
+            default: return "unknown config (" + config + ")" ;
+        }
+    }
+
+    // usage for setForceUse, must match audio_policy_force_use_t
+    /** @hide */ public static final int FOR_COMMUNICATION = 0;
+    /** @hide */ public static final int FOR_MEDIA = 1;
+    /** @hide */ public static final int FOR_RECORD = 2;
+    /** @hide */ public static final int FOR_DOCK = 3;
+    /** @hide */ public static final int FOR_SYSTEM = 4;
+    /** @hide */ public static final int FOR_HDMI_SYSTEM_AUDIO = 5;
+    /** @hide */ public static final int FOR_ENCODED_SURROUND = 6;
+    /** @hide */ public static final int FOR_VIBRATE_RINGING = 7;
+    private static final int NUM_FORCE_USE = 8;
+
+    // Device role in audio policy
+    public static final int DEVICE_ROLE_NONE = 0;
+    public static final int DEVICE_ROLE_PREFERRED = 1;
+    public static final int DEVICE_ROLE_DISABLED = 2;
+
+    /** @hide */
+    public static String forceUseUsageToString(int usage) {
+        switch (usage) {
+            case FOR_COMMUNICATION: return "FOR_COMMUNICATION";
+            case FOR_MEDIA: return "FOR_MEDIA";
+            case FOR_RECORD: return "FOR_RECORD";
+            case FOR_DOCK: return "FOR_DOCK";
+            case FOR_SYSTEM: return "FOR_SYSTEM";
+            case FOR_HDMI_SYSTEM_AUDIO: return "FOR_HDMI_SYSTEM_AUDIO";
+            case FOR_ENCODED_SURROUND: return "FOR_ENCODED_SURROUND";
+            case FOR_VIBRATE_RINGING: return "FOR_VIBRATE_RINGING";
+            default: return "unknown usage (" + usage + ")" ;
+        }
+    }
+
+    /** @hide Wrapper for native methods called from AudioService */
+    public static int setStreamVolumeIndexAS(int stream, int index, int device) {
+        if (DEBUG_VOLUME) {
+            Log.i(TAG, "setStreamVolumeIndex: " + STREAM_NAMES[stream]
+                    + " dev=" + Integer.toHexString(device) + " idx=" + index);
+        }
+        return setStreamVolumeIndex(stream, index, device);
+    }
+
+    // usage for AudioRecord.startRecordingSync(), must match AudioSystem::sync_event_t
+    /** @hide */ public static final int SYNC_EVENT_NONE = 0;
+    /** @hide */ public static final int SYNC_EVENT_PRESENTATION_COMPLETE = 1;
+    /** @hide
+     *  Not used by native implementation.
+     *  See {@link AudioRecord.Builder#setSharedAudioEvent(MediaSyncEvent) */
+    public static final int SYNC_EVENT_SHARE_AUDIO_HISTORY = 100;
+
+    /**
+     * @hide
+     * @return command completion status, one of {@link #AUDIO_STATUS_OK},
+     *     {@link #AUDIO_STATUS_ERROR} or {@link #AUDIO_STATUS_SERVER_DIED}
+     */
+    @UnsupportedAppUsage
+    public static native int setDeviceConnectionState(int device, int state,
+                                                      String device_address, String device_name,
+                                                      int codecFormat);
+    /** @hide */
+    @UnsupportedAppUsage
+    public static native int getDeviceConnectionState(int device, String device_address);
+    /** @hide */
+    public static native int handleDeviceConfigChange(int device,
+                                                      String device_address,
+                                                      String device_name,
+                                                      int codecFormat);
+    /** @hide */
+    @UnsupportedAppUsage
+    public static int setPhoneState(int state) {
+        Log.w(TAG, "Do not use this method! Use AudioManager.setMode() instead.");
+        return 0;
+    }
+    /**
+     * @hide
+     * Send the current audio mode to audio policy manager and audio HAL.
+     * @param state the audio mode
+     * @param uid the UID of the app owning the audio mode
+     * @return command completion status.
+     */
+    public static native int setPhoneState(int state, int uid);
+    /** @hide */
+    @UnsupportedAppUsage
+    public static native int setForceUse(int usage, int config);
+    /** @hide */
+    @UnsupportedAppUsage
+    public static native int getForceUse(int usage);
+    /** @hide */
+    @UnsupportedAppUsage
+    public static native int initStreamVolume(int stream, int indexMin, int indexMax);
+    @UnsupportedAppUsage
+    private static native int setStreamVolumeIndex(int stream, int index, int device);
+    /** @hide */
+    public static native int getStreamVolumeIndex(int stream, int device);
+    /**
+     * @hide
+     * set a volume for the given {@link AudioAttributes} and for all other stream that belong to
+     * the same volume group.
+     * @param attributes the {@link AudioAttributes} to be considered
+     * @param index to be applied
+     * @param device the volume device to be considered
+     * @return command completion status.
+     */
+    public static native int setVolumeIndexForAttributes(@NonNull AudioAttributes attributes,
+                                                         int index, int device);
+   /**
+    * @hide
+    * get the volume index for the given {@link AudioAttributes}.
+    * @param attributes the {@link AudioAttributes} to be considered
+    * @param device the volume device to be considered
+    * @return volume index for the given {@link AudioAttributes} and volume device.
+    */
+    public static native int getVolumeIndexForAttributes(@NonNull AudioAttributes attributes,
+                                                         int device);
+    /**
+     * @hide
+     * get the minimum volume index for the given {@link AudioAttributes}.
+     * @param attributes the {@link AudioAttributes} to be considered
+     * @return minimum volume index for the given {@link AudioAttributes}.
+     */
+    public static native int getMinVolumeIndexForAttributes(@NonNull AudioAttributes attributes);
+    /**
+     * @hide
+     * get the maximum volume index for the given {@link AudioAttributes}.
+     * @param attributes the {@link AudioAttributes} to be considered
+     * @return maximum volume index for the given {@link AudioAttributes}.
+     */
+    public static native int getMaxVolumeIndexForAttributes(@NonNull AudioAttributes attributes);
+
+    /** @hide */
+    public static native int setMasterVolume(float value);
+    /** @hide */
+    public static native float getMasterVolume();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static native int setMasterMute(boolean mute);
+    /** @hide */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public static native boolean getMasterMute();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static native int getDevicesForStream(int stream);
+
+    /**
+     * @hide
+     * Do not use directly, see {@link AudioManager#getDevicesForAttributes(AudioAttributes)}
+     * Get the audio devices that would be used for the routing of the given audio attributes.
+     * @param attributes the {@link AudioAttributes} for which the routing is being queried
+     * @return an empty list if there was an issue with the request, a list of audio devices
+     *   otherwise (typically one device, except for duplicated paths).
+     */
+    public static @NonNull ArrayList<AudioDeviceAttributes> getDevicesForAttributes(
+            @NonNull AudioAttributes attributes) {
+        Objects.requireNonNull(attributes);
+        final AudioDeviceAttributes[] devices = new AudioDeviceAttributes[MAX_DEVICE_ROUTING];
+        final int res = getDevicesForAttributes(attributes, devices);
+        final ArrayList<AudioDeviceAttributes> routeDevices = new ArrayList<>();
+        if (res != SUCCESS) {
+            Log.e(TAG, "error " + res + " in getDevicesForAttributes for " + attributes);
+            return routeDevices;
+        }
+
+        for (AudioDeviceAttributes device : devices) {
+            if (device != null) {
+                routeDevices.add(device);
+            }
+        }
+        return routeDevices;
+    }
+
+    /**
+     * Maximum number of audio devices a track is ever routed to, determines the size of the
+     * array passed to {@link #getDevicesForAttributes(AudioAttributes, AudioDeviceAttributes[])}
+     */
+    private static final int MAX_DEVICE_ROUTING = 4;
+
+    private static native int getDevicesForAttributes(@NonNull AudioAttributes aa,
+                                                      @NonNull AudioDeviceAttributes[] devices);
+
+    /** @hide returns true if master mono is enabled. */
+    public static native boolean getMasterMono();
+    /** @hide enables or disables the master mono mode. */
+    public static native int setMasterMono(boolean mono);
+    /** @hide enables or disables the RTT mode. */
+    public static native int setRttEnabled(boolean enabled);
+
+    /** @hide returns master balance value in range -1.f -> 1.f, where 0.f is dead center. */
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS)
+    public static native float getMasterBalance();
+    /** @hide Changes the audio balance of the device. */
+    @TestApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS)
+    public static native int setMasterBalance(float balance);
+
+    // helpers for android.media.AudioManager.getProperty(), see description there for meaning
+    /** @hide */
+    @UnsupportedAppUsage(trackingBug = 134049522)
+    public static native int getPrimaryOutputSamplingRate();
+    /** @hide */
+    @UnsupportedAppUsage(trackingBug = 134049522)
+    public static native int getPrimaryOutputFrameCount();
+    /** @hide */
+    @UnsupportedAppUsage
+    public static native int getOutputLatency(int stream);
+
+    /** @hide */
+    public static native int setLowRamDevice(boolean isLowRamDevice, long totalMemory);
+    /** @hide */
+    @UnsupportedAppUsage
+    public static native int checkAudioFlinger();
+    /** @hide */
+    public static native void setAudioFlingerBinder(IBinder audioFlinger);
+
+    /** @hide */
+    public static native int listAudioPorts(ArrayList<AudioPort> ports, int[] generation);
+    /** @hide */
+    public static native int createAudioPatch(AudioPatch[] patch,
+                                            AudioPortConfig[] sources, AudioPortConfig[] sinks);
+    /** @hide */
+    public static native int releaseAudioPatch(AudioPatch patch);
+    /** @hide */
+    public static native int listAudioPatches(ArrayList<AudioPatch> patches, int[] generation);
+    /** @hide */
+    public static native int setAudioPortConfig(AudioPortConfig config);
+
+    /** @hide */
+    public static native int startAudioSource(AudioPortConfig config,
+                                              AudioAttributes audioAttributes);
+    /** @hide */
+    public static native int stopAudioSource(int handle);
+
+    // declare this instance as having a dynamic policy callback handler
+    private static native final void native_register_dynamic_policy_callback();
+    // declare this instance as having a recording configuration update callback handler
+    private static native final void native_register_recording_callback();
+    // declare this instance as having a routing update callback handler
+    private static native void native_register_routing_callback();
+
+    // must be kept in sync with value in include/system/audio.h
+    /** @hide */ public static final int AUDIO_HW_SYNC_INVALID = 0;
+
+    /** @hide */
+    public static native int getAudioHwSyncForSession(int sessionId);
+
+    /** @hide */
+    public static native int registerPolicyMixes(ArrayList<AudioMix> mixes, boolean register);
+
+    /** @hide see AudioPolicy.setUidDeviceAffinities() */
+    public static native int setUidDeviceAffinities(int uid, @NonNull int[] types,
+            @NonNull String[] addresses);
+
+    /** @hide see AudioPolicy.removeUidDeviceAffinities() */
+    public static native int removeUidDeviceAffinities(int uid);
+
+    /** @hide see AudioPolicy.setUserIdDeviceAffinities() */
+    public static native int setUserIdDeviceAffinities(int userId, @NonNull int[] types,
+            @NonNull String[] addresses);
+
+    /** @hide see AudioPolicy.removeUserIdDeviceAffinities() */
+    public static native int removeUserIdDeviceAffinities(int userId);
+
+    /** @hide */
+    public static native int systemReady();
+
+    /** @hide */
+    public static native float getStreamVolumeDB(int stream, int index, int device);
+
+    /**
+     * @hide
+     * Communicate supported system usages to audio policy service.
+     */
+    public static native int setSupportedSystemUsages(int[] systemUsages);
+
+    /**
+     * @hide
+     * @see AudioManager#setAllowedCapturePolicy()
+     */
+    public static native int setAllowedCapturePolicy(int uid, int flags);
+
+    /**
+     * @hide
+     * Compressed audio offload decoding modes supported by audio HAL implementation.
+     * Keep in sync with system/media/include/media/audio.h.
+     */
+    public static final int OFFLOAD_NOT_SUPPORTED = 0;
+    public static final int OFFLOAD_SUPPORTED = 1;
+    public static final int OFFLOAD_GAPLESS_SUPPORTED = 2;
+
+    static int getOffloadSupport(@NonNull AudioFormat format, @NonNull AudioAttributes attr) {
+        return native_get_offload_support(format.getEncoding(), format.getSampleRate(),
+                format.getChannelMask(), format.getChannelIndexMask(),
+                attr.getVolumeControlStream());
+    }
+
+    private static native int native_get_offload_support(int encoding, int sampleRate,
+            int channelMask, int channelIndexMask, int streamType);
+
+    /** @hide */
+    public static native int getMicrophones(ArrayList<MicrophoneInfo> microphonesInfo);
+
+    /** @hide */
+    public static native int getSurroundFormats(Map<Integer, Boolean> surroundFormats);
+
+    /** @hide */
+    public static native int getReportedSurroundFormats(ArrayList<Integer> surroundFormats);
+
+    /**
+     * @hide
+     * Returns a list of audio formats (codec) supported on the A2DP offload path.
+     */
+    public static native int getHwOffloadEncodingFormatsSupportedForA2DP(
+            ArrayList<Integer> formatList);
+
+    /** @hide */
+    public static native int setSurroundFormatEnabled(int audioFormat, boolean enabled);
+
+    /**
+     * @hide
+     * Communicate UID of active assistant to audio policy service.
+     */
+    public static native int setAssistantUid(int uid);
+
+    /**
+     * Communicate UID of the current {@link android.service.voice.HotwordDetectionService} to audio
+     * policy service.
+     * @hide
+     */
+    public static native int setHotwordDetectionServiceUid(int uid);
+
+    /**
+     * @hide
+     * Communicate UIDs of active accessibility services to audio policy service.
+     */
+    public static native int setA11yServicesUids(int[] uids);
+
+    /**
+     * @hide
+     * Communicate UID of current InputMethodService to audio policy service.
+     */
+    public static native int setCurrentImeUid(int uid);
+
+
+    /**
+     * @hide
+     * @see AudioManager#isHapticPlaybackSupported()
+     */
+    public static native boolean isHapticPlaybackSupported();
+
+    /**
+     * @hide
+     * Send audio HAL server process pids to native audioserver process for use
+     * when generating audio HAL servers tombstones
+     */
+    public static native int setAudioHalPids(int[] pids);
+
+    /**
+     * @hide
+     * @see AudioManager#isCallScreeningModeSupported()
+     */
+    public static native boolean isCallScreeningModeSupported();
+
+    // use case routing by product strategy
+
+    /**
+     * @hide
+     * Set device as role for product strategy.
+     * @param strategy the id of the strategy to configure
+     * @param role the role of the devices
+     * @param devices the list of devices to be set as role for the given strategy
+     * @return {@link #SUCCESS} if successfully set
+     */
+    public static int setDevicesRoleForStrategy(
+            int strategy, int role, @NonNull List<AudioDeviceAttributes> devices) {
+        if (devices.isEmpty()) {
+            return BAD_VALUE;
+        }
+        int[] types = new int[devices.size()];
+        String[] addresses = new String[devices.size()];
+        for (int i = 0; i < devices.size(); ++i) {
+            types[i] = devices.get(i).getInternalType();
+            addresses[i] = devices.get(i).getAddress();
+        }
+        return setDevicesRoleForStrategy(strategy, role, types, addresses);
+    }
+
+    /**
+     * @hide
+     * Set device as role for product strategy.
+     * @param strategy the id of the strategy to configure
+     * @param role the role of the devices
+     * @param types all device types
+     * @param addresses all device addresses
+     * @return {@link #SUCCESS} if successfully set
+     */
+    private static native int setDevicesRoleForStrategy(
+            int strategy, int role, @NonNull int[] types, @NonNull String[] addresses);
+
+    /**
+     * @hide
+     * Remove devices as role for the strategy
+     * @param strategy the id of the strategy to configure
+     * @param role the role of the devices
+     * @return {@link #SUCCESS} if successfully removed
+     */
+    public static native int removeDevicesRoleForStrategy(int strategy, int role);
+
+    /**
+     * @hide
+     * Query previously set devices as role for a strategy
+     * @param strategy the id of the strategy to query for
+     * @param role the role of the devices
+     * @param devices a list that will contain the devices of role
+     * @return {@link #SUCCESS} if there is a preferred device and it was successfully retrieved
+     *     and written to the array
+     */
+    public static native int getDevicesForRoleAndStrategy(
+            int strategy, int role, @NonNull List<AudioDeviceAttributes> devices);
+
+    // use case routing by capture preset
+
+    private static Pair<int[], String[]> populateInputDevicesTypeAndAddress(
+            @NonNull List<AudioDeviceAttributes> devices) {
+        int[] types = new int[devices.size()];
+        String[] addresses = new String[devices.size()];
+        for (int i = 0; i < devices.size(); ++i) {
+            types[i] = devices.get(i).getInternalType();
+            if (types[i] == AudioSystem.DEVICE_NONE) {
+                types[i] = AudioDeviceInfo.convertDeviceTypeToInternalInputDevice(
+                        devices.get(i).getType());
+            }
+            addresses[i] = devices.get(i).getAddress();
+        }
+        return new Pair<int[], String[]>(types, addresses);
+    }
+
+    /**
+     * @hide
+     * Set devices as role for capture preset.
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @param devices the list of devices to be set as role for the given capture preset
+     * @return {@link #SUCCESS} if successfully set
+     */
+    public static int setDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) {
+        if (devices.isEmpty()) {
+            return BAD_VALUE;
+        }
+        Pair<int[], String[]> typeAddresses = populateInputDevicesTypeAndAddress(devices);
+        return setDevicesRoleForCapturePreset(
+                capturePreset, role, typeAddresses.first, typeAddresses.second);
+    }
+
+    /**
+     * @hide
+     * Set devices as role for capture preset.
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @param types all device types
+     * @param addresses all device addresses
+     * @return {@link #SUCCESS} if successfully set
+     */
+    private static native int setDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull int[] types, @NonNull String[] addresses);
+
+    /**
+     * @hide
+     * Add devices as role for capture preset.
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @param devices the list of devices to be added as role for the given capture preset
+     * @return {@link #SUCCESS} if successfully add
+     */
+    public static int addDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) {
+        if (devices.isEmpty()) {
+            return BAD_VALUE;
+        }
+        Pair<int[], String[]> typeAddresses = populateInputDevicesTypeAndAddress(devices);
+        return addDevicesRoleForCapturePreset(
+                capturePreset, role, typeAddresses.first, typeAddresses.second);
+    }
+
+    /**
+     * @hide
+     * Add devices as role for capture preset.
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @param types all device types
+     * @param addresses all device addresses
+     * @return {@link #SUCCESS} if successfully set
+     */
+    private static native int addDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull int[] types, @NonNull String[] addresses);
+
+    /**
+     * @hide
+     * Remove devices as role for the capture preset
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @param devices the devices to be removed
+     * @return {@link #SUCCESS} if successfully removed
+     */
+    public static int removeDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) {
+        if (devices.isEmpty()) {
+            return BAD_VALUE;
+        }
+        Pair<int[], String[]> typeAddresses = populateInputDevicesTypeAndAddress(devices);
+        return removeDevicesRoleForCapturePreset(
+                capturePreset, role, typeAddresses.first, typeAddresses.second);
+    }
+
+    /**
+     * @hide
+     * Remove devices as role for capture preset.
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @param types all device types
+     * @param addresses all device addresses
+     * @return {@link #SUCCESS} if successfully set
+     */
+    private static native int removeDevicesRoleForCapturePreset(
+            int capturePreset, int role, @NonNull int[] types, @NonNull String[] addresses);
+
+    /**
+     * @hide
+     * Remove all devices as role for the capture preset
+     * @param capturePreset the capture preset to configure
+     * @param role the role of the devices
+     * @return {@link #SUCCESS} if successfully removed
+     */
+    public static native int clearDevicesRoleForCapturePreset(int capturePreset, int role);
+
+    /**
+     * @hide
+     * Query previously set devices as role for a capture preset
+     * @param capturePreset the capture preset to query for
+     * @param role the role of the devices
+     * @param devices a list that will contain the devices of role
+     * @return {@link #SUCCESS} if there is a preferred device and it was successfully retrieved
+     *     and written to the array
+     */
+    public static native int getDevicesForRoleAndCapturePreset(
+            int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices);
+
+    /**
+     * @hide
+     * Set the vibrators' information. The value will be used to initialize HapticGenerator.
+     * @param vibrators a list of all available vibrators
+     * @return command completion status
+     */
+    public static native int setVibratorInfos(@NonNull List<Vibrator> vibrators);
+
+    // Items shared with audio service
+
+    /**
+     * @hide
+     * The delay before playing a sound. This small period exists so the user
+     * can press another key (non-volume keys, too) to have it NOT be audible.
+     * <p>
+     * PhoneWindow will implement this part.
+     */
+    public static final int PLAY_SOUND_DELAY = 300;
+
+    /**
+     * @hide
+     * Constant to identify a focus stack entry that is used to hold the focus while the phone
+     * is ringing or during a call. Used by com.android.internal.telephony.CallManager when
+     * entering and exiting calls.
+     */
+    public final static String IN_VOICE_COMM_FOCUS_ID = "AudioFocus_For_Phone_Ring_And_Calls";
+
+    /**
+     * @hide
+     * @see AudioManager#setVibrateSetting(int, int)
+     */
+    public static int getValueForVibrateSetting(int existingValue, int vibrateType,
+            int vibrateSetting) {
+
+        // First clear the existing setting. Each vibrate type has two bits in
+        // the value. Note '3' is '11' in binary.
+        existingValue &= ~(3 << (vibrateType * 2));
+
+        // Set into the old value
+        existingValue |= (vibrateSetting & 3) << (vibrateType * 2);
+
+        return existingValue;
+    }
+
+    /** @hide */
+    public static int getDefaultStreamVolume(int streamType) {
+        return DEFAULT_STREAM_VOLUME[streamType];
+    }
+
+    /** @hide */
+    public static int[] DEFAULT_STREAM_VOLUME = new int[] {
+        4,  // STREAM_VOICE_CALL
+        7,  // STREAM_SYSTEM
+        5,  // STREAM_RING
+        5, // STREAM_MUSIC
+        6,  // STREAM_ALARM
+        5,  // STREAM_NOTIFICATION
+        7,  // STREAM_BLUETOOTH_SCO
+        7,  // STREAM_SYSTEM_ENFORCED
+        5, // STREAM_DTMF
+        5, // STREAM_TTS
+        5, // STREAM_ACCESSIBILITY
+        5, // STREAM_ASSISTANT
+    };
+
+    /** @hide */
+    public static String streamToString(int stream) {
+        if (stream >= 0 && stream < STREAM_NAMES.length) return STREAM_NAMES[stream];
+        if (stream == AudioManager.USE_DEFAULT_STREAM_TYPE) return "USE_DEFAULT_STREAM_TYPE";
+        return "UNKNOWN_STREAM_" + stream;
+    }
+
+    /** @hide The platform has no specific capabilities */
+    public static final int PLATFORM_DEFAULT = 0;
+    /** @hide The platform is voice call capable (a phone) */
+    public static final int PLATFORM_VOICE = 1;
+    /** @hide The platform is a television or a set-top box */
+    public static final int PLATFORM_TELEVISION = 2;
+
+    /**
+     * @hide
+     * Return the platform type that this is running on. One of:
+     * <ul>
+     * <li>{@link #PLATFORM_VOICE}</li>
+     * <li>{@link #PLATFORM_TELEVISION}</li>
+     * <li>{@link #PLATFORM_DEFAULT}</li>
+     * </ul>
+     */
+    public static int getPlatformType(Context context) {
+        if (((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE))
+                .isVoiceCapable()) {
+            return PLATFORM_VOICE;
+        } else if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_LEANBACK)) {
+            return PLATFORM_TELEVISION;
+        } else {
+            return PLATFORM_DEFAULT;
+        }
+    }
+
+    /**
+     * @hide
+     * @return whether the system uses a single volume stream.
+     */
+    public static boolean isSingleVolume(Context context) {
+        boolean forceSingleVolume = context.getResources().getBoolean(
+                com.android.internal.R.bool.config_single_volume);
+        return getPlatformType(context) == PLATFORM_TELEVISION || forceSingleVolume;
+    }
+
+    /**
+     * @hide
+     * Return a set of audio device types from a bit mask audio device type, which may
+     * represent multiple audio device types.
+     * FIXME: Remove this when getting ride of bit mask usage of audio device types.
+     */
+    public static Set<Integer> generateAudioDeviceTypesSet(int types) {
+        Set<Integer> deviceTypes = new HashSet<>();
+        Set<Integer> allDeviceTypes =
+                (types & DEVICE_BIT_IN) == 0 ? DEVICE_OUT_ALL_SET : DEVICE_IN_ALL_SET;
+        for (int deviceType : allDeviceTypes) {
+            if ((types & deviceType) == deviceType) {
+                deviceTypes.add(deviceType);
+            }
+        }
+        return deviceTypes;
+    }
+
+    /**
+     * @hide
+     * Return the intersection of two audio device types collections.
+     */
+    public static Set<Integer> intersectionAudioDeviceTypes(
+            @NonNull Set<Integer> a, @NonNull Set<Integer> b) {
+        Set<Integer> intersection = new HashSet<>(a);
+        intersection.retainAll(b);
+        return intersection;
+    }
+
+    /**
+     * @hide
+     * Return true if the audio device types collection only contains the given device type.
+     */
+    public static boolean isSingleAudioDeviceType(@NonNull Set<Integer> types, int type) {
+        return types.size() == 1 && types.contains(type);
+    }
+
+    /** @hide */
+    public static final int DEFAULT_MUTE_STREAMS_AFFECTED =
+            (1 << STREAM_MUSIC) |
+            (1 << STREAM_RING) |
+            (1 << STREAM_NOTIFICATION) |
+            (1 << STREAM_SYSTEM) |
+            (1 << STREAM_VOICE_CALL) |
+            (1 << STREAM_BLUETOOTH_SCO);
+
+    /**
+     * @hide
+     * Event posted by AudioTrack and AudioRecord JNI (JNIDeviceCallback) when routing changes.
+     * Keep in sync with core/jni/android_media_DeviceCallback.h.
+     */
+    final static int NATIVE_EVENT_ROUTING_CHANGE = 1000;
+}
+
diff --git a/android/media/AudioTimestamp.java b/android/media/AudioTimestamp.java
new file mode 100644
index 0000000..be8ca15
--- /dev/null
+++ b/android/media/AudioTimestamp.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2013 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 java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import android.annotation.IntDef;
+
+/**
+ * Structure that groups a position in frame units relative to an assumed audio stream,
+ * together with the estimated time when that frame enters or leaves the audio
+ * processing pipeline on that device. This can be used to coordinate events
+ * and interactions with the external environment.
+ * <p>
+ * The time is based on the implementation's best effort, using whatever knowledge
+ * is available to the system, but cannot account for any delay unknown to the implementation.
+ *
+ * @see AudioTrack#getTimestamp AudioTrack.getTimestamp(AudioTimestamp)
+ * @see AudioRecord#getTimestamp AudioRecord.getTimestamp(AudioTimestamp, int)
+ */
+public final class AudioTimestamp
+{
+    /**
+     * Clock monotonic or its equivalent on the system,
+     * in the same units and timebase as {@link java.lang.System#nanoTime}.
+     */
+    public static final int TIMEBASE_MONOTONIC = 0;
+
+    /**
+     * Clock monotonic including suspend time or its equivalent on the system,
+     * in the same units and timebase as {@link android.os.SystemClock#elapsedRealtimeNanos}.
+     */
+    public static final int TIMEBASE_BOOTTIME = 1;
+
+    /** @hide */
+    @IntDef({
+        TIMEBASE_MONOTONIC,
+        TIMEBASE_BOOTTIME,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Timebase {}
+
+    /**
+     * Position in frames relative to start of an assumed audio stream.
+     * <p>
+     * When obtained through
+     * {@link AudioRecord#getTimestamp AudioRecord.getTimestamp(AudioTimestamp, int)},
+     * all 64 bits of position are valid.
+     * <p>
+     * When obtained through
+     * {@link AudioTrack#getTimestamp AudioTrack.getTimestamp(AudioTimestamp)},
+     * the low-order 32 bits of position is in wrapping frame units similar to
+     * {@link AudioTrack#getPlaybackHeadPosition AudioTrack.getPlaybackHeadPosition()}.
+     */
+    public long framePosition;
+
+    /**
+     * Time associated with the frame in the audio pipeline.
+     * <p>
+     * When obtained through
+     * {@link AudioRecord#getTimestamp AudioRecord.getTimestamp(AudioTimestamp, int)},
+     * this is the estimated time in nanoseconds when the frame referred to by
+     * {@link #framePosition} was captured. The timebase is either
+     * {@link #TIMEBASE_MONOTONIC} or {@link #TIMEBASE_BOOTTIME}, depending
+     * on the timebase parameter used in
+     * {@link AudioRecord#getTimestamp AudioRecord.getTimestamp(AudioTimestamp, int)}.
+     * <p>
+     * When obtained through
+     * {@link AudioTrack#getTimestamp AudioTrack.getTimestamp(AudioTimestamp)},
+     * this is the estimated time when the frame was presented or is committed to be presented,
+     * with a timebase of {@link #TIMEBASE_MONOTONIC}.
+     */
+    public long nanoTime;
+}
diff --git a/android/media/AudioTrack.java b/android/media/AudioTrack.java
new file mode 100644
index 0000000..23d9532
--- /dev/null
+++ b/android/media/AudioTrack.java
@@ -0,0 +1,4482 @@
+/*
+ * Copyright (C) 2008 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.annotation.CallbackExecutor;
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.media.metrics.LogSessionId;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.NioUtils;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * The AudioTrack class manages and plays a single audio resource for Java applications.
+ * It allows streaming of PCM audio buffers to the audio sink for playback. This is
+ * achieved by "pushing" the data to the AudioTrack object using one of the
+ *  {@link #write(byte[], int, int)}, {@link #write(short[], int, int)},
+ *  and {@link #write(float[], int, int, int)} methods.
+ *
+ * <p>An AudioTrack instance can operate under two modes: static or streaming.<br>
+ * In Streaming mode, the application writes a continuous stream of data to the AudioTrack, using
+ * one of the {@code write()} methods. These are blocking and return when the data has been
+ * transferred from the Java layer to the native layer and queued for playback. The streaming
+ * mode is most useful when playing blocks of audio data that for instance are:
+ *
+ * <ul>
+ *   <li>too big to fit in memory because of the duration of the sound to play,</li>
+ *   <li>too big to fit in memory because of the characteristics of the audio data
+ *         (high sampling rate, bits per sample ...)</li>
+ *   <li>received or generated while previously queued audio is playing.</li>
+ * </ul>
+ *
+ * The static mode should be chosen when dealing with short sounds that fit in memory and
+ * that need to be played with the smallest latency possible. The static mode will
+ * therefore be preferred for UI and game sounds that are played often, and with the
+ * smallest overhead possible.
+ *
+ * <p>Upon creation, an AudioTrack object initializes its associated audio buffer.
+ * The size of this buffer, specified during the construction, determines how long an AudioTrack
+ * can play before running out of data.<br>
+ * For an AudioTrack using the static mode, this size is the maximum size of the sound that can
+ * be played from it.<br>
+ * For the streaming mode, data will be written to the audio sink in chunks of
+ * sizes less than or equal to the total buffer size.
+ *
+ * AudioTrack is not final and thus permits subclasses, but such use is not recommended.
+ */
+public class AudioTrack extends PlayerBase
+                        implements AudioRouting
+                                 , VolumeAutomation
+{
+    //---------------------------------------------------------
+    // Constants
+    //--------------------
+    /** Minimum value for a linear gain or auxiliary effect level.
+     *  This value must be exactly equal to 0.0f; do not change it.
+     */
+    private static final float GAIN_MIN = 0.0f;
+    /** Maximum value for a linear gain or auxiliary effect level.
+     *  This value must be greater than or equal to 1.0f.
+     */
+    private static final float GAIN_MAX = 1.0f;
+
+    /** indicates AudioTrack state is stopped */
+    public static final int PLAYSTATE_STOPPED = 1;  // matches SL_PLAYSTATE_STOPPED
+    /** indicates AudioTrack state is paused */
+    public static final int PLAYSTATE_PAUSED  = 2;  // matches SL_PLAYSTATE_PAUSED
+    /** indicates AudioTrack state is playing */
+    public static final int PLAYSTATE_PLAYING = 3;  // matches SL_PLAYSTATE_PLAYING
+    /**
+      * @hide
+      * indicates AudioTrack state is stopping waiting for NATIVE_EVENT_STREAM_END to
+      * transition to PLAYSTATE_STOPPED.
+      * Only valid for offload mode.
+      */
+    private static final int PLAYSTATE_STOPPING = 4;
+    /**
+      * @hide
+      * indicates AudioTrack state is paused from stopping state. Will transition to
+      * PLAYSTATE_STOPPING if play() is called.
+      * Only valid for offload mode.
+      */
+    private static final int PLAYSTATE_PAUSED_STOPPING = 5;
+
+    // keep these values in sync with android_media_AudioTrack.cpp
+    /**
+     * Creation mode where audio data is transferred from Java to the native layer
+     * only once before the audio starts playing.
+     */
+    public static final int MODE_STATIC = 0;
+    /**
+     * Creation mode where audio data is streamed from Java to the native layer
+     * as the audio is playing.
+     */
+    public static final int MODE_STREAM = 1;
+
+    /** @hide */
+    @IntDef({
+        MODE_STATIC,
+        MODE_STREAM
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TransferMode {}
+
+    /**
+     * State of an AudioTrack that was not successfully initialized upon creation.
+     */
+    public static final int STATE_UNINITIALIZED = 0;
+    /**
+     * State of an AudioTrack that is ready to be used.
+     */
+    public static final int STATE_INITIALIZED   = 1;
+    /**
+     * State of a successfully initialized AudioTrack that uses static data,
+     * but that hasn't received that data yet.
+     */
+    public static final int STATE_NO_STATIC_DATA = 2;
+
+    /**
+     * Denotes a successful operation.
+     */
+    public  static final int SUCCESS                               = AudioSystem.SUCCESS;
+    /**
+     * Denotes a generic operation failure.
+     */
+    public  static final int ERROR                                 = AudioSystem.ERROR;
+    /**
+     * Denotes a failure due to the use of an invalid value.
+     */
+    public  static final int ERROR_BAD_VALUE                       = AudioSystem.BAD_VALUE;
+    /**
+     * Denotes a failure due to the improper use of a method.
+     */
+    public  static final int ERROR_INVALID_OPERATION               = AudioSystem.INVALID_OPERATION;
+    /**
+     * An error code indicating that the object reporting it is no longer valid and needs to
+     * be recreated.
+     */
+    public  static final int ERROR_DEAD_OBJECT                     = AudioSystem.DEAD_OBJECT;
+    /**
+     * {@link #getTimestampWithStatus(AudioTimestamp)} is called in STOPPED or FLUSHED state,
+     * or immediately after start/ACTIVE.
+     * @hide
+     */
+    public  static final int ERROR_WOULD_BLOCK                     = AudioSystem.WOULD_BLOCK;
+
+    // Error codes:
+    // to keep in sync with frameworks/base/core/jni/android_media_AudioTrack.cpp
+    private static final int ERROR_NATIVESETUP_AUDIOSYSTEM         = -16;
+    private static final int ERROR_NATIVESETUP_INVALIDCHANNELMASK  = -17;
+    private static final int ERROR_NATIVESETUP_INVALIDFORMAT       = -18;
+    private static final int ERROR_NATIVESETUP_INVALIDSTREAMTYPE   = -19;
+    private static final int ERROR_NATIVESETUP_NATIVEINITFAILED    = -20;
+
+    // Events:
+    // to keep in sync with frameworks/av/include/media/AudioTrack.h
+    // Note: To avoid collisions with other event constants,
+    // do not define an event here that is the same value as
+    // AudioSystem.NATIVE_EVENT_ROUTING_CHANGE.
+
+    /**
+     * Event id denotes when playback head has reached a previously set marker.
+     */
+    private static final int NATIVE_EVENT_MARKER  = 3;
+    /**
+     * Event id denotes when previously set update period has elapsed during playback.
+     */
+    private static final int NATIVE_EVENT_NEW_POS = 4;
+    /**
+     * Callback for more data
+     */
+    private static final int NATIVE_EVENT_CAN_WRITE_MORE_DATA = 9;
+    /**
+     * IAudioTrack tear down for offloaded tracks
+     * TODO: when received, java AudioTrack must be released
+     */
+    private static final int NATIVE_EVENT_NEW_IAUDIOTRACK = 6;
+    /**
+     * Event id denotes when all the buffers queued in AF and HW are played
+     * back (after stop is called) for an offloaded track.
+     */
+    private static final int NATIVE_EVENT_STREAM_END = 7;
+    /**
+     * Event id denotes when the codec format changes.
+     *
+     * Note: Similar to a device routing change (AudioSystem.NATIVE_EVENT_ROUTING_CHANGE),
+     * this event comes from the AudioFlinger Thread / Output Stream management
+     * (not from buffer indications as above).
+     */
+    private static final int NATIVE_EVENT_CODEC_FORMAT_CHANGE = 100;
+
+    private final static String TAG = "android.media.AudioTrack";
+
+    /** @hide */
+    @IntDef({
+        ENCAPSULATION_MODE_NONE,
+        ENCAPSULATION_MODE_ELEMENTARY_STREAM,
+        // ENCAPSULATION_MODE_HANDLE, @SystemApi
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EncapsulationMode {}
+
+    // Important: The ENCAPSULATION_MODE values must be kept in sync with native header files.
+    /**
+     * This mode indicates no metadata encapsulation,
+     * which is the default mode for sending audio data
+     * through {@code AudioTrack}.
+     */
+    public static final int ENCAPSULATION_MODE_NONE = 0;
+    /**
+     * This mode indicates metadata encapsulation with an elementary stream payload.
+     * Both compressed and PCM format is allowed.
+     */
+    public static final int ENCAPSULATION_MODE_ELEMENTARY_STREAM = 1;
+    /**
+     * This mode indicates metadata encapsulation with a handle payload
+     * and is set through {@link Builder#setEncapsulationMode(int)}.
+     * The handle is a 64 bit long, provided by the Tuner API
+     * in {@link android.os.Build.VERSION_CODES#R}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+    public static final int ENCAPSULATION_MODE_HANDLE = 2;
+
+    /* Enumeration of metadata types permitted for use by
+     * encapsulation mode audio streams.
+     */
+    /** @hide */
+    @IntDef(prefix = { "ENCAPSULATION_METADATA_TYPE_" }, value = {
+        ENCAPSULATION_METADATA_TYPE_NONE, /* reserved */
+        ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER,
+        ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface EncapsulationMetadataType {}
+
+    /**
+     * Reserved do not use.
+     * @hide
+     */
+    public static final int ENCAPSULATION_METADATA_TYPE_NONE = 0; // reserved
+
+    /**
+     * Encapsulation metadata type for framework tuner information.
+     *
+     * Refer to the Android Media TV Tuner API for details.
+     */
+    public static final int ENCAPSULATION_METADATA_TYPE_FRAMEWORK_TUNER = 1;
+
+    /**
+     * Encapsulation metadata type for DVB AD descriptor.
+     *
+     * This metadata is formatted per ETSI TS 101 154 Table E.1: AD_descriptor.
+     */
+    public static final int ENCAPSULATION_METADATA_TYPE_DVB_AD_DESCRIPTOR = 2;
+
+    /* Dual Mono handling is used when a stereo audio stream
+     * contains separate audio content on the left and right channels.
+     * Such information about the content of the stream may be found, for example, in
+     * ITU T-REC-J.94-201610 A.6.2.3 Component descriptor.
+     */
+    /** @hide */
+    @IntDef({
+        DUAL_MONO_MODE_OFF,
+        DUAL_MONO_MODE_LR,
+        DUAL_MONO_MODE_LL,
+        DUAL_MONO_MODE_RR,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DualMonoMode {}
+    // Important: The DUAL_MONO_MODE values must be kept in sync with native header files.
+    /**
+     * This mode disables any Dual Mono presentation effect.
+     *
+     */
+    public static final int DUAL_MONO_MODE_OFF = 0;
+
+    /**
+     * This mode indicates that a stereo stream should be presented
+     * with the left and right audio channels blended together
+     * and delivered to both channels.
+     *
+     * Behavior for non-stereo streams is implementation defined.
+     * A suggested guideline is that the left-right stereo symmetric
+     * channels are pairwise blended;
+     * the other channels such as center are left alone.
+     *
+     * The Dual Mono effect occurs before volume scaling.
+     */
+    public static final int DUAL_MONO_MODE_LR = 1;
+
+    /**
+     * This mode indicates that a stereo stream should be presented
+     * with the left audio channel replicated into the right audio channel.
+     *
+     * Behavior for non-stereo streams is implementation defined.
+     * A suggested guideline is that all channels with left-right
+     * stereo symmetry will have the left channel position replicated
+     * into the right channel position.
+     * The center channels (with no left/right symmetry) or unbalanced
+     * channels are left alone.
+     *
+     * The Dual Mono effect occurs before volume scaling.
+     */
+    public static final int DUAL_MONO_MODE_LL = 2;
+
+    /**
+     * This mode indicates that a stereo stream should be presented
+     * with the right audio channel replicated into the left audio channel.
+     *
+     * Behavior for non-stereo streams is implementation defined.
+     * A suggested guideline is that all channels with left-right
+     * stereo symmetry will have the right channel position replicated
+     * into the left channel position.
+     * The center channels (with no left/right symmetry) or unbalanced
+     * channels are left alone.
+     *
+     * The Dual Mono effect occurs before volume scaling.
+     */
+    public static final int DUAL_MONO_MODE_RR = 3;
+
+    /** @hide */
+    @IntDef({
+        WRITE_BLOCKING,
+        WRITE_NON_BLOCKING
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface WriteMode {}
+
+    /**
+     * The write mode indicating the write operation will block until all data has been written,
+     * to be used as the actual value of the writeMode parameter in
+     * {@link #write(byte[], int, int, int)}, {@link #write(short[], int, int, int)},
+     * {@link #write(float[], int, int, int)}, {@link #write(ByteBuffer, int, int)}, and
+     * {@link #write(ByteBuffer, int, int, long)}.
+     */
+    public final static int WRITE_BLOCKING = 0;
+
+    /**
+     * The write mode indicating the write operation will return immediately after
+     * queuing as much audio data for playback as possible without blocking,
+     * to be used as the actual value of the writeMode parameter in
+     * {@link #write(ByteBuffer, int, int)}, {@link #write(short[], int, int, int)},
+     * {@link #write(float[], int, int, int)}, {@link #write(ByteBuffer, int, int)}, and
+     * {@link #write(ByteBuffer, int, int, long)}.
+     */
+    public final static int WRITE_NON_BLOCKING = 1;
+
+    /** @hide */
+    @IntDef({
+        PERFORMANCE_MODE_NONE,
+        PERFORMANCE_MODE_LOW_LATENCY,
+        PERFORMANCE_MODE_POWER_SAVING
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PerformanceMode {}
+
+    /**
+     * Default performance mode for an {@link AudioTrack}.
+     */
+    public static final int PERFORMANCE_MODE_NONE = 0;
+
+    /**
+     * Low latency performance mode for an {@link AudioTrack}.
+     * If the device supports it, this mode
+     * enables a lower latency path through to the audio output sink.
+     * Effects may no longer work with such an {@code AudioTrack} and
+     * the sample rate must match that of the output sink.
+     * <p>
+     * Applications should be aware that low latency requires careful
+     * buffer management, with smaller chunks of audio data written by each
+     * {@code write()} call.
+     * <p>
+     * If this flag is used without specifying a {@code bufferSizeInBytes} then the
+     * {@code AudioTrack}'s actual buffer size may be too small.
+     * It is recommended that a fairly
+     * large buffer should be specified when the {@code AudioTrack} is created.
+     * Then the actual size can be reduced by calling
+     * {@link #setBufferSizeInFrames(int)}. The buffer size can be optimized
+     * by lowering it after each {@code write()} call until the audio glitches,
+     * which is detected by calling
+     * {@link #getUnderrunCount()}. Then the buffer size can be increased
+     * until there are no glitches.
+     * This tuning step should be done while playing silence.
+     * This technique provides a compromise between latency and glitch rate.
+     */
+    public static final int PERFORMANCE_MODE_LOW_LATENCY = 1;
+
+    /**
+     * Power saving performance mode for an {@link AudioTrack}.
+     * If the device supports it, this
+     * mode will enable a lower power path to the audio output sink.
+     * In addition, this lower power path typically will have
+     * deeper internal buffers and better underrun resistance,
+     * with a tradeoff of higher latency.
+     * <p>
+     * In this mode, applications should attempt to use a larger buffer size
+     * and deliver larger chunks of audio data per {@code write()} call.
+     * Use {@link #getBufferSizeInFrames()} to determine
+     * the actual buffer size of the {@code AudioTrack} as it may have increased
+     * to accommodate a deeper buffer.
+     */
+    public static final int PERFORMANCE_MODE_POWER_SAVING = 2;
+
+    // keep in sync with system/media/audio/include/system/audio-base.h
+    private static final int AUDIO_OUTPUT_FLAG_FAST = 0x4;
+    private static final int AUDIO_OUTPUT_FLAG_DEEP_BUFFER = 0x8;
+
+    // Size of HW_AV_SYNC track AV header.
+    private static final float HEADER_V2_SIZE_BYTES = 20.0f;
+
+    //--------------------------------------------------------------------------
+    // Member variables
+    //--------------------
+    /**
+     * Indicates the state of the AudioTrack instance.
+     * One of STATE_UNINITIALIZED, STATE_INITIALIZED, or STATE_NO_STATIC_DATA.
+     */
+    private int mState = STATE_UNINITIALIZED;
+    /**
+     * Indicates the play state of the AudioTrack instance.
+     * One of PLAYSTATE_STOPPED, PLAYSTATE_PAUSED, or PLAYSTATE_PLAYING.
+     */
+    private int mPlayState = PLAYSTATE_STOPPED;
+
+    /**
+     * Indicates that we are expecting an end of stream callback following a call
+     * to setOffloadEndOfStream() in a gapless track transition context. The native track
+     * will be restarted automatically.
+     */
+    private boolean mOffloadEosPending = false;
+
+    /**
+     * Lock to ensure mPlayState updates reflect the actual state of the object.
+     */
+    private final Object mPlayStateLock = new Object();
+    /**
+     * Sizes of the audio buffer.
+     * These values are set during construction and can be stale.
+     * To obtain the current audio buffer frame count use {@link #getBufferSizeInFrames()}.
+     */
+    private int mNativeBufferSizeInBytes = 0;
+    private int mNativeBufferSizeInFrames = 0;
+    /**
+     * Handler for events coming from the native code.
+     */
+    private NativePositionEventHandlerDelegate mEventHandlerDelegate;
+    /**
+     * Looper associated with the thread that creates the AudioTrack instance.
+     */
+    private final Looper mInitializationLooper;
+    /**
+     * The audio data source sampling rate in Hz.
+     * Never {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED}.
+     */
+    private int mSampleRate; // initialized by all constructors via audioParamCheck()
+    /**
+     * The number of audio output channels (1 is mono, 2 is stereo, etc.).
+     */
+    private int mChannelCount = 1;
+    /**
+     * The audio channel mask used for calling native AudioTrack
+     */
+    private int mChannelMask = AudioFormat.CHANNEL_OUT_MONO;
+
+    /**
+     * The type of the audio stream to play. See
+     *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
+     *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
+     *   {@link AudioManager#STREAM_ALARM}, {@link AudioManager#STREAM_NOTIFICATION}, and
+     *   {@link AudioManager#STREAM_DTMF}.
+     */
+    @UnsupportedAppUsage
+    private int mStreamType = AudioManager.STREAM_MUSIC;
+
+    /**
+     * The way audio is consumed by the audio sink, one of MODE_STATIC or MODE_STREAM.
+     */
+    private int mDataLoadMode = MODE_STREAM;
+    /**
+     * The current channel position mask, as specified on AudioTrack creation.
+     * Can be set simultaneously with channel index mask {@link #mChannelIndexMask}.
+     * May be set to {@link AudioFormat#CHANNEL_INVALID} if a channel index mask is specified.
+     */
+    private int mChannelConfiguration = AudioFormat.CHANNEL_OUT_MONO;
+    /**
+     * The channel index mask if specified, otherwise 0.
+     */
+    private int mChannelIndexMask = 0;
+    /**
+     * The encoding of the audio samples.
+     * @see AudioFormat#ENCODING_PCM_8BIT
+     * @see AudioFormat#ENCODING_PCM_16BIT
+     * @see AudioFormat#ENCODING_PCM_FLOAT
+     */
+    private int mAudioFormat;   // initialized by all constructors via audioParamCheck()
+    /**
+     * The AudioAttributes used in configuration.
+     */
+    private AudioAttributes mConfiguredAudioAttributes;
+    /**
+     * Audio session ID
+     */
+    private int mSessionId = AudioManager.AUDIO_SESSION_ID_GENERATE;
+    /**
+     * HW_AV_SYNC track AV Sync Header
+     */
+    private ByteBuffer mAvSyncHeader = null;
+    /**
+     * HW_AV_SYNC track audio data bytes remaining to write after current AV sync header
+     */
+    private int mAvSyncBytesRemaining = 0;
+    /**
+     * Offset of the first sample of the audio in byte from start of HW_AV_SYNC track AV header.
+     */
+    private int mOffset = 0;
+    /**
+     * Indicates whether the track is intended to play in offload mode.
+     */
+    private boolean mOffloaded = false;
+    /**
+     * When offloaded track: delay for decoder in frames
+     */
+    private int mOffloadDelayFrames = 0;
+    /**
+     * When offloaded track: padding for decoder in frames
+     */
+    private int mOffloadPaddingFrames = 0;
+
+    /**
+     * The log session id used for metrics.
+     * {@link LogSessionId#LOG_SESSION_ID_NONE} here means it is not set.
+     */
+    @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;
+
+    //--------------------------------
+    // Used exclusively by native code
+    //--------------------
+    /**
+     * @hide
+     * Accessed by native methods: provides access to C++ AudioTrack object.
+     */
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage
+    protected long mNativeTrackInJavaObj;
+    /**
+     * Accessed by native methods: provides access to the JNI data (i.e. resources used by
+     * the native AudioTrack object, but not stored in it).
+     */
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private long mJniData;
+
+
+    //--------------------------------------------------------------------------
+    // Constructor, Finalize
+    //--------------------
+    /**
+     * Class constructor.
+     * @param streamType the type of the audio stream. See
+     *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
+     *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
+     *   {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
+     * @param sampleRateInHz the initial source sample rate expressed in Hz.
+     *   {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED} means to use a route-dependent value
+     *   which is usually the sample rate of the sink.
+     *   {@link #getSampleRate()} can be used to retrieve the actual sample rate chosen.
+     * @param channelConfig describes the configuration of the audio channels.
+     *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
+     *   {@link AudioFormat#CHANNEL_OUT_STEREO}
+     * @param audioFormat the format in which the audio data is represented.
+     *   See {@link AudioFormat#ENCODING_PCM_16BIT},
+     *   {@link AudioFormat#ENCODING_PCM_8BIT},
+     *   and {@link AudioFormat#ENCODING_PCM_FLOAT}.
+     * @param bufferSizeInBytes the total size (in bytes) of the internal buffer where audio data is
+     *   read from for playback. This should be a nonzero multiple of the frame size in bytes.
+     *   <p> If the track's creation mode is {@link #MODE_STATIC},
+     *   this is the maximum length sample, or audio clip, that can be played by this instance.
+     *   <p> If the track's creation mode is {@link #MODE_STREAM},
+     *   this should be the desired buffer size
+     *   for the <code>AudioTrack</code> to satisfy the application's
+     *   latency requirements.
+     *   If <code>bufferSizeInBytes</code> is less than the
+     *   minimum buffer size for the output sink, it is increased to the minimum
+     *   buffer size.
+     *   The method {@link #getBufferSizeInFrames()} returns the
+     *   actual size in frames of the buffer created, which
+     *   determines the minimum frequency to write
+     *   to the streaming <code>AudioTrack</code> to avoid underrun.
+     *   See {@link #getMinBufferSize(int, int, int)} to determine the estimated minimum buffer size
+     *   for an AudioTrack instance in streaming mode.
+     * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
+     * @throws java.lang.IllegalArgumentException
+     * @deprecated use {@link Builder} or
+     *   {@link #AudioTrack(AudioAttributes, AudioFormat, int, int, int)} to specify the
+     *   {@link AudioAttributes} instead of the stream type which is only for volume control.
+     */
+    public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
+            int bufferSizeInBytes, int mode)
+    throws IllegalArgumentException {
+        this(streamType, sampleRateInHz, channelConfig, audioFormat,
+                bufferSizeInBytes, mode, AudioManager.AUDIO_SESSION_ID_GENERATE);
+    }
+
+    /**
+     * Class constructor with audio session. Use this constructor when the AudioTrack must be
+     * attached to a particular audio session. The primary use of the audio session ID is to
+     * associate audio effects to a particular instance of AudioTrack: if an audio session ID
+     * is provided when creating an AudioEffect, this effect will be applied only to audio tracks
+     * and media players in the same session and not to the output mix.
+     * When an AudioTrack is created without specifying a session, it will create its own session
+     * which can be retrieved by calling the {@link #getAudioSessionId()} method.
+     * If a non-zero session ID is provided, this AudioTrack will share effects attached to this
+     * session
+     * with all other media players or audio tracks in the same session, otherwise a new session
+     * will be created for this track if none is supplied.
+     * @param streamType the type of the audio stream. See
+     *   {@link AudioManager#STREAM_VOICE_CALL}, {@link AudioManager#STREAM_SYSTEM},
+     *   {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_MUSIC},
+     *   {@link AudioManager#STREAM_ALARM}, and {@link AudioManager#STREAM_NOTIFICATION}.
+     * @param sampleRateInHz the initial source sample rate expressed in Hz.
+     *   {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED} means to use a route-dependent value
+     *   which is usually the sample rate of the sink.
+     * @param channelConfig describes the configuration of the audio channels.
+     *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
+     *   {@link AudioFormat#CHANNEL_OUT_STEREO}
+     * @param audioFormat the format in which the audio data is represented.
+     *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
+     *   {@link AudioFormat#ENCODING_PCM_8BIT},
+     *   and {@link AudioFormat#ENCODING_PCM_FLOAT}.
+     * @param bufferSizeInBytes the total size (in bytes) of the internal buffer where audio data is
+     *   read from for playback. This should be a nonzero multiple of the frame size in bytes.
+     *   <p> If the track's creation mode is {@link #MODE_STATIC},
+     *   this is the maximum length sample, or audio clip, that can be played by this instance.
+     *   <p> If the track's creation mode is {@link #MODE_STREAM},
+     *   this should be the desired buffer size
+     *   for the <code>AudioTrack</code> to satisfy the application's
+     *   latency requirements.
+     *   If <code>bufferSizeInBytes</code> is less than the
+     *   minimum buffer size for the output sink, it is increased to the minimum
+     *   buffer size.
+     *   The method {@link #getBufferSizeInFrames()} returns the
+     *   actual size in frames of the buffer created, which
+     *   determines the minimum frequency to write
+     *   to the streaming <code>AudioTrack</code> to avoid underrun.
+     *   You can write data into this buffer in smaller chunks than this size.
+     *   See {@link #getMinBufferSize(int, int, int)} to determine the estimated minimum buffer size
+     *   for an AudioTrack instance in streaming mode.
+     * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}
+     * @param sessionId Id of audio session the AudioTrack must be attached to
+     * @throws java.lang.IllegalArgumentException
+     * @deprecated use {@link Builder} or
+     *   {@link #AudioTrack(AudioAttributes, AudioFormat, int, int, int)} to specify the
+     *   {@link AudioAttributes} instead of the stream type which is only for volume control.
+     */
+    public AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat,
+            int bufferSizeInBytes, int mode, int sessionId)
+    throws IllegalArgumentException {
+        // mState already == STATE_UNINITIALIZED
+        this((new AudioAttributes.Builder())
+                    .setLegacyStreamType(streamType)
+                    .build(),
+                (new AudioFormat.Builder())
+                    .setChannelMask(channelConfig)
+                    .setEncoding(audioFormat)
+                    .setSampleRate(sampleRateInHz)
+                    .build(),
+                bufferSizeInBytes,
+                mode, sessionId);
+        deprecateStreamTypeForPlayback(streamType, "AudioTrack", "AudioTrack()");
+    }
+
+    /**
+     * Class constructor with {@link AudioAttributes} and {@link AudioFormat}.
+     * @param attributes a non-null {@link AudioAttributes} instance.
+     * @param format a non-null {@link AudioFormat} instance describing the format of the data
+     *     that will be played through this AudioTrack. See {@link AudioFormat.Builder} for
+     *     configuring the audio format parameters such as encoding, channel mask and sample rate.
+     * @param bufferSizeInBytes the total size (in bytes) of the internal buffer where audio data is
+     *   read from for playback. This should be a nonzero multiple of the frame size in bytes.
+     *   <p> If the track's creation mode is {@link #MODE_STATIC},
+     *   this is the maximum length sample, or audio clip, that can be played by this instance.
+     *   <p> If the track's creation mode is {@link #MODE_STREAM},
+     *   this should be the desired buffer size
+     *   for the <code>AudioTrack</code> to satisfy the application's
+     *   latency requirements.
+     *   If <code>bufferSizeInBytes</code> is less than the
+     *   minimum buffer size for the output sink, it is increased to the minimum
+     *   buffer size.
+     *   The method {@link #getBufferSizeInFrames()} returns the
+     *   actual size in frames of the buffer created, which
+     *   determines the minimum frequency to write
+     *   to the streaming <code>AudioTrack</code> to avoid underrun.
+     *   See {@link #getMinBufferSize(int, int, int)} to determine the estimated minimum buffer size
+     *   for an AudioTrack instance in streaming mode.
+     * @param mode streaming or static buffer. See {@link #MODE_STATIC} and {@link #MODE_STREAM}.
+     * @param sessionId ID of audio session the AudioTrack must be attached to, or
+     *   {@link AudioManager#AUDIO_SESSION_ID_GENERATE} if the session isn't known at construction
+     *   time. See also {@link AudioManager#generateAudioSessionId()} to obtain a session ID before
+     *   construction.
+     * @throws IllegalArgumentException
+     */
+    public AudioTrack(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
+            int mode, int sessionId)
+                    throws IllegalArgumentException {
+        this(attributes, format, bufferSizeInBytes, mode, sessionId, false /*offload*/,
+                ENCAPSULATION_MODE_NONE, null /* tunerConfiguration */);
+    }
+
+    private AudioTrack(AudioAttributes attributes, AudioFormat format, int bufferSizeInBytes,
+            int mode, int sessionId, boolean offload, int encapsulationMode,
+            @Nullable TunerConfiguration tunerConfiguration)
+                    throws IllegalArgumentException {
+        super(attributes, AudioPlaybackConfiguration.PLAYER_TYPE_JAM_AUDIOTRACK);
+        // mState already == STATE_UNINITIALIZED
+
+        mConfiguredAudioAttributes = attributes; // object copy not needed, immutable.
+
+        if (format == null) {
+            throw new IllegalArgumentException("Illegal null AudioFormat");
+        }
+
+        // Check if we should enable deep buffer mode
+        if (shouldEnablePowerSaving(mAttributes, format, bufferSizeInBytes, mode)) {
+            mAttributes = new AudioAttributes.Builder(mAttributes)
+                .replaceFlags((mAttributes.getAllFlags()
+                        | AudioAttributes.FLAG_DEEP_BUFFER)
+                        & ~AudioAttributes.FLAG_LOW_LATENCY)
+                .build();
+        }
+
+        // remember which looper is associated with the AudioTrack instantiation
+        Looper looper;
+        if ((looper = Looper.myLooper()) == null) {
+            looper = Looper.getMainLooper();
+        }
+
+        int rate = format.getSampleRate();
+        if (rate == AudioFormat.SAMPLE_RATE_UNSPECIFIED) {
+            rate = 0;
+        }
+
+        int channelIndexMask = 0;
+        if ((format.getPropertySetMask()
+                & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_INDEX_MASK) != 0) {
+            channelIndexMask = format.getChannelIndexMask();
+        }
+        int channelMask = 0;
+        if ((format.getPropertySetMask()
+                & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_CHANNEL_MASK) != 0) {
+            channelMask = format.getChannelMask();
+        } else if (channelIndexMask == 0) { // if no masks at all, use stereo
+            channelMask = AudioFormat.CHANNEL_OUT_FRONT_LEFT
+                    | AudioFormat.CHANNEL_OUT_FRONT_RIGHT;
+        }
+        int encoding = AudioFormat.ENCODING_DEFAULT;
+        if ((format.getPropertySetMask() & AudioFormat.AUDIO_FORMAT_HAS_PROPERTY_ENCODING) != 0) {
+            encoding = format.getEncoding();
+        }
+        audioParamCheck(rate, channelMask, channelIndexMask, encoding, mode);
+        mOffloaded = offload;
+        mStreamType = AudioSystem.STREAM_DEFAULT;
+
+        audioBuffSizeCheck(bufferSizeInBytes);
+
+        mInitializationLooper = looper;
+
+        if (sessionId < 0) {
+            throw new IllegalArgumentException("Invalid audio session ID: "+sessionId);
+        }
+
+        int[] sampleRate = new int[] {mSampleRate};
+        int[] session = new int[1];
+        session[0] = sessionId;
+        // native initialization
+        int initResult = native_setup(new WeakReference<AudioTrack>(this), mAttributes,
+                sampleRate, mChannelMask, mChannelIndexMask, mAudioFormat,
+                mNativeBufferSizeInBytes, mDataLoadMode, session, 0 /*nativeTrackInJavaObj*/,
+                offload, encapsulationMode, tunerConfiguration,
+                getCurrentOpPackageName());
+        if (initResult != SUCCESS) {
+            loge("Error code "+initResult+" when initializing AudioTrack.");
+            return; // with mState == STATE_UNINITIALIZED
+        }
+
+        mSampleRate = sampleRate[0];
+        mSessionId = session[0];
+
+        // TODO: consider caching encapsulationMode and tunerConfiguration in the Java object.
+
+        if ((mAttributes.getFlags() & AudioAttributes.FLAG_HW_AV_SYNC) != 0) {
+            int frameSizeInBytes;
+            if (AudioFormat.isEncodingLinearFrames(mAudioFormat)) {
+                frameSizeInBytes = mChannelCount * AudioFormat.getBytesPerSample(mAudioFormat);
+            } else {
+                frameSizeInBytes = 1;
+            }
+            mOffset = ((int) Math.ceil(HEADER_V2_SIZE_BYTES / frameSizeInBytes)) * frameSizeInBytes;
+        }
+
+        if (mDataLoadMode == MODE_STATIC) {
+            mState = STATE_NO_STATIC_DATA;
+        } else {
+            mState = STATE_INITIALIZED;
+        }
+
+        baseRegisterPlayer(mSessionId);
+        native_setPlayerIId(mPlayerIId); // mPlayerIId now ready to send to native AudioTrack.
+    }
+
+    /**
+     * A constructor which explicitly connects a Native (C++) AudioTrack. For use by
+     * the AudioTrackRoutingProxy subclass.
+     * @param nativeTrackInJavaObj a C/C++ pointer to a native AudioTrack
+     * (associated with an OpenSL ES player).
+     * IMPORTANT: For "N", this method is ONLY called to setup a Java routing proxy,
+     * i.e. IAndroidConfiguration::AcquireJavaProxy(). If we call with a 0 in nativeTrackInJavaObj
+     * it means that the OpenSL player interface hasn't been realized, so there is no native
+     * Audiotrack to connect to. In this case wait to call deferred_connect() until the
+     * OpenSLES interface is realized.
+     */
+    /*package*/ AudioTrack(long nativeTrackInJavaObj) {
+        super(new AudioAttributes.Builder().build(),
+                AudioPlaybackConfiguration.PLAYER_TYPE_JAM_AUDIOTRACK);
+        // "final"s
+        mNativeTrackInJavaObj = 0;
+        mJniData = 0;
+
+        // remember which looper is associated with the AudioTrack instantiation
+        Looper looper;
+        if ((looper = Looper.myLooper()) == null) {
+            looper = Looper.getMainLooper();
+        }
+        mInitializationLooper = looper;
+
+        // other initialization...
+        if (nativeTrackInJavaObj != 0) {
+            baseRegisterPlayer(AudioSystem.AUDIO_SESSION_ALLOCATE);
+            deferred_connect(nativeTrackInJavaObj);
+        } else {
+            mState = STATE_UNINITIALIZED;
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    /* package */ void deferred_connect(long nativeTrackInJavaObj) {
+        if (mState != STATE_INITIALIZED) {
+            // Note that for this native_setup, we are providing an already created/initialized
+            // *Native* AudioTrack, so the attributes parameters to native_setup() are ignored.
+            int[] session = { 0 };
+            int[] rates = { 0 };
+            int initResult = native_setup(new WeakReference<AudioTrack>(this),
+                    null /*mAttributes - NA*/,
+                    rates /*sampleRate - NA*/,
+                    0 /*mChannelMask - NA*/,
+                    0 /*mChannelIndexMask - NA*/,
+                    0 /*mAudioFormat - NA*/,
+                    0 /*mNativeBufferSizeInBytes - NA*/,
+                    0 /*mDataLoadMode - NA*/,
+                    session,
+                    nativeTrackInJavaObj,
+                    false /*offload*/,
+                    ENCAPSULATION_MODE_NONE,
+                    null /* tunerConfiguration */,
+                    "" /* opPackagename */);
+            if (initResult != SUCCESS) {
+                loge("Error code "+initResult+" when initializing AudioTrack.");
+                return; // with mState == STATE_UNINITIALIZED
+            }
+
+            mSessionId = session[0];
+
+            mState = STATE_INITIALIZED;
+        }
+    }
+
+    /**
+     * TunerConfiguration is used to convey tuner information
+     * from the android.media.tv.Tuner API to AudioTrack construction.
+     *
+     * Use the Builder to construct the TunerConfiguration object,
+     * which is then used by the {@link AudioTrack.Builder} to create an AudioTrack.
+     * @hide
+     */
+    @SystemApi
+    public static class TunerConfiguration {
+        private final int mContentId;
+        private final int mSyncId;
+
+        /**
+         * A special content id for {@link #TunerConfiguration(int, int)}
+         * indicating audio is delivered
+         * from an {@code AudioTrack} write, not tunneled from the tuner stack.
+         */
+        public static final int CONTENT_ID_NONE = 0;
+
+        /**
+         * Constructs a TunerConfiguration instance for use in {@link AudioTrack.Builder}
+         *
+         * @param contentId selects the audio stream to use.
+         *     The contentId may be obtained from
+         *     {@link android.media.tv.tuner.filter.Filter#getId()},
+         *     such obtained id is always a positive number.
+         *     If audio is to be delivered through an {@code AudioTrack} write
+         *     then {@code CONTENT_ID_NONE} may be used.
+         * @param syncId selects the clock to use for synchronization
+         *     of audio with other streams such as video.
+         *     The syncId may be obtained from
+         *     {@link android.media.tv.tuner.Tuner#getAvSyncHwId()}.
+         *     This is always a positive number.
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+        public TunerConfiguration(
+                @IntRange(from = 0) int contentId, @IntRange(from = 1)int syncId) {
+            if (contentId < 0) {
+                throw new IllegalArgumentException(
+                        "contentId " + contentId + " must be positive or CONTENT_ID_NONE");
+            }
+            if (syncId < 1) {
+                throw new IllegalArgumentException("syncId " + syncId + " must be positive");
+            }
+            mContentId = contentId;
+            mSyncId = syncId;
+        }
+
+        /**
+         * Returns the contentId.
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+        public @IntRange(from = 1) int getContentId() {
+            return mContentId; // The Builder ensures this is > 0.
+        }
+
+        /**
+         * Returns the syncId.
+         */
+        @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+        public @IntRange(from = 1) int getSyncId() {
+            return mSyncId;  // The Builder ensures this is > 0.
+        }
+    }
+
+    /**
+     * Builder class for {@link AudioTrack} objects.
+     * Use this class to configure and create an <code>AudioTrack</code> instance. By setting audio
+     * attributes and audio format parameters, you indicate which of those vary from the default
+     * behavior on the device.
+     * <p> Here is an example where <code>Builder</code> is used to specify all {@link AudioFormat}
+     * parameters, to be used by a new <code>AudioTrack</code> instance:
+     *
+     * <pre class="prettyprint">
+     * AudioTrack player = new AudioTrack.Builder()
+     *         .setAudioAttributes(new AudioAttributes.Builder()
+     *                  .setUsage(AudioAttributes.USAGE_ALARM)
+     *                  .setContentType(AudioAttributes.CONTENT_TYPE_MUSIC)
+     *                  .build())
+     *         .setAudioFormat(new AudioFormat.Builder()
+     *                 .setEncoding(AudioFormat.ENCODING_PCM_16BIT)
+     *                 .setSampleRate(44100)
+     *                 .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
+     *                 .build())
+     *         .setBufferSizeInBytes(minBuffSize)
+     *         .build();
+     * </pre>
+     * <p>
+     * If the audio attributes are not set with {@link #setAudioAttributes(AudioAttributes)},
+     * attributes comprising {@link AudioAttributes#USAGE_MEDIA} will be used.
+     * <br>If the audio format is not specified or is incomplete, its channel configuration will be
+     * {@link AudioFormat#CHANNEL_OUT_STEREO} and the encoding will be
+     * {@link AudioFormat#ENCODING_PCM_16BIT}.
+     * The sample rate will depend on the device actually selected for playback and can be queried
+     * with {@link #getSampleRate()} method.
+     * <br>If the buffer size is not specified with {@link #setBufferSizeInBytes(int)},
+     * and the mode is {@link AudioTrack#MODE_STREAM}, the minimum buffer size is used.
+     * <br>If the transfer mode is not specified with {@link #setTransferMode(int)},
+     * <code>MODE_STREAM</code> will be used.
+     * <br>If the session ID is not specified with {@link #setSessionId(int)}, a new one will
+     * be generated.
+     * <br>Offload is false by default.
+     */
+    public static class Builder {
+        private AudioAttributes mAttributes;
+        private AudioFormat mFormat;
+        private int mBufferSizeInBytes;
+        private int mEncapsulationMode = ENCAPSULATION_MODE_NONE;
+        private int mSessionId = AudioManager.AUDIO_SESSION_ID_GENERATE;
+        private int mMode = MODE_STREAM;
+        private int mPerformanceMode = PERFORMANCE_MODE_NONE;
+        private boolean mOffload = false;
+        private TunerConfiguration mTunerConfiguration;
+
+        /**
+         * Constructs a new Builder with the default values as described above.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Sets the {@link AudioAttributes}.
+         * @param attributes a non-null {@link AudioAttributes} instance that describes the audio
+         *     data to be played.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        public @NonNull Builder setAudioAttributes(@NonNull AudioAttributes attributes)
+                throws IllegalArgumentException {
+            if (attributes == null) {
+                throw new IllegalArgumentException("Illegal null AudioAttributes argument");
+            }
+            // keep reference, we only copy the data when building
+            mAttributes = attributes;
+            return this;
+        }
+
+        /**
+         * Sets the format of the audio data to be played by the {@link AudioTrack}.
+         * See {@link AudioFormat.Builder} for configuring the audio format parameters such
+         * as encoding, channel mask and sample rate.
+         * @param format a non-null {@link AudioFormat} instance.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        public @NonNull Builder setAudioFormat(@NonNull AudioFormat format)
+                throws IllegalArgumentException {
+            if (format == null) {
+                throw new IllegalArgumentException("Illegal null AudioFormat argument");
+            }
+            // keep reference, we only copy the data when building
+            mFormat = format;
+            return this;
+        }
+
+        /**
+         * Sets the total size (in bytes) of the buffer where audio data is read from for playback.
+         * If using the {@link AudioTrack} in streaming mode
+         * (see {@link AudioTrack#MODE_STREAM}, you can write data into this buffer in smaller
+         * chunks than this size. See {@link #getMinBufferSize(int, int, int)} to determine
+         * the estimated minimum buffer size for the creation of an AudioTrack instance
+         * in streaming mode.
+         * <br>If using the <code>AudioTrack</code> in static mode (see
+         * {@link AudioTrack#MODE_STATIC}), this is the maximum size of the sound that will be
+         * played by this instance.
+         * @param bufferSizeInBytes
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        public @NonNull Builder setBufferSizeInBytes(@IntRange(from = 0) int bufferSizeInBytes)
+                throws IllegalArgumentException {
+            if (bufferSizeInBytes <= 0) {
+                throw new IllegalArgumentException("Invalid buffer size " + bufferSizeInBytes);
+            }
+            mBufferSizeInBytes = bufferSizeInBytes;
+            return this;
+        }
+
+        /**
+         * Sets the encapsulation mode.
+         *
+         * Encapsulation mode allows metadata to be sent together with
+         * the audio data payload in a {@code ByteBuffer}.
+         * This requires a compatible hardware audio codec.
+         *
+         * @param encapsulationMode one of {@link AudioTrack#ENCAPSULATION_MODE_NONE},
+         *        or {@link AudioTrack#ENCAPSULATION_MODE_ELEMENTARY_STREAM}.
+         * @return the same Builder instance.
+         */
+        // Note: with the correct permission {@code AudioTrack#ENCAPSULATION_MODE_HANDLE}
+        // may be used as well.
+        public @NonNull Builder setEncapsulationMode(@EncapsulationMode int encapsulationMode) {
+            switch (encapsulationMode) {
+                case ENCAPSULATION_MODE_NONE:
+                case ENCAPSULATION_MODE_ELEMENTARY_STREAM:
+                case ENCAPSULATION_MODE_HANDLE:
+                    mEncapsulationMode = encapsulationMode;
+                    break;
+                default:
+                    throw new IllegalArgumentException(
+                            "Invalid encapsulation mode " + encapsulationMode);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the mode under which buffers of audio data are transferred from the
+         * {@link AudioTrack} to the framework.
+         * @param mode one of {@link AudioTrack#MODE_STREAM}, {@link AudioTrack#MODE_STATIC}.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        public @NonNull Builder setTransferMode(@TransferMode int mode)
+                throws IllegalArgumentException {
+            switch(mode) {
+                case MODE_STREAM:
+                case MODE_STATIC:
+                    mMode = mode;
+                    break;
+                default:
+                    throw new IllegalArgumentException("Invalid transfer mode " + mode);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the session ID the {@link AudioTrack} will be attached to.
+         * @param sessionId a strictly positive ID number retrieved from another
+         *     <code>AudioTrack</code> via {@link AudioTrack#getAudioSessionId()} or allocated by
+         *     {@link AudioManager} via {@link AudioManager#generateAudioSessionId()}, or
+         *     {@link AudioManager#AUDIO_SESSION_ID_GENERATE}.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        public @NonNull Builder setSessionId(@IntRange(from = 1) int sessionId)
+                throws IllegalArgumentException {
+            if ((sessionId != AudioManager.AUDIO_SESSION_ID_GENERATE) && (sessionId < 1)) {
+                throw new IllegalArgumentException("Invalid audio session ID " + sessionId);
+            }
+            mSessionId = sessionId;
+            return this;
+        }
+
+        /**
+         * Sets the {@link AudioTrack} performance mode.  This is an advisory request which
+         * may not be supported by the particular device, and the framework is free
+         * to ignore such request if it is incompatible with other requests or hardware.
+         *
+         * @param performanceMode one of
+         * {@link AudioTrack#PERFORMANCE_MODE_NONE},
+         * {@link AudioTrack#PERFORMANCE_MODE_LOW_LATENCY},
+         * or {@link AudioTrack#PERFORMANCE_MODE_POWER_SAVING}.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException if {@code performanceMode} is not valid.
+         */
+        public @NonNull Builder setPerformanceMode(@PerformanceMode int performanceMode) {
+            switch (performanceMode) {
+                case PERFORMANCE_MODE_NONE:
+                case PERFORMANCE_MODE_LOW_LATENCY:
+                case PERFORMANCE_MODE_POWER_SAVING:
+                    mPerformanceMode = performanceMode;
+                    break;
+                default:
+                    throw new IllegalArgumentException(
+                            "Invalid performance mode " + performanceMode);
+            }
+            return this;
+        }
+
+        /**
+         * Sets whether this track will play through the offloaded audio path.
+         * When set to true, at build time, the audio format will be checked against
+         * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat,AudioAttributes)}
+         * to verify the audio format used by this track is supported on the device's offload
+         * path (if any).
+         * <br>Offload is only supported for media audio streams, and therefore requires that
+         * the usage be {@link AudioAttributes#USAGE_MEDIA}.
+         * @param offload true to require the offload path for playback.
+         * @return the same Builder instance.
+         */
+        public @NonNull Builder setOffloadedPlayback(boolean offload) {
+            mOffload = offload;
+            return this;
+        }
+
+        /**
+         * Sets the tuner configuration for the {@code AudioTrack}.
+         *
+         * The {@link AudioTrack.TunerConfiguration} consists of parameters obtained from
+         * the Android TV tuner API which indicate the audio content stream id and the
+         * synchronization id for the {@code AudioTrack}.
+         *
+         * @param tunerConfiguration obtained by {@link AudioTrack.TunerConfiguration.Builder}.
+         * @return the same Builder instance.
+         * @hide
+         */
+        @SystemApi
+        @RequiresPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING)
+        public @NonNull Builder setTunerConfiguration(
+                @NonNull TunerConfiguration tunerConfiguration) {
+            if (tunerConfiguration == null) {
+                throw new IllegalArgumentException("tunerConfiguration is null");
+            }
+            mTunerConfiguration = tunerConfiguration;
+            return this;
+        }
+
+        /**
+         * Builds an {@link AudioTrack} instance initialized with all the parameters set
+         * on this <code>Builder</code>.
+         * @return a new successfully initialized {@link AudioTrack} instance.
+         * @throws UnsupportedOperationException if the parameters set on the <code>Builder</code>
+         *     were incompatible, or if they are not supported by the device,
+         *     or if the device was not available.
+         */
+        public @NonNull AudioTrack build() throws UnsupportedOperationException {
+            if (mAttributes == null) {
+                mAttributes = new AudioAttributes.Builder()
+                        .setUsage(AudioAttributes.USAGE_MEDIA)
+                        .build();
+            }
+            switch (mPerformanceMode) {
+            case PERFORMANCE_MODE_LOW_LATENCY:
+                mAttributes = new AudioAttributes.Builder(mAttributes)
+                    .replaceFlags((mAttributes.getAllFlags()
+                            | AudioAttributes.FLAG_LOW_LATENCY)
+                            & ~AudioAttributes.FLAG_DEEP_BUFFER)
+                    .build();
+                break;
+            case PERFORMANCE_MODE_NONE:
+                if (!shouldEnablePowerSaving(mAttributes, mFormat, mBufferSizeInBytes, mMode)) {
+                    break; // do not enable deep buffer mode.
+                }
+                // permitted to fall through to enable deep buffer
+            case PERFORMANCE_MODE_POWER_SAVING:
+                mAttributes = new AudioAttributes.Builder(mAttributes)
+                .replaceFlags((mAttributes.getAllFlags()
+                        | AudioAttributes.FLAG_DEEP_BUFFER)
+                        & ~AudioAttributes.FLAG_LOW_LATENCY)
+                .build();
+                break;
+            }
+
+            if (mFormat == null) {
+                mFormat = new AudioFormat.Builder()
+                        .setChannelMask(AudioFormat.CHANNEL_OUT_STEREO)
+                        //.setSampleRate(AudioFormat.SAMPLE_RATE_UNSPECIFIED)
+                        .setEncoding(AudioFormat.ENCODING_DEFAULT)
+                        .build();
+            }
+
+            if (mOffload) {
+                if (mPerformanceMode == PERFORMANCE_MODE_LOW_LATENCY) {
+                    throw new UnsupportedOperationException(
+                            "Offload and low latency modes are incompatible");
+                }
+                if (AudioSystem.getOffloadSupport(mFormat, mAttributes)
+                        == AudioSystem.OFFLOAD_NOT_SUPPORTED) {
+                    throw new UnsupportedOperationException(
+                            "Cannot create AudioTrack, offload format / attributes not supported");
+                }
+            }
+
+            // TODO: Check mEncapsulationMode compatibility with MODE_STATIC, etc?
+
+            // If the buffer size is not specified in streaming mode,
+            // use a single frame for the buffer size and let the
+            // native code figure out the minimum buffer size.
+            if (mMode == MODE_STREAM && mBufferSizeInBytes == 0) {
+                int bytesPerSample = 1;
+                if (AudioFormat.isEncodingLinearFrames(mFormat.getEncoding())) {
+                    try {
+                        bytesPerSample = mFormat.getBytesPerSample(mFormat.getEncoding());
+                    } catch (IllegalArgumentException e) {
+                        // do nothing
+                    }
+                }
+                mBufferSizeInBytes = mFormat.getChannelCount() * bytesPerSample;
+            }
+
+            try {
+                final AudioTrack track = new AudioTrack(
+                        mAttributes, mFormat, mBufferSizeInBytes, mMode, mSessionId, mOffload,
+                        mEncapsulationMode, mTunerConfiguration);
+                if (track.getState() == STATE_UNINITIALIZED) {
+                    // release is not necessary
+                    throw new UnsupportedOperationException("Cannot create AudioTrack");
+                }
+                return track;
+            } catch (IllegalArgumentException e) {
+                throw new UnsupportedOperationException(e.getMessage());
+            }
+        }
+    }
+
+    /**
+     * Configures the delay and padding values for the current compressed stream playing
+     * in offload mode.
+     * This can only be used on a track successfully initialized with
+     * {@link AudioTrack.Builder#setOffloadedPlayback(boolean)}. The unit is frames, where a
+     * frame indicates the number of samples per channel, e.g. 100 frames for a stereo compressed
+     * stream corresponds to 200 decoded interleaved PCM samples.
+     * @param delayInFrames number of frames to be ignored at the beginning of the stream. A value
+     *     of 0 indicates no delay is to be applied.
+     * @param paddingInFrames number of frames to be ignored at the end of the stream. A value of 0
+     *     of 0 indicates no padding is to be applied.
+     */
+    public void setOffloadDelayPadding(@IntRange(from = 0) int delayInFrames,
+            @IntRange(from = 0) int paddingInFrames) {
+        if (paddingInFrames < 0) {
+            throw new IllegalArgumentException("Illegal negative padding");
+        }
+        if (delayInFrames < 0) {
+            throw new IllegalArgumentException("Illegal negative delay");
+        }
+        if (!mOffloaded) {
+            throw new IllegalStateException("Illegal use of delay/padding on non-offloaded track");
+        }
+        if (mState == STATE_UNINITIALIZED) {
+            throw new IllegalStateException("Uninitialized track");
+        }
+        mOffloadDelayFrames = delayInFrames;
+        mOffloadPaddingFrames = paddingInFrames;
+        native_set_delay_padding(delayInFrames, paddingInFrames);
+    }
+
+    /**
+     * Return the decoder delay of an offloaded track, expressed in frames, previously set with
+     * {@link #setOffloadDelayPadding(int, int)}, or 0 if it was never modified.
+     * <p>This delay indicates the number of frames to be ignored at the beginning of the stream.
+     * This value can only be queried on a track successfully initialized with
+     * {@link AudioTrack.Builder#setOffloadedPlayback(boolean)}.
+     * @return decoder delay expressed in frames.
+     */
+    public @IntRange(from = 0) int getOffloadDelay() {
+        if (!mOffloaded) {
+            throw new IllegalStateException("Illegal query of delay on non-offloaded track");
+        }
+        if (mState == STATE_UNINITIALIZED) {
+            throw new IllegalStateException("Illegal query of delay on uninitialized track");
+        }
+        return mOffloadDelayFrames;
+    }
+
+    /**
+     * Return the decoder padding of an offloaded track, expressed in frames, previously set with
+     * {@link #setOffloadDelayPadding(int, int)}, or 0 if it was never modified.
+     * <p>This padding indicates the number of frames to be ignored at the end of the stream.
+     * This value can only be queried on a track successfully initialized with
+     * {@link AudioTrack.Builder#setOffloadedPlayback(boolean)}.
+     * @return decoder padding expressed in frames.
+     */
+    public @IntRange(from = 0) int getOffloadPadding() {
+        if (!mOffloaded) {
+            throw new IllegalStateException("Illegal query of padding on non-offloaded track");
+        }
+        if (mState == STATE_UNINITIALIZED) {
+            throw new IllegalStateException("Illegal query of padding on uninitialized track");
+        }
+        return mOffloadPaddingFrames;
+    }
+
+    /**
+     * Declares that the last write() operation on this track provided the last buffer of this
+     * stream.
+     * After the end of stream, previously set padding and delay values are ignored.
+     * Can only be called only if the AudioTrack is opened in offload mode
+     * {@see Builder#setOffloadedPlayback(boolean)}.
+     * Can only be called only if the AudioTrack is in state {@link #PLAYSTATE_PLAYING}
+     * {@see #getPlayState()}.
+     * Use this method in the same thread as any write() operation.
+     */
+    public void setOffloadEndOfStream() {
+        if (!mOffloaded) {
+            throw new IllegalStateException("EOS not supported on non-offloaded track");
+        }
+        if (mState == STATE_UNINITIALIZED) {
+            throw new IllegalStateException("Uninitialized track");
+        }
+        if (mPlayState != PLAYSTATE_PLAYING) {
+            throw new IllegalStateException("EOS not supported if not playing");
+        }
+        synchronized (mStreamEventCbLock) {
+            if (mStreamEventCbInfoList.size() == 0) {
+                throw new IllegalStateException("EOS not supported without StreamEventCallback");
+            }
+        }
+
+        synchronized (mPlayStateLock) {
+            native_stop();
+            mOffloadEosPending = true;
+            mPlayState = PLAYSTATE_STOPPING;
+        }
+    }
+
+    /**
+     * Returns whether the track was built with {@link Builder#setOffloadedPlayback(boolean)} set
+     * to {@code true}.
+     * @return true if the track is using offloaded playback.
+     */
+    public boolean isOffloadedPlayback() {
+        return mOffloaded;
+    }
+
+    /**
+     * Returns whether direct playback of an audio format with the provided attributes is
+     * currently supported on the system.
+     * <p>Direct playback means that the audio stream is not resampled or downmixed
+     * by the framework. Checking for direct support can help the app select the representation
+     * of audio content that most closely matches the capabilities of the device and peripherials
+     * (e.g. A/V receiver) connected to it. Note that the provided stream can still be re-encoded
+     * or mixed with other streams, if needed.
+     * <p>Also note that this query only provides information about the support of an audio format.
+     * It does not indicate whether the resources necessary for the playback are available
+     * at that instant.
+     * @param format a non-null {@link AudioFormat} instance describing the format of
+     *   the audio data.
+     * @param attributes a non-null {@link AudioAttributes} instance.
+     * @return true if the given audio format can be played directly.
+     */
+    public static boolean isDirectPlaybackSupported(@NonNull AudioFormat format,
+            @NonNull AudioAttributes attributes) {
+        if (format == null) {
+            throw new IllegalArgumentException("Illegal null AudioFormat argument");
+        }
+        if (attributes == null) {
+            throw new IllegalArgumentException("Illegal null AudioAttributes argument");
+        }
+        return native_is_direct_output_supported(format.getEncoding(), format.getSampleRate(),
+                format.getChannelMask(), format.getChannelIndexMask(),
+                attributes.getContentType(), attributes.getUsage(), attributes.getFlags());
+    }
+
+    /*
+     * The MAX_LEVEL should be exactly representable by an IEEE 754-2008 base32 float.
+     * This means fractions must be divisible by a power of 2. For example,
+     * 10.25f is OK as 0.25 is 1/4, but 10.1f is NOT OK as 1/10 is not expressable by
+     * a finite binary fraction.
+     *
+     * 48.f is the nominal max for API level {@link android os.Build.VERSION_CODES#R}.
+     * We use this to suggest a baseline range for implementation.
+     *
+     * The API contract specification allows increasing this value in a future
+     * API release, but not decreasing this value.
+     */
+    private static final float MAX_AUDIO_DESCRIPTION_MIX_LEVEL = 48.f;
+
+    private static boolean isValidAudioDescriptionMixLevel(float level) {
+        return !(Float.isNaN(level) || level > MAX_AUDIO_DESCRIPTION_MIX_LEVEL);
+    }
+
+    /**
+     * Sets the Audio Description mix level in dB.
+     *
+     * For AudioTracks incorporating a secondary Audio Description stream
+     * (where such contents may be sent through an Encapsulation Mode
+     * other than {@link #ENCAPSULATION_MODE_NONE}).
+     * or internally by a HW channel),
+     * the level of mixing of the Audio Description to the Main Audio stream
+     * is controlled by this method.
+     *
+     * Such mixing occurs <strong>prior</strong> to overall volume scaling.
+     *
+     * @param level a floating point value between
+     *     {@code Float.NEGATIVE_INFINITY} to {@code +48.f},
+     *     where {@code Float.NEGATIVE_INFINITY} means the Audio Description is not mixed
+     *     and a level of {@code 0.f} means the Audio Description is mixed without scaling.
+     * @return true on success, false on failure.
+     */
+    public boolean setAudioDescriptionMixLeveldB(
+            @FloatRange(to = 48.f, toInclusive = true) float level) {
+        if (!isValidAudioDescriptionMixLevel(level)) {
+            throw new IllegalArgumentException("level is out of range" + level);
+        }
+        return native_set_audio_description_mix_level_db(level) == SUCCESS;
+    }
+
+    /**
+     * Returns the Audio Description mix level in dB.
+     *
+     * If Audio Description mixing is unavailable from the hardware device,
+     * a value of {@code Float.NEGATIVE_INFINITY} is returned.
+     *
+     * @return the current Audio Description Mix Level in dB.
+     *     A value of {@code Float.NEGATIVE_INFINITY} means
+     *     that the audio description is not mixed or
+     *     the hardware is not available.
+     *     This should reflect the <strong>true</strong> internal device mix level;
+     *     hence the application might receive any floating value
+     *     except {@code Float.NaN}.
+     */
+    public float getAudioDescriptionMixLeveldB() {
+        float[] level = { Float.NEGATIVE_INFINITY };
+        try {
+            final int status = native_get_audio_description_mix_level_db(level);
+            if (status != SUCCESS || Float.isNaN(level[0])) {
+                return Float.NEGATIVE_INFINITY;
+            }
+        } catch (Exception e) {
+            return Float.NEGATIVE_INFINITY;
+        }
+        return level[0];
+    }
+
+    private static boolean isValidDualMonoMode(@DualMonoMode int dualMonoMode) {
+        switch (dualMonoMode) {
+            case DUAL_MONO_MODE_OFF:
+            case DUAL_MONO_MODE_LR:
+            case DUAL_MONO_MODE_LL:
+            case DUAL_MONO_MODE_RR:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Sets the Dual Mono mode presentation on the output device.
+     *
+     * The Dual Mono mode is generally applied to stereo audio streams
+     * where the left and right channels come from separate sources.
+     *
+     * For compressed audio, where the decoding is done in hardware,
+     * Dual Mono presentation needs to be performed
+     * by the hardware output device
+     * as the PCM audio is not available to the framework.
+     *
+     * @param dualMonoMode one of {@link #DUAL_MONO_MODE_OFF},
+     *     {@link #DUAL_MONO_MODE_LR},
+     *     {@link #DUAL_MONO_MODE_LL},
+     *     {@link #DUAL_MONO_MODE_RR}.
+     *
+     * @return true on success, false on failure if the output device
+     *     does not support Dual Mono mode.
+     */
+    public boolean setDualMonoMode(@DualMonoMode int dualMonoMode) {
+        if (!isValidDualMonoMode(dualMonoMode)) {
+            throw new IllegalArgumentException(
+                    "Invalid Dual Mono mode " + dualMonoMode);
+        }
+        return native_set_dual_mono_mode(dualMonoMode) == SUCCESS;
+    }
+
+    /**
+     * Returns the Dual Mono mode presentation setting.
+     *
+     * If no Dual Mono presentation is available for the output device,
+     * then {@link #DUAL_MONO_MODE_OFF} is returned.
+     *
+     * @return one of {@link #DUAL_MONO_MODE_OFF},
+     *     {@link #DUAL_MONO_MODE_LR},
+     *     {@link #DUAL_MONO_MODE_LL},
+     *     {@link #DUAL_MONO_MODE_RR}.
+     */
+    public @DualMonoMode int getDualMonoMode() {
+        int[] dualMonoMode = { DUAL_MONO_MODE_OFF };
+        try {
+            final int status = native_get_dual_mono_mode(dualMonoMode);
+            if (status != SUCCESS || !isValidDualMonoMode(dualMonoMode[0])) {
+                return DUAL_MONO_MODE_OFF;
+            }
+        } catch (Exception e) {
+            return DUAL_MONO_MODE_OFF;
+        }
+        return dualMonoMode[0];
+    }
+
+    // mask of all the positional channels supported, however the allowed combinations
+    // are further restricted by the matching left/right rule and
+    // AudioSystem.OUT_CHANNEL_COUNT_MAX
+    private static final int SUPPORTED_OUT_CHANNELS =
+            AudioFormat.CHANNEL_OUT_FRONT_LEFT |
+            AudioFormat.CHANNEL_OUT_FRONT_RIGHT |
+            AudioFormat.CHANNEL_OUT_FRONT_CENTER |
+            AudioFormat.CHANNEL_OUT_LOW_FREQUENCY |
+            AudioFormat.CHANNEL_OUT_BACK_LEFT |
+            AudioFormat.CHANNEL_OUT_BACK_RIGHT |
+            AudioFormat.CHANNEL_OUT_FRONT_LEFT_OF_CENTER |
+            AudioFormat.CHANNEL_OUT_FRONT_RIGHT_OF_CENTER |
+            AudioFormat.CHANNEL_OUT_BACK_CENTER |
+            AudioFormat.CHANNEL_OUT_SIDE_LEFT |
+            AudioFormat.CHANNEL_OUT_SIDE_RIGHT |
+            AudioFormat.CHANNEL_OUT_TOP_CENTER |
+            AudioFormat.CHANNEL_OUT_TOP_FRONT_LEFT |
+            AudioFormat.CHANNEL_OUT_TOP_FRONT_CENTER |
+            AudioFormat.CHANNEL_OUT_TOP_FRONT_RIGHT |
+            AudioFormat.CHANNEL_OUT_TOP_BACK_LEFT |
+            AudioFormat.CHANNEL_OUT_TOP_BACK_CENTER |
+            AudioFormat.CHANNEL_OUT_TOP_BACK_RIGHT |
+            AudioFormat.CHANNEL_OUT_TOP_SIDE_LEFT |
+            AudioFormat.CHANNEL_OUT_TOP_SIDE_RIGHT |
+            AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_LEFT |
+            AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_CENTER |
+            AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_RIGHT |
+            AudioFormat.CHANNEL_OUT_LOW_FREQUENCY_2;
+
+    // Returns a boolean whether the attributes, format, bufferSizeInBytes, mode allow
+    // power saving to be automatically enabled for an AudioTrack. Returns false if
+    // power saving is already enabled in the attributes parameter.
+    private static boolean shouldEnablePowerSaving(
+            @Nullable AudioAttributes attributes, @Nullable AudioFormat format,
+            int bufferSizeInBytes, int mode) {
+        // If no attributes, OK
+        // otherwise check attributes for USAGE_MEDIA and CONTENT_UNKNOWN, MUSIC, or MOVIE.
+        // Only consider flags that are not compatible with FLAG_DEEP_BUFFER. We include
+        // FLAG_DEEP_BUFFER because if set the request is explicit and
+        // shouldEnablePowerSaving() should return false.
+        final int flags = attributes.getAllFlags()
+                & (AudioAttributes.FLAG_DEEP_BUFFER | AudioAttributes.FLAG_LOW_LATENCY
+                    | AudioAttributes.FLAG_HW_AV_SYNC | AudioAttributes.FLAG_BEACON);
+
+        if (attributes != null &&
+                (flags != 0  // cannot have any special flags
+                || attributes.getUsage() != AudioAttributes.USAGE_MEDIA
+                || (attributes.getContentType() != AudioAttributes.CONTENT_TYPE_UNKNOWN
+                    && attributes.getContentType() != AudioAttributes.CONTENT_TYPE_MUSIC
+                    && attributes.getContentType() != AudioAttributes.CONTENT_TYPE_MOVIE))) {
+            return false;
+        }
+
+        // Format must be fully specified and be linear pcm
+        if (format == null
+                || format.getSampleRate() == AudioFormat.SAMPLE_RATE_UNSPECIFIED
+                || !AudioFormat.isEncodingLinearPcm(format.getEncoding())
+                || !AudioFormat.isValidEncoding(format.getEncoding())
+                || format.getChannelCount() < 1) {
+            return false;
+        }
+
+        // Mode must be streaming
+        if (mode != MODE_STREAM) {
+            return false;
+        }
+
+        // A buffer size of 0 is always compatible with deep buffer (when called from the Builder)
+        // but for app compatibility we only use deep buffer power saving for large buffer sizes.
+        if (bufferSizeInBytes != 0) {
+            final long BUFFER_TARGET_MODE_STREAM_MS = 100;
+            final int MILLIS_PER_SECOND = 1000;
+            final long bufferTargetSize =
+                    BUFFER_TARGET_MODE_STREAM_MS
+                    * format.getChannelCount()
+                    * format.getBytesPerSample(format.getEncoding())
+                    * format.getSampleRate()
+                    / MILLIS_PER_SECOND;
+            if (bufferSizeInBytes < bufferTargetSize) {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    // Convenience method for the constructor's parameter checks.
+    // This is where constructor IllegalArgumentException-s are thrown
+    // postconditions:
+    //    mChannelCount is valid
+    //    mChannelMask is valid
+    //    mAudioFormat is valid
+    //    mSampleRate is valid
+    //    mDataLoadMode is valid
+    private void audioParamCheck(int sampleRateInHz, int channelConfig, int channelIndexMask,
+                                 int audioFormat, int mode) {
+        //--------------
+        // sample rate, note these values are subject to change
+        if ((sampleRateInHz < AudioFormat.SAMPLE_RATE_HZ_MIN ||
+                sampleRateInHz > AudioFormat.SAMPLE_RATE_HZ_MAX) &&
+                sampleRateInHz != AudioFormat.SAMPLE_RATE_UNSPECIFIED) {
+            throw new IllegalArgumentException(sampleRateInHz
+                    + "Hz is not a supported sample rate.");
+        }
+        mSampleRate = sampleRateInHz;
+
+        if (audioFormat == AudioFormat.ENCODING_IEC61937
+                && channelConfig != AudioFormat.CHANNEL_OUT_STEREO
+                && AudioFormat.channelCountFromOutChannelMask(channelConfig) != 8) {
+            Log.w(TAG, "ENCODING_IEC61937 is configured with channel mask as " + channelConfig
+                    + ", which is not 2 or 8 channels");
+        }
+
+        //--------------
+        // channel config
+        mChannelConfiguration = channelConfig;
+
+        switch (channelConfig) {
+        case AudioFormat.CHANNEL_OUT_DEFAULT: //AudioFormat.CHANNEL_CONFIGURATION_DEFAULT
+        case AudioFormat.CHANNEL_OUT_MONO:
+        case AudioFormat.CHANNEL_CONFIGURATION_MONO:
+            mChannelCount = 1;
+            mChannelMask = AudioFormat.CHANNEL_OUT_MONO;
+            break;
+        case AudioFormat.CHANNEL_OUT_STEREO:
+        case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
+            mChannelCount = 2;
+            mChannelMask = AudioFormat.CHANNEL_OUT_STEREO;
+            break;
+        default:
+            if (channelConfig == AudioFormat.CHANNEL_INVALID && channelIndexMask != 0) {
+                mChannelCount = 0;
+                break; // channel index configuration only
+            }
+            if (!isMultichannelConfigSupported(channelConfig, audioFormat)) {
+                throw new IllegalArgumentException(
+                        "Unsupported channel mask configuration " + channelConfig
+                        + " for encoding " + audioFormat);
+            }
+            mChannelMask = channelConfig;
+            mChannelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig);
+        }
+        // check the channel index configuration (if present)
+        mChannelIndexMask = channelIndexMask;
+        if (mChannelIndexMask != 0) {
+            // As of S, we accept up to 24 channel index mask.
+            final int fullIndexMask = (1 << AudioSystem.FCC_24) - 1;
+            final int channelIndexCount = Integer.bitCount(channelIndexMask);
+            final boolean accepted = (channelIndexMask & ~fullIndexMask) == 0
+                    && (!AudioFormat.isEncodingLinearFrames(audioFormat)  // compressed OK
+                            || channelIndexCount <= AudioSystem.OUT_CHANNEL_COUNT_MAX); // PCM
+            if (!accepted) {
+                throw new IllegalArgumentException(
+                        "Unsupported channel index mask configuration " + channelIndexMask
+                        + " for encoding " + audioFormat);
+            }
+            if (mChannelCount == 0) {
+                 mChannelCount = channelIndexCount;
+            } else if (mChannelCount != channelIndexCount) {
+                throw new IllegalArgumentException("Channel count must match");
+            }
+        }
+
+        //--------------
+        // audio format
+        if (audioFormat == AudioFormat.ENCODING_DEFAULT) {
+            audioFormat = AudioFormat.ENCODING_PCM_16BIT;
+        }
+
+        if (!AudioFormat.isPublicEncoding(audioFormat)) {
+            throw new IllegalArgumentException("Unsupported audio encoding.");
+        }
+        mAudioFormat = audioFormat;
+
+        //--------------
+        // audio load mode
+        if (((mode != MODE_STREAM) && (mode != MODE_STATIC)) ||
+                ((mode != MODE_STREAM) && !AudioFormat.isEncodingLinearPcm(mAudioFormat))) {
+            throw new IllegalArgumentException("Invalid mode.");
+        }
+        mDataLoadMode = mode;
+    }
+
+    // General pair map
+    private static final HashMap<String, Integer> CHANNEL_PAIR_MAP = new HashMap<>() {{
+        put("front", AudioFormat.CHANNEL_OUT_FRONT_LEFT
+                | AudioFormat.CHANNEL_OUT_FRONT_RIGHT);
+        put("back", AudioFormat.CHANNEL_OUT_BACK_LEFT
+                | AudioFormat.CHANNEL_OUT_BACK_RIGHT);
+        put("front of center", AudioFormat.CHANNEL_OUT_FRONT_LEFT_OF_CENTER
+                | AudioFormat.CHANNEL_OUT_FRONT_RIGHT_OF_CENTER);
+        put("side", AudioFormat.CHANNEL_OUT_SIDE_LEFT
+                | AudioFormat.CHANNEL_OUT_SIDE_RIGHT);
+        put("top front", AudioFormat.CHANNEL_OUT_TOP_FRONT_LEFT
+                | AudioFormat.CHANNEL_OUT_TOP_FRONT_RIGHT);
+        put("top back", AudioFormat.CHANNEL_OUT_TOP_BACK_LEFT
+                | AudioFormat.CHANNEL_OUT_TOP_BACK_RIGHT);
+        put("top side", AudioFormat.CHANNEL_OUT_TOP_SIDE_LEFT
+                | AudioFormat.CHANNEL_OUT_TOP_SIDE_RIGHT);
+        put("bottom front", AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_LEFT
+                | AudioFormat.CHANNEL_OUT_BOTTOM_FRONT_RIGHT);
+    }};
+
+    /**
+     * Convenience method to check that the channel configuration (a.k.a channel mask) is supported
+     * @param channelConfig the mask to validate
+     * @return false if the AudioTrack can't be used with such a mask
+     */
+    private static boolean isMultichannelConfigSupported(int channelConfig, int encoding) {
+        // check for unsupported channels
+        if ((channelConfig & SUPPORTED_OUT_CHANNELS) != channelConfig) {
+            loge("Channel configuration features unsupported channels");
+            return false;
+        }
+        final int channelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig);
+        final int channelCountLimit = AudioFormat.isEncodingLinearFrames(encoding)
+                ? AudioSystem.OUT_CHANNEL_COUNT_MAX  // PCM limited to OUT_CHANNEL_COUNT_MAX
+                : AudioSystem.FCC_24;                // Compressed limited to 24 channels
+        if (channelCount > channelCountLimit) {
+            loge("Channel configuration contains too many channels for encoding "
+                    + encoding + "(" + channelCount + " > " + channelCountLimit + ")");
+            return false;
+        }
+        // check for unsupported multichannel combinations:
+        // - FL/FR must be present
+        // - L/R channels must be paired (e.g. no single L channel)
+        final int frontPair =
+                AudioFormat.CHANNEL_OUT_FRONT_LEFT | AudioFormat.CHANNEL_OUT_FRONT_RIGHT;
+        if ((channelConfig & frontPair) != frontPair) {
+                loge("Front channels must be present in multichannel configurations");
+                return false;
+        }
+        // Check all pairs to see that they are matched (front duplicated here).
+        for (HashMap.Entry<String, Integer> e : CHANNEL_PAIR_MAP.entrySet()) {
+            final int positionPair = e.getValue();
+            if ((channelConfig & positionPair) != 0
+                    && (channelConfig & positionPair) != positionPair) {
+                loge("Channel pair (" + e.getKey() + ") cannot be used independently");
+                return false;
+            }
+        }
+        return true;
+    }
+
+
+    // Convenience method for the constructor's audio buffer size check.
+    // preconditions:
+    //    mChannelCount is valid
+    //    mAudioFormat is valid
+    // postcondition:
+    //    mNativeBufferSizeInBytes is valid (multiple of frame size, positive)
+    private void audioBuffSizeCheck(int audioBufferSize) {
+        // NB: this section is only valid with PCM or IEC61937 data.
+        //     To update when supporting compressed formats
+        int frameSizeInBytes;
+        if (AudioFormat.isEncodingLinearFrames(mAudioFormat)) {
+            frameSizeInBytes = mChannelCount * AudioFormat.getBytesPerSample(mAudioFormat);
+        } else {
+            frameSizeInBytes = 1;
+        }
+        if ((audioBufferSize % frameSizeInBytes != 0) || (audioBufferSize < 1)) {
+            throw new IllegalArgumentException("Invalid audio buffer size.");
+        }
+
+        mNativeBufferSizeInBytes = audioBufferSize;
+        mNativeBufferSizeInFrames = audioBufferSize / frameSizeInBytes;
+    }
+
+
+    /**
+     * Releases the native AudioTrack resources.
+     */
+    public void release() {
+        synchronized (mStreamEventCbLock){
+            endStreamEventHandling();
+        }
+        // even though native_release() stops the native AudioTrack, we need to stop
+        // AudioTrack subclasses too.
+        try {
+            stop();
+        } catch(IllegalStateException ise) {
+            // don't raise an exception, we're releasing the resources.
+        }
+        baseRelease();
+        native_release();
+        synchronized (mPlayStateLock) {
+            mState = STATE_UNINITIALIZED;
+            mPlayState = PLAYSTATE_STOPPED;
+            mPlayStateLock.notify();
+        }
+    }
+
+    @Override
+    protected void finalize() {
+        tryToDisableNativeRoutingCallback();
+        baseRelease();
+        native_finalize();
+    }
+
+    //--------------------------------------------------------------------------
+    // Getters
+    //--------------------
+    /**
+     * Returns the minimum gain value, which is the constant 0.0.
+     * Gain values less than 0.0 will be clamped to 0.0.
+     * <p>The word "volume" in the API name is historical; this is actually a linear gain.
+     * @return the minimum value, which is the constant 0.0.
+     */
+    static public float getMinVolume() {
+        return GAIN_MIN;
+    }
+
+    /**
+     * Returns the maximum gain value, which is greater than or equal to 1.0.
+     * Gain values greater than the maximum will be clamped to the maximum.
+     * <p>The word "volume" in the API name is historical; this is actually a gain.
+     * expressed as a linear multiplier on sample values, where a maximum value of 1.0
+     * corresponds to a gain of 0 dB (sample values left unmodified).
+     * @return the maximum value, which is greater than or equal to 1.0.
+     */
+    static public float getMaxVolume() {
+        return GAIN_MAX;
+    }
+
+    /**
+     * Returns the configured audio source sample rate in Hz.
+     * The initial source sample rate depends on the constructor parameters,
+     * but the source sample rate may change if {@link #setPlaybackRate(int)} is called.
+     * If the constructor had a specific sample rate, then the initial sink sample rate is that
+     * value.
+     * If the constructor had {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED},
+     * then the initial sink sample rate is a route-dependent default value based on the source [sic].
+     */
+    public int getSampleRate() {
+        return mSampleRate;
+    }
+
+    /**
+     * Returns the current playback sample rate rate in Hz.
+     */
+    public int getPlaybackRate() {
+        return native_get_playback_rate();
+    }
+
+    /**
+     * Returns the current playback parameters.
+     * See {@link #setPlaybackParams(PlaybackParams)} to set playback parameters
+     * @return current {@link PlaybackParams}.
+     * @throws IllegalStateException if track is not initialized.
+     */
+    public @NonNull PlaybackParams getPlaybackParams() {
+        return native_get_playback_params();
+    }
+
+    /**
+     * Returns the {@link AudioAttributes} used in configuration.
+     * If a {@code streamType} is used instead of an {@code AudioAttributes}
+     * to configure the AudioTrack
+     * (the use of {@code streamType} for configuration is deprecated),
+     * then the {@code AudioAttributes}
+     * equivalent to the {@code streamType} is returned.
+     * @return The {@code AudioAttributes} used to configure the AudioTrack.
+     * @throws IllegalStateException If the track is not initialized.
+     */
+    public @NonNull AudioAttributes getAudioAttributes() {
+        if (mState == STATE_UNINITIALIZED || mConfiguredAudioAttributes == null) {
+            throw new IllegalStateException("track not initialized");
+        }
+        return mConfiguredAudioAttributes;
+    }
+
+    /**
+     * Returns the configured audio data encoding. See {@link AudioFormat#ENCODING_PCM_8BIT},
+     * {@link AudioFormat#ENCODING_PCM_16BIT}, and {@link AudioFormat#ENCODING_PCM_FLOAT}.
+     */
+    public int getAudioFormat() {
+        return mAudioFormat;
+    }
+
+    /**
+     * Returns the volume stream type of this AudioTrack.
+     * Compare the result against {@link AudioManager#STREAM_VOICE_CALL},
+     * {@link AudioManager#STREAM_SYSTEM}, {@link AudioManager#STREAM_RING},
+     * {@link AudioManager#STREAM_MUSIC}, {@link AudioManager#STREAM_ALARM},
+     * {@link AudioManager#STREAM_NOTIFICATION}, {@link AudioManager#STREAM_DTMF} or
+     * {@link AudioManager#STREAM_ACCESSIBILITY}.
+     */
+    public int getStreamType() {
+        return mStreamType;
+    }
+
+    /**
+     * Returns the configured channel position mask.
+     * <p> For example, refer to {@link AudioFormat#CHANNEL_OUT_MONO},
+     * {@link AudioFormat#CHANNEL_OUT_STEREO}, {@link AudioFormat#CHANNEL_OUT_5POINT1}.
+     * This method may return {@link AudioFormat#CHANNEL_INVALID} if
+     * a channel index mask was used. Consider
+     * {@link #getFormat()} instead, to obtain an {@link AudioFormat},
+     * which contains both the channel position mask and the channel index mask.
+     */
+    public int getChannelConfiguration() {
+        return mChannelConfiguration;
+    }
+
+    /**
+     * Returns the configured <code>AudioTrack</code> format.
+     * @return an {@link AudioFormat} containing the
+     * <code>AudioTrack</code> parameters at the time of configuration.
+     */
+    public @NonNull AudioFormat getFormat() {
+        AudioFormat.Builder builder = new AudioFormat.Builder()
+            .setSampleRate(mSampleRate)
+            .setEncoding(mAudioFormat);
+        if (mChannelConfiguration != AudioFormat.CHANNEL_INVALID) {
+            builder.setChannelMask(mChannelConfiguration);
+        }
+        if (mChannelIndexMask != AudioFormat.CHANNEL_INVALID /* 0 */) {
+            builder.setChannelIndexMask(mChannelIndexMask);
+        }
+        return builder.build();
+    }
+
+    /**
+     * Returns the configured number of channels.
+     */
+    public int getChannelCount() {
+        return mChannelCount;
+    }
+
+    /**
+     * Returns the state of the AudioTrack instance. This is useful after the
+     * AudioTrack instance has been created to check if it was initialized
+     * properly. This ensures that the appropriate resources have been acquired.
+     * @see #STATE_UNINITIALIZED
+     * @see #STATE_INITIALIZED
+     * @see #STATE_NO_STATIC_DATA
+     */
+    public int getState() {
+        return mState;
+    }
+
+    /**
+     * Returns the playback state of the AudioTrack instance.
+     * @see #PLAYSTATE_STOPPED
+     * @see #PLAYSTATE_PAUSED
+     * @see #PLAYSTATE_PLAYING
+     */
+    public int getPlayState() {
+        synchronized (mPlayStateLock) {
+            switch (mPlayState) {
+                case PLAYSTATE_STOPPING:
+                    return PLAYSTATE_PLAYING;
+                case PLAYSTATE_PAUSED_STOPPING:
+                    return PLAYSTATE_PAUSED;
+                default:
+                    return mPlayState;
+            }
+        }
+    }
+
+
+    /**
+     * Returns the effective size of the <code>AudioTrack</code> buffer
+     * that the application writes to.
+     * <p> This will be less than or equal to the result of
+     * {@link #getBufferCapacityInFrames()}.
+     * It will be equal if {@link #setBufferSizeInFrames(int)} has never been called.
+     * <p> If the track is subsequently routed to a different output sink, the buffer
+     * size and capacity may enlarge to accommodate.
+     * <p> If the <code>AudioTrack</code> encoding indicates compressed data,
+     * e.g. {@link AudioFormat#ENCODING_AC3}, then the frame count returned is
+     * the size of the <code>AudioTrack</code> buffer in bytes.
+     * <p> See also {@link AudioManager#getProperty(String)} for key
+     * {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
+     * @return current size in frames of the <code>AudioTrack</code> buffer.
+     * @throws IllegalStateException if track is not initialized.
+     */
+    public @IntRange (from = 0) int getBufferSizeInFrames() {
+        return native_get_buffer_size_frames();
+    }
+
+    /**
+     * Limits the effective size of the <code>AudioTrack</code> buffer
+     * that the application writes to.
+     * <p> A write to this AudioTrack will not fill the buffer beyond this limit.
+     * If a blocking write is used then the write will block until the data
+     * can fit within this limit.
+     * <p>Changing this limit modifies the latency associated with
+     * the buffer for this track. A smaller size will give lower latency
+     * but there may be more glitches due to buffer underruns.
+     * <p>The actual size used may not be equal to this requested size.
+     * It will be limited to a valid range with a maximum of
+     * {@link #getBufferCapacityInFrames()}.
+     * It may also be adjusted slightly for internal reasons.
+     * If bufferSizeInFrames is less than zero then {@link #ERROR_BAD_VALUE}
+     * will be returned.
+     * <p>This method is only supported for PCM audio.
+     * It is not supported for compressed audio tracks.
+     *
+     * @param bufferSizeInFrames requested buffer size in frames
+     * @return the actual buffer size in frames or an error code,
+     *    {@link #ERROR_BAD_VALUE}, {@link #ERROR_INVALID_OPERATION}
+     * @throws IllegalStateException if track is not initialized.
+     */
+    public int setBufferSizeInFrames(@IntRange (from = 0) int bufferSizeInFrames) {
+        if (mDataLoadMode == MODE_STATIC || mState == STATE_UNINITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
+        if (bufferSizeInFrames < 0) {
+            return ERROR_BAD_VALUE;
+        }
+        return native_set_buffer_size_frames(bufferSizeInFrames);
+    }
+
+    /**
+     *  Returns the maximum size of the <code>AudioTrack</code> buffer in frames.
+     *  <p> If the track's creation mode is {@link #MODE_STATIC},
+     *  it is equal to the specified bufferSizeInBytes on construction, converted to frame units.
+     *  A static track's frame count will not change.
+     *  <p> If the track's creation mode is {@link #MODE_STREAM},
+     *  it is greater than or equal to the specified bufferSizeInBytes converted to frame units.
+     *  For streaming tracks, this value may be rounded up to a larger value if needed by
+     *  the target output sink, and
+     *  if the track is subsequently routed to a different output sink, the
+     *  frame count may enlarge to accommodate.
+     *  <p> If the <code>AudioTrack</code> encoding indicates compressed data,
+     *  e.g. {@link AudioFormat#ENCODING_AC3}, then the frame count returned is
+     *  the size of the <code>AudioTrack</code> buffer in bytes.
+     *  <p> See also {@link AudioManager#getProperty(String)} for key
+     *  {@link AudioManager#PROPERTY_OUTPUT_FRAMES_PER_BUFFER}.
+     *  @return maximum size in frames of the <code>AudioTrack</code> buffer.
+     *  @throws IllegalStateException if track is not initialized.
+     */
+    public @IntRange (from = 0) int getBufferCapacityInFrames() {
+        return native_get_buffer_capacity_frames();
+    }
+
+    /**
+     * Sets the streaming start threshold for an <code>AudioTrack</code>.
+     * <p> The streaming start threshold is the buffer level that the written audio
+     * data must reach for audio streaming to start after {@link #play()} is called.
+     * <p> For compressed streams, the size of a frame is considered to be exactly one byte.
+     *
+     * @param startThresholdInFrames the desired start threshold.
+     * @return the actual start threshold in frames value. This is
+     *         an integer between 1 to the buffer capacity
+     *         (see {@link #getBufferCapacityInFrames()}),
+     *         and might change if the output sink changes after track creation.
+     * @throws IllegalStateException if the track is not initialized or the
+     *         track transfer mode is not {@link #MODE_STREAM}.
+     * @throws IllegalArgumentException if startThresholdInFrames is not positive.
+     * @see #getStartThresholdInFrames()
+     */
+    public @IntRange(from = 1) int setStartThresholdInFrames(
+            @IntRange (from = 1) int startThresholdInFrames) {
+        if (mState != STATE_INITIALIZED) {
+            throw new IllegalStateException("AudioTrack is not initialized");
+        }
+        if (mDataLoadMode != MODE_STREAM) {
+            throw new IllegalStateException("AudioTrack must be a streaming track");
+        }
+        if (startThresholdInFrames < 1) {
+            throw new IllegalArgumentException("startThresholdInFrames "
+                    + startThresholdInFrames + " must be positive");
+        }
+        return native_setStartThresholdInFrames(startThresholdInFrames);
+    }
+
+    /**
+     * Returns the streaming start threshold of the <code>AudioTrack</code>.
+     * <p> The streaming start threshold is the buffer level that the written audio
+     * data must reach for audio streaming to start after {@link #play()} is called.
+     * When an <code>AudioTrack</code> is created, the streaming start threshold
+     * is the buffer capacity in frames. If the buffer size in frames is reduced
+     * by {@link #setBufferSizeInFrames(int)} to a value smaller than the start threshold
+     * then that value will be used instead for the streaming start threshold.
+     * <p> For compressed streams, the size of a frame is considered to be exactly one byte.
+     *
+     * @return the current start threshold in frames value. This is
+     *         an integer between 1 to the buffer capacity
+     *         (see {@link #getBufferCapacityInFrames()}),
+     *         and might change if the  output sink changes after track creation.
+     * @throws IllegalStateException if the track is not initialized or the
+     *         track is not {@link #MODE_STREAM}.
+     * @see #setStartThresholdInFrames(int)
+     */
+    public @IntRange (from = 1) int getStartThresholdInFrames() {
+        if (mState != STATE_INITIALIZED) {
+            throw new IllegalStateException("AudioTrack is not initialized");
+        }
+        if (mDataLoadMode != MODE_STREAM) {
+            throw new IllegalStateException("AudioTrack must be a streaming track");
+        }
+        return native_getStartThresholdInFrames();
+    }
+
+    /**
+     *  Returns the frame count of the native <code>AudioTrack</code> buffer.
+     *  @return current size in frames of the <code>AudioTrack</code> buffer.
+     *  @throws IllegalStateException
+     *  @deprecated Use the identical public method {@link #getBufferSizeInFrames()} instead.
+     */
+    @Deprecated
+    protected int getNativeFrameCount() {
+        return native_get_buffer_capacity_frames();
+    }
+
+    /**
+     * Returns marker position expressed in frames.
+     * @return marker position in wrapping frame units similar to {@link #getPlaybackHeadPosition},
+     * or zero if marker is disabled.
+     */
+    public int getNotificationMarkerPosition() {
+        return native_get_marker_pos();
+    }
+
+    /**
+     * Returns the notification update period expressed in frames.
+     * Zero means that no position update notifications are being delivered.
+     */
+    public int getPositionNotificationPeriod() {
+        return native_get_pos_update_period();
+    }
+
+    /**
+     * Returns the playback head position expressed in frames.
+     * Though the "int" type is signed 32-bits, the value should be reinterpreted as if it is
+     * unsigned 32-bits.  That is, the next position after 0x7FFFFFFF is (int) 0x80000000.
+     * This is a continuously advancing counter.  It will wrap (overflow) periodically,
+     * for example approximately once every 27:03:11 hours:minutes:seconds at 44.1 kHz.
+     * It is reset to zero by {@link #flush()}, {@link #reloadStaticData()}, and {@link #stop()}.
+     * If the track's creation mode is {@link #MODE_STATIC}, the return value indicates
+     * the total number of frames played since reset,
+     * <i>not</i> the current offset within the buffer.
+     */
+    public int getPlaybackHeadPosition() {
+        return native_get_position();
+    }
+
+    /**
+     * Returns this track's estimated latency in milliseconds. This includes the latency due
+     * to AudioTrack buffer size, AudioMixer (if any) and audio hardware driver.
+     *
+     * DO NOT UNHIDE. The existing approach for doing A/V sync has too many problems. We need
+     * a better solution.
+     * @hide
+     */
+    @UnsupportedAppUsage(trackingBug = 130237544)
+    public int getLatency() {
+        return native_get_latency();
+    }
+
+    /**
+     * Returns the number of underrun occurrences in the application-level write buffer
+     * since the AudioTrack was created.
+     * An underrun occurs if the application does not write audio
+     * data quickly enough, causing the buffer to underflow
+     * and a potential audio glitch or pop.
+     * <p>
+     * Underruns are less likely when buffer sizes are large.
+     * It may be possible to eliminate underruns by recreating the AudioTrack with
+     * a larger buffer.
+     * Or by using {@link #setBufferSizeInFrames(int)} to dynamically increase the
+     * effective size of the buffer.
+     */
+    public int getUnderrunCount() {
+        return native_get_underrun_count();
+    }
+
+    /**
+     * Returns the current performance mode of the {@link AudioTrack}.
+     *
+     * @return one of {@link AudioTrack#PERFORMANCE_MODE_NONE},
+     * {@link AudioTrack#PERFORMANCE_MODE_LOW_LATENCY},
+     * or {@link AudioTrack#PERFORMANCE_MODE_POWER_SAVING}.
+     * Use {@link AudioTrack.Builder#setPerformanceMode}
+     * in the {@link AudioTrack.Builder} to enable a performance mode.
+     * @throws IllegalStateException if track is not initialized.
+     */
+    public @PerformanceMode int getPerformanceMode() {
+        final int flags = native_get_flags();
+        if ((flags & AUDIO_OUTPUT_FLAG_FAST) != 0) {
+            return PERFORMANCE_MODE_LOW_LATENCY;
+        } else if ((flags & AUDIO_OUTPUT_FLAG_DEEP_BUFFER) != 0) {
+            return PERFORMANCE_MODE_POWER_SAVING;
+        } else {
+            return PERFORMANCE_MODE_NONE;
+        }
+    }
+
+    /**
+     *  Returns the output sample rate in Hz for the specified stream type.
+     */
+    static public int getNativeOutputSampleRate(int streamType) {
+        return native_get_output_sample_rate(streamType);
+    }
+
+    /**
+     * Returns the estimated minimum buffer size required for an AudioTrack
+     * object to be created in the {@link #MODE_STREAM} mode.
+     * The size is an estimate because it does not consider either the route or the sink,
+     * since neither is known yet.  Note that this size doesn't
+     * guarantee a smooth playback under load, and higher values should be chosen according to
+     * the expected frequency at which the buffer will be refilled with additional data to play.
+     * For example, if you intend to dynamically set the source sample rate of an AudioTrack
+     * to a higher value than the initial source sample rate, be sure to configure the buffer size
+     * based on the highest planned sample rate.
+     * @param sampleRateInHz the source sample rate expressed in Hz.
+     *   {@link AudioFormat#SAMPLE_RATE_UNSPECIFIED} is not permitted.
+     * @param channelConfig describes the configuration of the audio channels.
+     *   See {@link AudioFormat#CHANNEL_OUT_MONO} and
+     *   {@link AudioFormat#CHANNEL_OUT_STEREO}
+     * @param audioFormat the format in which the audio data is represented.
+     *   See {@link AudioFormat#ENCODING_PCM_16BIT} and
+     *   {@link AudioFormat#ENCODING_PCM_8BIT},
+     *   and {@link AudioFormat#ENCODING_PCM_FLOAT}.
+     * @return {@link #ERROR_BAD_VALUE} if an invalid parameter was passed,
+     *   or {@link #ERROR} if unable to query for output properties,
+     *   or the minimum buffer size expressed in bytes.
+     */
+    static public int getMinBufferSize(int sampleRateInHz, int channelConfig, int audioFormat) {
+        int channelCount = 0;
+        switch(channelConfig) {
+        case AudioFormat.CHANNEL_OUT_MONO:
+        case AudioFormat.CHANNEL_CONFIGURATION_MONO:
+            channelCount = 1;
+            break;
+        case AudioFormat.CHANNEL_OUT_STEREO:
+        case AudioFormat.CHANNEL_CONFIGURATION_STEREO:
+            channelCount = 2;
+            break;
+        default:
+            if (!isMultichannelConfigSupported(channelConfig, audioFormat)) {
+                loge("getMinBufferSize(): Invalid channel configuration.");
+                return ERROR_BAD_VALUE;
+            } else {
+                channelCount = AudioFormat.channelCountFromOutChannelMask(channelConfig);
+            }
+        }
+
+        if (!AudioFormat.isPublicEncoding(audioFormat)) {
+            loge("getMinBufferSize(): Invalid audio format.");
+            return ERROR_BAD_VALUE;
+        }
+
+        // sample rate, note these values are subject to change
+        // Note: AudioFormat.SAMPLE_RATE_UNSPECIFIED is not allowed
+        if ( (sampleRateInHz < AudioFormat.SAMPLE_RATE_HZ_MIN) ||
+                (sampleRateInHz > AudioFormat.SAMPLE_RATE_HZ_MAX) ) {
+            loge("getMinBufferSize(): " + sampleRateInHz + " Hz is not a supported sample rate.");
+            return ERROR_BAD_VALUE;
+        }
+
+        int size = native_get_min_buff_size(sampleRateInHz, channelCount, audioFormat);
+        if (size <= 0) {
+            loge("getMinBufferSize(): error querying hardware");
+            return ERROR;
+        }
+        else {
+            return size;
+        }
+    }
+
+    /**
+     * Returns the audio session ID.
+     *
+     * @return the ID of the audio session this AudioTrack belongs to.
+     */
+    public int getAudioSessionId() {
+        return mSessionId;
+    }
+
+   /**
+    * Poll for a timestamp on demand.
+    * <p>
+    * If you need to track timestamps during initial warmup or after a routing or mode change,
+    * you should request a new timestamp periodically until the reported timestamps
+    * show that the frame position is advancing, or until it becomes clear that
+    * timestamps are unavailable for this route.
+    * <p>
+    * After the clock is advancing at a stable rate,
+    * query for a new timestamp approximately once every 10 seconds to once per minute.
+    * Calling this method more often is inefficient.
+    * It is also counter-productive to call this method more often than recommended,
+    * because the short-term differences between successive timestamp reports are not meaningful.
+    * If you need a high-resolution mapping between frame position and presentation time,
+    * consider implementing that at application level, based on low-resolution timestamps.
+    * <p>
+    * The audio data at the returned position may either already have been
+    * presented, or may have not yet been presented but is committed to be presented.
+    * It is not possible to request the time corresponding to a particular position,
+    * or to request the (fractional) position corresponding to a particular time.
+    * If you need such features, consider implementing them at application level.
+    *
+    * @param timestamp a reference to a non-null AudioTimestamp instance allocated
+    *        and owned by caller.
+    * @return true if a timestamp is available, or false if no timestamp is available.
+    *         If a timestamp is available,
+    *         the AudioTimestamp instance is filled in with a position in frame units, together
+    *         with the estimated time when that frame was presented or is committed to
+    *         be presented.
+    *         In the case that no timestamp is available, any supplied instance is left unaltered.
+    *         A timestamp may be temporarily unavailable while the audio clock is stabilizing,
+    *         or during and immediately after a route change.
+    *         A timestamp is permanently unavailable for a given route if the route does not support
+    *         timestamps.  In this case, the approximate frame position can be obtained
+    *         using {@link #getPlaybackHeadPosition}.
+    *         However, it may be useful to continue to query for
+    *         timestamps occasionally, to recover after a route change.
+    */
+    // Add this text when the "on new timestamp" API is added:
+    //   Use if you need to get the most recent timestamp outside of the event callback handler.
+    public boolean getTimestamp(AudioTimestamp timestamp)
+    {
+        if (timestamp == null) {
+            throw new IllegalArgumentException();
+        }
+        // It's unfortunate, but we have to either create garbage every time or use synchronized
+        long[] longArray = new long[2];
+        int ret = native_get_timestamp(longArray);
+        if (ret != SUCCESS) {
+            return false;
+        }
+        timestamp.framePosition = longArray[0];
+        timestamp.nanoTime = longArray[1];
+        return true;
+    }
+
+    /**
+     * Poll for a timestamp on demand.
+     * <p>
+     * Same as {@link #getTimestamp(AudioTimestamp)} but with a more useful return code.
+     *
+     * @param timestamp a reference to a non-null AudioTimestamp instance allocated
+     *        and owned by caller.
+     * @return {@link #SUCCESS} if a timestamp is available
+     *         {@link #ERROR_WOULD_BLOCK} if called in STOPPED or FLUSHED state, or if called
+     *         immediately after start/ACTIVE, when the number of frames consumed is less than the
+     *         overall hardware latency to physical output. In WOULD_BLOCK cases, one might poll
+     *         again, or use {@link #getPlaybackHeadPosition}, or use 0 position and current time
+     *         for the timestamp.
+     *         {@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
+     *         needs to be recreated.
+     *         {@link #ERROR_INVALID_OPERATION} if current route does not support
+     *         timestamps. In this case, the approximate frame position can be obtained
+     *         using {@link #getPlaybackHeadPosition}.
+     *
+     *         The AudioTimestamp instance is filled in with a position in frame units, together
+     *         with the estimated time when that frame was presented or is committed to
+     *         be presented.
+     * @hide
+     */
+     // Add this text when the "on new timestamp" API is added:
+     //   Use if you need to get the most recent timestamp outside of the event callback handler.
+     public int getTimestampWithStatus(AudioTimestamp timestamp)
+     {
+         if (timestamp == null) {
+             throw new IllegalArgumentException();
+         }
+         // It's unfortunate, but we have to either create garbage every time or use synchronized
+         long[] longArray = new long[2];
+         int ret = native_get_timestamp(longArray);
+         timestamp.framePosition = longArray[0];
+         timestamp.nanoTime = longArray[1];
+         return ret;
+     }
+
+    /**
+     *  Return Metrics data about the current AudioTrack instance.
+     *
+     * @return a {@link PersistableBundle} containing the set of attributes and values
+     * available for the media being handled by this instance of AudioTrack
+     * The attributes are descibed in {@link MetricsConstants}.
+     *
+     * Additional vendor-specific fields may also be present in
+     * the return value.
+     */
+    public PersistableBundle getMetrics() {
+        PersistableBundle bundle = native_getMetrics();
+        return bundle;
+    }
+
+    private native PersistableBundle native_getMetrics();
+
+    //--------------------------------------------------------------------------
+    // Initialization / configuration
+    //--------------------
+    /**
+     * Sets the listener the AudioTrack notifies when a previously set marker is reached or
+     * for each periodic playback head position update.
+     * Notifications will be received in the same thread as the one in which the AudioTrack
+     * instance was created.
+     * @param listener
+     */
+    public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener) {
+        setPlaybackPositionUpdateListener(listener, null);
+    }
+
+    /**
+     * Sets the listener the AudioTrack notifies when a previously set marker is reached or
+     * for each periodic playback head position update.
+     * Use this method to receive AudioTrack events in the Handler associated with another
+     * thread than the one in which you created the AudioTrack instance.
+     * @param listener
+     * @param handler the Handler that will receive the event notification messages.
+     */
+    public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener listener,
+                                                    Handler handler) {
+        if (listener != null) {
+            mEventHandlerDelegate = new NativePositionEventHandlerDelegate(this, listener, handler);
+        } else {
+            mEventHandlerDelegate = null;
+        }
+    }
+
+
+    private static float clampGainOrLevel(float gainOrLevel) {
+        if (Float.isNaN(gainOrLevel)) {
+            throw new IllegalArgumentException();
+        }
+        if (gainOrLevel < GAIN_MIN) {
+            gainOrLevel = GAIN_MIN;
+        } else if (gainOrLevel > GAIN_MAX) {
+            gainOrLevel = GAIN_MAX;
+        }
+        return gainOrLevel;
+    }
+
+
+     /**
+     * Sets the specified left and right output gain values on the AudioTrack.
+     * <p>Gain values are clamped to the closed interval [0.0, max] where
+     * max is the value of {@link #getMaxVolume}.
+     * A value of 0.0 results in zero gain (silence), and
+     * a value of 1.0 means unity gain (signal unchanged).
+     * The default value is 1.0 meaning unity gain.
+     * <p>The word "volume" in the API name is historical; this is actually a linear gain.
+     * @param leftGain output gain for the left channel.
+     * @param rightGain output gain for the right channel
+     * @return error code or success, see {@link #SUCCESS},
+     *    {@link #ERROR_INVALID_OPERATION}
+     * @deprecated Applications should use {@link #setVolume} instead, as it
+     * more gracefully scales down to mono, and up to multi-channel content beyond stereo.
+     */
+    @Deprecated
+    public int setStereoVolume(float leftGain, float rightGain) {
+        if (mState == STATE_UNINITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
+
+        baseSetVolume(leftGain, rightGain);
+        return SUCCESS;
+    }
+
+    @Override
+    void playerSetVolume(boolean muting, float leftVolume, float rightVolume) {
+        leftVolume = clampGainOrLevel(muting ? 0.0f : leftVolume);
+        rightVolume = clampGainOrLevel(muting ? 0.0f : rightVolume);
+
+        native_setVolume(leftVolume, rightVolume);
+    }
+
+
+    /**
+     * Sets the specified output gain value on all channels of this track.
+     * <p>Gain values are clamped to the closed interval [0.0, max] where
+     * max is the value of {@link #getMaxVolume}.
+     * A value of 0.0 results in zero gain (silence), and
+     * a value of 1.0 means unity gain (signal unchanged).
+     * The default value is 1.0 meaning unity gain.
+     * <p>This API is preferred over {@link #setStereoVolume}, as it
+     * more gracefully scales down to mono, and up to multi-channel content beyond stereo.
+     * <p>The word "volume" in the API name is historical; this is actually a linear gain.
+     * @param gain output gain for all channels.
+     * @return error code or success, see {@link #SUCCESS},
+     *    {@link #ERROR_INVALID_OPERATION}
+     */
+    public int setVolume(float gain) {
+        return setStereoVolume(gain, gain);
+    }
+
+    @Override
+    /* package */ int playerApplyVolumeShaper(
+            @NonNull VolumeShaper.Configuration configuration,
+            @NonNull VolumeShaper.Operation operation) {
+        return native_applyVolumeShaper(configuration, operation);
+    }
+
+    @Override
+    /* package */ @Nullable VolumeShaper.State playerGetVolumeShaperState(int id) {
+        return native_getVolumeShaperState(id);
+    }
+
+    @Override
+    public @NonNull VolumeShaper createVolumeShaper(
+            @NonNull VolumeShaper.Configuration configuration) {
+        return new VolumeShaper(configuration, this);
+    }
+
+    /**
+     * Sets the playback sample rate for this track. This sets the sampling rate at which
+     * the audio data will be consumed and played back
+     * (as set by the sampleRateInHz parameter in the
+     * {@link #AudioTrack(int, int, int, int, int, int)} constructor),
+     * not the original sampling rate of the
+     * content. For example, setting it to half the sample rate of the content will cause the
+     * playback to last twice as long, but will also result in a pitch shift down by one octave.
+     * The valid sample rate range is from 1 Hz to twice the value returned by
+     * {@link #getNativeOutputSampleRate(int)}.
+     * Use {@link #setPlaybackParams(PlaybackParams)} for speed control.
+     * <p> This method may also be used to repurpose an existing <code>AudioTrack</code>
+     * for playback of content of differing sample rate,
+     * but with identical encoding and channel mask.
+     * @param sampleRateInHz the sample rate expressed in Hz
+     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
+     *    {@link #ERROR_INVALID_OPERATION}
+     */
+    public int setPlaybackRate(int sampleRateInHz) {
+        if (mState != STATE_INITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
+        if (sampleRateInHz <= 0) {
+            return ERROR_BAD_VALUE;
+        }
+        return native_set_playback_rate(sampleRateInHz);
+    }
+
+
+    /**
+     * Sets the playback parameters.
+     * This method returns failure if it cannot apply the playback parameters.
+     * One possible cause is that the parameters for speed or pitch are out of range.
+     * Another possible cause is that the <code>AudioTrack</code> is streaming
+     * (see {@link #MODE_STREAM}) and the
+     * buffer size is too small. For speeds greater than 1.0f, the <code>AudioTrack</code> buffer
+     * on configuration must be larger than the speed multiplied by the minimum size
+     * {@link #getMinBufferSize(int, int, int)}) to allow proper playback.
+     * @param params see {@link PlaybackParams}. In particular,
+     * speed, pitch, and audio mode should be set.
+     * @throws IllegalArgumentException if the parameters are invalid or not accepted.
+     * @throws IllegalStateException if track is not initialized.
+     */
+    public void setPlaybackParams(@NonNull PlaybackParams params) {
+        if (params == null) {
+            throw new IllegalArgumentException("params is null");
+        }
+        native_set_playback_params(params);
+    }
+
+
+    /**
+     * Sets the position of the notification marker.  At most one marker can be active.
+     * @param markerInFrames marker position in wrapping frame units similar to
+     * {@link #getPlaybackHeadPosition}, or zero to disable the marker.
+     * To set a marker at a position which would appear as zero due to wraparound,
+     * a workaround is to use a non-zero position near zero, such as -1 or 1.
+     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
+     *  {@link #ERROR_INVALID_OPERATION}
+     */
+    public int setNotificationMarkerPosition(int markerInFrames) {
+        if (mState == STATE_UNINITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
+        return native_set_marker_pos(markerInFrames);
+    }
+
+
+    /**
+     * Sets the period for the periodic notification event.
+     * @param periodInFrames update period expressed in frames.
+     * Zero period means no position updates.  A negative period is not allowed.
+     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_INVALID_OPERATION}
+     */
+    public int setPositionNotificationPeriod(int periodInFrames) {
+        if (mState == STATE_UNINITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
+        return native_set_pos_update_period(periodInFrames);
+    }
+
+
+    /**
+     * Sets the playback head position within the static buffer.
+     * The track must be stopped or paused for the position to be changed,
+     * and must use the {@link #MODE_STATIC} mode.
+     * @param positionInFrames playback head position within buffer, expressed in frames.
+     * Zero corresponds to start of buffer.
+     * The position must not be greater than the buffer size in frames, or negative.
+     * Though this method and {@link #getPlaybackHeadPosition()} have similar names,
+     * the position values have different meanings.
+     * <br>
+     * If looping is currently enabled and the new position is greater than or equal to the
+     * loop end marker, the behavior varies by API level:
+     * as of {@link android.os.Build.VERSION_CODES#M},
+     * the looping is first disabled and then the position is set.
+     * For earlier API levels, the behavior is unspecified.
+     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
+     *    {@link #ERROR_INVALID_OPERATION}
+     */
+    public int setPlaybackHeadPosition(@IntRange (from = 0) int positionInFrames) {
+        if (mDataLoadMode == MODE_STREAM || mState == STATE_UNINITIALIZED ||
+                getPlayState() == PLAYSTATE_PLAYING) {
+            return ERROR_INVALID_OPERATION;
+        }
+        if (!(0 <= positionInFrames && positionInFrames <= mNativeBufferSizeInFrames)) {
+            return ERROR_BAD_VALUE;
+        }
+        return native_set_position(positionInFrames);
+    }
+
+    /**
+     * Sets the loop points and the loop count. The loop can be infinite.
+     * Similarly to setPlaybackHeadPosition,
+     * the track must be stopped or paused for the loop points to be changed,
+     * and must use the {@link #MODE_STATIC} mode.
+     * @param startInFrames loop start marker expressed in frames.
+     * Zero corresponds to start of buffer.
+     * The start marker must not be greater than or equal to the buffer size in frames, or negative.
+     * @param endInFrames loop end marker expressed in frames.
+     * The total buffer size in frames corresponds to end of buffer.
+     * The end marker must not be greater than the buffer size in frames.
+     * For looping, the end marker must not be less than or equal to the start marker,
+     * but to disable looping
+     * it is permitted for start marker, end marker, and loop count to all be 0.
+     * If any input parameters are out of range, this method returns {@link #ERROR_BAD_VALUE}.
+     * If the loop period (endInFrames - startInFrames) is too small for the implementation to
+     * support,
+     * {@link #ERROR_BAD_VALUE} is returned.
+     * The loop range is the interval [startInFrames, endInFrames).
+     * <br>
+     * As of {@link android.os.Build.VERSION_CODES#M}, the position is left unchanged,
+     * unless it is greater than or equal to the loop end marker, in which case
+     * it is forced to the loop start marker.
+     * For earlier API levels, the effect on position is unspecified.
+     * @param loopCount the number of times the loop is looped; must be greater than or equal to -1.
+     *    A value of -1 means infinite looping, and 0 disables looping.
+     *    A value of positive N means to "loop" (go back) N times.  For example,
+     *    a value of one means to play the region two times in total.
+     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
+     *    {@link #ERROR_INVALID_OPERATION}
+     */
+    public int setLoopPoints(@IntRange (from = 0) int startInFrames,
+            @IntRange (from = 0) int endInFrames, @IntRange (from = -1) int loopCount) {
+        if (mDataLoadMode == MODE_STREAM || mState == STATE_UNINITIALIZED ||
+                getPlayState() == PLAYSTATE_PLAYING) {
+            return ERROR_INVALID_OPERATION;
+        }
+        if (loopCount == 0) {
+            ;   // explicitly allowed as an exception to the loop region range check
+        } else if (!(0 <= startInFrames && startInFrames < mNativeBufferSizeInFrames &&
+                startInFrames < endInFrames && endInFrames <= mNativeBufferSizeInFrames)) {
+            return ERROR_BAD_VALUE;
+        }
+        return native_set_loop(startInFrames, endInFrames, loopCount);
+    }
+
+    /**
+     * Sets the audio presentation.
+     * If the audio presentation is invalid then {@link #ERROR_BAD_VALUE} will be returned.
+     * If a multi-stream decoder (MSD) is not present, or the format does not support
+     * multiple presentations, then {@link #ERROR_INVALID_OPERATION} will be returned.
+     * {@link #ERROR} is returned in case of any other error.
+     * @param presentation see {@link AudioPresentation}. In particular, id should be set.
+     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR},
+     *    {@link #ERROR_BAD_VALUE}, {@link #ERROR_INVALID_OPERATION}
+     * @throws IllegalArgumentException if the audio presentation is null.
+     * @throws IllegalStateException if track is not initialized.
+     */
+    public int setPresentation(@NonNull AudioPresentation presentation) {
+        if (presentation == null) {
+            throw new IllegalArgumentException("audio presentation is null");
+        }
+        return native_setPresentation(presentation.getPresentationId(),
+                presentation.getProgramId());
+    }
+
+    /**
+     * Sets the initialization state of the instance. This method was originally intended to be used
+     * in an AudioTrack subclass constructor to set a subclass-specific post-initialization state.
+     * However, subclasses of AudioTrack are no longer recommended, so this method is obsolete.
+     * @param state the state of the AudioTrack instance
+     * @deprecated Only accessible by subclasses, which are not recommended for AudioTrack.
+     */
+    @Deprecated
+    protected void setState(int state) {
+        mState = state;
+    }
+
+
+    //---------------------------------------------------------
+    // Transport control methods
+    //--------------------
+    /**
+     * Starts playing an AudioTrack.
+     * <p>
+     * If track's creation mode is {@link #MODE_STATIC}, you must have called one of
+     * the write methods ({@link #write(byte[], int, int)}, {@link #write(byte[], int, int, int)},
+     * {@link #write(short[], int, int)}, {@link #write(short[], int, int, int)},
+     * {@link #write(float[], int, int, int)}, or {@link #write(ByteBuffer, int, int)}) prior to
+     * play().
+     * <p>
+     * If the mode is {@link #MODE_STREAM}, you can optionally prime the data path prior to
+     * calling play(), by writing up to <code>bufferSizeInBytes</code> (from constructor).
+     * If you don't call write() first, or if you call write() but with an insufficient amount of
+     * data, then the track will be in underrun state at play().  In this case,
+     * playback will not actually start playing until the data path is filled to a
+     * device-specific minimum level.  This requirement for the path to be filled
+     * to a minimum level is also true when resuming audio playback after calling stop().
+     * Similarly the buffer will need to be filled up again after
+     * the track underruns due to failure to call write() in a timely manner with sufficient data.
+     * For portability, an application should prime the data path to the maximum allowed
+     * by writing data until the write() method returns a short transfer count.
+     * This allows play() to start immediately, and reduces the chance of underrun.
+     *
+     * @throws IllegalStateException if the track isn't properly initialized
+     */
+    public void play()
+    throws IllegalStateException {
+        if (mState != STATE_INITIALIZED) {
+            throw new IllegalStateException("play() called on uninitialized AudioTrack.");
+        }
+        //FIXME use lambda to pass startImpl to superclass
+        final int delay = getStartDelayMs();
+        if (delay == 0) {
+            startImpl();
+        } else {
+            new Thread() {
+                public void run() {
+                    try {
+                        Thread.sleep(delay);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    baseSetStartDelayMs(0);
+                    try {
+                        startImpl();
+                    } catch (IllegalStateException e) {
+                        // fail silently for a state exception when it is happening after
+                        // a delayed start, as the player state could have changed between the
+                        // call to start() and the execution of startImpl()
+                    }
+                }
+            }.start();
+        }
+    }
+
+    private void startImpl() {
+        synchronized (mRoutingChangeListeners) {
+            if (!mEnableSelfRoutingMonitor) {
+                mEnableSelfRoutingMonitor = testEnableNativeRoutingCallbacksLocked();
+            }
+        }
+        synchronized(mPlayStateLock) {
+            baseStart(0); // unknown device at this point
+            native_start();
+            // FIXME see b/179218630
+            //baseStart(native_getRoutedDeviceId());
+            if (mPlayState == PLAYSTATE_PAUSED_STOPPING) {
+                mPlayState = PLAYSTATE_STOPPING;
+            } else {
+                mPlayState = PLAYSTATE_PLAYING;
+                mOffloadEosPending = false;
+            }
+        }
+    }
+
+    /**
+     * Stops playing the audio data.
+     * When used on an instance created in {@link #MODE_STREAM} mode, audio will stop playing
+     * after the last buffer that was written has been played. For an immediate stop, use
+     * {@link #pause()}, followed by {@link #flush()} to discard audio data that hasn't been played
+     * back yet.
+     * @throws IllegalStateException
+     */
+    public void stop()
+    throws IllegalStateException {
+        if (mState != STATE_INITIALIZED) {
+            throw new IllegalStateException("stop() called on uninitialized AudioTrack.");
+        }
+
+        // stop playing
+        synchronized(mPlayStateLock) {
+            native_stop();
+            baseStop();
+            if (mOffloaded && mPlayState != PLAYSTATE_PAUSED_STOPPING) {
+                mPlayState = PLAYSTATE_STOPPING;
+            } else {
+                mPlayState = PLAYSTATE_STOPPED;
+                mOffloadEosPending = false;
+                mAvSyncHeader = null;
+                mAvSyncBytesRemaining = 0;
+                mPlayStateLock.notify();
+            }
+        }
+        tryToDisableNativeRoutingCallback();
+    }
+
+    /**
+     * Pauses the playback of the audio data. Data that has not been played
+     * back will not be discarded. Subsequent calls to {@link #play} will play
+     * this data back. See {@link #flush()} to discard this data.
+     *
+     * @throws IllegalStateException
+     */
+    public void pause()
+    throws IllegalStateException {
+        if (mState != STATE_INITIALIZED) {
+            throw new IllegalStateException("pause() called on uninitialized AudioTrack.");
+        }
+
+        // pause playback
+        synchronized(mPlayStateLock) {
+            native_pause();
+            basePause();
+            if (mPlayState == PLAYSTATE_STOPPING) {
+                mPlayState = PLAYSTATE_PAUSED_STOPPING;
+            } else {
+                mPlayState = PLAYSTATE_PAUSED;
+            }
+        }
+    }
+
+
+    //---------------------------------------------------------
+    // Audio data supply
+    //--------------------
+
+    /**
+     * Flushes the audio data currently queued for playback. Any data that has
+     * been written but not yet presented will be discarded.  No-op if not stopped or paused,
+     * or if the track's creation mode is not {@link #MODE_STREAM}.
+     * <BR> Note that although data written but not yet presented is discarded, there is no
+     * guarantee that all of the buffer space formerly used by that data
+     * is available for a subsequent write.
+     * For example, a call to {@link #write(byte[], int, int)} with <code>sizeInBytes</code>
+     * less than or equal to the total buffer size
+     * may return a short actual transfer count.
+     */
+    public void flush() {
+        if (mState == STATE_INITIALIZED) {
+            // flush the data in native layer
+            native_flush();
+            mAvSyncHeader = null;
+            mAvSyncBytesRemaining = 0;
+        }
+
+    }
+
+    /**
+     * Writes the audio data to the audio sink for playback (streaming mode),
+     * or copies audio data for later playback (static buffer mode).
+     * The format specified in the AudioTrack constructor should be
+     * {@link AudioFormat#ENCODING_PCM_8BIT} to correspond to the data in the array.
+     * The format can be {@link AudioFormat#ENCODING_PCM_16BIT}, but this is deprecated.
+     * <p>
+     * In streaming mode, the write will normally block until all the data has been enqueued for
+     * playback, and will return a full transfer count.  However, if the track is stopped or paused
+     * on entry, or another thread interrupts the write by calling stop or pause, or an I/O error
+     * occurs during the write, then the write may return a short transfer count.
+     * <p>
+     * In static buffer mode, copies the data to the buffer starting at offset 0.
+     * Note that the actual playback of this data might occur after this function returns.
+     *
+     * @param audioData the array that holds the data to play.
+     * @param offsetInBytes the offset expressed in bytes in audioData where the data to write
+     *    starts.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param sizeInBytes the number of bytes to write in audioData after the offset.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
+     * @return zero or the positive number of bytes that were written, or one of the following
+     *    error codes. The number of bytes will be a multiple of the frame size in bytes
+     *    not to exceed sizeInBytes.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next write()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     * This is equivalent to {@link #write(byte[], int, int, int)} with <code>writeMode</code>
+     * set to  {@link #WRITE_BLOCKING}.
+     */
+    public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes) {
+        return write(audioData, offsetInBytes, sizeInBytes, WRITE_BLOCKING);
+    }
+
+    /**
+     * Writes the audio data to the audio sink for playback (streaming mode),
+     * or copies audio data for later playback (static buffer mode).
+     * The format specified in the AudioTrack constructor should be
+     * {@link AudioFormat#ENCODING_PCM_8BIT} to correspond to the data in the array.
+     * The format can be {@link AudioFormat#ENCODING_PCM_16BIT}, but this is deprecated.
+     * <p>
+     * In streaming mode, the blocking behavior depends on the write mode.  If the write mode is
+     * {@link #WRITE_BLOCKING}, the write will normally block until all the data has been enqueued
+     * for playback, and will return a full transfer count.  However, if the write mode is
+     * {@link #WRITE_NON_BLOCKING}, or the track is stopped or paused on entry, or another thread
+     * interrupts the write by calling stop or pause, or an I/O error
+     * occurs during the write, then the write may return a short transfer count.
+     * <p>
+     * In static buffer mode, copies the data to the buffer starting at offset 0,
+     * and the write mode is ignored.
+     * Note that the actual playback of this data might occur after this function returns.
+     *
+     * @param audioData the array that holds the data to play.
+     * @param offsetInBytes the offset expressed in bytes in audioData where the data to write
+     *    starts.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param sizeInBytes the number of bytes to write in audioData after the offset.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
+     *     effect in static mode.
+     *     <br>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
+     *         to the audio sink.
+     *     <br>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
+     *     queuing as much audio data for playback as possible without blocking.
+     * @return zero or the positive number of bytes that were written, or one of the following
+     *    error codes. The number of bytes will be a multiple of the frame size in bytes
+     *    not to exceed sizeInBytes.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next write()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     */
+    public int write(@NonNull byte[] audioData, int offsetInBytes, int sizeInBytes,
+            @WriteMode int writeMode) {
+        // Note: we allow writes of extended integers and compressed formats from a byte array.
+        if (mState == STATE_UNINITIALIZED || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT) {
+            return ERROR_INVALID_OPERATION;
+        }
+
+        if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
+            Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
+            return ERROR_BAD_VALUE;
+        }
+
+        if ( (audioData == null) || (offsetInBytes < 0 ) || (sizeInBytes < 0)
+                || (offsetInBytes + sizeInBytes < 0)    // detect integer overflow
+                || (offsetInBytes + sizeInBytes > audioData.length)) {
+            return ERROR_BAD_VALUE;
+        }
+
+        if (!blockUntilOffloadDrain(writeMode)) {
+            return 0;
+        }
+
+        final int ret = native_write_byte(audioData, offsetInBytes, sizeInBytes, mAudioFormat,
+                writeMode == WRITE_BLOCKING);
+
+        if ((mDataLoadMode == MODE_STATIC)
+                && (mState == STATE_NO_STATIC_DATA)
+                && (ret > 0)) {
+            // benign race with respect to other APIs that read mState
+            mState = STATE_INITIALIZED;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Writes the audio data to the audio sink for playback (streaming mode),
+     * or copies audio data for later playback (static buffer mode).
+     * The format specified in the AudioTrack constructor should be
+     * {@link AudioFormat#ENCODING_PCM_16BIT} to correspond to the data in the array.
+     * <p>
+     * In streaming mode, the write will normally block until all the data has been enqueued for
+     * playback, and will return a full transfer count.  However, if the track is stopped or paused
+     * on entry, or another thread interrupts the write by calling stop or pause, or an I/O error
+     * occurs during the write, then the write may return a short transfer count.
+     * <p>
+     * In static buffer mode, copies the data to the buffer starting at offset 0.
+     * Note that the actual playback of this data might occur after this function returns.
+     *
+     * @param audioData the array that holds the data to play.
+     * @param offsetInShorts the offset expressed in shorts in audioData where the data to play
+     *     starts.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param sizeInShorts the number of shorts to read in audioData after the offset.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
+     * @return zero or the positive number of shorts that were written, or one of the following
+     *    error codes. The number of shorts will be a multiple of the channel count not to
+     *    exceed sizeInShorts.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next write()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     * This is equivalent to {@link #write(short[], int, int, int)} with <code>writeMode</code>
+     * set to  {@link #WRITE_BLOCKING}.
+     */
+    public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts) {
+        return write(audioData, offsetInShorts, sizeInShorts, WRITE_BLOCKING);
+    }
+
+    /**
+     * Writes the audio data to the audio sink for playback (streaming mode),
+     * or copies audio data for later playback (static buffer mode).
+     * The format specified in the AudioTrack constructor should be
+     * {@link AudioFormat#ENCODING_PCM_16BIT} to correspond to the data in the array.
+     * <p>
+     * In streaming mode, the blocking behavior depends on the write mode.  If the write mode is
+     * {@link #WRITE_BLOCKING}, the write will normally block until all the data has been enqueued
+     * for playback, and will return a full transfer count.  However, if the write mode is
+     * {@link #WRITE_NON_BLOCKING}, or the track is stopped or paused on entry, or another thread
+     * interrupts the write by calling stop or pause, or an I/O error
+     * occurs during the write, then the write may return a short transfer count.
+     * <p>
+     * In static buffer mode, copies the data to the buffer starting at offset 0.
+     * Note that the actual playback of this data might occur after this function returns.
+     *
+     * @param audioData the array that holds the data to write.
+     * @param offsetInShorts the offset expressed in shorts in audioData where the data to write
+     *     starts.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param sizeInShorts the number of shorts to read in audioData after the offset.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
+     *     effect in static mode.
+     *     <br>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
+     *         to the audio sink.
+     *     <br>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
+     *     queuing as much audio data for playback as possible without blocking.
+     * @return zero or the positive number of shorts that were written, or one of the following
+     *    error codes. The number of shorts will be a multiple of the channel count not to
+     *    exceed sizeInShorts.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next write()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     */
+    public int write(@NonNull short[] audioData, int offsetInShorts, int sizeInShorts,
+            @WriteMode int writeMode) {
+
+        if (mState == STATE_UNINITIALIZED
+                || mAudioFormat == AudioFormat.ENCODING_PCM_FLOAT
+                // use ByteBuffer or byte[] instead for later encodings
+                || mAudioFormat > AudioFormat.ENCODING_LEGACY_SHORT_ARRAY_THRESHOLD) {
+            return ERROR_INVALID_OPERATION;
+        }
+
+        if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
+            Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
+            return ERROR_BAD_VALUE;
+        }
+
+        if ( (audioData == null) || (offsetInShorts < 0 ) || (sizeInShorts < 0)
+                || (offsetInShorts + sizeInShorts < 0)  // detect integer overflow
+                || (offsetInShorts + sizeInShorts > audioData.length)) {
+            return ERROR_BAD_VALUE;
+        }
+
+        if (!blockUntilOffloadDrain(writeMode)) {
+            return 0;
+        }
+
+        final int ret = native_write_short(audioData, offsetInShorts, sizeInShorts, mAudioFormat,
+                writeMode == WRITE_BLOCKING);
+
+        if ((mDataLoadMode == MODE_STATIC)
+                && (mState == STATE_NO_STATIC_DATA)
+                && (ret > 0)) {
+            // benign race with respect to other APIs that read mState
+            mState = STATE_INITIALIZED;
+        }
+
+        return ret;
+    }
+
+    /**
+     * Writes the audio data to the audio sink for playback (streaming mode),
+     * or copies audio data for later playback (static buffer mode).
+     * The format specified in the AudioTrack constructor should be
+     * {@link AudioFormat#ENCODING_PCM_FLOAT} to correspond to the data in the array.
+     * <p>
+     * In streaming mode, the blocking behavior depends on the write mode.  If the write mode is
+     * {@link #WRITE_BLOCKING}, the write will normally block until all the data has been enqueued
+     * for playback, and will return a full transfer count.  However, if the write mode is
+     * {@link #WRITE_NON_BLOCKING}, or the track is stopped or paused on entry, or another thread
+     * interrupts the write by calling stop or pause, or an I/O error
+     * occurs during the write, then the write may return a short transfer count.
+     * <p>
+     * In static buffer mode, copies the data to the buffer starting at offset 0,
+     * and the write mode is ignored.
+     * Note that the actual playback of this data might occur after this function returns.
+     *
+     * @param audioData the array that holds the data to write.
+     *     The implementation does not clip for sample values within the nominal range
+     *     [-1.0f, 1.0f], provided that all gains in the audio pipeline are
+     *     less than or equal to unity (1.0f), and in the absence of post-processing effects
+     *     that could add energy, such as reverb.  For the convenience of applications
+     *     that compute samples using filters with non-unity gain,
+     *     sample values +3 dB beyond the nominal range are permitted.
+     *     However such values may eventually be limited or clipped, depending on various gains
+     *     and later processing in the audio path.  Therefore applications are encouraged
+     *     to provide samples values within the nominal range.
+     * @param offsetInFloats the offset, expressed as a number of floats,
+     *     in audioData where the data to write starts.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param sizeInFloats the number of floats to write in audioData after the offset.
+     *    Must not be negative, or cause the data access to go out of bounds of the array.
+     * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
+     *     effect in static mode.
+     *     <br>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
+     *         to the audio sink.
+     *     <br>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
+     *     queuing as much audio data for playback as possible without blocking.
+     * @return zero or the positive number of floats that were written, or one of the following
+     *    error codes. The number of floats will be a multiple of the channel count not to
+     *    exceed sizeInFloats.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next write()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     */
+    public int write(@NonNull float[] audioData, int offsetInFloats, int sizeInFloats,
+            @WriteMode int writeMode) {
+
+        if (mState == STATE_UNINITIALIZED) {
+            Log.e(TAG, "AudioTrack.write() called in invalid state STATE_UNINITIALIZED");
+            return ERROR_INVALID_OPERATION;
+        }
+
+        if (mAudioFormat != AudioFormat.ENCODING_PCM_FLOAT) {
+            Log.e(TAG, "AudioTrack.write(float[] ...) requires format ENCODING_PCM_FLOAT");
+            return ERROR_INVALID_OPERATION;
+        }
+
+        if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
+            Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
+            return ERROR_BAD_VALUE;
+        }
+
+        if ( (audioData == null) || (offsetInFloats < 0 ) || (sizeInFloats < 0)
+                || (offsetInFloats + sizeInFloats < 0)  // detect integer overflow
+                || (offsetInFloats + sizeInFloats > audioData.length)) {
+            Log.e(TAG, "AudioTrack.write() called with invalid array, offset, or size");
+            return ERROR_BAD_VALUE;
+        }
+
+        if (!blockUntilOffloadDrain(writeMode)) {
+            return 0;
+        }
+
+        final int ret = native_write_float(audioData, offsetInFloats, sizeInFloats, mAudioFormat,
+                writeMode == WRITE_BLOCKING);
+
+        if ((mDataLoadMode == MODE_STATIC)
+                && (mState == STATE_NO_STATIC_DATA)
+                && (ret > 0)) {
+            // benign race with respect to other APIs that read mState
+            mState = STATE_INITIALIZED;
+        }
+
+        return ret;
+    }
+
+
+    /**
+     * Writes the audio data to the audio sink for playback (streaming mode),
+     * or copies audio data for later playback (static buffer mode).
+     * The audioData in ByteBuffer should match the format specified in the AudioTrack constructor.
+     * <p>
+     * In streaming mode, the blocking behavior depends on the write mode.  If the write mode is
+     * {@link #WRITE_BLOCKING}, the write will normally block until all the data has been enqueued
+     * for playback, and will return a full transfer count.  However, if the write mode is
+     * {@link #WRITE_NON_BLOCKING}, or the track is stopped or paused on entry, or another thread
+     * interrupts the write by calling stop or pause, or an I/O error
+     * occurs during the write, then the write may return a short transfer count.
+     * <p>
+     * In static buffer mode, copies the data to the buffer starting at offset 0,
+     * and the write mode is ignored.
+     * Note that the actual playback of this data might occur after this function returns.
+     *
+     * @param audioData the buffer that holds the data to write, starting at the position reported
+     *     by <code>audioData.position()</code>.
+     *     <BR>Note that upon return, the buffer position (<code>audioData.position()</code>) will
+     *     have been advanced to reflect the amount of data that was successfully written to
+     *     the AudioTrack.
+     * @param sizeInBytes number of bytes to write.  It is recommended but not enforced
+     *     that the number of bytes requested be a multiple of the frame size (sample size in
+     *     bytes multiplied by the channel count).
+     *     <BR>Note this may differ from <code>audioData.remaining()</code>, but cannot exceed it.
+     * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}. It has no
+     *     effect in static mode.
+     *     <BR>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
+     *         to the audio sink.
+     *     <BR>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
+     *     queuing as much audio data for playback as possible without blocking.
+     * @return zero or the positive number of bytes that were written, or one of the following
+     *    error codes.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next write()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     */
+    public int write(@NonNull ByteBuffer audioData, int sizeInBytes,
+            @WriteMode int writeMode) {
+
+        if (mState == STATE_UNINITIALIZED) {
+            Log.e(TAG, "AudioTrack.write() called in invalid state STATE_UNINITIALIZED");
+            return ERROR_INVALID_OPERATION;
+        }
+
+        if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
+            Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
+            return ERROR_BAD_VALUE;
+        }
+
+        if ( (audioData == null) || (sizeInBytes < 0) || (sizeInBytes > audioData.remaining())) {
+            Log.e(TAG, "AudioTrack.write() called with invalid size (" + sizeInBytes + ") value");
+            return ERROR_BAD_VALUE;
+        }
+
+        if (!blockUntilOffloadDrain(writeMode)) {
+            return 0;
+        }
+
+        int ret = 0;
+        if (audioData.isDirect()) {
+            ret = native_write_native_bytes(audioData,
+                    audioData.position(), sizeInBytes, mAudioFormat,
+                    writeMode == WRITE_BLOCKING);
+        } else {
+            ret = native_write_byte(NioUtils.unsafeArray(audioData),
+                    NioUtils.unsafeArrayOffset(audioData) + audioData.position(),
+                    sizeInBytes, mAudioFormat,
+                    writeMode == WRITE_BLOCKING);
+        }
+
+        if ((mDataLoadMode == MODE_STATIC)
+                && (mState == STATE_NO_STATIC_DATA)
+                && (ret > 0)) {
+            // benign race with respect to other APIs that read mState
+            mState = STATE_INITIALIZED;
+        }
+
+        if (ret > 0) {
+            audioData.position(audioData.position() + ret);
+        }
+
+        return ret;
+    }
+
+    /**
+     * Writes the audio data to the audio sink for playback in streaming mode on a HW_AV_SYNC track.
+     * The blocking behavior will depend on the write mode.
+     * @param audioData the buffer that holds the data to write, starting at the position reported
+     *     by <code>audioData.position()</code>.
+     *     <BR>Note that upon return, the buffer position (<code>audioData.position()</code>) will
+     *     have been advanced to reflect the amount of data that was successfully written to
+     *     the AudioTrack.
+     * @param sizeInBytes number of bytes to write.  It is recommended but not enforced
+     *     that the number of bytes requested be a multiple of the frame size (sample size in
+     *     bytes multiplied by the channel count).
+     *     <BR>Note this may differ from <code>audioData.remaining()</code>, but cannot exceed it.
+     * @param writeMode one of {@link #WRITE_BLOCKING}, {@link #WRITE_NON_BLOCKING}.
+     *     <BR>With {@link #WRITE_BLOCKING}, the write will block until all data has been written
+     *         to the audio sink.
+     *     <BR>With {@link #WRITE_NON_BLOCKING}, the write will return immediately after
+     *     queuing as much audio data for playback as possible without blocking.
+     * @param timestamp The timestamp, in nanoseconds, of the first decodable audio frame in the
+     *     provided audioData.
+     * @return zero or the positive number of bytes that were written, or one of the following
+     *    error codes.
+     * <ul>
+     * <li>{@link #ERROR_INVALID_OPERATION} if the track isn't properly initialized</li>
+     * <li>{@link #ERROR_BAD_VALUE} if the parameters don't resolve to valid data and indexes</li>
+     * <li>{@link #ERROR_DEAD_OBJECT} if the AudioTrack is not valid anymore and
+     *    needs to be recreated. The dead object error code is not returned if some data was
+     *    successfully transferred. In this case, the error is returned at the next write()</li>
+     * <li>{@link #ERROR} in case of other error</li>
+     * </ul>
+     */
+    public int write(@NonNull ByteBuffer audioData, int sizeInBytes,
+            @WriteMode int writeMode, long timestamp) {
+
+        if (mState == STATE_UNINITIALIZED) {
+            Log.e(TAG, "AudioTrack.write() called in invalid state STATE_UNINITIALIZED");
+            return ERROR_INVALID_OPERATION;
+        }
+
+        if ((writeMode != WRITE_BLOCKING) && (writeMode != WRITE_NON_BLOCKING)) {
+            Log.e(TAG, "AudioTrack.write() called with invalid blocking mode");
+            return ERROR_BAD_VALUE;
+        }
+
+        if (mDataLoadMode != MODE_STREAM) {
+            Log.e(TAG, "AudioTrack.write() with timestamp called for non-streaming mode track");
+            return ERROR_INVALID_OPERATION;
+        }
+
+        if ((mAttributes.getFlags() & AudioAttributes.FLAG_HW_AV_SYNC) == 0) {
+            Log.d(TAG, "AudioTrack.write() called on a regular AudioTrack. Ignoring pts...");
+            return write(audioData, sizeInBytes, writeMode);
+        }
+
+        if ((audioData == null) || (sizeInBytes < 0) || (sizeInBytes > audioData.remaining())) {
+            Log.e(TAG, "AudioTrack.write() called with invalid size (" + sizeInBytes + ") value");
+            return ERROR_BAD_VALUE;
+        }
+
+        if (!blockUntilOffloadDrain(writeMode)) {
+            return 0;
+        }
+
+        // create timestamp header if none exists
+        if (mAvSyncHeader == null) {
+            mAvSyncHeader = ByteBuffer.allocate(mOffset);
+            mAvSyncHeader.order(ByteOrder.BIG_ENDIAN);
+            mAvSyncHeader.putInt(0x55550002);
+        }
+
+        if (mAvSyncBytesRemaining == 0) {
+            mAvSyncHeader.putInt(4, sizeInBytes);
+            mAvSyncHeader.putLong(8, timestamp);
+            mAvSyncHeader.putInt(16, mOffset);
+            mAvSyncHeader.position(0);
+            mAvSyncBytesRemaining = sizeInBytes;
+        }
+
+        // write timestamp header if not completely written already
+        int ret = 0;
+        if (mAvSyncHeader.remaining() != 0) {
+            ret = write(mAvSyncHeader, mAvSyncHeader.remaining(), writeMode);
+            if (ret < 0) {
+                Log.e(TAG, "AudioTrack.write() could not write timestamp header!");
+                mAvSyncHeader = null;
+                mAvSyncBytesRemaining = 0;
+                return ret;
+            }
+            if (mAvSyncHeader.remaining() > 0) {
+                Log.v(TAG, "AudioTrack.write() partial timestamp header written.");
+                return 0;
+            }
+        }
+
+        // write audio data
+        int sizeToWrite = Math.min(mAvSyncBytesRemaining, sizeInBytes);
+        ret = write(audioData, sizeToWrite, writeMode);
+        if (ret < 0) {
+            Log.e(TAG, "AudioTrack.write() could not write audio data!");
+            mAvSyncHeader = null;
+            mAvSyncBytesRemaining = 0;
+            return ret;
+        }
+
+        mAvSyncBytesRemaining -= ret;
+
+        return ret;
+    }
+
+
+    /**
+     * Sets the playback head position within the static buffer to zero,
+     * that is it rewinds to start of static buffer.
+     * The track must be stopped or paused, and
+     * the track's creation mode must be {@link #MODE_STATIC}.
+     * <p>
+     * As of {@link android.os.Build.VERSION_CODES#M}, also resets the value returned by
+     * {@link #getPlaybackHeadPosition()} to zero.
+     * For earlier API levels, the reset behavior is unspecified.
+     * <p>
+     * Use {@link #setPlaybackHeadPosition(int)} with a zero position
+     * if the reset of <code>getPlaybackHeadPosition()</code> is not needed.
+     * @return error code or success, see {@link #SUCCESS}, {@link #ERROR_BAD_VALUE},
+     *  {@link #ERROR_INVALID_OPERATION}
+     */
+    public int reloadStaticData() {
+        if (mDataLoadMode == MODE_STREAM || mState != STATE_INITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
+        return native_reload_static();
+    }
+
+    /**
+     * When an AudioTrack in offload mode is in STOPPING play state, wait until event STREAM_END is
+     * received if blocking write or return with 0 frames written if non blocking mode.
+     */
+    private boolean blockUntilOffloadDrain(int writeMode) {
+        synchronized (mPlayStateLock) {
+            while (mPlayState == PLAYSTATE_STOPPING || mPlayState == PLAYSTATE_PAUSED_STOPPING) {
+                if (writeMode == WRITE_NON_BLOCKING) {
+                    return false;
+                }
+                try {
+                    mPlayStateLock.wait();
+                } catch (InterruptedException e) {
+                }
+            }
+            return true;
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Audio effects management
+    //--------------------
+
+    /**
+     * Attaches an auxiliary effect to the audio track. A typical auxiliary
+     * effect is a reverberation effect which can be applied on any sound source
+     * that directs a certain amount of its energy to this effect. This amount
+     * is defined by setAuxEffectSendLevel().
+     * {@see #setAuxEffectSendLevel(float)}.
+     * <p>After creating an auxiliary effect (e.g.
+     * {@link android.media.audiofx.EnvironmentalReverb}), retrieve its ID with
+     * {@link android.media.audiofx.AudioEffect#getId()} and use it when calling
+     * this method to attach the audio track to the effect.
+     * <p>To detach the effect from the audio track, call this method with a
+     * null effect id.
+     *
+     * @param effectId system wide unique id of the effect to attach
+     * @return error code or success, see {@link #SUCCESS},
+     *    {@link #ERROR_INVALID_OPERATION}, {@link #ERROR_BAD_VALUE}
+     */
+    public int attachAuxEffect(int effectId) {
+        if (mState == STATE_UNINITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
+        return native_attachAuxEffect(effectId);
+    }
+
+    /**
+     * Sets the send level of the audio track to the attached auxiliary effect
+     * {@link #attachAuxEffect(int)}.  Effect levels
+     * are clamped to the closed interval [0.0, max] where
+     * max is the value of {@link #getMaxVolume}.
+     * A value of 0.0 results in no effect, and a value of 1.0 is full send.
+     * <p>By default the send level is 0.0f, so even if an effect is attached to the player
+     * this method must be called for the effect to be applied.
+     * <p>Note that the passed level value is a linear scalar. UI controls should be scaled
+     * logarithmically: the gain applied by audio framework ranges from -72dB to at least 0dB,
+     * so an appropriate conversion from linear UI input x to level is:
+     * x == 0 -&gt; level = 0
+     * 0 &lt; x &lt;= R -&gt; level = 10^(72*(x-R)/20/R)
+     *
+     * @param level linear send level
+     * @return error code or success, see {@link #SUCCESS},
+     *    {@link #ERROR_INVALID_OPERATION}, {@link #ERROR}
+     */
+    public int setAuxEffectSendLevel(@FloatRange(from = 0.0) float level) {
+        if (mState == STATE_UNINITIALIZED) {
+            return ERROR_INVALID_OPERATION;
+        }
+        return baseSetAuxEffectSendLevel(level);
+    }
+
+    @Override
+    int playerSetAuxEffectSendLevel(boolean muting, float level) {
+        level = clampGainOrLevel(muting ? 0.0f : level);
+        int err = native_setAuxEffectSendLevel(level);
+        return err == 0 ? SUCCESS : ERROR;
+    }
+
+    //--------------------------------------------------------------------------
+    // Explicit Routing
+    //--------------------
+    private AudioDeviceInfo mPreferredDevice = null;
+
+    /**
+     * Specifies an audio device (via an {@link AudioDeviceInfo} object) to route
+     * the output from this AudioTrack.
+     * @param deviceInfo The {@link AudioDeviceInfo} specifying the audio sink.
+     *  If deviceInfo is null, default routing is restored.
+     * @return true if succesful, false if the specified {@link AudioDeviceInfo} is non-null and
+     * does not correspond to a valid audio output device.
+     */
+    @Override
+    public boolean setPreferredDevice(AudioDeviceInfo deviceInfo) {
+        // Do some validation....
+        if (deviceInfo != null && !deviceInfo.isSink()) {
+            return false;
+        }
+        int preferredDeviceId = deviceInfo != null ? deviceInfo.getId() : 0;
+        boolean status = native_setOutputDevice(preferredDeviceId);
+        if (status == true) {
+            synchronized (this) {
+                mPreferredDevice = deviceInfo;
+            }
+        }
+        return status;
+    }
+
+    /**
+     * Returns the selected output specified by {@link #setPreferredDevice}. Note that this
+     * is not guaranteed to correspond to the actual device being used for playback.
+     */
+    @Override
+    public AudioDeviceInfo getPreferredDevice() {
+        synchronized (this) {
+            return mPreferredDevice;
+        }
+    }
+
+    /**
+     * Returns an {@link AudioDeviceInfo} identifying the current routing of this AudioTrack.
+     * Note: The query is only valid if the AudioTrack is currently playing. If it is not,
+     * <code>getRoutedDevice()</code> will return null.
+     */
+    @Override
+    public AudioDeviceInfo getRoutedDevice() {
+        int deviceId = native_getRoutedDeviceId();
+        if (deviceId == 0) {
+            return null;
+        }
+        return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_OUTPUTS);
+    }
+
+    private void tryToDisableNativeRoutingCallback() {
+        synchronized (mRoutingChangeListeners) {
+            if (mEnableSelfRoutingMonitor) {
+                mEnableSelfRoutingMonitor = false;
+                testDisableNativeRoutingCallbacksLocked();
+            }
+        }
+    }
+
+    /**
+     * Call BEFORE adding a routing callback handler and when enabling self routing listener
+     * @return returns true for success, false otherwise.
+     */
+    @GuardedBy("mRoutingChangeListeners")
+    private boolean testEnableNativeRoutingCallbacksLocked() {
+        if (mRoutingChangeListeners.size() == 0 && !mEnableSelfRoutingMonitor) {
+            try {
+                native_enableDeviceCallback();
+                return true;
+            } catch (IllegalStateException e) {
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "testEnableNativeRoutingCallbacks failed", e);
+                }
+            }
+        }
+        return false;
+    }
+
+    /*
+     * Call AFTER removing a routing callback handler and when disabling self routing listener.
+     */
+    @GuardedBy("mRoutingChangeListeners")
+    private void testDisableNativeRoutingCallbacksLocked() {
+        if (mRoutingChangeListeners.size() == 0 && !mEnableSelfRoutingMonitor) {
+            try {
+                native_disableDeviceCallback();
+            } catch (IllegalStateException e) {
+                // Fail silently as track state could have changed in between stop
+                // and disabling routing callback
+            }
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // (Re)Routing Info
+    //--------------------
+    /**
+     * The list of AudioRouting.OnRoutingChangedListener interfaces added (with
+     * {@link #addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, Handler)}
+     * by an app to receive (re)routing notifications.
+     */
+    @GuardedBy("mRoutingChangeListeners")
+    private ArrayMap<AudioRouting.OnRoutingChangedListener,
+            NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<>();
+
+    @GuardedBy("mRoutingChangeListeners")
+    private boolean mEnableSelfRoutingMonitor;
+
+   /**
+    * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
+    * changes on this AudioTrack.
+    * @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive
+    * notifications of rerouting events.
+    * @param handler  Specifies the {@link Handler} object for the thread on which to execute
+    * the callback. If <code>null</code>, the {@link Handler} associated with the main
+    * {@link Looper} will be used.
+    */
+    @Override
+    public void addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener,
+            Handler handler) {
+        synchronized (mRoutingChangeListeners) {
+            if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
+                mEnableSelfRoutingMonitor = testEnableNativeRoutingCallbacksLocked();
+                mRoutingChangeListeners.put(
+                        listener, new NativeRoutingEventHandlerDelegate(this, listener,
+                                handler != null ? handler : new Handler(mInitializationLooper)));
+            }
+        }
+    }
+
+    /**
+     * Removes an {@link AudioRouting.OnRoutingChangedListener} which has been previously added
+     * to receive rerouting notifications.
+     * @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
+     * to remove.
+     */
+    @Override
+    public void removeOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener) {
+        synchronized (mRoutingChangeListeners) {
+            if (mRoutingChangeListeners.containsKey(listener)) {
+                mRoutingChangeListeners.remove(listener);
+            }
+            testDisableNativeRoutingCallbacksLocked();
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // (Re)Routing Info
+    //--------------------
+    /**
+     * Defines the interface by which applications can receive notifications of
+     * routing changes for the associated {@link AudioTrack}.
+     *
+     * @deprecated users should switch to the general purpose
+     *             {@link AudioRouting.OnRoutingChangedListener} class instead.
+     */
+    @Deprecated
+    public interface OnRoutingChangedListener extends AudioRouting.OnRoutingChangedListener {
+        /**
+         * Called when the routing of an AudioTrack changes from either and
+         * explicit or policy rerouting. Use {@link #getRoutedDevice()} to
+         * retrieve the newly routed-to device.
+         */
+        public void onRoutingChanged(AudioTrack audioTrack);
+
+        @Override
+        default public void onRoutingChanged(AudioRouting router) {
+            if (router instanceof AudioTrack) {
+                onRoutingChanged((AudioTrack) router);
+            }
+        }
+    }
+
+    /**
+     * Adds an {@link OnRoutingChangedListener} to receive notifications of routing changes
+     * on this AudioTrack.
+     * @param listener The {@link OnRoutingChangedListener} interface to receive notifications
+     * of rerouting events.
+     * @param handler  Specifies the {@link Handler} object for the thread on which to execute
+     * the callback. If <code>null</code>, the {@link Handler} associated with the main
+     * {@link Looper} will be used.
+     * @deprecated users should switch to the general purpose
+     *             {@link AudioRouting.OnRoutingChangedListener} class instead.
+     */
+    @Deprecated
+    public void addOnRoutingChangedListener(OnRoutingChangedListener listener,
+            android.os.Handler handler) {
+        addOnRoutingChangedListener((AudioRouting.OnRoutingChangedListener) listener, handler);
+    }
+
+    /**
+     * Removes an {@link OnRoutingChangedListener} which has been previously added
+     * to receive rerouting notifications.
+     * @param listener The previously added {@link OnRoutingChangedListener} interface to remove.
+     * @deprecated users should switch to the general purpose
+     *             {@link AudioRouting.OnRoutingChangedListener} class instead.
+     */
+    @Deprecated
+    public void removeOnRoutingChangedListener(OnRoutingChangedListener listener) {
+        removeOnRoutingChangedListener((AudioRouting.OnRoutingChangedListener) listener);
+    }
+
+    /**
+     * Sends device list change notification to all listeners.
+     */
+    private void broadcastRoutingChange() {
+        AudioManager.resetAudioPortGeneration();
+        baseUpdateDeviceId(getRoutedDevice());
+        synchronized (mRoutingChangeListeners) {
+            for (NativeRoutingEventHandlerDelegate delegate : mRoutingChangeListeners.values()) {
+                delegate.notifyClient();
+            }
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Codec notifications
+    //--------------------
+
+    // OnCodecFormatChangedListener notifications uses an instance
+    // of ListenerList to manage its listeners.
+
+    private final Utils.ListenerList<AudioMetadataReadMap> mCodecFormatChangedListeners =
+            new Utils.ListenerList();
+
+    /**
+     * Interface definition for a listener for codec format changes.
+     */
+    public interface OnCodecFormatChangedListener {
+        /**
+         * Called when the compressed codec format changes.
+         *
+         * @param audioTrack is the {@code AudioTrack} instance associated with the codec.
+         * @param info is a {@link AudioMetadataReadMap} of values which contains decoded format
+         *     changes reported by the codec.  Not all hardware
+         *     codecs indicate codec format changes. Acceptable keys are taken from
+         *     {@code AudioMetadata.Format.KEY_*} range, with the associated value type.
+         */
+        void onCodecFormatChanged(
+                @NonNull AudioTrack audioTrack, @Nullable AudioMetadataReadMap info);
+    }
+
+    /**
+     * Adds an {@link OnCodecFormatChangedListener} to receive notifications of
+     * codec format change events on this {@code AudioTrack}.
+     *
+     * @param executor  Specifies the {@link Executor} object to control execution.
+     *
+     * @param listener The {@link OnCodecFormatChangedListener} interface to receive
+     *     notifications of codec events.
+     */
+    public void addOnCodecFormatChangedListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnCodecFormatChangedListener listener) { // NPE checks done by ListenerList.
+        mCodecFormatChangedListeners.add(
+                listener, /* key for removal */
+                executor,
+                (int eventCode, AudioMetadataReadMap readMap) -> {
+                    // eventCode is unused by this implementation.
+                    listener.onCodecFormatChanged(this, readMap);
+                }
+        );
+    }
+
+    /**
+     * Removes an {@link OnCodecFormatChangedListener} which has been previously added
+     * to receive codec format change events.
+     *
+     * @param listener The previously added {@link OnCodecFormatChangedListener} interface
+     * to remove.
+     */
+    public void removeOnCodecFormatChangedListener(
+            @NonNull OnCodecFormatChangedListener listener) {
+        mCodecFormatChangedListeners.remove(listener);  // NPE checks done by ListenerList.
+    }
+
+    //---------------------------------------------------------
+    // Interface definitions
+    //--------------------
+    /**
+     * Interface definition for a callback to be invoked when the playback head position of
+     * an AudioTrack has reached a notification marker or has increased by a certain period.
+     */
+    public interface OnPlaybackPositionUpdateListener  {
+        /**
+         * Called on the listener to notify it that the previously set marker has been reached
+         * by the playback head.
+         */
+        void onMarkerReached(AudioTrack track);
+
+        /**
+         * Called on the listener to periodically notify it that the playback head has reached
+         * a multiple of the notification period.
+         */
+        void onPeriodicNotification(AudioTrack track);
+    }
+
+    /**
+     * Abstract class to receive event notifications about the stream playback in offloaded mode.
+     * See {@link AudioTrack#registerStreamEventCallback(Executor, StreamEventCallback)} to register
+     * the callback on the given {@link AudioTrack} instance.
+     */
+    public abstract static class StreamEventCallback {
+        /**
+         * Called when an offloaded track is no longer valid and has been discarded by the system.
+         * An example of this happening is when an offloaded track has been paused too long, and
+         * gets invalidated by the system to prevent any other offload.
+         * @param track the {@link AudioTrack} on which the event happened.
+         */
+        public void onTearDown(@NonNull AudioTrack track) { }
+        /**
+         * Called when all the buffers of an offloaded track that were queued in the audio system
+         * (e.g. the combination of the Android audio framework and the device's audio hardware)
+         * have been played after {@link AudioTrack#stop()} has been called.
+         * @param track the {@link AudioTrack} on which the event happened.
+         */
+        public void onPresentationEnded(@NonNull AudioTrack track) { }
+        /**
+         * Called when more audio data can be written without blocking on an offloaded track.
+         * @param track the {@link AudioTrack} on which the event happened.
+         * @param sizeInFrames the number of frames available to write without blocking.
+         *   Note that the frame size of a compressed stream is 1 byte.
+         */
+        public void onDataRequest(@NonNull AudioTrack track, @IntRange(from = 0) int sizeInFrames) {
+        }
+    }
+
+    /**
+     * Registers a callback for the notification of stream events.
+     * This callback can only be registered for instances operating in offloaded mode
+     * (see {@link AudioTrack.Builder#setOffloadedPlayback(boolean)} and
+     * {@link AudioManager#isOffloadedPlaybackSupported(AudioFormat,AudioAttributes)} for
+     * more details).
+     * @param executor {@link Executor} to handle the callbacks.
+     * @param eventCallback the callback to receive the stream event notifications.
+     */
+    public void registerStreamEventCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull StreamEventCallback eventCallback) {
+        if (eventCallback == null) {
+            throw new IllegalArgumentException("Illegal null StreamEventCallback");
+        }
+        if (!mOffloaded) {
+            throw new IllegalStateException(
+                    "Cannot register StreamEventCallback on non-offloaded AudioTrack");
+        }
+        if (executor == null) {
+            throw new IllegalArgumentException("Illegal null Executor for the StreamEventCallback");
+        }
+        synchronized (mStreamEventCbLock) {
+            // check if eventCallback already in list
+            for (StreamEventCbInfo seci : mStreamEventCbInfoList) {
+                if (seci.mStreamEventCb == eventCallback) {
+                    throw new IllegalArgumentException(
+                            "StreamEventCallback already registered");
+                }
+            }
+            beginStreamEventHandling();
+            mStreamEventCbInfoList.add(new StreamEventCbInfo(executor, eventCallback));
+        }
+    }
+
+    /**
+     * Unregisters the callback for notification of stream events, previously registered
+     * with {@link #registerStreamEventCallback(Executor, StreamEventCallback)}.
+     * @param eventCallback the callback to unregister.
+     */
+    public void unregisterStreamEventCallback(@NonNull StreamEventCallback eventCallback) {
+        if (eventCallback == null) {
+            throw new IllegalArgumentException("Illegal null StreamEventCallback");
+        }
+        if (!mOffloaded) {
+            throw new IllegalStateException("No StreamEventCallback on non-offloaded AudioTrack");
+        }
+        synchronized (mStreamEventCbLock) {
+            StreamEventCbInfo seciToRemove = null;
+            for (StreamEventCbInfo seci : mStreamEventCbInfoList) {
+                if (seci.mStreamEventCb == eventCallback) {
+                    // ok to remove while iterating over list as we exit iteration
+                    mStreamEventCbInfoList.remove(seci);
+                    if (mStreamEventCbInfoList.size() == 0) {
+                        endStreamEventHandling();
+                    }
+                    return;
+                }
+            }
+            throw new IllegalArgumentException("StreamEventCallback was not registered");
+        }
+    }
+
+    //---------------------------------------------------------
+    // Offload
+    //--------------------
+    private static class StreamEventCbInfo {
+        final Executor mStreamEventExec;
+        final StreamEventCallback mStreamEventCb;
+
+        StreamEventCbInfo(Executor e, StreamEventCallback cb) {
+            mStreamEventExec = e;
+            mStreamEventCb = cb;
+        }
+    }
+
+    private final Object mStreamEventCbLock = new Object();
+    @GuardedBy("mStreamEventCbLock")
+    @NonNull private LinkedList<StreamEventCbInfo> mStreamEventCbInfoList =
+            new LinkedList<StreamEventCbInfo>();
+    /**
+     * Dedicated thread for handling the StreamEvent callbacks
+     */
+    private @Nullable HandlerThread mStreamEventHandlerThread;
+    private @Nullable volatile StreamEventHandler mStreamEventHandler;
+
+    /**
+     * Called from native AudioTrack callback thread, filter messages if necessary
+     * and repost event on AudioTrack message loop to prevent blocking native thread.
+     * @param what event code received from native
+     * @param arg optional argument for event
+     */
+    void handleStreamEventFromNative(int what, int arg) {
+        if (mStreamEventHandler == null) {
+            return;
+        }
+        switch (what) {
+            case NATIVE_EVENT_CAN_WRITE_MORE_DATA:
+                // replace previous CAN_WRITE_MORE_DATA messages with the latest value
+                mStreamEventHandler.removeMessages(NATIVE_EVENT_CAN_WRITE_MORE_DATA);
+                mStreamEventHandler.sendMessage(
+                        mStreamEventHandler.obtainMessage(
+                                NATIVE_EVENT_CAN_WRITE_MORE_DATA, arg, 0/*ignored*/));
+                break;
+            case NATIVE_EVENT_NEW_IAUDIOTRACK:
+                mStreamEventHandler.sendMessage(
+                        mStreamEventHandler.obtainMessage(NATIVE_EVENT_NEW_IAUDIOTRACK));
+                break;
+            case NATIVE_EVENT_STREAM_END:
+                mStreamEventHandler.sendMessage(
+                        mStreamEventHandler.obtainMessage(NATIVE_EVENT_STREAM_END));
+                break;
+        }
+    }
+
+    private class StreamEventHandler extends Handler {
+
+        StreamEventHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            final LinkedList<StreamEventCbInfo> cbInfoList;
+            synchronized (mStreamEventCbLock) {
+                if (msg.what == NATIVE_EVENT_STREAM_END) {
+                    synchronized (mPlayStateLock) {
+                        if (mPlayState == PLAYSTATE_STOPPING) {
+                            if (mOffloadEosPending) {
+                                native_start();
+                                mPlayState = PLAYSTATE_PLAYING;
+                            } else {
+                                mAvSyncHeader = null;
+                                mAvSyncBytesRemaining = 0;
+                                mPlayState = PLAYSTATE_STOPPED;
+                            }
+                            mOffloadEosPending = false;
+                            mPlayStateLock.notify();
+                        }
+                    }
+                }
+                if (mStreamEventCbInfoList.size() == 0) {
+                    return;
+                }
+                cbInfoList = new LinkedList<StreamEventCbInfo>(mStreamEventCbInfoList);
+            }
+
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                for (StreamEventCbInfo cbi : cbInfoList) {
+                    switch (msg.what) {
+                        case NATIVE_EVENT_CAN_WRITE_MORE_DATA:
+                            cbi.mStreamEventExec.execute(() ->
+                                    cbi.mStreamEventCb.onDataRequest(AudioTrack.this, msg.arg1));
+                            break;
+                        case NATIVE_EVENT_NEW_IAUDIOTRACK:
+                            // TODO also release track as it's not longer usable
+                            cbi.mStreamEventExec.execute(() ->
+                                    cbi.mStreamEventCb.onTearDown(AudioTrack.this));
+                            break;
+                        case NATIVE_EVENT_STREAM_END:
+                            cbi.mStreamEventExec.execute(() ->
+                                    cbi.mStreamEventCb.onPresentationEnded(AudioTrack.this));
+                            break;
+                    }
+                }
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
+    }
+
+    @GuardedBy("mStreamEventCbLock")
+    private void beginStreamEventHandling() {
+        if (mStreamEventHandlerThread == null) {
+            mStreamEventHandlerThread = new HandlerThread(TAG + ".StreamEvent");
+            mStreamEventHandlerThread.start();
+            final Looper looper = mStreamEventHandlerThread.getLooper();
+            if (looper != null) {
+                mStreamEventHandler = new StreamEventHandler(looper);
+            }
+        }
+    }
+
+    @GuardedBy("mStreamEventCbLock")
+    private void endStreamEventHandling() {
+        if (mStreamEventHandlerThread != null) {
+            mStreamEventHandlerThread.quit();
+            mStreamEventHandlerThread = null;
+        }
+    }
+
+    /**
+     * Sets a {@link LogSessionId} instance to this AudioTrack for metrics collection.
+     *
+     * @param logSessionId a {@link LogSessionId} instance which is used to
+     *        identify this object to the metrics service. Proper generated
+     *        Ids must be obtained from the Java metrics service and should
+     *        be considered opaque. Use
+     *        {@link LogSessionId#LOG_SESSION_ID_NONE} to remove the
+     *        logSessionId association.
+     * @throws IllegalStateException if AudioTrack not initialized.
+     *
+     */
+    public void setLogSessionId(@NonNull LogSessionId logSessionId) {
+        Objects.requireNonNull(logSessionId);
+        if (mState == STATE_UNINITIALIZED) {
+            throw new IllegalStateException("track not initialized");
+        }
+        String stringId = logSessionId.getStringId();
+        native_setLogSessionId(stringId);
+        mLogSessionId = logSessionId;
+    }
+
+    /**
+     * Returns the {@link LogSessionId}.
+     */
+    @NonNull
+    public LogSessionId getLogSessionId() {
+        return mLogSessionId;
+    }
+
+    //---------------------------------------------------------
+    // Inner classes
+    //--------------------
+    /**
+     * Helper class to handle the forwarding of native events to the appropriate listener
+     * (potentially) handled in a different thread
+     */
+    private class NativePositionEventHandlerDelegate {
+        private final Handler mHandler;
+
+        NativePositionEventHandlerDelegate(final AudioTrack track,
+                                   final OnPlaybackPositionUpdateListener listener,
+                                   Handler handler) {
+            // find the looper for our new event handler
+            Looper looper;
+            if (handler != null) {
+                looper = handler.getLooper();
+            } else {
+                // no given handler, use the looper the AudioTrack was created in
+                looper = mInitializationLooper;
+            }
+
+            // construct the event handler with this looper
+            if (looper != null) {
+                // implement the event handler delegate
+                mHandler = new Handler(looper) {
+                    @Override
+                    public void handleMessage(Message msg) {
+                        if (track == null) {
+                            return;
+                        }
+                        switch(msg.what) {
+                        case NATIVE_EVENT_MARKER:
+                            if (listener != null) {
+                                listener.onMarkerReached(track);
+                            }
+                            break;
+                        case NATIVE_EVENT_NEW_POS:
+                            if (listener != null) {
+                                listener.onPeriodicNotification(track);
+                            }
+                            break;
+                        default:
+                            loge("Unknown native event type: " + msg.what);
+                            break;
+                        }
+                    }
+                };
+            } else {
+                mHandler = null;
+            }
+        }
+
+        Handler getHandler() {
+            return mHandler;
+        }
+    }
+
+    //---------------------------------------------------------
+    // Methods for IPlayer interface
+    //--------------------
+    @Override
+    void playerStart() {
+        play();
+    }
+
+    @Override
+    void playerPause() {
+        pause();
+    }
+
+    @Override
+    void playerStop() {
+        stop();
+    }
+
+    //---------------------------------------------------------
+    // Java methods called from the native side
+    //--------------------
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static void postEventFromNative(Object audiotrack_ref,
+            int what, int arg1, int arg2, Object obj) {
+        //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2);
+        final AudioTrack track = (AudioTrack) ((WeakReference) audiotrack_ref).get();
+        if (track == null) {
+            return;
+        }
+
+        if (what == AudioSystem.NATIVE_EVENT_ROUTING_CHANGE) {
+            track.broadcastRoutingChange();
+            return;
+        }
+
+        if (what == NATIVE_EVENT_CODEC_FORMAT_CHANGE) {
+            ByteBuffer buffer = (ByteBuffer) obj;
+            buffer.order(ByteOrder.nativeOrder());
+            buffer.rewind();
+            AudioMetadataReadMap audioMetaData = AudioMetadata.fromByteBuffer(buffer);
+            if (audioMetaData == null) {
+                Log.e(TAG, "Unable to get audio metadata from byte buffer");
+                return;
+            }
+            track.mCodecFormatChangedListeners.notify(0 /* eventCode, unused */, audioMetaData);
+            return;
+        }
+
+        if (what == NATIVE_EVENT_CAN_WRITE_MORE_DATA
+                || what == NATIVE_EVENT_NEW_IAUDIOTRACK
+                || what == NATIVE_EVENT_STREAM_END) {
+            track.handleStreamEventFromNative(what, arg1);
+            return;
+        }
+
+        NativePositionEventHandlerDelegate delegate = track.mEventHandlerDelegate;
+        if (delegate != null) {
+            Handler handler = delegate.getHandler();
+            if (handler != null) {
+                Message m = handler.obtainMessage(what, arg1, arg2, obj);
+                handler.sendMessage(m);
+            }
+        }
+    }
+
+    //---------------------------------------------------------
+    // Native methods called from the Java side
+    //--------------------
+
+    private static native boolean native_is_direct_output_supported(int encoding, int sampleRate,
+            int channelMask, int channelIndexMask, int contentType, int usage, int flags);
+
+    // post-condition: mStreamType is overwritten with a value
+    //     that reflects the audio attributes (e.g. an AudioAttributes object with a usage of
+    //     AudioAttributes.USAGE_MEDIA will map to AudioManager.STREAM_MUSIC
+    private native final int native_setup(Object /*WeakReference<AudioTrack>*/ audiotrack_this,
+            Object /*AudioAttributes*/ attributes,
+            int[] sampleRate, int channelMask, int channelIndexMask, int audioFormat,
+            int buffSizeInBytes, int mode, int[] sessionId, long nativeAudioTrack,
+            boolean offload, int encapsulationMode, Object tunerConfiguration,
+            @NonNull String opPackageName);
+
+    private native final void native_finalize();
+
+    /**
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public native final void native_release();
+
+    private native final void native_start();
+
+    private native final void native_stop();
+
+    private native final void native_pause();
+
+    private native final void native_flush();
+
+    private native final int native_write_byte(byte[] audioData,
+                                               int offsetInBytes, int sizeInBytes, int format,
+                                               boolean isBlocking);
+
+    private native final int native_write_short(short[] audioData,
+                                                int offsetInShorts, int sizeInShorts, int format,
+                                                boolean isBlocking);
+
+    private native final int native_write_float(float[] audioData,
+                                                int offsetInFloats, int sizeInFloats, int format,
+                                                boolean isBlocking);
+
+    private native final int native_write_native_bytes(ByteBuffer audioData,
+            int positionInBytes, int sizeInBytes, int format, boolean blocking);
+
+    private native final int native_reload_static();
+
+    private native final int native_get_buffer_size_frames();
+    private native final int native_set_buffer_size_frames(int bufferSizeInFrames);
+    private native final int native_get_buffer_capacity_frames();
+
+    private native final void native_setVolume(float leftVolume, float rightVolume);
+
+    private native final int native_set_playback_rate(int sampleRateInHz);
+    private native final int native_get_playback_rate();
+
+    private native final void native_set_playback_params(@NonNull PlaybackParams params);
+    private native final @NonNull PlaybackParams native_get_playback_params();
+
+    private native final int native_set_marker_pos(int marker);
+    private native final int native_get_marker_pos();
+
+    private native final int native_set_pos_update_period(int updatePeriod);
+    private native final int native_get_pos_update_period();
+
+    private native final int native_set_position(int position);
+    private native final int native_get_position();
+
+    private native final int native_get_latency();
+
+    private native final int native_get_underrun_count();
+
+    private native final int native_get_flags();
+
+    // longArray must be a non-null array of length >= 2
+    // [0] is assigned the frame position
+    // [1] is assigned the time in CLOCK_MONOTONIC nanoseconds
+    private native final int native_get_timestamp(long[] longArray);
+
+    private native final int native_set_loop(int start, int end, int loopCount);
+
+    static private native final int native_get_output_sample_rate(int streamType);
+    static private native final int native_get_min_buff_size(
+            int sampleRateInHz, int channelConfig, int audioFormat);
+
+    private native final int native_attachAuxEffect(int effectId);
+    private native final int native_setAuxEffectSendLevel(float level);
+
+    private native final boolean native_setOutputDevice(int deviceId);
+    private native final int native_getRoutedDeviceId();
+    private native final void native_enableDeviceCallback();
+    private native final void native_disableDeviceCallback();
+
+    private native int native_applyVolumeShaper(
+            @NonNull VolumeShaper.Configuration configuration,
+            @NonNull VolumeShaper.Operation operation);
+
+    private native @Nullable VolumeShaper.State native_getVolumeShaperState(int id);
+    private native final int native_setPresentation(int presentationId, int programId);
+
+    private native int native_getPortId();
+
+    private native void native_set_delay_padding(int delayInFrames, int paddingInFrames);
+
+    private native int native_set_audio_description_mix_level_db(float level);
+    private native int native_get_audio_description_mix_level_db(float[] level);
+    private native int native_set_dual_mono_mode(int dualMonoMode);
+    private native int native_get_dual_mono_mode(int[] dualMonoMode);
+    private native void native_setLogSessionId(@Nullable String logSessionId);
+    private native int native_setStartThresholdInFrames(int startThresholdInFrames);
+    private native int native_getStartThresholdInFrames();
+
+    /**
+     * Sets the audio service Player Interface Id.
+     *
+     * The playerIId does not change over the lifetime of the client
+     * Java AudioTrack and is set automatically on creation.
+     *
+     * This call informs the native AudioTrack for metrics logging purposes.
+     *
+     * @param id the value reported by AudioManager when registering the track.
+     *           A value of -1 indicates invalid - the playerIId was never set.
+     * @throws IllegalStateException if AudioTrack not initialized.
+     */
+    private native void native_setPlayerIId(int playerIId);
+
+    //---------------------------------------------------------
+    // Utility methods
+    //------------------
+
+    private static void logd(String msg) {
+        Log.d(TAG, msg);
+    }
+
+    private static void loge(String msg) {
+        Log.e(TAG, msg);
+    }
+
+    public final static class MetricsConstants
+    {
+        private MetricsConstants() {}
+
+        // MM_PREFIX is slightly different than TAG, used to avoid cut-n-paste errors.
+        private static final String MM_PREFIX = "android.media.audiotrack.";
+
+        /**
+         * Key to extract the stream type for this track
+         * from the {@link AudioTrack#getMetrics} return value.
+         * This value may not exist in API level {@link android.os.Build.VERSION_CODES#P}.
+         * The value is a {@code String}.
+         */
+        public static final String STREAMTYPE = MM_PREFIX + "streamtype";
+
+        /**
+         * Key to extract the attribute content type for this track
+         * from the {@link AudioTrack#getMetrics} return value.
+         * The value is a {@code String}.
+         */
+        public static final String CONTENTTYPE = MM_PREFIX + "type";
+
+        /**
+         * Key to extract the attribute usage for this track
+         * from the {@link AudioTrack#getMetrics} return value.
+         * The value is a {@code String}.
+         */
+        public static final String USAGE = MM_PREFIX + "usage";
+
+        /**
+         * Key to extract the sample rate for this track in Hz
+         * from the {@link AudioTrack#getMetrics} return value.
+         * The value is an {@code int}.
+         * @deprecated This does not work. Use {@link AudioTrack#getSampleRate()} instead.
+         */
+        @Deprecated
+        public static final String SAMPLERATE = "android.media.audiorecord.samplerate";
+
+        /**
+         * Key to extract the native channel mask information for this track
+         * from the {@link AudioTrack#getMetrics} return value.
+         *
+         * The value is a {@code long}.
+         * @deprecated This does not work. Use {@link AudioTrack#getFormat()} and read from
+         * the returned format instead.
+         */
+        @Deprecated
+        public static final String CHANNELMASK = "android.media.audiorecord.channelmask";
+
+        /**
+         * Use for testing only. Do not expose.
+         * The current sample rate.
+         * The value is an {@code int}.
+         * @hide
+         */
+        @TestApi
+        public static final String SAMPLE_RATE = MM_PREFIX + "sampleRate";
+
+        /**
+         * Use for testing only. Do not expose.
+         * The native channel mask.
+         * The value is a {@code long}.
+         * @hide
+         */
+        @TestApi
+        public static final String CHANNEL_MASK = MM_PREFIX + "channelMask";
+
+        /**
+         * Use for testing only. Do not expose.
+         * The output audio data encoding.
+         * The value is a {@code String}.
+         * @hide
+         */
+        @TestApi
+        public static final String ENCODING = MM_PREFIX + "encoding";
+
+        /**
+         * Use for testing only. Do not expose.
+         * The port id of this track port in audioserver.
+         * The value is an {@code int}.
+         * @hide
+         */
+        @TestApi
+        public static final String PORT_ID = MM_PREFIX + "portId";
+
+        /**
+         * Use for testing only. Do not expose.
+         * The buffer frameCount.
+         * The value is an {@code int}.
+         * @hide
+         */
+        @TestApi
+        public static final String FRAME_COUNT = MM_PREFIX + "frameCount";
+
+        /**
+         * Use for testing only. Do not expose.
+         * The actual track attributes used.
+         * The value is a {@code String}.
+         * @hide
+         */
+        @TestApi
+        public static final String ATTRIBUTES = MM_PREFIX + "attributes";
+    }
+}
diff --git a/android/media/AudioTrackRoutingProxy.java b/android/media/AudioTrackRoutingProxy.java
new file mode 100644
index 0000000..9b97ae9
--- /dev/null
+++ b/android/media/AudioTrackRoutingProxy.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2008 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;
+
+/**
+ * An AudioTrack connected to a native (C/C++) which allows access only to routing methods.
+ */
+class AudioTrackRoutingProxy extends AudioTrack {
+    /**
+     * A constructor which explicitly connects a Native (C++) AudioTrack. For use by
+     * the AudioTrackRoutingProxy subclass.
+     * @param nativeTrackInJavaObj a C/C++ pointer to a native AudioTrack
+     * (associated with an OpenSL ES player).
+     */
+    public AudioTrackRoutingProxy(long nativeTrackInJavaObj) {
+        super(nativeTrackInJavaObj);
+    }
+}
diff --git a/android/media/BaseMediaParceledListSlice.java b/android/media/BaseMediaParceledListSlice.java
new file mode 100644
index 0000000..fb66609
--- /dev/null
+++ b/android/media/BaseMediaParceledListSlice.java
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2020 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.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is a copied version of BaseParceledListSlice in framework with hidden API usages
+ * removed.
+ *
+ * Transfer a large list of Parcelable objects across an IPC.  Splits into
+ * multiple transactions if needed.
+ *
+ * Caveat: for efficiency and security, all elements must be the same concrete type.
+ * In order to avoid writing the class name of each object, we must ensure that
+ * each object is the same type, or else unparceling then reparceling the data may yield
+ * a different result if the class name encoded in the Parcelable is a Base type.
+ * See b/17671747.
+ *
+ * @hide
+ */
+abstract class BaseMediaParceledListSlice<T> implements Parcelable {
+    private static String TAG = "BaseMediaParceledListSlice";
+    private static boolean DEBUG = false;
+
+    /*
+     * TODO get this number from somewhere else. For now set it to a quarter of
+     * the 1MB limit.
+     */
+    // private static final int MAX_IPC_SIZE = IBinder.getSuggestedMaxIpcSizeBytes();
+    private static final int MAX_IPC_SIZE = 64 * 1024;
+
+    private final List<T> mList;
+
+    private int mInlineCountLimit = Integer.MAX_VALUE;
+
+    public BaseMediaParceledListSlice(List<T> list) {
+        mList = list;
+    }
+
+    @SuppressWarnings("unchecked")
+    BaseMediaParceledListSlice(Parcel p, ClassLoader loader) {
+        final int N = p.readInt();
+        mList = new ArrayList<T>(N);
+        if (DEBUG) Log.d(TAG, "Retrieving " + N + " items");
+        if (N <= 0) {
+            return;
+        }
+
+        Parcelable.Creator<?> creator = readParcelableCreator(p, loader);
+        Class<?> listElementClass = null;
+
+        int i = 0;
+        while (i < N) {
+            if (p.readInt() == 0) {
+                break;
+            }
+
+            final T parcelable = readCreator(creator, p, loader);
+            if (listElementClass == null) {
+                listElementClass = parcelable.getClass();
+            } else {
+                verifySameType(listElementClass, parcelable.getClass());
+            }
+
+            mList.add(parcelable);
+
+            if (DEBUG) Log.d(TAG, "Read inline #" + i + ": " + mList.get(mList.size()-1));
+            i++;
+        }
+        if (i >= N) {
+            return;
+        }
+        final IBinder retriever = p.readStrongBinder();
+        while (i < N) {
+            if (DEBUG) Log.d(TAG, "Reading more @" + i + " of " + N + ": retriever=" + retriever);
+            Parcel data = Parcel.obtain();
+            Parcel reply = Parcel.obtain();
+            data.writeInt(i);
+            try {
+                retriever.transact(IBinder.FIRST_CALL_TRANSACTION, data, reply, 0);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Failure retrieving array; only received " + i + " of " + N, e);
+                return;
+            }
+            while (i < N && reply.readInt() != 0) {
+                final T parcelable = readCreator(creator, reply, loader);
+                verifySameType(listElementClass, parcelable.getClass());
+
+                mList.add(parcelable);
+
+                if (DEBUG) Log.d(TAG, "Read extra #" + i + ": " + mList.get(mList.size()-1));
+                i++;
+            }
+            reply.recycle();
+            data.recycle();
+        }
+    }
+
+    private T readCreator(Parcelable.Creator<?> creator, Parcel p, ClassLoader loader) {
+        if (creator instanceof Parcelable.ClassLoaderCreator<?>) {
+            Parcelable.ClassLoaderCreator<?> classLoaderCreator =
+                    (Parcelable.ClassLoaderCreator<?>) creator;
+            return (T) classLoaderCreator.createFromParcel(p, loader);
+        }
+        return (T) creator.createFromParcel(p);
+    }
+
+    private static void verifySameType(final Class<?> expected, final Class<?> actual) {
+        if (!actual.equals(expected)) {
+            throw new IllegalArgumentException("Can't unparcel type "
+                    + (actual == null ? null : actual.getName()) + " in list of type "
+                    + (expected == null ? null : expected.getName()));
+        }
+    }
+
+    public List<T> getList() {
+        return mList;
+    }
+
+    /**
+     * Set a limit on the maximum number of entries in the array that will be included
+     * inline in the initial parcelling of this object.
+     */
+    public void setInlineCountLimit(int maxCount) {
+        mInlineCountLimit = maxCount;
+    }
+
+    /**
+     * Write this to another Parcel. Note that this discards the internal Parcel
+     * and should not be used anymore. This is so we can pass this to a Binder
+     * where we won't have a chance to call recycle on this.
+     */
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        final int N = mList.size();
+        final int callFlags = flags;
+        dest.writeInt(N);
+        if (DEBUG) Log.d(TAG, "Writing " + N + " items");
+        if (N > 0) {
+            final Class<?> listElementClass = mList.get(0).getClass();
+            writeParcelableCreator(mList.get(0), dest);
+            int i = 0;
+            while (i < N && i < mInlineCountLimit && dest.dataSize() < MAX_IPC_SIZE) {
+                dest.writeInt(1);
+
+                final T parcelable = mList.get(i);
+                verifySameType(listElementClass, parcelable.getClass());
+                writeElement(parcelable, dest, callFlags);
+
+                if (DEBUG) Log.d(TAG, "Wrote inline #" + i + ": " + mList.get(i));
+                i++;
+            }
+            if (i < N) {
+                dest.writeInt(0);
+                Binder retriever = new Binder() {
+                    @Override
+                    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+                            throws RemoteException {
+                        if (code != FIRST_CALL_TRANSACTION) {
+                            return super.onTransact(code, data, reply, flags);
+                        }
+                        int i = data.readInt();
+                        if (DEBUG) Log.d(TAG, "Writing more @" + i + " of " + N);
+                        while (i < N && reply.dataSize() < MAX_IPC_SIZE) {
+                            reply.writeInt(1);
+
+                            final T parcelable = mList.get(i);
+                            verifySameType(listElementClass, parcelable.getClass());
+                            writeElement(parcelable, reply, callFlags);
+
+                            if (DEBUG) Log.d(TAG, "Wrote extra #" + i + ": " + mList.get(i));
+                            i++;
+                        }
+                        if (i < N) {
+                            if (DEBUG) Log.d(TAG, "Breaking @" + i + " of " + N);
+                            reply.writeInt(0);
+                        }
+                        return true;
+                    }
+                };
+                if (DEBUG) Log.d(TAG, "Breaking @" + i + " of " + N + ": retriever=" + retriever);
+                dest.writeStrongBinder(retriever);
+            }
+        }
+    }
+
+    abstract void writeElement(T parcelable, Parcel reply, int callFlags);
+
+    abstract void writeParcelableCreator(T parcelable, Parcel dest);
+
+    abstract Parcelable.Creator<?> readParcelableCreator(Parcel from, ClassLoader loader);
+}
diff --git a/android/media/BufferingParams.java b/android/media/BufferingParams.java
new file mode 100644
index 0000000..04af028
--- /dev/null
+++ b/android/media/BufferingParams.java
@@ -0,0 +1,188 @@
+/*
+ * Copyright 2017 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.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Structure for source buffering management params.
+ *
+ * Used by {@link MediaPlayer#getBufferingParams()} and
+ * {@link MediaPlayer#setBufferingParams(BufferingParams)}
+ * to control source buffering behavior.
+ *
+ * <p>There are two stages of source buffering in {@link MediaPlayer}: initial buffering
+ * (when {@link MediaPlayer} is being prepared) and rebuffering (when {@link MediaPlayer}
+ * is playing back source). {@link BufferingParams} includes corresponding marks for each
+ * stage of source buffering. The marks are time based (in milliseconds).
+ *
+ * <p>{@link MediaPlayer} source component has default marks which can be queried by
+ * calling {@link MediaPlayer#getBufferingParams()} before any change is made by
+ * {@link MediaPlayer#setBufferingParams()}.
+ * <ul>
+ * <li><strong>initial buffering:</strong> initialMarkMs is used when
+ * {@link MediaPlayer} is being prepared. When cached data amount exceeds this mark
+ * {@link MediaPlayer} is prepared. </li>
+ * <li><strong>rebuffering during playback:</strong> resumePlaybackMarkMs is used when
+ * {@link MediaPlayer} is playing back content.
+ * <ul>
+ * <li> {@link MediaPlayer} has internal mark, namely pausePlaybackMarkMs, to decide when
+ * to pause playback if cached data amount runs low. This internal mark varies based on
+ * type of data source. </li>
+ * <li> When cached data amount exceeds resumePlaybackMarkMs, {@link MediaPlayer} will
+ * resume playback if it has been paused due to low cached data amount. The internal mark
+ * pausePlaybackMarkMs shall be less than resumePlaybackMarkMs. </li>
+ * <li> {@link MediaPlayer} has internal mark, namely pauseRebufferingMarkMs, to decide
+ * when to pause rebuffering. Apparently, this internal mark shall be no less than
+ * resumePlaybackMarkMs. </li>
+ * <li> {@link MediaPlayer} has internal mark, namely resumeRebufferingMarkMs, to decide
+ * when to resume buffering. This internal mark varies based on type of data source. This
+ * mark shall be larger than pausePlaybackMarkMs, and less than pauseRebufferingMarkMs.
+ * </li>
+ * </ul> </li>
+ * </ul>
+ * <p>Users should use {@link Builder} to change {@link BufferingParams}.
+ * @hide
+ */
+public final class BufferingParams implements Parcelable {
+    private static final int BUFFERING_NO_MARK = -1;
+
+    // params
+    private int mInitialMarkMs = BUFFERING_NO_MARK;
+
+    private int mResumePlaybackMarkMs = BUFFERING_NO_MARK;
+
+    private BufferingParams() {
+    }
+
+    /**
+     * Return initial buffering mark in milliseconds.
+     * @return initial buffering mark in milliseconds
+     */
+    public int getInitialMarkMs() {
+        return mInitialMarkMs;
+    }
+
+    /**
+     * Return the mark in milliseconds for resuming playback.
+     * @return the mark for resuming playback in milliseconds
+     */
+    public int getResumePlaybackMarkMs() {
+        return mResumePlaybackMarkMs;
+    }
+
+    /**
+     * Builder class for {@link BufferingParams} objects.
+     * <p> Here is an example where <code>Builder</code> is used to define the
+     * {@link BufferingParams} to be used by a {@link MediaPlayer} instance:
+     *
+     * <pre class="prettyprint">
+     * BufferingParams myParams = mediaplayer.getDefaultBufferingParams();
+     * myParams = new BufferingParams.Builder(myParams)
+     *         .setInitialMarkMs(10000)
+     *         .setResumePlaybackMarkMs(15000)
+     *         .build();
+     * mediaplayer.setBufferingParams(myParams);
+     * </pre>
+     */
+    public static class Builder {
+        private int mInitialMarkMs = BUFFERING_NO_MARK;
+        private int mResumePlaybackMarkMs = BUFFERING_NO_MARK;
+
+        /**
+         * Constructs a new Builder with the defaults.
+         * By default, all marks are -1.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Constructs a new Builder from a given {@link BufferingParams} instance
+         * @param bp the {@link BufferingParams} object whose data will be reused
+         * in the new Builder.
+         */
+        public Builder(BufferingParams bp) {
+            mInitialMarkMs = bp.mInitialMarkMs;
+            mResumePlaybackMarkMs = bp.mResumePlaybackMarkMs;
+        }
+
+        /**
+         * Combines all of the fields that have been set and return a new
+         * {@link BufferingParams} object. <code>IllegalStateException</code> will be
+         * thrown if there is conflict between fields.
+         * @return a new {@link BufferingParams} object
+         */
+        public BufferingParams build() {
+            BufferingParams bp = new BufferingParams();
+            bp.mInitialMarkMs = mInitialMarkMs;
+            bp.mResumePlaybackMarkMs = mResumePlaybackMarkMs;
+
+            return bp;
+        }
+
+        /**
+         * Sets the time based mark in milliseconds for initial buffering.
+         * @param markMs time based mark in milliseconds
+         * @return the same Builder instance.
+         */
+        public Builder setInitialMarkMs(int markMs) {
+            mInitialMarkMs = markMs;
+            return this;
+        }
+
+        /**
+         * Sets the time based mark in milliseconds for resuming playback.
+         * @param markMs time based mark in milliseconds for resuming playback
+         * @return the same Builder instance.
+         */
+        public Builder setResumePlaybackMarkMs(int markMs) {
+            mResumePlaybackMarkMs = markMs;
+            return this;
+        }
+    }
+
+    private BufferingParams(Parcel in) {
+        mInitialMarkMs = in.readInt();
+        mResumePlaybackMarkMs = in.readInt();
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<BufferingParams> CREATOR =
+            new Parcelable.Creator<BufferingParams>() {
+                @Override
+                public BufferingParams createFromParcel(Parcel in) {
+                    return new BufferingParams(in);
+                }
+
+                @Override
+                public BufferingParams[] newArray(int size) {
+                    return new BufferingParams[size];
+                }
+            };
+
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mInitialMarkMs);
+        dest.writeInt(mResumePlaybackMarkMs);
+    }
+}
diff --git a/android/media/CamcorderProfile.java b/android/media/CamcorderProfile.java
new file mode 100644
index 0000000..b4fdcb9
--- /dev/null
+++ b/android/media/CamcorderProfile.java
@@ -0,0 +1,718 @@
+/*
+ * Copyright (C) 2010 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.hardware.Camera;
+import android.hardware.Camera.CameraInfo;
+import android.hardware.camera2.CameraManager;
+import android.hardware.camera2.CameraMetadata;
+import android.os.Build;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Retrieves the
+ * predefined camcorder profile settings for camcorder applications.
+ * These settings are read-only.
+ *
+ * <p>The compressed output from a recording session with a given
+ * CamcorderProfile contains two tracks: one for audio and one for video.
+ *
+ * <p>Each profile specifies the following set of parameters:
+ * <ul>
+ * <li> The file output format
+ * <li> Video codec format
+ * <li> Video bit rate in bits per second
+ * <li> Video frame rate in frames per second
+ * <li> Video frame width and height,
+ * <li> Audio codec format
+ * <li> Audio bit rate in bits per second,
+ * <li> Audio sample rate
+ * <li> Number of audio channels for recording.
+ * </ul>
+ */
+public class CamcorderProfile
+{
+    // Do not change these values/ordinals without updating their counterpart
+    // in include/media/MediaProfiles.h!
+
+    /**
+     * Quality level corresponding to the lowest available resolution.
+     */
+    public static final int QUALITY_LOW  = 0;
+
+    /**
+     * Quality level corresponding to the highest available resolution.
+     */
+    public static final int QUALITY_HIGH = 1;
+
+    /**
+     * Quality level corresponding to the qcif (176 x 144) resolution.
+     */
+    public static final int QUALITY_QCIF = 2;
+
+    /**
+     * Quality level corresponding to the cif (352 x 288) resolution.
+     */
+    public static final int QUALITY_CIF = 3;
+
+    /**
+     * Quality level corresponding to the 480p (720 x 480) resolution.
+     * Note that the horizontal resolution for 480p can also be other
+     * values, such as 640 or 704, instead of 720.
+     */
+    public static final int QUALITY_480P = 4;
+
+    /**
+     * Quality level corresponding to the 720p (1280 x 720) resolution.
+     */
+    public static final int QUALITY_720P = 5;
+
+    /**
+     * Quality level corresponding to the 1080p (1920 x 1080) resolution.
+     * Note that the vertical resolution for 1080p can also be 1088,
+     * instead of 1080 (used by some vendors to avoid cropping during
+     * video playback).
+     */
+    public static final int QUALITY_1080P = 6;
+
+    /**
+     * Quality level corresponding to the QVGA (320x240) resolution.
+     */
+    public static final int QUALITY_QVGA = 7;
+
+    /**
+     * Quality level corresponding to the 2160p (3840x2160) resolution.
+     */
+    public static final int QUALITY_2160P = 8;
+
+    /**
+     * Quality level corresponding to the VGA (640 x 480) resolution.
+     */
+    public static final int QUALITY_VGA = 9;
+
+    /**
+     * Quality level corresponding to 4k-DCI (4096 x 2160) resolution.
+     */
+    public static final int QUALITY_4KDCI = 10;
+
+    /**
+     * Quality level corresponding to QHD (2560 x 1440) resolution
+     */
+    public static final int QUALITY_QHD = 11;
+
+    /**
+     * Quality level corresponding to 2K (2048 x 1080) resolution
+     */
+    public static final int QUALITY_2K = 12;
+
+    /**
+     * Quality level corresponding to 8K UHD (7680 x 4320) resolution
+     */
+    public static final int QUALITY_8KUHD = 13;
+
+    // Start and end of quality list
+    private static final int QUALITY_LIST_START = QUALITY_LOW;
+    private static final int QUALITY_LIST_END = QUALITY_8KUHD;
+
+    /**
+     * Time lapse quality level corresponding to the lowest available resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_LOW  = 1000;
+
+    /**
+     * Time lapse quality level corresponding to the highest available resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_HIGH = 1001;
+
+    /**
+     * Time lapse quality level corresponding to the qcif (176 x 144) resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_QCIF = 1002;
+
+    /**
+     * Time lapse quality level corresponding to the cif (352 x 288) resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_CIF = 1003;
+
+    /**
+     * Time lapse quality level corresponding to the 480p (720 x 480) resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_480P = 1004;
+
+    /**
+     * Time lapse quality level corresponding to the 720p (1280 x 720) resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_720P = 1005;
+
+    /**
+     * Time lapse quality level corresponding to the 1080p (1920 x 1088) resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_1080P = 1006;
+
+    /**
+     * Time lapse quality level corresponding to the QVGA (320 x 240) resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_QVGA = 1007;
+
+    /**
+     * Time lapse quality level corresponding to the 2160p (3840 x 2160) resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_2160P = 1008;
+
+    /**
+     * Time lapse quality level corresponding to the VGA (640 x 480) resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_VGA = 1009;
+
+    /**
+     * Time lapse quality level corresponding to the 4k-DCI (4096 x 2160) resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_4KDCI = 1010;
+
+    /**
+     * Time lapse quality level corresponding to the QHD (2560 x 1440) resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_QHD = 1011;
+
+    /**
+     * Time lapse quality level corresponding to the 2K (2048 x 1080) resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_2K = 1012;
+
+    /**
+     * Time lapse quality level corresponding to the 8K UHD (7680 x 4320) resolution.
+     */
+    public static final int QUALITY_TIME_LAPSE_8KUHD = 1013;
+
+    // Start and end of timelapse quality list
+    private static final int QUALITY_TIME_LAPSE_LIST_START = QUALITY_TIME_LAPSE_LOW;
+    private static final int QUALITY_TIME_LAPSE_LIST_END = QUALITY_TIME_LAPSE_8KUHD;
+
+    /**
+     * High speed ( >= 100fps) quality level corresponding to the lowest available resolution.
+     * <p>
+     * For all the high speed profiles defined below ((from {@link #QUALITY_HIGH_SPEED_LOW} to
+     * {@link #QUALITY_HIGH_SPEED_2160P}), they are similar as normal recording profiles, with just
+     * higher output frame rate and bit rate. Therefore, setting these profiles with
+     * {@link MediaRecorder#setProfile} without specifying any other encoding parameters will
+     * produce high speed videos rather than slow motion videos that have different capture and
+     * output (playback) frame rates. To record slow motion videos, the application must set video
+     * output (playback) frame rate and bit rate appropriately via
+     * {@link MediaRecorder#setVideoFrameRate} and {@link MediaRecorder#setVideoEncodingBitRate}
+     * based on the slow motion factor. If the application intends to do the video recording with
+     * {@link MediaCodec} encoder, it must set each individual field of {@link MediaFormat}
+     * similarly according to this CamcorderProfile.
+     * </p>
+     *
+     * @see #videoBitRate
+     * @see #videoFrameRate
+     * @see MediaRecorder
+     * @see MediaCodec
+     * @see MediaFormat
+     */
+    public static final int QUALITY_HIGH_SPEED_LOW = 2000;
+
+    /**
+     * High speed ( >= 100fps) quality level corresponding to the highest available resolution.
+     */
+    public static final int QUALITY_HIGH_SPEED_HIGH = 2001;
+
+    /**
+     * High speed ( >= 100fps) quality level corresponding to the 480p (720 x 480) resolution.
+     *
+     * Note that the horizontal resolution for 480p can also be other
+     * values, such as 640 or 704, instead of 720.
+     */
+    public static final int QUALITY_HIGH_SPEED_480P = 2002;
+
+    /**
+     * High speed ( >= 100fps) quality level corresponding to the 720p (1280 x 720) resolution.
+     */
+    public static final int QUALITY_HIGH_SPEED_720P = 2003;
+
+    /**
+     * High speed ( >= 100fps) quality level corresponding to the 1080p (1920 x 1080 or 1920x1088)
+     * resolution.
+     */
+    public static final int QUALITY_HIGH_SPEED_1080P = 2004;
+
+    /**
+     * High speed ( >= 100fps) quality level corresponding to the 2160p (3840 x 2160)
+     * resolution.
+     */
+    public static final int QUALITY_HIGH_SPEED_2160P = 2005;
+
+    /**
+     * High speed ( >= 100fps) quality level corresponding to the CIF (352 x 288)
+     */
+    public static final int QUALITY_HIGH_SPEED_CIF = 2006;
+
+    /**
+     * High speed ( >= 100fps) quality level corresponding to the VGA (640 x 480)
+     */
+    public static final int QUALITY_HIGH_SPEED_VGA = 2007;
+
+    /**
+     * High speed ( >= 100fps) quality level corresponding to the 4K-DCI (4096 x 2160)
+     */
+    public static final int QUALITY_HIGH_SPEED_4KDCI = 2008;
+
+    // Start and end of high speed quality list
+    private static final int QUALITY_HIGH_SPEED_LIST_START = QUALITY_HIGH_SPEED_LOW;
+    private static final int QUALITY_HIGH_SPEED_LIST_END = QUALITY_HIGH_SPEED_4KDCI;
+
+    /**
+     * @hide
+     */
+    @IntDef({
+        QUALITY_LOW,
+        QUALITY_HIGH,
+        QUALITY_QCIF,
+        QUALITY_CIF,
+        QUALITY_480P,
+        QUALITY_720P,
+        QUALITY_1080P,
+        QUALITY_QVGA,
+        QUALITY_2160P,
+        QUALITY_VGA,
+        QUALITY_4KDCI,
+        QUALITY_QHD,
+        QUALITY_2K,
+        QUALITY_8KUHD,
+
+        QUALITY_TIME_LAPSE_LOW ,
+        QUALITY_TIME_LAPSE_HIGH,
+        QUALITY_TIME_LAPSE_QCIF,
+        QUALITY_TIME_LAPSE_CIF,
+        QUALITY_TIME_LAPSE_480P,
+        QUALITY_TIME_LAPSE_720P,
+        QUALITY_TIME_LAPSE_1080P,
+        QUALITY_TIME_LAPSE_QVGA,
+        QUALITY_TIME_LAPSE_2160P,
+        QUALITY_TIME_LAPSE_VGA,
+        QUALITY_TIME_LAPSE_4KDCI,
+        QUALITY_TIME_LAPSE_QHD,
+        QUALITY_TIME_LAPSE_2K,
+        QUALITY_TIME_LAPSE_8KUHD,
+
+        QUALITY_HIGH_SPEED_LOW,
+        QUALITY_HIGH_SPEED_HIGH,
+        QUALITY_HIGH_SPEED_480P,
+        QUALITY_HIGH_SPEED_720P,
+        QUALITY_HIGH_SPEED_1080P,
+        QUALITY_HIGH_SPEED_2160P,
+        QUALITY_HIGH_SPEED_CIF,
+        QUALITY_HIGH_SPEED_VGA,
+        QUALITY_HIGH_SPEED_4KDCI,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Quality {}
+
+    /**
+     * Default recording duration in seconds before the session is terminated.
+     * This is useful for applications like MMS has limited file size requirement.
+     */
+    public int duration;
+
+    /**
+     * The quality level of the camcorder profile
+     */
+    public int quality;
+
+    /**
+     * The file output format of the camcorder profile
+     * @see android.media.MediaRecorder.OutputFormat
+     */
+    public int fileFormat;
+
+    /**
+     * The video encoder being used for the video track
+     * @see android.media.MediaRecorder.VideoEncoder
+     */
+    public int videoCodec;
+
+    /**
+     * The target video output bit rate in bits per second
+     * <p>
+     * This is the target recorded video output bit rate if the application configures the video
+     * recording via {@link MediaRecorder#setProfile} without specifying any other
+     * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles (from
+     * {@link #QUALITY_HIGH_SPEED_LOW} to {@link #QUALITY_HIGH_SPEED_2160P}), this is the bit rate
+     * where the video is recorded with. If the application intends to record slow motion videos
+     * with the high speed quality profiles, it must set a different video bit rate that is
+     * corresponding to the desired recording output bit rate (i.e., the encoded video bit rate
+     * during normal playback) via {@link MediaRecorder#setVideoEncodingBitRate}. For example, if
+     * {@link #QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #videoFrameRate} and 64Mbps
+     * {@link #videoBitRate} in the high speed CamcorderProfile, and the application intends to
+     * record 1/8 factor slow motion recording videos, the application must set 30fps via
+     * {@link MediaRecorder#setVideoFrameRate} and 8Mbps ( {@link #videoBitRate} * slow motion
+     * factor) via {@link MediaRecorder#setVideoEncodingBitRate}. Failing to do so will result in
+     * videos with unexpected frame rate and bit rate, or {@link MediaRecorder} error if the output
+     * bit rate exceeds the encoder limit. If the application intends to do the video recording with
+     * {@link MediaCodec} encoder, it must set each individual field of {@link MediaFormat}
+     * similarly according to this CamcorderProfile.
+     * </p>
+     *
+     * @see #videoFrameRate
+     * @see MediaRecorder
+     * @see MediaCodec
+     * @see MediaFormat
+     */
+    public int videoBitRate;
+
+    /**
+     * The target video frame rate in frames per second.
+     * <p>
+     * This is the target recorded video output frame rate per second if the application configures
+     * the video recording via {@link MediaRecorder#setProfile} without specifying any other
+     * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles (from
+     * {@link #QUALITY_HIGH_SPEED_LOW} to {@link #QUALITY_HIGH_SPEED_2160P}), this is the frame rate
+     * where the video is recorded and played back with. If the application intends to create slow
+     * motion use case with the high speed quality profiles, it must set a different video frame
+     * rate that is corresponding to the desired output (playback) frame rate via
+     * {@link MediaRecorder#setVideoFrameRate}. For example, if {@link #QUALITY_HIGH_SPEED_720P}
+     * advertises 240fps {@link #videoFrameRate} in the CamcorderProfile, and the application
+     * intends to create 1/8 factor slow motion recording videos, the application must set 30fps via
+     * {@link MediaRecorder#setVideoFrameRate}. Failing to do so will result in high speed videos
+     * with normal speed playback frame rate (240fps for above example). If the application intends
+     * to do the video recording with {@link MediaCodec} encoder, it must set each individual field
+     * of {@link MediaFormat} similarly according to this CamcorderProfile.
+     * </p>
+     *
+     * @see #videoBitRate
+     * @see MediaRecorder
+     * @see MediaCodec
+     * @see MediaFormat
+     */
+    public int videoFrameRate;
+
+    /**
+     * The target video frame width in pixels
+     */
+    public int videoFrameWidth;
+
+    /**
+     * The target video frame height in pixels
+     */
+    public int videoFrameHeight;
+
+    /**
+     * The audio encoder being used for the audio track.
+     * @see android.media.MediaRecorder.AudioEncoder
+     */
+    public int audioCodec;
+
+    /**
+     * The target audio output bit rate in bits per second
+     */
+    public int audioBitRate;
+
+    /**
+     * The audio sampling rate used for the audio track
+     */
+    public int audioSampleRate;
+
+    /**
+     * The number of audio channels used for the audio track
+     */
+    public int audioChannels;
+
+    /**
+     * Returns the default camcorder profile at the given quality level for the first back-facing
+     * camera on the device. If the device has no back-facing camera, this returns null.
+     * @param quality the target quality level for the camcorder profile
+     * @see #get(int, int)
+     * @deprecated Use {@link #getAll} instead
+     */
+    public static CamcorderProfile get(int quality) {
+        int numberOfCameras = Camera.getNumberOfCameras();
+        CameraInfo cameraInfo = new CameraInfo();
+        for (int i = 0; i < numberOfCameras; i++) {
+            Camera.getCameraInfo(i, cameraInfo);
+            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
+                return get(i, quality);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the default camcorder profile for the given camera at the given quality level.
+     *
+     * Quality levels QUALITY_LOW, QUALITY_HIGH are guaranteed to be supported, while
+     * other levels may or may not be supported. The supported levels can be checked using
+     * {@link #hasProfile(int, int)}.
+     * QUALITY_LOW refers to the lowest quality available, while QUALITY_HIGH refers to
+     * the highest quality available.
+     * QUALITY_LOW/QUALITY_HIGH have to match one of qcif, cif, 480p, 720p, 1080p or 2160p.
+     * E.g. if the device supports 480p, 720p, 1080p and 2160p, then low is 480p and high is
+     * 2160p.
+     *
+     * The same is true for time lapse quality levels, i.e. QUALITY_TIME_LAPSE_LOW,
+     * QUALITY_TIME_LAPSE_HIGH are guaranteed to be supported and have to match one of
+     * qcif, cif, 480p, 720p, 1080p, or 2160p.
+     *
+     * For high speed quality levels, they may or may not be supported. If a subset of the levels
+     * are supported, QUALITY_HIGH_SPEED_LOW and QUALITY_HIGH_SPEED_HIGH are guaranteed to be
+     * supported and have to match one of 480p, 720p, or 1080p.
+     *
+     * A camcorder recording session with higher quality level usually has higher output
+     * bit rate, better video and/or audio recording quality, larger video frame
+     * resolution and higher audio sampling rate, etc, than those with lower quality
+     * level.
+     *
+     * @param cameraId the id for the camera. Integer camera ids parsed from the list received by
+     *                 invoking {@link CameraManager#getCameraIdList} can be used as long as they
+     *                 are {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE}
+     *                 and not
+     *                 {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL EXTERNAL}.
+     * @param quality the target quality level for the camcorder profile.
+     * @see #QUALITY_LOW
+     * @see #QUALITY_HIGH
+     * @see #QUALITY_QCIF
+     * @see #QUALITY_CIF
+     * @see #QUALITY_480P
+     * @see #QUALITY_720P
+     * @see #QUALITY_1080P
+     * @see #QUALITY_2160P
+     * @see #QUALITY_TIME_LAPSE_LOW
+     * @see #QUALITY_TIME_LAPSE_HIGH
+     * @see #QUALITY_TIME_LAPSE_QCIF
+     * @see #QUALITY_TIME_LAPSE_CIF
+     * @see #QUALITY_TIME_LAPSE_480P
+     * @see #QUALITY_TIME_LAPSE_720P
+     * @see #QUALITY_TIME_LAPSE_1080P
+     * @see #QUALITY_TIME_LAPSE_2160P
+     * @see #QUALITY_HIGH_SPEED_LOW
+     * @see #QUALITY_HIGH_SPEED_HIGH
+     * @see #QUALITY_HIGH_SPEED_480P
+     * @see #QUALITY_HIGH_SPEED_720P
+     * @see #QUALITY_HIGH_SPEED_1080P
+     * @see #QUALITY_HIGH_SPEED_2160P
+     * @deprecated Use {@link #getAll} instead
+     * @throws IllegalArgumentException if quality is not one of the defined QUALITY_ values.
+    */
+    public static CamcorderProfile get(int cameraId, int quality) {
+        if (!((quality >= QUALITY_LIST_START &&
+               quality <= QUALITY_LIST_END) ||
+              (quality >= QUALITY_TIME_LAPSE_LIST_START &&
+               quality <= QUALITY_TIME_LAPSE_LIST_END) ||
+               (quality >= QUALITY_HIGH_SPEED_LIST_START &&
+               quality <= QUALITY_HIGH_SPEED_LIST_END))) {
+            String errMessage = "Unsupported quality level: " + quality;
+            throw new IllegalArgumentException(errMessage);
+        }
+        return native_get_camcorder_profile(cameraId, quality);
+    }
+
+    /**
+     * Returns all encoder profiles of a camcorder profile for the given camera at
+     * the given quality level.
+     *
+     * Quality levels QUALITY_LOW, QUALITY_HIGH are guaranteed to be supported, while
+     * other levels may or may not be supported. The supported levels can be checked using
+     * {@link #hasProfile(int, int)}.
+     * QUALITY_LOW refers to the lowest quality available, while QUALITY_HIGH refers to
+     * the highest quality available.
+     * QUALITY_LOW/QUALITY_HIGH have to match one of qcif, cif, 480p, 720p, 1080p or 2160p.
+     * E.g. if the device supports 480p, 720p, 1080p and 2160p, then low is 480p and high is
+     * 2160p.
+     *
+     * The same is true for time lapse quality levels, i.e. QUALITY_TIME_LAPSE_LOW,
+     * QUALITY_TIME_LAPSE_HIGH are guaranteed to be supported and have to match one of
+     * qcif, cif, 480p, 720p, 1080p, or 2160p.
+     *
+     * For high speed quality levels, they may or may not be supported. If a subset of the levels
+     * are supported, QUALITY_HIGH_SPEED_LOW and QUALITY_HIGH_SPEED_HIGH are guaranteed to be
+     * supported and have to match one of 480p, 720p, or 1080p.
+     *
+     * A camcorder recording session with higher quality level usually has higher output
+     * bit rate, better video and/or audio recording quality, larger video frame
+     * resolution and higher audio sampling rate, etc, than those with lower quality
+     * level.
+     *
+     * @param cameraId the id for the camera. Numeric camera ids from the list received by invoking
+     *                 {@link CameraManager#getCameraIdList} can be used as long as they are
+     *                 {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE}
+     *                 and not
+     *                 {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL EXTERNAL}.
+     * @param quality the target quality level for the camcorder profile.
+     * @return null if there are no encoder profiles defined for the quality level for the
+     * given camera.
+     * @throws IllegalArgumentException if quality is not one of the defined QUALITY_ values.
+     * @see #QUALITY_LOW
+     * @see #QUALITY_HIGH
+     * @see #QUALITY_QCIF
+     * @see #QUALITY_CIF
+     * @see #QUALITY_480P
+     * @see #QUALITY_720P
+     * @see #QUALITY_1080P
+     * @see #QUALITY_2160P
+     * @see #QUALITY_TIME_LAPSE_LOW
+     * @see #QUALITY_TIME_LAPSE_HIGH
+     * @see #QUALITY_TIME_LAPSE_QCIF
+     * @see #QUALITY_TIME_LAPSE_CIF
+     * @see #QUALITY_TIME_LAPSE_480P
+     * @see #QUALITY_TIME_LAPSE_720P
+     * @see #QUALITY_TIME_LAPSE_1080P
+     * @see #QUALITY_TIME_LAPSE_2160P
+     * @see #QUALITY_HIGH_SPEED_LOW
+     * @see #QUALITY_HIGH_SPEED_HIGH
+     * @see #QUALITY_HIGH_SPEED_480P
+     * @see #QUALITY_HIGH_SPEED_720P
+     * @see #QUALITY_HIGH_SPEED_1080P
+     * @see #QUALITY_HIGH_SPEED_2160P
+    */
+    @Nullable public static EncoderProfiles getAll(
+            @NonNull String cameraId, @Quality int quality) {
+        if (!((quality >= QUALITY_LIST_START &&
+               quality <= QUALITY_LIST_END) ||
+              (quality >= QUALITY_TIME_LAPSE_LIST_START &&
+               quality <= QUALITY_TIME_LAPSE_LIST_END) ||
+               (quality >= QUALITY_HIGH_SPEED_LIST_START &&
+               quality <= QUALITY_HIGH_SPEED_LIST_END))) {
+            String errMessage = "Unsupported quality level: " + quality;
+            throw new IllegalArgumentException(errMessage);
+        }
+
+        // TODO: get all profiles
+        int id;
+        try {
+            id = Integer.valueOf(cameraId);
+        } catch (NumberFormatException e) {
+            return null;
+        }
+        return native_get_camcorder_profiles(id, quality);
+    }
+
+    /**
+     * Returns true if a camcorder profile exists for the first back-facing
+     * camera at the given quality level.
+     *
+     * <p>
+     * When using the Camera 2 API in {@code LEGACY} mode (i.e. when
+     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} is set
+     * to
+     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}),
+     * {@link #hasProfile} may return {@code true} for unsupported resolutions.  To ensure a
+     * a given resolution is supported in LEGACY mode, the configuration given in
+     * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}
+     * must contain the the resolution in the supported output sizes.  The recommended way to check
+     * this is with
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes(Class)} with the
+     * class of the desired recording endpoint, and check that the desired resolution is contained
+     * in the list returned.
+     * </p>
+     * @see android.hardware.camera2.CameraManager
+     * @see android.hardware.camera2.CameraCharacteristics
+     *
+     * @param quality the target quality level for the camcorder profile
+     */
+    public static boolean hasProfile(int quality) {
+        int numberOfCameras = Camera.getNumberOfCameras();
+        CameraInfo cameraInfo = new CameraInfo();
+        for (int i = 0; i < numberOfCameras; i++) {
+            Camera.getCameraInfo(i, cameraInfo);
+            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
+                return hasProfile(i, quality);
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if a camcorder profile exists for the given camera at
+     * the given quality level.
+     *
+     * <p>
+     * When using the Camera 2 API in LEGACY mode (i.e. when
+     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL} is set
+     * to
+     * {@link android.hardware.camera2.CameraCharacteristics#INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY}),
+     * {@link #hasProfile} may return {@code true} for unsupported resolutions.  To ensure a
+     * a given resolution is supported in LEGACY mode, the configuration given in
+     * {@link android.hardware.camera2.CameraCharacteristics#SCALER_STREAM_CONFIGURATION_MAP}
+     * must contain the the resolution in the supported output sizes.  The recommended way to check
+     * this is with
+     * {@link android.hardware.camera2.params.StreamConfigurationMap#getOutputSizes(Class)} with the
+     * class of the desired recording endpoint, and check that the desired resolution is contained
+     * in the list returned.
+     * </p>
+     * @see android.hardware.camera2.CameraManager
+     * @see android.hardware.camera2.CameraCharacteristics
+     *
+     * @param cameraId the id for the camera. Integer camera ids parsed from the list received by
+     *                 invoking {@link CameraManager#getCameraIdList} can be used as long as they
+     *                 are {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_BACKWARD_COMPATIBLE}
+     *                 and not
+     *                 {@link CameraMetadata#INFO_SUPPORTED_HARDWARE_LEVEL_EXTERNAL EXTERNAL}.
+     * @param quality the target quality level for the camcorder profile
+     */
+    public static boolean hasProfile(int cameraId, int quality) {
+        return native_has_camcorder_profile(cameraId, quality);
+    }
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    // Private constructor called by JNI
+    private CamcorderProfile(int duration,
+                             int quality,
+                             int fileFormat,
+                             int videoCodec,
+                             int videoBitRate,
+                             int videoFrameRate,
+                             int videoWidth,
+                             int videoHeight,
+                             int audioCodec,
+                             int audioBitRate,
+                             int audioSampleRate,
+                             int audioChannels) {
+
+        this.duration         = duration;
+        this.quality          = quality;
+        this.fileFormat       = fileFormat;
+        this.videoCodec       = videoCodec;
+        this.videoBitRate     = videoBitRate;
+        this.videoFrameRate   = videoFrameRate;
+        this.videoFrameWidth  = videoWidth;
+        this.videoFrameHeight = videoHeight;
+        this.audioCodec       = audioCodec;
+        this.audioBitRate     = audioBitRate;
+        this.audioSampleRate  = audioSampleRate;
+        this.audioChannels    = audioChannels;
+    }
+
+    // Methods implemented by JNI
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private static native final void native_init();
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static native final CamcorderProfile native_get_camcorder_profile(
+            int cameraId, int quality);
+    private static native final EncoderProfiles native_get_camcorder_profiles(
+            int cameraId, int quality);
+    private static native final boolean native_has_camcorder_profile(
+            int cameraId, int quality);
+}
diff --git a/android/media/CameraProfile.java b/android/media/CameraProfile.java
new file mode 100644
index 0000000..905e2d2
--- /dev/null
+++ b/android/media/CameraProfile.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2010 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.hardware.Camera;
+import android.hardware.Camera.CameraInfo;
+
+import java.util.Arrays;
+import java.util.HashMap;
+
+/**
+ * The CameraProfile class is used to retrieve the pre-defined still image
+ * capture (jpeg) quality levels (0-100) used for low, medium, and high
+ * quality settings in the Camera application.
+ *
+ */
+public class CameraProfile
+{
+    /**
+     * Define three quality levels for JPEG image encoding.
+     */
+    /*
+     * Don't change the values for these constants unless getImageEncodingQualityLevels()
+     * method is also changed accordingly.
+     */
+    public static final int QUALITY_LOW    = 0;
+    public static final int QUALITY_MEDIUM = 1;
+    public static final int QUALITY_HIGH   = 2;
+
+    /*
+     * Cache the Jpeg encoding quality parameters
+     */
+    private static final HashMap<Integer, int[]> sCache = new HashMap<Integer, int[]>();
+
+    /**
+     * Returns a pre-defined still image capture (jpeg) quality level
+     * used for the given quality level in the Camera application for
+     * the first back-facing camera on the device. If the device has no
+     * back-facing camera, this returns 0.
+     *
+     * @param quality The target quality level
+     */
+    public static int getJpegEncodingQualityParameter(int quality) {
+        int numberOfCameras = Camera.getNumberOfCameras();
+        CameraInfo cameraInfo = new CameraInfo();
+        for (int i = 0; i < numberOfCameras; i++) {
+            Camera.getCameraInfo(i, cameraInfo);
+            if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
+                return getJpegEncodingQualityParameter(i, quality);
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Returns a pre-defined still image capture (jpeg) quality level
+     * used for the given quality level in the Camera application for
+     * the specified camera.
+     *
+     * @param cameraId The id of the camera
+     * @param quality The target quality level
+     */
+    public static int getJpegEncodingQualityParameter(int cameraId, int quality) {
+        if (quality < QUALITY_LOW || quality > QUALITY_HIGH) {
+            throw new IllegalArgumentException("Unsupported quality level: " + quality);
+        }
+        synchronized (sCache) {
+            int[] levels = sCache.get(cameraId);
+            if (levels == null) {
+                levels = getImageEncodingQualityLevels(cameraId);
+                sCache.put(cameraId, levels);
+            }
+            return levels[quality];
+        }
+    }
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    private static int[] getImageEncodingQualityLevels(int cameraId) {
+        int nLevels = native_get_num_image_encoding_quality_levels(cameraId);
+        if (nLevels != QUALITY_HIGH + 1) {
+            throw new RuntimeException("Unexpected Jpeg encoding quality levels " + nLevels);
+        }
+
+        int[] levels = new int[nLevels];
+        for (int i = 0; i < nLevels; ++i) {
+            levels[i] = native_get_image_encoding_quality_level(cameraId, i);
+        }
+        Arrays.sort(levels);  // Lower quality level ALWAYS comes before higher one
+        return levels;
+    }
+
+    // Methods implemented by JNI
+    private static native final void native_init();
+    private static native final int native_get_num_image_encoding_quality_levels(int cameraId);
+    private static native final int native_get_image_encoding_quality_level(int cameraId, int index);
+}
diff --git a/android/media/Cea708CaptionRenderer.java b/android/media/Cea708CaptionRenderer.java
new file mode 100644
index 0000000..88912fe
--- /dev/null
+++ b/android/media/Cea708CaptionRenderer.java
@@ -0,0 +1,2151 @@
+/*
+ * Copyright (C) 2015 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.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.os.Handler;
+import android.os.Message;
+import android.text.SpannableStringBuilder;
+import android.text.Spanned;
+import android.text.style.CharacterStyle;
+import android.text.style.RelativeSizeSpan;
+import android.text.style.StyleSpan;
+import android.text.style.SubscriptSpan;
+import android.text.style.SuperscriptSpan;
+import android.text.style.UnderlineSpan;
+import android.util.AttributeSet;
+import android.text.Layout.Alignment;
+import android.util.Log;
+import android.text.TextUtils;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.CaptioningManager;
+import android.view.accessibility.CaptioningManager.CaptionStyle;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import java.io.UnsupportedEncodingException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Vector;
+
+import com.android.internal.widget.SubtitleView;
+
+/** @hide */
+public class Cea708CaptionRenderer extends SubtitleController.Renderer {
+    private final Context mContext;
+    private Cea708CCWidget mCCWidget;
+
+    public Cea708CaptionRenderer(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public boolean supports(MediaFormat format) {
+        if (format.containsKey(MediaFormat.KEY_MIME)) {
+            String mimeType = format.getString(MediaFormat.KEY_MIME);
+            return MediaPlayer.MEDIA_MIMETYPE_TEXT_CEA_708.equals(mimeType);
+        }
+        return false;
+    }
+
+    @Override
+    public SubtitleTrack createTrack(MediaFormat format) {
+        String mimeType = format.getString(MediaFormat.KEY_MIME);
+        if (MediaPlayer.MEDIA_MIMETYPE_TEXT_CEA_708.equals(mimeType)) {
+            if (mCCWidget == null) {
+                mCCWidget = new Cea708CCWidget(mContext);
+            }
+            return new Cea708CaptionTrack(mCCWidget, format);
+        }
+        throw new RuntimeException("No matching format: " + format.toString());
+    }
+}
+
+/** @hide */
+class Cea708CaptionTrack extends SubtitleTrack {
+    private final Cea708CCParser mCCParser;
+    private final Cea708CCWidget mRenderingWidget;
+
+    Cea708CaptionTrack(Cea708CCWidget renderingWidget, MediaFormat format) {
+        super(format);
+
+        mRenderingWidget = renderingWidget;
+        mCCParser = new Cea708CCParser(mRenderingWidget);
+    }
+
+    @Override
+    public void onData(byte[] data, boolean eos, long runID) {
+        mCCParser.parse(data);
+    }
+
+    @Override
+    public RenderingWidget getRenderingWidget() {
+        return mRenderingWidget;
+    }
+
+    @Override
+    public void updateView(Vector<Cue> activeCues) {
+        // Overriding with NO-OP, CC rendering by-passes this
+    }
+}
+
+/**
+ * @hide
+ *
+ * A class for parsing CEA-708, which is the standard for closed captioning for ATSC DTV.
+ *
+ * <p>ATSC DTV closed caption data are carried on picture user data of video streams.
+ * This class starts to parse from picture user data payload, so extraction process of user_data
+ * from video streams is up to outside of this code.
+ *
+ * <p>There are 4 steps to decode user_data to provide closed caption services. Step 1 and 2 are
+ * done in NuPlayer and libstagefright.
+ *
+ * <h3>Step 1. user_data -&gt; CcPacket</h3>
+ *
+ * <p>First, user_data consists of cc_data packets, which are 3-byte segments. Here, CcPacket is a
+ * collection of cc_data packets in a frame along with same presentation timestamp. Because cc_data
+ * packets must be reassembled in the frame display order, CcPackets are reordered.
+ *
+ * <h3>Step 2. CcPacket -&gt; DTVCC packet</h3>
+ *
+ * <p>Each cc_data packet has a one byte for declaring a type of itself and data validity, and the
+ * subsequent two bytes for input data of a DTVCC packet. There are 4 types for cc_data packet.
+ * We're interested in DTVCC_PACKET_START(type 3) and DTVCC_PACKET_DATA(type 2). Each DTVCC packet
+ * begins with DTVCC_PACKET_START(type 3) and the following cc_data packets which has
+ * DTVCC_PACKET_DATA(type 2) are appended into the DTVCC packet being assembled.
+ *
+ * <h3>Step 3. DTVCC packet -&gt; Service Blocks</h3>
+ *
+ * <p>A DTVCC packet consists of multiple service blocks. Each service block represents a caption
+ * track and has a service number, which ranges from 1 to 63, that denotes caption track identity.
+ * In here, we listen at most one chosen caption track by service number. Otherwise, just skip the
+ * other service blocks.
+ *
+ * <h3>Step 4. Interpreting Service Block Data ({@link #parseServiceBlockData}, {@code parseXX},
+ * and {@link #parseExt1} methods)</h3>
+ *
+ * <p>Service block data is actual caption stream. it looks similar to telnet. It uses most parts of
+ * ASCII table and consists of specially defined commands and some ASCII control codes which work
+ * in a behavior slightly different from their original purpose. ASCII control codes and caption
+ * commands are explicit instructions that control the state of a closed caption service and the
+ * other ASCII and text codes are implicit instructions that send their characters to buffer.
+ *
+ * <p>There are 4 main code groups and 4 extended code groups. Both the range of code groups are the
+ * same as the range of a byte.
+ *
+ * <p>4 main code groups: C0, C1, G0, G1
+ * <br>4 extended code groups: C2, C3, G2, G3
+ *
+ * <p>Each code group has its own handle method. For example, {@link #parseC0} handles C0 code group
+ * and so on. And {@link #parseServiceBlockData} method maps a stream on the main code groups while
+ * {@link #parseExt1} method maps on the extended code groups.
+ *
+ * <p>The main code groups:
+ * <ul>
+ * <li>C0 - contains modified ASCII control codes. It is not intended by CEA-708 but Korea TTA
+ *      standard for ATSC CC uses P16 character heavily, which is unclear entity in CEA-708 doc,
+ *      even for the alphanumeric characters instead of ASCII characters.</li>
+ * <li>C1 - contains the caption commands. There are 3 categories of a caption command.</li>
+ * <ul>
+ * <li>Window commands: The window commands control a caption window which is addressable area being
+ *                  with in the Safe title area. (CWX, CLW, DSW, HDW, TGW, DLW, SWA, DFX)</li>
+ * <li>Pen commands: Th pen commands control text style and location. (SPA, SPC, SPL)</li>
+ * <li>Job commands: The job commands make a delay and recover from the delay. (DLY, DLC, RST)</li>
+ * </ul>
+ * <li>G0 - same as printable ASCII character set except music note character.</li>
+ * <li>G1 - same as ISO 8859-1 Latin 1 character set.</li>
+ * </ul>
+ * <p>Most of the extended code groups are being skipped.
+ *
+ */
+class Cea708CCParser {
+    private static final String TAG = "Cea708CCParser";
+    private static final boolean DEBUG = false;
+
+    private static final String MUSIC_NOTE_CHAR = new String(
+            "\u266B".getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8);
+
+    private final StringBuffer mBuffer = new StringBuffer();
+    private int mCommand = 0;
+
+    // Assign a dummy listener in order to avoid null checks.
+    private DisplayListener mListener = new DisplayListener() {
+        @Override
+        public void emitEvent(CaptionEvent event) {
+            // do nothing
+        }
+    };
+
+    /**
+     * {@link Cea708Parser} emits caption event of three different types.
+     * {@link DisplayListener#emitEvent} is invoked with the parameter
+     * {@link CaptionEvent} to pass all the results to an observer of the decoding process .
+     *
+     * <p>{@link CaptionEvent#type} determines the type of the result and
+     * {@link CaptionEvent#obj} contains the output value of a caption event.
+     * The observer must do the casting to the corresponding type.
+     *
+     * <ul><li>{@code CAPTION_EMIT_TYPE_BUFFER}: Passes a caption text buffer to a observer.
+     * {@code obj} must be of {@link String}.</li>
+     *
+     * <li>{@code CAPTION_EMIT_TYPE_CONTROL}: Passes a caption character control code to a observer.
+     * {@code obj} must be of {@link Character}.</li>
+     *
+     * <li>{@code CAPTION_EMIT_TYPE_CLEAR_COMMAND}: Passes a clear command to a observer.
+     * {@code obj} must be {@code NULL}.</li></ul>
+     */
+    public static final int CAPTION_EMIT_TYPE_BUFFER = 1;
+    public static final int CAPTION_EMIT_TYPE_CONTROL = 2;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_CWX = 3;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_CLW = 4;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_DSW = 5;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_HDW = 6;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_TGW = 7;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_DLW = 8;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_DLY = 9;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_DLC = 10;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_RST = 11;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_SPA = 12;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_SPC = 13;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_SPL = 14;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_SWA = 15;
+    public static final int CAPTION_EMIT_TYPE_COMMAND_DFX = 16;
+
+    Cea708CCParser(DisplayListener listener) {
+        if (listener != null) {
+            mListener = listener;
+        }
+    }
+
+    interface DisplayListener {
+        void emitEvent(CaptionEvent event);
+    }
+
+    private void emitCaptionEvent(CaptionEvent captionEvent) {
+        // Emit the existing string buffer before a new event is arrived.
+        emitCaptionBuffer();
+        mListener.emitEvent(captionEvent);
+    }
+
+    private void emitCaptionBuffer() {
+        if (mBuffer.length() > 0) {
+            mListener.emitEvent(new CaptionEvent(CAPTION_EMIT_TYPE_BUFFER, mBuffer.toString()));
+            mBuffer.setLength(0);
+        }
+    }
+
+    // Step 3. DTVCC packet -> Service Blocks (parseDtvCcPacket method)
+    public void parse(byte[] data) {
+        // From this point, starts to read DTVCC coding layer.
+        // First, identify code groups, which is defined in CEA-708B Section 7.1.
+        int pos = 0;
+        while (pos < data.length) {
+            pos = parseServiceBlockData(data, pos);
+        }
+
+        // Emit the buffer after reading codes.
+        emitCaptionBuffer();
+    }
+
+    // Step 4. Main code groups
+    private int parseServiceBlockData(byte[] data, int pos) {
+        // For the details of the ranges of DTVCC code groups, see CEA-708B Table 6.
+        mCommand = data[pos] & 0xff;
+        ++pos;
+        if (mCommand == Const.CODE_C0_EXT1) {
+            if (DEBUG) {
+                Log.d(TAG, String.format("parseServiceBlockData EXT1 %x", mCommand));
+            }
+            pos = parseExt1(data, pos);
+        } else if (mCommand >= Const.CODE_C0_RANGE_START
+                && mCommand <= Const.CODE_C0_RANGE_END) {
+            if (DEBUG) {
+                Log.d(TAG, String.format("parseServiceBlockData C0 %x", mCommand));
+            }
+            pos = parseC0(data, pos);
+        } else if (mCommand >= Const.CODE_C1_RANGE_START
+                && mCommand <= Const.CODE_C1_RANGE_END) {
+            if (DEBUG) {
+                Log.d(TAG, String.format("parseServiceBlockData C1 %x", mCommand));
+            }
+            pos = parseC1(data, pos);
+        } else if (mCommand >= Const.CODE_G0_RANGE_START
+                && mCommand <= Const.CODE_G0_RANGE_END) {
+            if (DEBUG) {
+                Log.d(TAG, String.format("parseServiceBlockData G0 %x", mCommand));
+            }
+            pos = parseG0(data, pos);
+        } else if (mCommand >= Const.CODE_G1_RANGE_START
+                && mCommand <= Const.CODE_G1_RANGE_END) {
+            if (DEBUG) {
+                Log.d(TAG, String.format("parseServiceBlockData G1 %x", mCommand));
+            }
+            pos = parseG1(data, pos);
+        }
+        return pos;
+    }
+
+    private int parseC0(byte[] data, int pos) {
+        // For the details of C0 code group, see CEA-708B Section 7.4.1.
+        // CL Group: C0 Subset of ASCII Control codes
+        if (mCommand >= Const.CODE_C0_SKIP2_RANGE_START
+                && mCommand <= Const.CODE_C0_SKIP2_RANGE_END) {
+            if (mCommand == Const.CODE_C0_P16) {
+                // P16 escapes next two bytes for the large character maps.(no standard rule)
+                // For Korea broadcasting, express whole letters by using this.
+                try {
+                    if (data[pos] == 0) {
+                        mBuffer.append((char) data[pos + 1]);
+                    } else {
+                        String value = new String(Arrays.copyOfRange(data, pos, pos + 2), "EUC-KR");
+                        mBuffer.append(value);
+                    }
+                } catch (UnsupportedEncodingException e) {
+                    Log.e(TAG, "P16 Code - Could not find supported encoding", e);
+                }
+            }
+            pos += 2;
+        } else if (mCommand >= Const.CODE_C0_SKIP1_RANGE_START
+                && mCommand <= Const.CODE_C0_SKIP1_RANGE_END) {
+            ++pos;
+        } else {
+            // NUL, BS, FF, CR interpreted as they are in ASCII control codes.
+            // HCR moves the pen location to th beginning of the current line and deletes contents.
+            // FF clears the screen and moves the pen location to (0,0).
+            // ETX is the NULL command which is used to flush text to the current window when no
+            // other command is pending.
+            switch (mCommand) {
+                case Const.CODE_C0_NUL:
+                    break;
+                case Const.CODE_C0_ETX:
+                    emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_CONTROL, (char) mCommand));
+                    break;
+                case Const.CODE_C0_BS:
+                    emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_CONTROL, (char) mCommand));
+                    break;
+                case Const.CODE_C0_FF:
+                    emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_CONTROL, (char) mCommand));
+                    break;
+                case Const.CODE_C0_CR:
+                    mBuffer.append('\n');
+                    break;
+                case Const.CODE_C0_HCR:
+                    emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_CONTROL, (char) mCommand));
+                    break;
+                default:
+                    break;
+            }
+        }
+        return pos;
+    }
+
+    private int parseC1(byte[] data, int pos) {
+        // For the details of C1 code group, see CEA-708B Section 8.10.
+        // CR Group: C1 Caption Control Codes
+        switch (mCommand) {
+            case Const.CODE_C1_CW0:
+            case Const.CODE_C1_CW1:
+            case Const.CODE_C1_CW2:
+            case Const.CODE_C1_CW3:
+            case Const.CODE_C1_CW4:
+            case Const.CODE_C1_CW5:
+            case Const.CODE_C1_CW6:
+            case Const.CODE_C1_CW7: {
+                // SetCurrentWindow0-7
+                int windowId = mCommand - Const.CODE_C1_CW0;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_CWX, windowId));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand CWX windowId: %d", windowId));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_CLW: {
+                // ClearWindows
+                int windowBitmap = data[pos] & 0xff;
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_CLW, windowBitmap));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand CLW windowBitmap: %d", windowBitmap));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_DSW: {
+                // DisplayWindows
+                int windowBitmap = data[pos] & 0xff;
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_DSW, windowBitmap));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand DSW windowBitmap: %d", windowBitmap));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_HDW: {
+                // HideWindows
+                int windowBitmap = data[pos] & 0xff;
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_HDW, windowBitmap));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand HDW windowBitmap: %d", windowBitmap));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_TGW: {
+                // ToggleWindows
+                int windowBitmap = data[pos] & 0xff;
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_TGW, windowBitmap));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand TGW windowBitmap: %d", windowBitmap));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_DLW: {
+                // DeleteWindows
+                int windowBitmap = data[pos] & 0xff;
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_DLW, windowBitmap));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand DLW windowBitmap: %d", windowBitmap));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_DLY: {
+                // Delay
+                int tenthsOfSeconds = data[pos] & 0xff;
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_DLY, tenthsOfSeconds));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand DLY %d tenths of seconds",
+                            tenthsOfSeconds));
+                }
+                break;
+            }
+            case Const.CODE_C1_DLC: {
+                // DelayCancel
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_DLC, null));
+                if (DEBUG) {
+                    Log.d(TAG, "CaptionCommand DLC");
+                }
+                break;
+            }
+
+            case Const.CODE_C1_RST: {
+                // Reset
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_RST, null));
+                if (DEBUG) {
+                    Log.d(TAG, "CaptionCommand RST");
+                }
+                break;
+            }
+
+            case Const.CODE_C1_SPA: {
+                // SetPenAttributes
+                int textTag = (data[pos] & 0xf0) >> 4;
+                int penSize = data[pos] & 0x03;
+                int penOffset = (data[pos] & 0x0c) >> 2;
+                boolean italic = (data[pos + 1] & 0x80) != 0;
+                boolean underline = (data[pos + 1] & 0x40) != 0;
+                int edgeType = (data[pos + 1] & 0x38) >> 3;
+                int fontTag = data[pos + 1] & 0x7;
+                pos += 2;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_SPA,
+                        new CaptionPenAttr(penSize, penOffset, textTag, fontTag, edgeType,
+                                underline, italic)));
+                if (DEBUG) {
+                    Log.d(TAG, String.format(
+                            "CaptionCommand SPA penSize: %d, penOffset: %d, textTag: %d, "
+                                    + "fontTag: %d, edgeType: %d, underline: %s, italic: %s",
+                            penSize, penOffset, textTag, fontTag, edgeType, underline, italic));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_SPC: {
+                // SetPenColor
+                int opacity = (data[pos] & 0xc0) >> 6;
+                int red = (data[pos] & 0x30) >> 4;
+                int green = (data[pos] & 0x0c) >> 2;
+                int blue = data[pos] & 0x03;
+                CaptionColor foregroundColor = new CaptionColor(opacity, red, green, blue);
+                ++pos;
+                opacity = (data[pos] & 0xc0) >> 6;
+                red = (data[pos] & 0x30) >> 4;
+                green = (data[pos] & 0x0c) >> 2;
+                blue = data[pos] & 0x03;
+                CaptionColor backgroundColor = new CaptionColor(opacity, red, green, blue);
+                ++pos;
+                red = (data[pos] & 0x30) >> 4;
+                green = (data[pos] & 0x0c) >> 2;
+                blue = data[pos] & 0x03;
+                CaptionColor edgeColor = new CaptionColor(
+                        CaptionColor.OPACITY_SOLID, red, green, blue);
+                ++pos;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_SPC,
+                        new CaptionPenColor(foregroundColor, backgroundColor, edgeColor)));
+                if (DEBUG) {
+                    Log.d(TAG, String.format(
+                            "CaptionCommand SPC foregroundColor %s backgroundColor %s edgeColor %s",
+                            foregroundColor, backgroundColor, edgeColor));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_SPL: {
+                // SetPenLocation
+                // column is normally 0-31 for 4:3 formats, and 0-41 for 16:9 formats
+                int row = data[pos] & 0x0f;
+                int column = data[pos + 1] & 0x3f;
+                pos += 2;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_SPL,
+                        new CaptionPenLocation(row, column)));
+                if (DEBUG) {
+                    Log.d(TAG, String.format("CaptionCommand SPL row: %d, column: %d",
+                            row, column));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_SWA: {
+                // SetWindowAttributes
+                int opacity = (data[pos] & 0xc0) >> 6;
+                int red = (data[pos] & 0x30) >> 4;
+                int green = (data[pos] & 0x0c) >> 2;
+                int blue = data[pos] & 0x03;
+                CaptionColor fillColor = new CaptionColor(opacity, red, green, blue);
+                int borderType = (data[pos + 1] & 0xc0) >> 6 | (data[pos + 2] & 0x80) >> 5;
+                red = (data[pos + 1] & 0x30) >> 4;
+                green = (data[pos + 1] & 0x0c) >> 2;
+                blue = data[pos + 1] & 0x03;
+                CaptionColor borderColor = new CaptionColor(
+                        CaptionColor.OPACITY_SOLID, red, green, blue);
+                boolean wordWrap = (data[pos + 2] & 0x40) != 0;
+                int printDirection = (data[pos + 2] & 0x30) >> 4;
+                int scrollDirection = (data[pos + 2] & 0x0c) >> 2;
+                int justify = (data[pos + 2] & 0x03);
+                int effectSpeed = (data[pos + 3] & 0xf0) >> 4;
+                int effectDirection = (data[pos + 3] & 0x0c) >> 2;
+                int displayEffect = data[pos + 3] & 0x3;
+                pos += 4;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_SWA,
+                        new CaptionWindowAttr(fillColor, borderColor, borderType, wordWrap,
+                                printDirection, scrollDirection, justify,
+                                effectDirection, effectSpeed, displayEffect)));
+                if (DEBUG) {
+                    Log.d(TAG, String.format(
+                            "CaptionCommand SWA fillColor: %s, borderColor: %s, borderType: %d"
+                                    + "wordWrap: %s, printDirection: %d, scrollDirection: %d, "
+                                    + "justify: %s, effectDirection: %d, effectSpeed: %d, "
+                                    + "displayEffect: %d",
+                            fillColor, borderColor, borderType, wordWrap, printDirection,
+                            scrollDirection, justify, effectDirection, effectSpeed, displayEffect));
+                }
+                break;
+            }
+
+            case Const.CODE_C1_DF0:
+            case Const.CODE_C1_DF1:
+            case Const.CODE_C1_DF2:
+            case Const.CODE_C1_DF3:
+            case Const.CODE_C1_DF4:
+            case Const.CODE_C1_DF5:
+            case Const.CODE_C1_DF6:
+            case Const.CODE_C1_DF7: {
+                // DefineWindow0-7
+                int windowId = mCommand - Const.CODE_C1_DF0;
+                boolean visible = (data[pos] & 0x20) != 0;
+                boolean rowLock = (data[pos] & 0x10) != 0;
+                boolean columnLock = (data[pos] & 0x08) != 0;
+                int priority = data[pos] & 0x07;
+                boolean relativePositioning = (data[pos + 1] & 0x80) != 0;
+                int anchorVertical = data[pos + 1] & 0x7f;
+                int anchorHorizontal = data[pos + 2] & 0xff;
+                int anchorId = (data[pos + 3] & 0xf0) >> 4;
+                int rowCount = data[pos + 3] & 0x0f;
+                int columnCount = data[pos + 4] & 0x3f;
+                int windowStyle = (data[pos + 5] & 0x38) >> 3;
+                int penStyle = data[pos + 5] & 0x07;
+                pos += 6;
+                emitCaptionEvent(new CaptionEvent(CAPTION_EMIT_TYPE_COMMAND_DFX,
+                        new CaptionWindow(windowId, visible, rowLock, columnLock, priority,
+                                relativePositioning, anchorVertical, anchorHorizontal, anchorId,
+                                rowCount, columnCount, penStyle, windowStyle)));
+                if (DEBUG) {
+                    Log.d(TAG, String.format(
+                            "CaptionCommand DFx windowId: %d, priority: %d, columnLock: %s, "
+                                    + "rowLock: %s, visible: %s, anchorVertical: %d, "
+                                    + "relativePositioning: %s, anchorHorizontal: %d, "
+                                    + "rowCount: %d, anchorId: %d, columnCount: %d, penStyle: %d, "
+                                    + "windowStyle: %d",
+                            windowId, priority, columnLock, rowLock, visible, anchorVertical,
+                            relativePositioning, anchorHorizontal, rowCount, anchorId, columnCount,
+                            penStyle, windowStyle));
+                }
+                break;
+            }
+
+            default:
+                break;
+        }
+        return pos;
+    }
+
+    private int parseG0(byte[] data, int pos) {
+        // For the details of G0 code group, see CEA-708B Section 7.4.3.
+        // GL Group: G0 Modified version of ANSI X3.4 Printable Character Set (ASCII)
+        if (mCommand == Const.CODE_G0_MUSICNOTE) {
+            // Music note.
+            mBuffer.append(MUSIC_NOTE_CHAR);
+        } else {
+            // Put ASCII code into buffer.
+            mBuffer.append((char) mCommand);
+        }
+        return pos;
+    }
+
+    private int parseG1(byte[] data, int pos) {
+        // For the details of G0 code group, see CEA-708B Section 7.4.4.
+        // GR Group: G1 ISO 8859-1 Latin 1 Characters
+        // Put ASCII Extended character set into buffer.
+        mBuffer.append((char) mCommand);
+        return pos;
+    }
+
+    // Step 4. Extended code groups
+    private int parseExt1(byte[] data, int pos) {
+        // For the details of EXT1 code group, see CEA-708B Section 7.2.
+        mCommand = data[pos] & 0xff;
+        ++pos;
+        if (mCommand >= Const.CODE_C2_RANGE_START
+                && mCommand <= Const.CODE_C2_RANGE_END) {
+            pos = parseC2(data, pos);
+        } else if (mCommand >= Const.CODE_C3_RANGE_START
+                && mCommand <= Const.CODE_C3_RANGE_END) {
+            pos = parseC3(data, pos);
+        } else if (mCommand >= Const.CODE_G2_RANGE_START
+                && mCommand <= Const.CODE_G2_RANGE_END) {
+            pos = parseG2(data, pos);
+        } else if (mCommand >= Const.CODE_G3_RANGE_START
+                && mCommand <= Const.CODE_G3_RANGE_END) {
+            pos = parseG3(data ,pos);
+        }
+        return pos;
+    }
+
+    private int parseC2(byte[] data, int pos) {
+        // For the details of C2 code group, see CEA-708B Section 7.4.7.
+        // Extended Miscellaneous Control Codes
+        // C2 Table : No commands as of CEA-708B. A decoder must skip.
+        if (mCommand >= Const.CODE_C2_SKIP0_RANGE_START
+                && mCommand <= Const.CODE_C2_SKIP0_RANGE_END) {
+            // Do nothing.
+        } else if (mCommand >= Const.CODE_C2_SKIP1_RANGE_START
+                && mCommand <= Const.CODE_C2_SKIP1_RANGE_END) {
+            ++pos;
+        } else if (mCommand >= Const.CODE_C2_SKIP2_RANGE_START
+                && mCommand <= Const.CODE_C2_SKIP2_RANGE_END) {
+            pos += 2;
+        } else if (mCommand >= Const.CODE_C2_SKIP3_RANGE_START
+                && mCommand <= Const.CODE_C2_SKIP3_RANGE_END) {
+            pos += 3;
+        }
+        return pos;
+    }
+
+    private int parseC3(byte[] data, int pos) {
+        // For the details of C3 code group, see CEA-708B Section 7.4.8.
+        // Extended Control Code Set 2
+        // C3 Table : No commands as of CEA-708B. A decoder must skip.
+        if (mCommand >= Const.CODE_C3_SKIP4_RANGE_START
+                && mCommand <= Const.CODE_C3_SKIP4_RANGE_END) {
+            pos += 4;
+        } else if (mCommand >= Const.CODE_C3_SKIP5_RANGE_START
+                && mCommand <= Const.CODE_C3_SKIP5_RANGE_END) {
+            pos += 5;
+        }
+        return pos;
+    }
+
+    private int parseG2(byte[] data, int pos) {
+        // For the details of C3 code group, see CEA-708B Section 7.4.5.
+        // Extended Control Code Set 1(G2 Table)
+        switch (mCommand) {
+            case Const.CODE_G2_TSP:
+                // TODO : TSP is the Transparent space
+                break;
+            case Const.CODE_G2_NBTSP:
+                // TODO : NBTSP is Non-Breaking Transparent Space.
+                break;
+            case Const.CODE_G2_BLK:
+                // TODO : BLK indicates a solid block which fills the entire character block
+                // TODO : with a solid foreground color.
+                break;
+            default:
+                break;
+        }
+        return pos;
+    }
+
+    private int parseG3(byte[] data, int pos) {
+        // For the details of C3 code group, see CEA-708B Section 7.4.6.
+        // Future characters and icons(G3 Table)
+        if (mCommand == Const.CODE_G3_CC) {
+            // TODO : [CC] icon with square corners
+        }
+
+        // Do nothing
+        return pos;
+    }
+
+    /**
+     * @hide
+     *
+     * Collection of CEA-708 structures.
+     */
+    private static class Const {
+
+        private Const() {
+        }
+
+        // For the details of the ranges of DTVCC code groups, see CEA-708B Table 6.
+        public static final int CODE_C0_RANGE_START = 0x00;
+        public static final int CODE_C0_RANGE_END = 0x1f;
+        public static final int CODE_C1_RANGE_START = 0x80;
+        public static final int CODE_C1_RANGE_END = 0x9f;
+        public static final int CODE_G0_RANGE_START = 0x20;
+        public static final int CODE_G0_RANGE_END = 0x7f;
+        public static final int CODE_G1_RANGE_START = 0xa0;
+        public static final int CODE_G1_RANGE_END = 0xff;
+        public static final int CODE_C2_RANGE_START = 0x00;
+        public static final int CODE_C2_RANGE_END = 0x1f;
+        public static final int CODE_C3_RANGE_START = 0x80;
+        public static final int CODE_C3_RANGE_END = 0x9f;
+        public static final int CODE_G2_RANGE_START = 0x20;
+        public static final int CODE_G2_RANGE_END = 0x7f;
+        public static final int CODE_G3_RANGE_START = 0xa0;
+        public static final int CODE_G3_RANGE_END = 0xff;
+
+        // The following ranges are defined in CEA-708B Section 7.4.1.
+        public static final int CODE_C0_SKIP2_RANGE_START = 0x18;
+        public static final int CODE_C0_SKIP2_RANGE_END = 0x1f;
+        public static final int CODE_C0_SKIP1_RANGE_START = 0x10;
+        public static final int CODE_C0_SKIP1_RANGE_END = 0x17;
+
+        // The following ranges are defined in CEA-708B Section 7.4.7.
+        public static final int CODE_C2_SKIP0_RANGE_START = 0x00;
+        public static final int CODE_C2_SKIP0_RANGE_END = 0x07;
+        public static final int CODE_C2_SKIP1_RANGE_START = 0x08;
+        public static final int CODE_C2_SKIP1_RANGE_END = 0x0f;
+        public static final int CODE_C2_SKIP2_RANGE_START = 0x10;
+        public static final int CODE_C2_SKIP2_RANGE_END = 0x17;
+        public static final int CODE_C2_SKIP3_RANGE_START = 0x18;
+        public static final int CODE_C2_SKIP3_RANGE_END = 0x1f;
+
+        // The following ranges are defined in CEA-708B Section 7.4.8.
+        public static final int CODE_C3_SKIP4_RANGE_START = 0x80;
+        public static final int CODE_C3_SKIP4_RANGE_END = 0x87;
+        public static final int CODE_C3_SKIP5_RANGE_START = 0x88;
+        public static final int CODE_C3_SKIP5_RANGE_END = 0x8f;
+
+        // The following values are the special characters of CEA-708 spec.
+        public static final int CODE_C0_NUL = 0x00;
+        public static final int CODE_C0_ETX = 0x03;
+        public static final int CODE_C0_BS = 0x08;
+        public static final int CODE_C0_FF = 0x0c;
+        public static final int CODE_C0_CR = 0x0d;
+        public static final int CODE_C0_HCR = 0x0e;
+        public static final int CODE_C0_EXT1 = 0x10;
+        public static final int CODE_C0_P16 = 0x18;
+        public static final int CODE_G0_MUSICNOTE = 0x7f;
+        public static final int CODE_G2_TSP = 0x20;
+        public static final int CODE_G2_NBTSP = 0x21;
+        public static final int CODE_G2_BLK = 0x30;
+        public static final int CODE_G3_CC = 0xa0;
+
+        // The following values are the command bits of CEA-708 spec.
+        public static final int CODE_C1_CW0 = 0x80;
+        public static final int CODE_C1_CW1 = 0x81;
+        public static final int CODE_C1_CW2 = 0x82;
+        public static final int CODE_C1_CW3 = 0x83;
+        public static final int CODE_C1_CW4 = 0x84;
+        public static final int CODE_C1_CW5 = 0x85;
+        public static final int CODE_C1_CW6 = 0x86;
+        public static final int CODE_C1_CW7 = 0x87;
+        public static final int CODE_C1_CLW = 0x88;
+        public static final int CODE_C1_DSW = 0x89;
+        public static final int CODE_C1_HDW = 0x8a;
+        public static final int CODE_C1_TGW = 0x8b;
+        public static final int CODE_C1_DLW = 0x8c;
+        public static final int CODE_C1_DLY = 0x8d;
+        public static final int CODE_C1_DLC = 0x8e;
+        public static final int CODE_C1_RST = 0x8f;
+        public static final int CODE_C1_SPA = 0x90;
+        public static final int CODE_C1_SPC = 0x91;
+        public static final int CODE_C1_SPL = 0x92;
+        public static final int CODE_C1_SWA = 0x97;
+        public static final int CODE_C1_DF0 = 0x98;
+        public static final int CODE_C1_DF1 = 0x99;
+        public static final int CODE_C1_DF2 = 0x9a;
+        public static final int CODE_C1_DF3 = 0x9b;
+        public static final int CODE_C1_DF4 = 0x9c;
+        public static final int CODE_C1_DF5 = 0x9d;
+        public static final int CODE_C1_DF6 = 0x9e;
+        public static final int CODE_C1_DF7 = 0x9f;
+    }
+
+    /**
+     * @hide
+     *
+     * CEA-708B-specific color.
+     */
+    public static class CaptionColor {
+        public static final int OPACITY_SOLID = 0;
+        public static final int OPACITY_FLASH = 1;
+        public static final int OPACITY_TRANSLUCENT = 2;
+        public static final int OPACITY_TRANSPARENT = 3;
+
+        private static final int[] COLOR_MAP = new int[] { 0x00, 0x0f, 0xf0, 0xff };
+        private static final int[] OPACITY_MAP = new int[] { 0xff, 0xfe, 0x80, 0x00 };
+
+        public final int opacity;
+        public final int red;
+        public final int green;
+        public final int blue;
+
+        public CaptionColor(int opacity, int red, int green, int blue) {
+            this.opacity = opacity;
+            this.red = red;
+            this.green = green;
+            this.blue = blue;
+        }
+
+        public int getArgbValue() {
+            return Color.argb(
+                    OPACITY_MAP[opacity], COLOR_MAP[red], COLOR_MAP[green], COLOR_MAP[blue]);
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Caption event generated by {@link Cea708CCParser}.
+     */
+    public static class CaptionEvent {
+        public final int type;
+        public final Object obj;
+
+        public CaptionEvent(int type, Object obj) {
+            this.type = type;
+            this.obj = obj;
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Pen style information.
+     */
+    public static class CaptionPenAttr {
+        // Pen sizes
+        public static final int PEN_SIZE_SMALL = 0;
+        public static final int PEN_SIZE_STANDARD = 1;
+        public static final int PEN_SIZE_LARGE = 2;
+
+        // Offsets
+        public static final int OFFSET_SUBSCRIPT = 0;
+        public static final int OFFSET_NORMAL = 1;
+        public static final int OFFSET_SUPERSCRIPT = 2;
+
+        public final int penSize;
+        public final int penOffset;
+        public final int textTag;
+        public final int fontTag;
+        public final int edgeType;
+        public final boolean underline;
+        public final boolean italic;
+
+        public CaptionPenAttr(int penSize, int penOffset, int textTag, int fontTag, int edgeType,
+                boolean underline, boolean italic) {
+            this.penSize = penSize;
+            this.penOffset = penOffset;
+            this.textTag = textTag;
+            this.fontTag = fontTag;
+            this.edgeType = edgeType;
+            this.underline = underline;
+            this.italic = italic;
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * {@link CaptionColor} objects that indicate the foreground, background, and edge color of a
+     * pen.
+     */
+    public static class CaptionPenColor {
+        public final CaptionColor foregroundColor;
+        public final CaptionColor backgroundColor;
+        public final CaptionColor edgeColor;
+
+        public CaptionPenColor(CaptionColor foregroundColor, CaptionColor backgroundColor,
+                CaptionColor edgeColor) {
+            this.foregroundColor = foregroundColor;
+            this.backgroundColor = backgroundColor;
+            this.edgeColor = edgeColor;
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Location information of a pen.
+     */
+    public static class CaptionPenLocation {
+        public final int row;
+        public final int column;
+
+        public CaptionPenLocation(int row, int column) {
+            this.row = row;
+            this.column = column;
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Attributes of a caption window, which is defined in CEA-708B.
+     */
+    public static class CaptionWindowAttr {
+        public final CaptionColor fillColor;
+        public final CaptionColor borderColor;
+        public final int borderType;
+        public final boolean wordWrap;
+        public final int printDirection;
+        public final int scrollDirection;
+        public final int justify;
+        public final int effectDirection;
+        public final int effectSpeed;
+        public final int displayEffect;
+
+        public CaptionWindowAttr(CaptionColor fillColor, CaptionColor borderColor, int borderType,
+                boolean wordWrap, int printDirection, int scrollDirection, int justify,
+                int effectDirection,
+                int effectSpeed, int displayEffect) {
+            this.fillColor = fillColor;
+            this.borderColor = borderColor;
+            this.borderType = borderType;
+            this.wordWrap = wordWrap;
+            this.printDirection = printDirection;
+            this.scrollDirection = scrollDirection;
+            this.justify = justify;
+            this.effectDirection = effectDirection;
+            this.effectSpeed = effectSpeed;
+            this.displayEffect = displayEffect;
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Construction information of the caption window of CEA-708B.
+     */
+    public static class CaptionWindow {
+        public final int id;
+        public final boolean visible;
+        public final boolean rowLock;
+        public final boolean columnLock;
+        public final int priority;
+        public final boolean relativePositioning;
+        public final int anchorVertical;
+        public final int anchorHorizontal;
+        public final int anchorId;
+        public final int rowCount;
+        public final int columnCount;
+        public final int penStyle;
+        public final int windowStyle;
+
+        public CaptionWindow(int id, boolean visible,
+                boolean rowLock, boolean columnLock, int priority, boolean relativePositioning,
+                int anchorVertical, int anchorHorizontal, int anchorId,
+                int rowCount, int columnCount, int penStyle, int windowStyle) {
+            this.id = id;
+            this.visible = visible;
+            this.rowLock = rowLock;
+            this.columnLock = columnLock;
+            this.priority = priority;
+            this.relativePositioning = relativePositioning;
+            this.anchorVertical = anchorVertical;
+            this.anchorHorizontal = anchorHorizontal;
+            this.anchorId = anchorId;
+            this.rowCount = rowCount;
+            this.columnCount = columnCount;
+            this.penStyle = penStyle;
+            this.windowStyle = windowStyle;
+        }
+    }
+}
+
+/**
+ * Widget capable of rendering CEA-708 closed captions.
+ *
+ * @hide
+ */
+class Cea708CCWidget extends ClosedCaptionWidget implements Cea708CCParser.DisplayListener {
+    private final CCHandler mCCHandler;
+
+    public Cea708CCWidget(Context context) {
+        this(context, null);
+    }
+
+    public Cea708CCWidget(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public Cea708CCWidget(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public Cea708CCWidget(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        mCCHandler = new CCHandler((CCLayout) mClosedCaptionLayout);
+    }
+
+    @Override
+    public ClosedCaptionLayout createCaptionLayout(Context context) {
+        return new CCLayout(context);
+    }
+
+    @Override
+    public void emitEvent(Cea708CCParser.CaptionEvent event) {
+        mCCHandler.processCaptionEvent(event);
+
+        setSize(getWidth(), getHeight());
+
+        if (mListener != null) {
+            mListener.onChanged(this);
+        }
+    }
+
+    @Override
+    public void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        ((ViewGroup) mClosedCaptionLayout).draw(canvas);
+    }
+
+    /**
+     * @hide
+     *
+     * A layout that scales its children using the given percentage value.
+     */
+    static class ScaledLayout extends ViewGroup {
+        private static final String TAG = "ScaledLayout";
+        private static final boolean DEBUG = false;
+        private static final Comparator<Rect> mRectTopLeftSorter = new Comparator<Rect>() {
+            @Override
+            public int compare(Rect lhs, Rect rhs) {
+                if (lhs.top != rhs.top) {
+                    return lhs.top - rhs.top;
+                } else {
+                    return lhs.left - rhs.left;
+                }
+            }
+        };
+
+        private Rect[] mRectArray;
+
+        public ScaledLayout(Context context) {
+            super(context);
+        }
+
+        /**
+         * @hide
+         *
+         * ScaledLayoutParams stores the four scale factors.
+         * <br>
+         * Vertical coordinate system:   (scaleStartRow * 100) % ~ (scaleEndRow * 100) %
+         * Horizontal coordinate system: (scaleStartCol * 100) % ~ (scaleEndCol * 100) %
+         * <br>
+         * In XML, for example,
+         * <pre>
+         * {@code
+         * <View
+         *     app:layout_scaleStartRow="0.1"
+         *     app:layout_scaleEndRow="0.5"
+         *     app:layout_scaleStartCol="0.4"
+         *     app:layout_scaleEndCol="1" />
+         * }
+         * </pre>
+         */
+        static class ScaledLayoutParams extends ViewGroup.LayoutParams {
+            public static final float SCALE_UNSPECIFIED = -1;
+            public float scaleStartRow;
+            public float scaleEndRow;
+            public float scaleStartCol;
+            public float scaleEndCol;
+
+            public ScaledLayoutParams(float scaleStartRow, float scaleEndRow,
+                    float scaleStartCol, float scaleEndCol) {
+                super(MATCH_PARENT, MATCH_PARENT);
+                this.scaleStartRow = scaleStartRow;
+                this.scaleEndRow = scaleEndRow;
+                this.scaleStartCol = scaleStartCol;
+                this.scaleEndCol = scaleEndCol;
+            }
+
+            public ScaledLayoutParams(Context context, AttributeSet attrs) {
+                super(MATCH_PARENT, MATCH_PARENT);
+            }
+        }
+
+        @Override
+        public LayoutParams generateLayoutParams(AttributeSet attrs) {
+            return new ScaledLayoutParams(getContext(), attrs);
+        }
+
+        @Override
+        protected boolean checkLayoutParams(LayoutParams p) {
+            return (p instanceof ScaledLayoutParams);
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            int widthSpecSize = MeasureSpec.getSize(widthMeasureSpec);
+            int heightSpecSize = MeasureSpec.getSize(heightMeasureSpec);
+            int width = widthSpecSize - getPaddingLeft() - getPaddingRight();
+            int height = heightSpecSize - getPaddingTop() - getPaddingBottom();
+            if (DEBUG) {
+                Log.d(TAG, String.format("onMeasure width: %d, height: %d", width, height));
+            }
+            int count = getChildCount();
+            mRectArray = new Rect[count];
+            for (int i = 0; i < count; ++i) {
+                View child = getChildAt(i);
+                ViewGroup.LayoutParams params = child.getLayoutParams();
+                float scaleStartRow, scaleEndRow, scaleStartCol, scaleEndCol;
+                if (!(params instanceof ScaledLayoutParams)) {
+                    throw new RuntimeException(
+                            "A child of ScaledLayout cannot have the UNSPECIFIED scale factors");
+                }
+                scaleStartRow = ((ScaledLayoutParams) params).scaleStartRow;
+                scaleEndRow = ((ScaledLayoutParams) params).scaleEndRow;
+                scaleStartCol = ((ScaledLayoutParams) params).scaleStartCol;
+                scaleEndCol = ((ScaledLayoutParams) params).scaleEndCol;
+                if (scaleStartRow < 0 || scaleStartRow > 1) {
+                    throw new RuntimeException("A child of ScaledLayout should have a range of "
+                            + "scaleStartRow between 0 and 1");
+                }
+                if (scaleEndRow < scaleStartRow || scaleStartRow > 1) {
+                    throw new RuntimeException("A child of ScaledLayout should have a range of "
+                            + "scaleEndRow between scaleStartRow and 1");
+                }
+                if (scaleEndCol < 0 || scaleEndCol > 1) {
+                    throw new RuntimeException("A child of ScaledLayout should have a range of "
+                            + "scaleStartCol between 0 and 1");
+                }
+                if (scaleEndCol < scaleStartCol || scaleEndCol > 1) {
+                    throw new RuntimeException("A child of ScaledLayout should have a range of "
+                            + "scaleEndCol between scaleStartCol and 1");
+                }
+                if (DEBUG) {
+                    Log.d(TAG, String.format("onMeasure child scaleStartRow: %f scaleEndRow: %f "
+                                    + "scaleStartCol: %f scaleEndCol: %f",
+                            scaleStartRow, scaleEndRow, scaleStartCol, scaleEndCol));
+                }
+                mRectArray[i] = new Rect((int) (scaleStartCol * width), (int) (scaleStartRow
+                        * height), (int) (scaleEndCol * width), (int) (scaleEndRow * height));
+                int childWidthSpec = MeasureSpec.makeMeasureSpec(
+                        (int) (width * (scaleEndCol - scaleStartCol)), MeasureSpec.EXACTLY);
+                int childHeightSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+                child.measure(childWidthSpec, childHeightSpec);
+
+                // If the height of the measured child view is bigger than the height of the
+                // calculated region by the given ScaleLayoutParams, the height of the region should
+                // be increased to fit the size of the child view.
+                if (child.getMeasuredHeight() > mRectArray[i].height()) {
+                    int overflowedHeight = child.getMeasuredHeight() - mRectArray[i].height();
+                    overflowedHeight = (overflowedHeight + 1) / 2;
+                    mRectArray[i].bottom += overflowedHeight;
+                    mRectArray[i].top -= overflowedHeight;
+                    if (mRectArray[i].top < 0) {
+                        mRectArray[i].bottom -= mRectArray[i].top;
+                        mRectArray[i].top = 0;
+                    }
+                    if (mRectArray[i].bottom > height) {
+                        mRectArray[i].top -= mRectArray[i].bottom - height;
+                        mRectArray[i].bottom = height;
+                    }
+                }
+                childHeightSpec = MeasureSpec.makeMeasureSpec(
+                        (int) (height * (scaleEndRow - scaleStartRow)), MeasureSpec.EXACTLY);
+                child.measure(childWidthSpec, childHeightSpec);
+            }
+
+            // Avoid overlapping rectangles.
+            // Step 1. Sort rectangles by position (top-left).
+            int visibleRectCount = 0;
+            int[] visibleRectGroup = new int[count];
+            Rect[] visibleRectArray = new Rect[count];
+            for (int i = 0; i < count; ++i) {
+                if (getChildAt(i).getVisibility() == View.VISIBLE) {
+                    visibleRectGroup[visibleRectCount] = visibleRectCount;
+                    visibleRectArray[visibleRectCount] = mRectArray[i];
+                    ++visibleRectCount;
+                }
+            }
+            Arrays.sort(visibleRectArray, 0, visibleRectCount, mRectTopLeftSorter);
+
+            // Step 2. Move down if there are overlapping rectangles.
+            for (int i = 0; i < visibleRectCount - 1; ++i) {
+                for (int j = i + 1; j < visibleRectCount; ++j) {
+                    if (Rect.intersects(visibleRectArray[i], visibleRectArray[j])) {
+                        visibleRectGroup[j] = visibleRectGroup[i];
+                        visibleRectArray[j].set(visibleRectArray[j].left,
+                                visibleRectArray[i].bottom,
+                                visibleRectArray[j].right,
+                                visibleRectArray[i].bottom + visibleRectArray[j].height());
+                    }
+                }
+            }
+
+            // Step 3. Move up if there is any overflowed rectangle.
+            for (int i = visibleRectCount - 1; i >= 0; --i) {
+                if (visibleRectArray[i].bottom > height) {
+                    int overflowedHeight = visibleRectArray[i].bottom - height;
+                    for (int j = 0; j <= i; ++j) {
+                        if (visibleRectGroup[i] == visibleRectGroup[j]) {
+                            visibleRectArray[j].set(visibleRectArray[j].left,
+                                    visibleRectArray[j].top - overflowedHeight,
+                                    visibleRectArray[j].right,
+                                    visibleRectArray[j].bottom - overflowedHeight);
+                        }
+                    }
+                }
+            }
+            setMeasuredDimension(widthSpecSize, heightSpecSize);
+        }
+
+        @Override
+        protected void onLayout(boolean changed, int l, int t, int r, int b) {
+            int paddingLeft = getPaddingLeft();
+            int paddingTop = getPaddingTop();
+            int count = getChildCount();
+            for (int i = 0; i < count; ++i) {
+                View child = getChildAt(i);
+                if (child.getVisibility() != GONE) {
+                    int childLeft = paddingLeft + mRectArray[i].left;
+                    int childTop = paddingTop + mRectArray[i].top;
+                    int childBottom = paddingLeft + mRectArray[i].bottom;
+                    int childRight = paddingTop + mRectArray[i].right;
+                    if (DEBUG) {
+                        Log.d(TAG, String.format(
+                                "child layout bottom: %d left: %d right: %d top: %d",
+                                childBottom, childLeft, childRight, childTop));
+                    }
+                    child.layout(childLeft, childTop, childRight, childBottom);
+                }
+            }
+        }
+
+        @Override
+        public void dispatchDraw(Canvas canvas) {
+            int paddingLeft = getPaddingLeft();
+            int paddingTop = getPaddingTop();
+            int count = getChildCount();
+            for (int i = 0; i < count; ++i) {
+                View child = getChildAt(i);
+                if (child.getVisibility() != GONE) {
+                    if (i >= mRectArray.length) {
+                        break;
+                    }
+                    int childLeft = paddingLeft + mRectArray[i].left;
+                    int childTop = paddingTop + mRectArray[i].top;
+                    final int saveCount = canvas.save();
+                    canvas.translate(childLeft, childTop);
+                    child.draw(canvas);
+                    canvas.restoreToCount(saveCount);
+                }
+            }
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Layout containing the safe title area that helps the closed captions look more prominent.
+     *
+     * <p>This is required by CEA-708B.
+     */
+    static class CCLayout extends ScaledLayout implements ClosedCaptionLayout {
+        private static final float SAFE_TITLE_AREA_SCALE_START_X = 0.1f;
+        private static final float SAFE_TITLE_AREA_SCALE_END_X = 0.9f;
+        private static final float SAFE_TITLE_AREA_SCALE_START_Y = 0.1f;
+        private static final float SAFE_TITLE_AREA_SCALE_END_Y = 0.9f;
+
+        private final ScaledLayout mSafeTitleAreaLayout;
+
+        public CCLayout(Context context) {
+            super(context);
+
+            mSafeTitleAreaLayout = new ScaledLayout(context);
+            addView(mSafeTitleAreaLayout, new ScaledLayout.ScaledLayoutParams(
+                    SAFE_TITLE_AREA_SCALE_START_X, SAFE_TITLE_AREA_SCALE_END_X,
+                    SAFE_TITLE_AREA_SCALE_START_Y, SAFE_TITLE_AREA_SCALE_END_Y));
+        }
+
+        public void addOrUpdateViewToSafeTitleArea(CCWindowLayout captionWindowLayout,
+                ScaledLayoutParams scaledLayoutParams) {
+            int index = mSafeTitleAreaLayout.indexOfChild(captionWindowLayout);
+            if (index < 0) {
+                mSafeTitleAreaLayout.addView(captionWindowLayout, scaledLayoutParams);
+                return;
+            }
+            mSafeTitleAreaLayout.updateViewLayout(captionWindowLayout, scaledLayoutParams);
+        }
+
+        public void removeViewFromSafeTitleArea(CCWindowLayout captionWindowLayout) {
+            mSafeTitleAreaLayout.removeView(captionWindowLayout);
+        }
+
+        public void setCaptionStyle(CaptionStyle style) {
+            final int count = mSafeTitleAreaLayout.getChildCount();
+            for (int i = 0; i < count; ++i) {
+                final CCWindowLayout windowLayout =
+                        (CCWindowLayout) mSafeTitleAreaLayout.getChildAt(i);
+                windowLayout.setCaptionStyle(style);
+            }
+        }
+
+        public void setFontScale(float fontScale) {
+            final int count = mSafeTitleAreaLayout.getChildCount();
+            for (int i = 0; i < count; ++i) {
+                final CCWindowLayout windowLayout =
+                        (CCWindowLayout) mSafeTitleAreaLayout.getChildAt(i);
+                windowLayout.setFontScale(fontScale);
+            }
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Renders the selected CC track.
+     */
+    static class CCHandler implements Handler.Callback {
+        // TODO: Remaining works
+        // CaptionTrackRenderer does not support the full spec of CEA-708. The remaining works are
+        // described in the follows.
+        // C0 Table: Backspace, FF, and HCR are not supported. The rule for P16 is not standardized
+        //           but it is handled as EUC-KR charset for Korea broadcasting.
+        // C1 Table: All the styles of windows and pens except underline, italic, pen size, and pen
+        //           offset specified in CEA-708 are ignored and this follows system wide CC
+        //           preferences for look and feel. SetPenLocation is not implemented.
+        // G2 Table: TSP, NBTSP and BLK are not supported.
+        // Text/commands: Word wrapping, fonts, row and column locking are not supported.
+
+        private static final String TAG = "CCHandler";
+        private static final boolean DEBUG = false;
+
+        private static final int TENTHS_OF_SECOND_IN_MILLIS = 100;
+
+        // According to CEA-708B, there can exist up to 8 caption windows.
+        private static final int CAPTION_WINDOWS_MAX = 8;
+        private static final int CAPTION_ALL_WINDOWS_BITMAP = 255;
+
+        private static final int MSG_DELAY_CANCEL = 1;
+        private static final int MSG_CAPTION_CLEAR = 2;
+
+        private static final long CAPTION_CLEAR_INTERVAL_MS = 60000;
+
+        private final CCLayout mCCLayout;
+        private boolean mIsDelayed = false;
+        private CCWindowLayout mCurrentWindowLayout;
+        private final CCWindowLayout[] mCaptionWindowLayouts =
+                new CCWindowLayout[CAPTION_WINDOWS_MAX];
+        private final ArrayList<Cea708CCParser.CaptionEvent> mPendingCaptionEvents
+                = new ArrayList<>();
+        private final Handler mHandler;
+
+        public CCHandler(CCLayout ccLayout) {
+            mCCLayout = ccLayout;
+            mHandler = new Handler(this);
+        }
+
+        @Override
+        public boolean handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_DELAY_CANCEL:
+                    delayCancel();
+                    return true;
+                case MSG_CAPTION_CLEAR:
+                    clearWindows(CAPTION_ALL_WINDOWS_BITMAP);
+                    return true;
+            }
+            return false;
+        }
+
+        public void processCaptionEvent(Cea708CCParser.CaptionEvent event) {
+            if (mIsDelayed) {
+                mPendingCaptionEvents.add(event);
+                return;
+            }
+            switch (event.type) {
+                case Cea708CCParser.CAPTION_EMIT_TYPE_BUFFER:
+                    sendBufferToCurrentWindow((String) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_CONTROL:
+                    sendControlToCurrentWindow((char) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_CWX:
+                    setCurrentWindowLayout((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_CLW:
+                    clearWindows((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_DSW:
+                    displayWindows((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_HDW:
+                    hideWindows((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_TGW:
+                    toggleWindows((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_DLW:
+                    deleteWindows((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_DLY:
+                    delay((int) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_DLC:
+                    delayCancel();
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_RST:
+                    reset();
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_SPA:
+                    setPenAttr((Cea708CCParser.CaptionPenAttr) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_SPC:
+                    setPenColor((Cea708CCParser.CaptionPenColor) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_SPL:
+                    setPenLocation((Cea708CCParser.CaptionPenLocation) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_SWA:
+                    setWindowAttr((Cea708CCParser.CaptionWindowAttr) event.obj);
+                    break;
+                case Cea708CCParser.CAPTION_EMIT_TYPE_COMMAND_DFX:
+                    defineWindow((Cea708CCParser.CaptionWindow) event.obj);
+                    break;
+            }
+        }
+
+        // The window related caption commands
+        private void setCurrentWindowLayout(int windowId) {
+            if (windowId < 0 || windowId >= mCaptionWindowLayouts.length) {
+                return;
+            }
+            CCWindowLayout windowLayout = mCaptionWindowLayouts[windowId];
+            if (windowLayout == null) {
+                return;
+            }
+            if (DEBUG) {
+                Log.d(TAG, "setCurrentWindowLayout to " + windowId);
+            }
+            mCurrentWindowLayout = windowLayout;
+        }
+
+        // Each bit of windowBitmap indicates a window.
+        // If a bit is set, the window id is the same as the number of the trailing zeros of the
+        // bit.
+        private ArrayList<CCWindowLayout> getWindowsFromBitmap(int windowBitmap) {
+            ArrayList<CCWindowLayout> windows = new ArrayList<>();
+            for (int i = 0; i < CAPTION_WINDOWS_MAX; ++i) {
+                if ((windowBitmap & (1 << i)) != 0) {
+                    CCWindowLayout windowLayout = mCaptionWindowLayouts[i];
+                    if (windowLayout != null) {
+                        windows.add(windowLayout);
+                    }
+                }
+            }
+            return windows;
+        }
+
+        private void clearWindows(int windowBitmap) {
+            if (windowBitmap == 0) {
+                return;
+            }
+            for (CCWindowLayout windowLayout : getWindowsFromBitmap(windowBitmap)) {
+                windowLayout.clear();
+            }
+        }
+
+        private void displayWindows(int windowBitmap) {
+            if (windowBitmap == 0) {
+                return;
+            }
+            for (CCWindowLayout windowLayout : getWindowsFromBitmap(windowBitmap)) {
+                windowLayout.show();
+            }
+        }
+
+        private void hideWindows(int windowBitmap) {
+            if (windowBitmap == 0) {
+                return;
+            }
+            for (CCWindowLayout windowLayout : getWindowsFromBitmap(windowBitmap)) {
+                windowLayout.hide();
+            }
+        }
+
+        private void toggleWindows(int windowBitmap) {
+            if (windowBitmap == 0) {
+                return;
+            }
+            for (CCWindowLayout windowLayout : getWindowsFromBitmap(windowBitmap)) {
+                if (windowLayout.isShown()) {
+                    windowLayout.hide();
+                } else {
+                    windowLayout.show();
+                }
+            }
+        }
+
+        private void deleteWindows(int windowBitmap) {
+            if (windowBitmap == 0) {
+                return;
+            }
+            for (CCWindowLayout windowLayout : getWindowsFromBitmap(windowBitmap)) {
+                windowLayout.removeFromCaptionView();
+                mCaptionWindowLayouts[windowLayout.getCaptionWindowId()] = null;
+            }
+        }
+
+        public void reset() {
+            mCurrentWindowLayout = null;
+            mIsDelayed = false;
+            mPendingCaptionEvents.clear();
+            for (int i = 0; i < CAPTION_WINDOWS_MAX; ++i) {
+                if (mCaptionWindowLayouts[i] != null) {
+                    mCaptionWindowLayouts[i].removeFromCaptionView();
+                }
+                mCaptionWindowLayouts[i] = null;
+            }
+            mCCLayout.setVisibility(View.INVISIBLE);
+            mHandler.removeMessages(MSG_CAPTION_CLEAR);
+        }
+
+        private void setWindowAttr(Cea708CCParser.CaptionWindowAttr windowAttr) {
+            if (mCurrentWindowLayout != null) {
+                mCurrentWindowLayout.setWindowAttr(windowAttr);
+            }
+        }
+
+        private void defineWindow(Cea708CCParser.CaptionWindow window) {
+            if (window == null) {
+                return;
+            }
+            int windowId = window.id;
+            if (windowId < 0 || windowId >= mCaptionWindowLayouts.length) {
+                return;
+            }
+            CCWindowLayout windowLayout = mCaptionWindowLayouts[windowId];
+            if (windowLayout == null) {
+                windowLayout = new CCWindowLayout(mCCLayout.getContext());
+            }
+            windowLayout.initWindow(mCCLayout, window);
+            mCurrentWindowLayout = mCaptionWindowLayouts[windowId] = windowLayout;
+        }
+
+        // The job related caption commands
+        private void delay(int tenthsOfSeconds) {
+            if (tenthsOfSeconds < 0 || tenthsOfSeconds > 255) {
+                return;
+            }
+            mIsDelayed = true;
+            mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_DELAY_CANCEL),
+                    tenthsOfSeconds * TENTHS_OF_SECOND_IN_MILLIS);
+        }
+
+        private void delayCancel() {
+            mIsDelayed = false;
+            processPendingBuffer();
+        }
+
+        private void processPendingBuffer() {
+            for (Cea708CCParser.CaptionEvent event : mPendingCaptionEvents) {
+                processCaptionEvent(event);
+            }
+            mPendingCaptionEvents.clear();
+        }
+
+        // The implicit write caption commands
+        private void sendControlToCurrentWindow(char control) {
+            if (mCurrentWindowLayout != null) {
+                mCurrentWindowLayout.sendControl(control);
+            }
+        }
+
+        private void sendBufferToCurrentWindow(String buffer) {
+            if (mCurrentWindowLayout != null) {
+                mCurrentWindowLayout.sendBuffer(buffer);
+                mHandler.removeMessages(MSG_CAPTION_CLEAR);
+                mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CAPTION_CLEAR),
+                        CAPTION_CLEAR_INTERVAL_MS);
+            }
+        }
+
+        // The pen related caption commands
+        private void setPenAttr(Cea708CCParser.CaptionPenAttr attr) {
+            if (mCurrentWindowLayout != null) {
+                mCurrentWindowLayout.setPenAttr(attr);
+            }
+        }
+
+        private void setPenColor(Cea708CCParser.CaptionPenColor color) {
+            if (mCurrentWindowLayout != null) {
+                mCurrentWindowLayout.setPenColor(color);
+            }
+        }
+
+        private void setPenLocation(Cea708CCParser.CaptionPenLocation location) {
+            if (mCurrentWindowLayout != null) {
+                mCurrentWindowLayout.setPenLocation(location.row, location.column);
+            }
+        }
+    }
+
+    /**
+     * @hide
+     *
+     * Layout which renders a caption window of CEA-708B. It contains a {@link TextView} that takes
+     * care of displaying the actual CC text.
+     */
+    static class CCWindowLayout extends RelativeLayout implements View.OnLayoutChangeListener {
+        private static final String TAG = "CCWindowLayout";
+
+        private static final float PROPORTION_PEN_SIZE_SMALL = .75f;
+        private static final float PROPORTION_PEN_SIZE_LARGE = 1.25f;
+
+        // The following values indicates the maximum cell number of a window.
+        private static final int ANCHOR_RELATIVE_POSITIONING_MAX = 99;
+        private static final int ANCHOR_VERTICAL_MAX = 74;
+        private static final int ANCHOR_HORIZONTAL_16_9_MAX = 209;
+        private static final int MAX_COLUMN_COUNT_16_9 = 42;
+
+        // The following values indicates a gravity of a window.
+        private static final int ANCHOR_MODE_DIVIDER = 3;
+        private static final int ANCHOR_HORIZONTAL_MODE_LEFT = 0;
+        private static final int ANCHOR_HORIZONTAL_MODE_CENTER = 1;
+        private static final int ANCHOR_HORIZONTAL_MODE_RIGHT = 2;
+        private static final int ANCHOR_VERTICAL_MODE_TOP = 0;
+        private static final int ANCHOR_VERTICAL_MODE_CENTER = 1;
+        private static final int ANCHOR_VERTICAL_MODE_BOTTOM = 2;
+
+        private CCLayout mCCLayout;
+
+        private CCView mCCView;
+        private CaptionStyle mCaptionStyle;
+        private int mRowLimit = 0;
+        private final SpannableStringBuilder mBuilder = new SpannableStringBuilder();
+        private final List<CharacterStyle> mCharacterStyles = new ArrayList<>();
+        private int mCaptionWindowId;
+        private int mRow = -1;
+        private float mFontScale;
+        private float mTextSize;
+        private String mWidestChar;
+        private int mLastCaptionLayoutWidth;
+        private int mLastCaptionLayoutHeight;
+
+        public CCWindowLayout(Context context) {
+            this(context, null);
+        }
+
+        public CCWindowLayout(Context context, AttributeSet attrs) {
+            this(context, attrs, 0);
+        }
+
+        public CCWindowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+            this(context, attrs, defStyleAttr, 0);
+        }
+
+        public CCWindowLayout(Context context, AttributeSet attrs, int defStyleAttr,
+                int defStyleRes) {
+            super(context, attrs, defStyleAttr, defStyleRes);
+
+            // Add a subtitle view to the layout.
+            mCCView = new CCView(context);
+            LayoutParams params = new RelativeLayout.LayoutParams(
+                    ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
+            addView(mCCView, params);
+
+            // Set the system wide CC preferences to the subtitle view.
+            CaptioningManager captioningManager =
+                    (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
+            mFontScale = captioningManager.getFontScale();
+            setCaptionStyle(captioningManager.getUserStyle());
+            mCCView.setText("");
+            updateWidestChar();
+        }
+
+        public void setCaptionStyle(CaptionStyle style) {
+            mCaptionStyle = style;
+            mCCView.setCaptionStyle(style);
+        }
+
+        public void setFontScale(float fontScale) {
+            mFontScale = fontScale;
+            updateTextSize();
+        }
+
+        public int getCaptionWindowId() {
+            return mCaptionWindowId;
+        }
+
+        public void setCaptionWindowId(int captionWindowId) {
+            mCaptionWindowId = captionWindowId;
+        }
+
+        public void clear() {
+            clearText();
+            hide();
+        }
+
+        public void show() {
+            setVisibility(View.VISIBLE);
+            requestLayout();
+        }
+
+        public void hide() {
+            setVisibility(View.INVISIBLE);
+            requestLayout();
+        }
+
+        public void setPenAttr(Cea708CCParser.CaptionPenAttr penAttr) {
+            mCharacterStyles.clear();
+            if (penAttr.italic) {
+                mCharacterStyles.add(new StyleSpan(Typeface.ITALIC));
+            }
+            if (penAttr.underline) {
+                mCharacterStyles.add(new UnderlineSpan());
+            }
+            switch (penAttr.penSize) {
+                case Cea708CCParser.CaptionPenAttr.PEN_SIZE_SMALL:
+                    mCharacterStyles.add(new RelativeSizeSpan(PROPORTION_PEN_SIZE_SMALL));
+                    break;
+                case Cea708CCParser.CaptionPenAttr.PEN_SIZE_LARGE:
+                    mCharacterStyles.add(new RelativeSizeSpan(PROPORTION_PEN_SIZE_LARGE));
+                    break;
+            }
+            switch (penAttr.penOffset) {
+                case Cea708CCParser.CaptionPenAttr.OFFSET_SUBSCRIPT:
+                    mCharacterStyles.add(new SubscriptSpan());
+                    break;
+                case Cea708CCParser.CaptionPenAttr.OFFSET_SUPERSCRIPT:
+                    mCharacterStyles.add(new SuperscriptSpan());
+                    break;
+            }
+        }
+
+        public void setPenColor(Cea708CCParser.CaptionPenColor penColor) {
+            // TODO: apply pen colors or skip this and use the style of system wide CC style as is.
+        }
+
+        public void setPenLocation(int row, int column) {
+            // TODO: change the location of pen based on row and column both.
+            if (mRow >= 0) {
+                for (int r = mRow; r < row; ++r) {
+                    appendText("\n");
+                }
+            }
+            mRow = row;
+        }
+
+        public void setWindowAttr(Cea708CCParser.CaptionWindowAttr windowAttr) {
+            // TODO: apply window attrs or skip this and use the style of system wide CC style as
+            // is.
+        }
+
+        public void sendBuffer(String buffer) {
+            appendText(buffer);
+        }
+
+        public void sendControl(char control) {
+            // TODO: there are a bunch of ASCII-style control codes.
+        }
+
+        /**
+         * This method places the window on a given CaptionLayout along with the anchor of the
+         * window.
+         * <p>
+         * According to CEA-708B, the anchor id indicates the gravity of the window as the follows.
+         * For example, A value 7 of a anchor id says that a window is align with its parent bottom
+         * and is located at the center horizontally of its parent.
+         * </p>
+         * <h4>Anchor id and the gravity of a window</h4>
+         * <table>
+         *     <tr>
+         *         <th>GRAVITY</th>
+         *         <th>LEFT</th>
+         *         <th>CENTER_HORIZONTAL</th>
+         *         <th>RIGHT</th>
+         *     </tr>
+         *     <tr>
+         *         <th>TOP</th>
+         *         <td>0</td>
+         *         <td>1</td>
+         *         <td>2</td>
+         *     </tr>
+         *     <tr>
+         *         <th>CENTER_VERTICAL</th>
+         *         <td>3</td>
+         *         <td>4</td>
+         *         <td>5</td>
+         *     </tr>
+         *     <tr>
+         *         <th>BOTTOM</th>
+         *         <td>6</td>
+         *         <td>7</td>
+         *         <td>8</td>
+         *     </tr>
+         * </table>
+         * <p>
+         * In order to handle the gravity of a window, there are two steps. First, set the size of
+         * the window. Since the window will be positioned at ScaledLayout, the size factors are
+         * determined in a ratio. Second, set the gravity of the window. CaptionWindowLayout is
+         * inherited from RelativeLayout. Hence, we could set the gravity of its child view,
+         * SubtitleView.
+         * </p>
+         * <p>
+         * The gravity of the window is also related to its size. When it should be pushed to a one
+         * of the end of the window, like LEFT, RIGHT, TOP or BOTTOM, the anchor point should be a
+         * boundary of the window. When it should be pushed in the horizontal/vertical center of its
+         * container, the horizontal/vertical center point of the window should be the same as the
+         * anchor point.
+         * </p>
+         *
+         * @param ccLayout a given CaptionLayout, which contains a safe title area.
+         * @param captionWindow a given CaptionWindow, which stores the construction info of the
+         *                      window.
+         */
+        public void initWindow(CCLayout ccLayout, Cea708CCParser.CaptionWindow captionWindow) {
+            if (mCCLayout != ccLayout) {
+                if (mCCLayout != null) {
+                    mCCLayout.removeOnLayoutChangeListener(this);
+                }
+                mCCLayout = ccLayout;
+                mCCLayout.addOnLayoutChangeListener(this);
+                updateWidestChar();
+            }
+
+            // Both anchor vertical and horizontal indicates the position cell number of the window.
+            float scaleRow = (float) captionWindow.anchorVertical /
+                    (captionWindow.relativePositioning
+                            ? ANCHOR_RELATIVE_POSITIONING_MAX : ANCHOR_VERTICAL_MAX);
+
+            // Assumes it has a wide aspect ratio track.
+            float scaleCol = (float) captionWindow.anchorHorizontal /
+                    (captionWindow.relativePositioning ? ANCHOR_RELATIVE_POSITIONING_MAX
+                            : ANCHOR_HORIZONTAL_16_9_MAX);
+
+            // The range of scaleRow/Col need to be verified to be in [0, 1].
+            // Otherwise a RuntimeException will be raised in ScaledLayout.
+            if (scaleRow < 0 || scaleRow > 1) {
+                Log.i(TAG, "The vertical position of the anchor point should be at the range of 0 "
+                        + "and 1 but " + scaleRow);
+                scaleRow = Math.max(0, Math.min(scaleRow, 1));
+            }
+            if (scaleCol < 0 || scaleCol > 1) {
+                Log.i(TAG, "The horizontal position of the anchor point should be at the range of 0"
+                        + " and 1 but " + scaleCol);
+                scaleCol = Math.max(0, Math.min(scaleCol, 1));
+            }
+            int gravity = Gravity.CENTER;
+            int horizontalMode = captionWindow.anchorId % ANCHOR_MODE_DIVIDER;
+            int verticalMode = captionWindow.anchorId / ANCHOR_MODE_DIVIDER;
+            float scaleStartRow = 0;
+            float scaleEndRow = 1;
+            float scaleStartCol = 0;
+            float scaleEndCol = 1;
+            switch (horizontalMode) {
+                case ANCHOR_HORIZONTAL_MODE_LEFT:
+                    gravity = Gravity.LEFT;
+                    mCCView.setAlignment(Alignment.ALIGN_NORMAL);
+                    scaleStartCol = scaleCol;
+                    break;
+                case ANCHOR_HORIZONTAL_MODE_CENTER:
+                    float gap = Math.min(1 - scaleCol, scaleCol);
+
+                    // Since all TV sets use left text alignment instead of center text alignment
+                    // for this case, we follow the industry convention if possible.
+                    int columnCount = captionWindow.columnCount + 1;
+                    columnCount = Math.min(getScreenColumnCount(), columnCount);
+                    StringBuilder widestTextBuilder = new StringBuilder();
+                    for (int i = 0; i < columnCount; ++i) {
+                        widestTextBuilder.append(mWidestChar);
+                    }
+                    Paint paint = new Paint();
+                    paint.setTypeface(mCaptionStyle.getTypeface());
+                    paint.setTextSize(mTextSize);
+                    float maxWindowWidth = paint.measureText(widestTextBuilder.toString());
+                    float halfMaxWidthScale = mCCLayout.getWidth() > 0
+                            ? maxWindowWidth / 2.0f / (mCCLayout.getWidth() * 0.8f) : 0.0f;
+                    if (halfMaxWidthScale > 0f && halfMaxWidthScale < scaleCol) {
+                        // Calculate the expected max window size based on the column count of the
+                        // caption window multiplied by average alphabets char width, then align the
+                        // left side of the window with the left side of the expected max window.
+                        gravity = Gravity.LEFT;
+                        mCCView.setAlignment(Alignment.ALIGN_NORMAL);
+                        scaleStartCol = scaleCol - halfMaxWidthScale;
+                        scaleEndCol = 1.0f;
+                    } else {
+                        // The gap will be the minimum distance value of the distances from both
+                        // horizontal end points to the anchor point.
+                        // If scaleCol <= 0.5, the range of scaleCol is [0, the anchor point * 2].
+                        // If scaleCol > 0.5, the range of scaleCol is
+                        // [(1 - the anchor point) * 2, 1].
+                        // The anchor point is located at the horizontal center of the window in
+                        // both cases.
+                        gravity = Gravity.CENTER_HORIZONTAL;
+                        mCCView.setAlignment(Alignment.ALIGN_CENTER);
+                        scaleStartCol = scaleCol - gap;
+                        scaleEndCol = scaleCol + gap;
+                    }
+                    break;
+                case ANCHOR_HORIZONTAL_MODE_RIGHT:
+                    gravity = Gravity.RIGHT;
+                    mCCView.setAlignment(Alignment.ALIGN_RIGHT);
+                    scaleEndCol = scaleCol;
+                    break;
+            }
+            switch (verticalMode) {
+                case ANCHOR_VERTICAL_MODE_TOP:
+                    gravity |= Gravity.TOP;
+                    scaleStartRow = scaleRow;
+                    break;
+                case ANCHOR_VERTICAL_MODE_CENTER:
+                    gravity |= Gravity.CENTER_VERTICAL;
+
+                    // See the above comment.
+                    float gap = Math.min(1 - scaleRow, scaleRow);
+                    scaleStartRow = scaleRow - gap;
+                    scaleEndRow = scaleRow + gap;
+                    break;
+                case ANCHOR_VERTICAL_MODE_BOTTOM:
+                    gravity |= Gravity.BOTTOM;
+                    scaleEndRow = scaleRow;
+                    break;
+            }
+            mCCLayout.addOrUpdateViewToSafeTitleArea(this, new ScaledLayout
+                    .ScaledLayoutParams(scaleStartRow, scaleEndRow, scaleStartCol, scaleEndCol));
+            setCaptionWindowId(captionWindow.id);
+            setRowLimit(captionWindow.rowCount);
+            setGravity(gravity);
+            if (captionWindow.visible) {
+                show();
+            } else {
+                hide();
+            }
+        }
+
+        @Override
+        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft,
+                int oldTop, int oldRight, int oldBottom) {
+            int width = right - left;
+            int height = bottom - top;
+            if (width != mLastCaptionLayoutWidth || height != mLastCaptionLayoutHeight) {
+                mLastCaptionLayoutWidth = width;
+                mLastCaptionLayoutHeight = height;
+                updateTextSize();
+            }
+        }
+
+        private void updateWidestChar() {
+            Paint paint = new Paint();
+            paint.setTypeface(mCaptionStyle.getTypeface());
+            Charset latin1 = Charset.forName("ISO-8859-1");
+            float widestCharWidth = 0f;
+            for (int i = 0; i < 256; ++i) {
+                String ch = new String(new byte[]{(byte) i}, latin1);
+                float charWidth = paint.measureText(ch);
+                if (widestCharWidth < charWidth) {
+                    widestCharWidth = charWidth;
+                    mWidestChar = ch;
+                }
+            }
+            updateTextSize();
+        }
+
+        private void updateTextSize() {
+            if (mCCLayout == null) return;
+
+            // Calculate text size based on the max window size.
+            StringBuilder widestTextBuilder = new StringBuilder();
+            int screenColumnCount = getScreenColumnCount();
+            for (int i = 0; i < screenColumnCount; ++i) {
+                widestTextBuilder.append(mWidestChar);
+            }
+            String widestText = widestTextBuilder.toString();
+            Paint paint = new Paint();
+            paint.setTypeface(mCaptionStyle.getTypeface());
+            float startFontSize = 0f;
+            float endFontSize = 255f;
+            while (startFontSize < endFontSize) {
+                float testTextSize = (startFontSize + endFontSize) / 2f;
+                paint.setTextSize(testTextSize);
+                float width = paint.measureText(widestText);
+                if (mCCLayout.getWidth() * 0.8f > width) {
+                    startFontSize = testTextSize + 0.01f;
+                } else {
+                    endFontSize = testTextSize - 0.01f;
+                }
+            }
+            mTextSize = endFontSize * mFontScale;
+            mCCView.setTextSize(mTextSize);
+        }
+
+        private int getScreenColumnCount() {
+            // Assume it has a wide aspect ratio track.
+            return MAX_COLUMN_COUNT_16_9;
+        }
+
+        public void removeFromCaptionView() {
+            if (mCCLayout != null) {
+                mCCLayout.removeViewFromSafeTitleArea(this);
+                mCCLayout.removeOnLayoutChangeListener(this);
+                mCCLayout = null;
+            }
+        }
+
+        public void setText(String text) {
+            updateText(text, false);
+        }
+
+        public void appendText(String text) {
+            updateText(text, true);
+        }
+
+        public void clearText() {
+            mBuilder.clear();
+            mCCView.setText("");
+        }
+
+        private void updateText(String text, boolean appended) {
+            if (!appended) {
+                mBuilder.clear();
+            }
+            if (text != null && text.length() > 0) {
+                int length = mBuilder.length();
+                mBuilder.append(text);
+                for (CharacterStyle characterStyle : mCharacterStyles) {
+                    mBuilder.setSpan(characterStyle, length, mBuilder.length(),
+                            Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
+                }
+            }
+            String[] lines = TextUtils.split(mBuilder.toString(), "\n");
+
+            // Truncate text not to exceed the row limit.
+            // Plus one here since the range of the rows is [0, mRowLimit].
+            String truncatedText = TextUtils.join("\n", Arrays.copyOfRange(
+                    lines, Math.max(0, lines.length - (mRowLimit + 1)), lines.length));
+            mBuilder.delete(0, mBuilder.length() - truncatedText.length());
+
+            // Trim the buffer first then set text to CCView.
+            int start = 0, last = mBuilder.length() - 1;
+            int end = last;
+            while ((start <= end) && (mBuilder.charAt(start) <= ' ')) {
+                ++start;
+            }
+            while ((end >= start) && (mBuilder.charAt(end) <= ' ')) {
+                --end;
+            }
+            if (start == 0 && end == last) {
+                mCCView.setText(mBuilder);
+            } else {
+                SpannableStringBuilder trim = new SpannableStringBuilder();
+                trim.append(mBuilder);
+                if (end < last) {
+                    trim.delete(end + 1, last + 1);
+                }
+                if (start > 0) {
+                    trim.delete(0, start);
+                }
+                mCCView.setText(trim);
+            }
+        }
+
+        public void setRowLimit(int rowLimit) {
+            if (rowLimit < 0) {
+                throw new IllegalArgumentException("A rowLimit should have a positive number");
+            }
+            mRowLimit = rowLimit;
+        }
+    }
+
+    /** @hide */
+    static class CCView extends SubtitleView {
+        private static final CaptionStyle DEFAULT_CAPTION_STYLE = CaptionStyle.DEFAULT;
+
+        public CCView(Context context) {
+            this(context, null);
+        }
+
+        public CCView(Context context, AttributeSet attrs) {
+            this(context, attrs, 0);
+        }
+
+        public CCView(Context context, AttributeSet attrs, int defStyleAttr) {
+            this(context, attrs, defStyleAttr, 0);
+        }
+
+        public CCView(Context context, AttributeSet attrs, int defStyleAttr,
+                int defStyleRes) {
+            super(context, attrs, defStyleAttr, defStyleRes);
+        }
+
+        public void setCaptionStyle(CaptionStyle style) {
+            setForegroundColor(style.hasForegroundColor()
+                    ? style.foregroundColor : DEFAULT_CAPTION_STYLE.foregroundColor);
+            setBackgroundColor(style.hasBackgroundColor()
+                    ? style.backgroundColor : DEFAULT_CAPTION_STYLE.backgroundColor);
+            setEdgeType(style.hasEdgeType()
+                    ? style.edgeType : DEFAULT_CAPTION_STYLE.edgeType);
+            setEdgeColor(style.hasEdgeColor()
+                    ? style.edgeColor : DEFAULT_CAPTION_STYLE.edgeColor);
+            setTypeface(style.getTypeface());
+        }
+    }
+}
diff --git a/android/media/ClosedCaptionRenderer.java b/android/media/ClosedCaptionRenderer.java
new file mode 100644
index 0000000..66759e5
--- /dev/null
+++ b/android/media/ClosedCaptionRenderer.java
@@ -0,0 +1,1510 @@
+/*
+ * Copyright (C) 2014 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.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Typeface;
+import android.text.Spannable;
+import android.text.SpannableStringBuilder;
+import android.text.TextPaint;
+import android.text.style.CharacterStyle;
+import android.text.style.StyleSpan;
+import android.text.style.UnderlineSpan;
+import android.text.style.UpdateAppearance;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.TypedValue;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.CaptioningManager;
+import android.view.accessibility.CaptioningManager.CaptionStyle;
+import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Vector;
+
+/** @hide */
+public class ClosedCaptionRenderer extends SubtitleController.Renderer {
+    private final Context mContext;
+    private Cea608CCWidget mCCWidget;
+
+    public ClosedCaptionRenderer(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public boolean supports(MediaFormat format) {
+        if (format.containsKey(MediaFormat.KEY_MIME)) {
+            String mimeType = format.getString(MediaFormat.KEY_MIME);
+            return MediaFormat.MIMETYPE_TEXT_CEA_608.equals(mimeType);
+        }
+        return false;
+    }
+
+    @Override
+    public SubtitleTrack createTrack(MediaFormat format) {
+        String mimeType = format.getString(MediaFormat.KEY_MIME);
+        if (MediaFormat.MIMETYPE_TEXT_CEA_608.equals(mimeType)) {
+            if (mCCWidget == null) {
+                mCCWidget = new Cea608CCWidget(mContext);
+            }
+            return new Cea608CaptionTrack(mCCWidget, format);
+        }
+        throw new RuntimeException("No matching format: " + format.toString());
+    }
+}
+
+/** @hide */
+class Cea608CaptionTrack extends SubtitleTrack {
+    private final Cea608CCParser mCCParser;
+    private final Cea608CCWidget mRenderingWidget;
+
+    Cea608CaptionTrack(Cea608CCWidget renderingWidget, MediaFormat format) {
+        super(format);
+
+        mRenderingWidget = renderingWidget;
+        mCCParser = new Cea608CCParser(mRenderingWidget);
+    }
+
+    @Override
+    public void onData(byte[] data, boolean eos, long runID) {
+        mCCParser.parse(data);
+    }
+
+    @Override
+    public RenderingWidget getRenderingWidget() {
+        return mRenderingWidget;
+    }
+
+    @Override
+    public void updateView(Vector<Cue> activeCues) {
+        // Overriding with NO-OP, CC rendering by-passes this
+    }
+}
+
+/**
+ * Abstract widget class to render a closed caption track.
+ *
+ * @hide
+ */
+abstract class ClosedCaptionWidget extends ViewGroup implements SubtitleTrack.RenderingWidget {
+
+    /** @hide */
+    interface ClosedCaptionLayout {
+        void setCaptionStyle(CaptionStyle captionStyle);
+        void setFontScale(float scale);
+    }
+
+    private static final CaptionStyle DEFAULT_CAPTION_STYLE = CaptionStyle.DEFAULT;
+
+    /** Captioning manager, used to obtain and track caption properties. */
+    private final CaptioningManager mManager;
+
+    /** Current caption style. */
+    protected CaptionStyle mCaptionStyle;
+
+    /** Callback for rendering changes. */
+    protected OnChangedListener mListener;
+
+    /** Concrete layout of CC. */
+    protected ClosedCaptionLayout mClosedCaptionLayout;
+
+    /** Whether a caption style change listener is registered. */
+    private boolean mHasChangeListener;
+
+    public ClosedCaptionWidget(Context context) {
+        this(context, null);
+    }
+
+    public ClosedCaptionWidget(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public ClosedCaptionWidget(Context context, AttributeSet attrs, int defStyle) {
+        this(context, attrs, defStyle, 0);
+    }
+
+    public ClosedCaptionWidget(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        // Cannot render text over video when layer type is hardware.
+        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+
+        mManager = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
+        mCaptionStyle = DEFAULT_CAPTION_STYLE.applyStyle(mManager.getUserStyle());
+
+        mClosedCaptionLayout = createCaptionLayout(context);
+        mClosedCaptionLayout.setCaptionStyle(mCaptionStyle);
+        mClosedCaptionLayout.setFontScale(mManager.getFontScale());
+        addView((ViewGroup) mClosedCaptionLayout, LayoutParams.MATCH_PARENT,
+                LayoutParams.MATCH_PARENT);
+
+        requestLayout();
+    }
+
+    public abstract ClosedCaptionLayout createCaptionLayout(Context context);
+
+    @Override
+    public void setOnChangedListener(OnChangedListener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    public void setSize(int width, int height) {
+        final int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
+        final int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
+
+        measure(widthSpec, heightSpec);
+        layout(0, 0, width, height);
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        if (visible) {
+            setVisibility(View.VISIBLE);
+        } else {
+            setVisibility(View.GONE);
+        }
+
+        manageChangeListener();
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        manageChangeListener();
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        manageChangeListener();
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        ((ViewGroup) mClosedCaptionLayout).measure(widthMeasureSpec, heightMeasureSpec);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        ((ViewGroup) mClosedCaptionLayout).layout(l, t, r, b);
+    }
+
+    /**
+     * Manages whether this renderer is listening for caption style changes.
+     */
+    private final CaptioningChangeListener mCaptioningListener = new CaptioningChangeListener() {
+        @Override
+        public void onUserStyleChanged(CaptionStyle userStyle) {
+            mCaptionStyle = DEFAULT_CAPTION_STYLE.applyStyle(userStyle);
+            mClosedCaptionLayout.setCaptionStyle(mCaptionStyle);
+        }
+
+        @Override
+        public void onFontScaleChanged(float fontScale) {
+            mClosedCaptionLayout.setFontScale(fontScale);
+        }
+    };
+
+    private void manageChangeListener() {
+        final boolean needsListener = isAttachedToWindow() && getVisibility() == View.VISIBLE;
+        if (mHasChangeListener != needsListener) {
+            mHasChangeListener = needsListener;
+
+            if (needsListener) {
+                mManager.addCaptioningChangeListener(mCaptioningListener);
+            } else {
+                mManager.removeCaptioningChangeListener(mCaptioningListener);
+            }
+        }
+    }
+}
+
+/**
+ * @hide
+ *
+ * CCParser processes CEA-608 closed caption data.
+ *
+ * It calls back into OnDisplayChangedListener upon
+ * display change with styled text for rendering.
+ *
+ */
+class Cea608CCParser {
+    public static final int MAX_ROWS = 15;
+    public static final int MAX_COLS = 32;
+
+    private static final String TAG = "Cea608CCParser";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private static final int INVALID = -1;
+
+    // EIA-CEA-608: Table 70 - Control Codes
+    private static final int RCL = 0x20;
+    private static final int BS  = 0x21;
+    private static final int AOF = 0x22;
+    private static final int AON = 0x23;
+    private static final int DER = 0x24;
+    private static final int RU2 = 0x25;
+    private static final int RU3 = 0x26;
+    private static final int RU4 = 0x27;
+    private static final int FON = 0x28;
+    private static final int RDC = 0x29;
+    private static final int TR  = 0x2a;
+    private static final int RTD = 0x2b;
+    private static final int EDM = 0x2c;
+    private static final int CR  = 0x2d;
+    private static final int ENM = 0x2e;
+    private static final int EOC = 0x2f;
+
+    // Transparent Space
+    private static final char TS = '\u00A0';
+
+    // Captioning Modes
+    private static final int MODE_UNKNOWN = 0;
+    private static final int MODE_PAINT_ON = 1;
+    private static final int MODE_ROLL_UP = 2;
+    private static final int MODE_POP_ON = 3;
+    private static final int MODE_TEXT = 4;
+
+    private final DisplayListener mListener;
+
+    private int mMode = MODE_PAINT_ON;
+    private int mRollUpSize = 4;
+    private int mPrevCtrlCode = INVALID;
+
+    private CCMemory mDisplay = new CCMemory();
+    private CCMemory mNonDisplay = new CCMemory();
+    private CCMemory mTextMem = new CCMemory();
+
+    Cea608CCParser(DisplayListener listener) {
+        mListener = listener;
+    }
+
+    public void parse(byte[] data) {
+        CCData[] ccData = CCData.fromByteArray(data);
+
+        for (int i = 0; i < ccData.length; i++) {
+            if (DEBUG) {
+                Log.d(TAG, ccData[i].toString());
+            }
+
+            if (handleCtrlCode(ccData[i])
+                    || handleTabOffsets(ccData[i])
+                    || handlePACCode(ccData[i])
+                    || handleMidRowCode(ccData[i])) {
+                continue;
+            }
+
+            handleDisplayableChars(ccData[i]);
+        }
+    }
+
+    interface DisplayListener {
+        void onDisplayChanged(SpannableStringBuilder[] styledTexts);
+        CaptionStyle getCaptionStyle();
+    }
+
+    private CCMemory getMemory() {
+        // get the CC memory to operate on for current mode
+        switch (mMode) {
+        case MODE_POP_ON:
+            return mNonDisplay;
+        case MODE_TEXT:
+            // TODO(chz): support only caption mode for now,
+            // in text mode, dump everything to text mem.
+            return mTextMem;
+        case MODE_PAINT_ON:
+        case MODE_ROLL_UP:
+            return mDisplay;
+        default:
+            Log.w(TAG, "unrecoginized mode: " + mMode);
+        }
+        return mDisplay;
+    }
+
+    private boolean handleDisplayableChars(CCData ccData) {
+        if (!ccData.isDisplayableChar()) {
+            return false;
+        }
+
+        // Extended char includes 1 automatic backspace
+        if (ccData.isExtendedChar()) {
+            getMemory().bs();
+        }
+
+        getMemory().writeText(ccData.getDisplayText());
+
+        if (mMode == MODE_PAINT_ON || mMode == MODE_ROLL_UP) {
+            updateDisplay();
+        }
+
+        return true;
+    }
+
+    private boolean handleMidRowCode(CCData ccData) {
+        StyleCode m = ccData.getMidRow();
+        if (m != null) {
+            getMemory().writeMidRowCode(m);
+            return true;
+        }
+        return false;
+    }
+
+    private boolean handlePACCode(CCData ccData) {
+        PAC pac = ccData.getPAC();
+
+        if (pac != null) {
+            if (mMode == MODE_ROLL_UP) {
+                getMemory().moveBaselineTo(pac.getRow(), mRollUpSize);
+            }
+            getMemory().writePAC(pac);
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean handleTabOffsets(CCData ccData) {
+        int tabs = ccData.getTabOffset();
+
+        if (tabs > 0) {
+            getMemory().tab(tabs);
+            return true;
+        }
+
+        return false;
+    }
+
+    private boolean handleCtrlCode(CCData ccData) {
+        int ctrlCode = ccData.getCtrlCode();
+
+        if (mPrevCtrlCode != INVALID && mPrevCtrlCode == ctrlCode) {
+            // discard double ctrl codes (but if there's a 3rd one, we still take that)
+            mPrevCtrlCode = INVALID;
+            return true;
+        }
+
+        switch(ctrlCode) {
+        case RCL:
+            // select pop-on style
+            mMode = MODE_POP_ON;
+            break;
+        case BS:
+            getMemory().bs();
+            break;
+        case DER:
+            getMemory().der();
+            break;
+        case RU2:
+        case RU3:
+        case RU4:
+            mRollUpSize = (ctrlCode - 0x23);
+            // erase memory if currently in other style
+            if (mMode != MODE_ROLL_UP) {
+                mDisplay.erase();
+                mNonDisplay.erase();
+            }
+            // select roll-up style
+            mMode = MODE_ROLL_UP;
+            break;
+        case FON:
+            Log.i(TAG, "Flash On");
+            break;
+        case RDC:
+            // select paint-on style
+            mMode = MODE_PAINT_ON;
+            break;
+        case TR:
+            mMode = MODE_TEXT;
+            mTextMem.erase();
+            break;
+        case RTD:
+            mMode = MODE_TEXT;
+            break;
+        case EDM:
+            // erase display memory
+            mDisplay.erase();
+            updateDisplay();
+            break;
+        case CR:
+            if (mMode == MODE_ROLL_UP) {
+                getMemory().rollUp(mRollUpSize);
+            } else {
+                getMemory().cr();
+            }
+            if (mMode == MODE_ROLL_UP) {
+                updateDisplay();
+            }
+            break;
+        case ENM:
+            // erase non-display memory
+            mNonDisplay.erase();
+            break;
+        case EOC:
+            // swap display/non-display memory
+            swapMemory();
+            // switch to pop-on style
+            mMode = MODE_POP_ON;
+            updateDisplay();
+            break;
+        case INVALID:
+        default:
+            mPrevCtrlCode = INVALID;
+            return false;
+        }
+
+        mPrevCtrlCode = ctrlCode;
+
+        // handled
+        return true;
+    }
+
+    private void updateDisplay() {
+        if (mListener != null) {
+            CaptionStyle captionStyle = mListener.getCaptionStyle();
+            mListener.onDisplayChanged(mDisplay.getStyledText(captionStyle));
+        }
+    }
+
+    private void swapMemory() {
+        CCMemory temp = mDisplay;
+        mDisplay = mNonDisplay;
+        mNonDisplay = temp;
+    }
+
+    private static class StyleCode {
+        static final int COLOR_WHITE = 0;
+        static final int COLOR_GREEN = 1;
+        static final int COLOR_BLUE = 2;
+        static final int COLOR_CYAN = 3;
+        static final int COLOR_RED = 4;
+        static final int COLOR_YELLOW = 5;
+        static final int COLOR_MAGENTA = 6;
+        static final int COLOR_INVALID = 7;
+
+        static final int STYLE_ITALICS   = 0x00000001;
+        static final int STYLE_UNDERLINE = 0x00000002;
+
+        static final String[] mColorMap = {
+            "WHITE", "GREEN", "BLUE", "CYAN", "RED", "YELLOW", "MAGENTA", "INVALID"
+        };
+
+        final int mStyle;
+        final int mColor;
+
+        static StyleCode fromByte(byte data2) {
+            int style = 0;
+            int color = (data2 >> 1) & 0x7;
+
+            if ((data2 & 0x1) != 0) {
+                style |= STYLE_UNDERLINE;
+            }
+
+            if (color == COLOR_INVALID) {
+                // WHITE ITALICS
+                color = COLOR_WHITE;
+                style |= STYLE_ITALICS;
+            }
+
+            return new StyleCode(style, color);
+        }
+
+        StyleCode(int style, int color) {
+            mStyle = style;
+            mColor = color;
+        }
+
+        boolean isItalics() {
+            return (mStyle & STYLE_ITALICS) != 0;
+        }
+
+        boolean isUnderline() {
+            return (mStyle & STYLE_UNDERLINE) != 0;
+        }
+
+        int getColor() {
+            return mColor;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder str = new StringBuilder();
+            str.append("{");
+            str.append(mColorMap[mColor]);
+            if ((mStyle & STYLE_ITALICS) != 0) {
+                str.append(", ITALICS");
+            }
+            if ((mStyle & STYLE_UNDERLINE) != 0) {
+                str.append(", UNDERLINE");
+            }
+            str.append("}");
+
+            return str.toString();
+        }
+    }
+
+    private static class PAC extends StyleCode {
+        final int mRow;
+        final int mCol;
+
+        static PAC fromBytes(byte data1, byte data2) {
+            int[] rowTable = {11, 1, 3, 12, 14, 5, 7, 9};
+            int row = rowTable[data1 & 0x07] + ((data2 & 0x20) >> 5);
+            int style = 0;
+            if ((data2 & 1) != 0) {
+                style |= STYLE_UNDERLINE;
+            }
+            if ((data2 & 0x10) != 0) {
+                // indent code
+                int indent = (data2 >> 1) & 0x7;
+                return new PAC(row, indent * 4, style, COLOR_WHITE);
+            } else {
+                // style code
+                int color = (data2 >> 1) & 0x7;
+
+                if (color == COLOR_INVALID) {
+                    // WHITE ITALICS
+                    color = COLOR_WHITE;
+                    style |= STYLE_ITALICS;
+                }
+                return new PAC(row, -1, style, color);
+            }
+        }
+
+        PAC(int row, int col, int style, int color) {
+            super(style, color);
+            mRow = row;
+            mCol = col;
+        }
+
+        boolean isIndentPAC() {
+            return (mCol >= 0);
+        }
+
+        int getRow() {
+            return mRow;
+        }
+
+        int getCol() {
+            return mCol;
+        }
+
+        @Override
+        public String toString() {
+            return String.format("{%d, %d}, %s",
+                    mRow, mCol, super.toString());
+        }
+    }
+
+    /**
+     * Mutable version of BackgroundSpan to facilitate text rendering with edge styles.
+     *
+     * @hide
+     */
+    public static class MutableBackgroundColorSpan extends CharacterStyle
+            implements UpdateAppearance {
+        private int mColor;
+
+        public MutableBackgroundColorSpan(int color) {
+            mColor = color;
+        }
+
+        public void setBackgroundColor(int color) {
+            mColor = color;
+        }
+
+        public int getBackgroundColor() {
+            return mColor;
+        }
+
+        @Override
+        public void updateDrawState(TextPaint ds) {
+            ds.bgColor = mColor;
+        }
+    }
+
+    /* CCLineBuilder keeps track of displayable chars, as well as
+     * MidRow styles and PACs, for a single line of CC memory.
+     *
+     * It generates styled text via getStyledText() method.
+     */
+    private static class CCLineBuilder {
+        private final StringBuilder mDisplayChars;
+        private final StyleCode[] mMidRowStyles;
+        private final StyleCode[] mPACStyles;
+
+        CCLineBuilder(String str) {
+            mDisplayChars = new StringBuilder(str);
+            mMidRowStyles = new StyleCode[mDisplayChars.length()];
+            mPACStyles = new StyleCode[mDisplayChars.length()];
+        }
+
+        void setCharAt(int index, char ch) {
+            mDisplayChars.setCharAt(index, ch);
+            mMidRowStyles[index] = null;
+        }
+
+        void setMidRowAt(int index, StyleCode m) {
+            mDisplayChars.setCharAt(index, ' ');
+            mMidRowStyles[index] = m;
+        }
+
+        void setPACAt(int index, PAC pac) {
+            mPACStyles[index] = pac;
+        }
+
+        char charAt(int index) {
+            return mDisplayChars.charAt(index);
+        }
+
+        int length() {
+            return mDisplayChars.length();
+        }
+
+        void applyStyleSpan(
+                SpannableStringBuilder styledText,
+                StyleCode s, int start, int end) {
+            if (s.isItalics()) {
+                styledText.setSpan(
+                        new StyleSpan(android.graphics.Typeface.ITALIC),
+                        start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+            }
+            if (s.isUnderline()) {
+                styledText.setSpan(
+                        new UnderlineSpan(),
+                        start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+            }
+        }
+
+        SpannableStringBuilder getStyledText(CaptionStyle captionStyle) {
+            SpannableStringBuilder styledText = new SpannableStringBuilder(mDisplayChars);
+            int start = -1, next = 0;
+            int styleStart = -1;
+            StyleCode curStyle = null;
+            while (next < mDisplayChars.length()) {
+                StyleCode newStyle = null;
+                if (mMidRowStyles[next] != null) {
+                    // apply mid-row style change
+                    newStyle = mMidRowStyles[next];
+                } else if (mPACStyles[next] != null
+                    && (styleStart < 0 || start < 0)) {
+                    // apply PAC style change, only if:
+                    // 1. no style set, or
+                    // 2. style set, but prev char is none-displayable
+                    newStyle = mPACStyles[next];
+                }
+                if (newStyle != null) {
+                    curStyle = newStyle;
+                    if (styleStart >= 0 && start >= 0) {
+                        applyStyleSpan(styledText, newStyle, styleStart, next);
+                    }
+                    styleStart = next;
+                }
+
+                if (mDisplayChars.charAt(next) != TS) {
+                    if (start < 0) {
+                        start = next;
+                    }
+                } else if (start >= 0) {
+                    int expandedStart = mDisplayChars.charAt(start) == ' ' ? start : start - 1;
+                    int expandedEnd = mDisplayChars.charAt(next - 1) == ' ' ? next : next + 1;
+                    styledText.setSpan(
+                            new MutableBackgroundColorSpan(captionStyle.backgroundColor),
+                            expandedStart, expandedEnd,
+                            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
+                    if (styleStart >= 0) {
+                        applyStyleSpan(styledText, curStyle, styleStart, expandedEnd);
+                    }
+                    start = -1;
+                }
+                next++;
+            }
+
+            return styledText;
+        }
+    }
+
+    /*
+     * CCMemory models a console-style display.
+     */
+    private static class CCMemory {
+        private final String mBlankLine;
+        private final CCLineBuilder[] mLines = new CCLineBuilder[MAX_ROWS + 2];
+        private int mRow;
+        private int mCol;
+
+        CCMemory() {
+            char[] blank = new char[MAX_COLS + 2];
+            Arrays.fill(blank, TS);
+            mBlankLine = new String(blank);
+        }
+
+        void erase() {
+            // erase all lines
+            for (int i = 0; i < mLines.length; i++) {
+                mLines[i] = null;
+            }
+            mRow = MAX_ROWS;
+            mCol = 1;
+        }
+
+        void der() {
+            if (mLines[mRow] != null) {
+                for (int i = 0; i < mCol; i++) {
+                    if (mLines[mRow].charAt(i) != TS) {
+                        for (int j = mCol; j < mLines[mRow].length(); j++) {
+                            mLines[j].setCharAt(j, TS);
+                        }
+                        return;
+                    }
+                }
+                mLines[mRow] = null;
+            }
+        }
+
+        void tab(int tabs) {
+            moveCursorByCol(tabs);
+        }
+
+        void bs() {
+            moveCursorByCol(-1);
+            if (mLines[mRow] != null) {
+                mLines[mRow].setCharAt(mCol, TS);
+                if (mCol == MAX_COLS - 1) {
+                    // Spec recommendation:
+                    // if cursor was at col 32, move cursor
+                    // back to col 31 and erase both col 31&32
+                    mLines[mRow].setCharAt(MAX_COLS, TS);
+                }
+            }
+        }
+
+        void cr() {
+            moveCursorTo(mRow + 1, 1);
+        }
+
+        void rollUp(int windowSize) {
+            int i;
+            for (i = 0; i <= mRow - windowSize; i++) {
+                mLines[i] = null;
+            }
+            int startRow = mRow - windowSize + 1;
+            if (startRow < 1) {
+                startRow = 1;
+            }
+            for (i = startRow; i < mRow; i++) {
+                mLines[i] = mLines[i + 1];
+            }
+            for (i = mRow; i < mLines.length; i++) {
+                // clear base row
+                mLines[i] = null;
+            }
+            // default to col 1, in case PAC is not sent
+            mCol = 1;
+        }
+
+        void writeText(String text) {
+            for (int i = 0; i < text.length(); i++) {
+                getLineBuffer(mRow).setCharAt(mCol, text.charAt(i));
+                moveCursorByCol(1);
+            }
+        }
+
+        void writeMidRowCode(StyleCode m) {
+            getLineBuffer(mRow).setMidRowAt(mCol, m);
+            moveCursorByCol(1);
+        }
+
+        void writePAC(PAC pac) {
+            if (pac.isIndentPAC()) {
+                moveCursorTo(pac.getRow(), pac.getCol());
+            } else {
+                moveCursorTo(pac.getRow(), 1);
+            }
+            getLineBuffer(mRow).setPACAt(mCol, pac);
+        }
+
+        SpannableStringBuilder[] getStyledText(CaptionStyle captionStyle) {
+            ArrayList<SpannableStringBuilder> rows = new ArrayList<>(MAX_ROWS);
+            for (int i = 1; i <= MAX_ROWS; i++) {
+                rows.add(mLines[i] != null ?
+                        mLines[i].getStyledText(captionStyle) : null);
+            }
+            return rows.toArray(new SpannableStringBuilder[MAX_ROWS]);
+        }
+
+        private static int clamp(int x, int min, int max) {
+            return x < min ? min : (x > max ? max : x);
+        }
+
+        private void moveCursorTo(int row, int col) {
+            mRow = clamp(row, 1, MAX_ROWS);
+            mCol = clamp(col, 1, MAX_COLS);
+        }
+
+        private void moveCursorToRow(int row) {
+            mRow = clamp(row, 1, MAX_ROWS);
+        }
+
+        private void moveCursorByCol(int col) {
+            mCol = clamp(mCol + col, 1, MAX_COLS);
+        }
+
+        private void moveBaselineTo(int baseRow, int windowSize) {
+            if (mRow == baseRow) {
+                return;
+            }
+            int actualWindowSize = windowSize;
+            if (baseRow < actualWindowSize) {
+                actualWindowSize = baseRow;
+            }
+            if (mRow < actualWindowSize) {
+                actualWindowSize = mRow;
+            }
+
+            int i;
+            if (baseRow < mRow) {
+                // copy from bottom to top row
+                for (i = actualWindowSize - 1; i >= 0; i--) {
+                    mLines[baseRow - i] = mLines[mRow - i];
+                }
+            } else {
+                // copy from top to bottom row
+                for (i = 0; i < actualWindowSize; i++) {
+                    mLines[baseRow - i] = mLines[mRow - i];
+                }
+            }
+            // clear rest of the rows
+            for (i = 0; i <= baseRow - windowSize; i++) {
+                mLines[i] = null;
+            }
+            for (i = baseRow + 1; i < mLines.length; i++) {
+                mLines[i] = null;
+            }
+        }
+
+        private CCLineBuilder getLineBuffer(int row) {
+            if (mLines[row] == null) {
+                mLines[row] = new CCLineBuilder(mBlankLine);
+            }
+            return mLines[row];
+        }
+    }
+
+    /*
+     * CCData parses the raw CC byte pair into displayable chars,
+     * misc control codes, Mid-Row or Preamble Address Codes.
+     */
+    private static class CCData {
+        private final byte mType;
+        private final byte mData1;
+        private final byte mData2;
+
+        private static final String[] mCtrlCodeMap = {
+            "RCL", "BS" , "AOF", "AON",
+            "DER", "RU2", "RU3", "RU4",
+            "FON", "RDC", "TR" , "RTD",
+            "EDM", "CR" , "ENM", "EOC",
+        };
+
+        private static final String[] mSpecialCharMap = {
+            "\u00AE",
+            "\u00B0",
+            "\u00BD",
+            "\u00BF",
+            "\u2122",
+            "\u00A2",
+            "\u00A3",
+            "\u266A", // Eighth note
+            "\u00E0",
+            "\u00A0", // Transparent space
+            "\u00E8",
+            "\u00E2",
+            "\u00EA",
+            "\u00EE",
+            "\u00F4",
+            "\u00FB",
+        };
+
+        private static final String[] mSpanishCharMap = {
+            // Spanish and misc chars
+            "\u00C1", // A
+            "\u00C9", // E
+            "\u00D3", // I
+            "\u00DA", // O
+            "\u00DC", // U
+            "\u00FC", // u
+            "\u2018", // opening single quote
+            "\u00A1", // inverted exclamation mark
+            "*",
+            "'",
+            "\u2014", // em dash
+            "\u00A9", // Copyright
+            "\u2120", // Servicemark
+            "\u2022", // round bullet
+            "\u201C", // opening double quote
+            "\u201D", // closing double quote
+            // French
+            "\u00C0",
+            "\u00C2",
+            "\u00C7",
+            "\u00C8",
+            "\u00CA",
+            "\u00CB",
+            "\u00EB",
+            "\u00CE",
+            "\u00CF",
+            "\u00EF",
+            "\u00D4",
+            "\u00D9",
+            "\u00F9",
+            "\u00DB",
+            "\u00AB",
+            "\u00BB"
+        };
+
+        private static final String[] mProtugueseCharMap = {
+            // Portuguese
+            "\u00C3",
+            "\u00E3",
+            "\u00CD",
+            "\u00CC",
+            "\u00EC",
+            "\u00D2",
+            "\u00F2",
+            "\u00D5",
+            "\u00F5",
+            "{",
+            "}",
+            "\\",
+            "^",
+            "_",
+            "|",
+            "~",
+            // German and misc chars
+            "\u00C4",
+            "\u00E4",
+            "\u00D6",
+            "\u00F6",
+            "\u00DF",
+            "\u00A5",
+            "\u00A4",
+            "\u2502", // vertical bar
+            "\u00C5",
+            "\u00E5",
+            "\u00D8",
+            "\u00F8",
+            "\u250C", // top-left corner
+            "\u2510", // top-right corner
+            "\u2514", // lower-left corner
+            "\u2518", // lower-right corner
+        };
+
+        static CCData[] fromByteArray(byte[] data) {
+            CCData[] ccData = new CCData[data.length / 3];
+
+            for (int i = 0; i < ccData.length; i++) {
+                ccData[i] = new CCData(
+                        data[i * 3],
+                        data[i * 3 + 1],
+                        data[i * 3 + 2]);
+            }
+
+            return ccData;
+        }
+
+        CCData(byte type, byte data1, byte data2) {
+            mType = type;
+            mData1 = data1;
+            mData2 = data2;
+        }
+
+        int getCtrlCode() {
+            if ((mData1 == 0x14 || mData1 == 0x1c)
+                    && mData2 >= 0x20 && mData2 <= 0x2f) {
+                return mData2;
+            }
+            return INVALID;
+        }
+
+        StyleCode getMidRow() {
+            // only support standard Mid-row codes, ignore
+            // optional background/foreground mid-row codes
+            if ((mData1 == 0x11 || mData1 == 0x19)
+                    && mData2 >= 0x20 && mData2 <= 0x2f) {
+                return StyleCode.fromByte(mData2);
+            }
+            return null;
+        }
+
+        PAC getPAC() {
+            if ((mData1 & 0x70) == 0x10
+                    && (mData2 & 0x40) == 0x40
+                    && ((mData1 & 0x07) != 0 || (mData2 & 0x20) == 0)) {
+                return PAC.fromBytes(mData1, mData2);
+            }
+            return null;
+        }
+
+        int getTabOffset() {
+            if ((mData1 == 0x17 || mData1 == 0x1f)
+                    && mData2 >= 0x21 && mData2 <= 0x23) {
+                return mData2 & 0x3;
+            }
+            return 0;
+        }
+
+        boolean isDisplayableChar() {
+            return isBasicChar() || isSpecialChar() || isExtendedChar();
+        }
+
+        String getDisplayText() {
+            String str = getBasicChars();
+
+            if (str == null) {
+                str =  getSpecialChar();
+
+                if (str == null) {
+                    str = getExtendedChar();
+                }
+            }
+
+            return str;
+        }
+
+        private String ctrlCodeToString(int ctrlCode) {
+            return mCtrlCodeMap[ctrlCode - 0x20];
+        }
+
+        private boolean isBasicChar() {
+            return mData1 >= 0x20 && mData1 <= 0x7f;
+        }
+
+        private boolean isSpecialChar() {
+            return ((mData1 == 0x11 || mData1 == 0x19)
+                    && mData2 >= 0x30 && mData2 <= 0x3f);
+        }
+
+        private boolean isExtendedChar() {
+            return ((mData1 == 0x12 || mData1 == 0x1A
+                    || mData1 == 0x13 || mData1 == 0x1B)
+                    && mData2 >= 0x20 && mData2 <= 0x3f);
+        }
+
+        private char getBasicChar(byte data) {
+            char c;
+            // replace the non-ASCII ones
+            switch (data) {
+                case 0x2A: c = '\u00E1'; break;
+                case 0x5C: c = '\u00E9'; break;
+                case 0x5E: c = '\u00ED'; break;
+                case 0x5F: c = '\u00F3'; break;
+                case 0x60: c = '\u00FA'; break;
+                case 0x7B: c = '\u00E7'; break;
+                case 0x7C: c = '\u00F7'; break;
+                case 0x7D: c = '\u00D1'; break;
+                case 0x7E: c = '\u00F1'; break;
+                case 0x7F: c = '\u2588'; break; // Full block
+                default: c = (char) data; break;
+            }
+            return c;
+        }
+
+        private String getBasicChars() {
+            if (mData1 >= 0x20 && mData1 <= 0x7f) {
+                StringBuilder builder = new StringBuilder(2);
+                builder.append(getBasicChar(mData1));
+                if (mData2 >= 0x20 && mData2 <= 0x7f) {
+                    builder.append(getBasicChar(mData2));
+                }
+                return builder.toString();
+            }
+
+            return null;
+        }
+
+        private String getSpecialChar() {
+            if ((mData1 == 0x11 || mData1 == 0x19)
+                    && mData2 >= 0x30 && mData2 <= 0x3f) {
+                return mSpecialCharMap[mData2 - 0x30];
+            }
+
+            return null;
+        }
+
+        private String getExtendedChar() {
+            if ((mData1 == 0x12 || mData1 == 0x1A)
+                    && mData2 >= 0x20 && mData2 <= 0x3f){
+                // 1 Spanish/French char
+                return mSpanishCharMap[mData2 - 0x20];
+            } else if ((mData1 == 0x13 || mData1 == 0x1B)
+                    && mData2 >= 0x20 && mData2 <= 0x3f){
+                // 1 Portuguese/German/Danish char
+                return mProtugueseCharMap[mData2 - 0x20];
+            }
+
+            return null;
+        }
+
+        @Override
+        public String toString() {
+            String str;
+
+            if (mData1 < 0x10 && mData2 < 0x10) {
+                // Null Pad, ignore
+                return String.format("[%d]Null: %02x %02x", mType, mData1, mData2);
+            }
+
+            int ctrlCode = getCtrlCode();
+            if (ctrlCode != INVALID) {
+                return String.format("[%d]%s", mType, ctrlCodeToString(ctrlCode));
+            }
+
+            int tabOffset = getTabOffset();
+            if (tabOffset > 0) {
+                return String.format("[%d]Tab%d", mType, tabOffset);
+            }
+
+            PAC pac = getPAC();
+            if (pac != null) {
+                return String.format("[%d]PAC: %s", mType, pac.toString());
+            }
+
+            StyleCode m = getMidRow();
+            if (m != null) {
+                return String.format("[%d]Mid-row: %s", mType, m.toString());
+            }
+
+            if (isDisplayableChar()) {
+                return String.format("[%d]Displayable: %s (%02x %02x)",
+                        mType, getDisplayText(), mData1, mData2);
+            }
+
+            return String.format("[%d]Invalid: %02x %02x", mType, mData1, mData2);
+        }
+    }
+}
+
+/**
+ * Widget capable of rendering CEA-608 closed captions.
+ *
+ * @hide
+ */
+class Cea608CCWidget extends ClosedCaptionWidget implements Cea608CCParser.DisplayListener {
+    private static final Rect mTextBounds = new Rect();
+    private static final String mDummyText = "1234567890123456789012345678901234";
+
+    public Cea608CCWidget(Context context) {
+        this(context, null);
+    }
+
+    public Cea608CCWidget(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public Cea608CCWidget(Context context, AttributeSet attrs, int defStyle) {
+        this(context, attrs, defStyle, 0);
+    }
+
+    public Cea608CCWidget(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+    }
+
+    @Override
+    public ClosedCaptionLayout createCaptionLayout(Context context) {
+        return new CCLayout(context);
+    }
+
+    @Override
+    public void onDisplayChanged(SpannableStringBuilder[] styledTexts) {
+        ((CCLayout) mClosedCaptionLayout).update(styledTexts);
+
+        if (mListener != null) {
+            mListener.onChanged(this);
+        }
+    }
+
+    @Override
+    public CaptionStyle getCaptionStyle() {
+        return mCaptionStyle;
+    }
+
+    private static class CCLineBox extends TextView {
+        private static final float FONT_PADDING_RATIO = 0.75f;
+        private static final float EDGE_OUTLINE_RATIO = 0.1f;
+        private static final float EDGE_SHADOW_RATIO = 0.05f;
+        private float mOutlineWidth;
+        private float mShadowRadius;
+        private float mShadowOffset;
+
+        private int mTextColor = Color.WHITE;
+        private int mBgColor = Color.BLACK;
+        private int mEdgeType = CaptionStyle.EDGE_TYPE_NONE;
+        private int mEdgeColor = Color.TRANSPARENT;
+
+        CCLineBox(Context context) {
+            super(context);
+            setGravity(Gravity.CENTER);
+            setBackgroundColor(Color.TRANSPARENT);
+            setTextColor(Color.WHITE);
+            setTypeface(Typeface.MONOSPACE);
+            setVisibility(View.INVISIBLE);
+
+            final Resources res = getContext().getResources();
+
+            // get the default (will be updated later during measure)
+            mOutlineWidth = res.getDimensionPixelSize(
+                    com.android.internal.R.dimen.subtitle_outline_width);
+            mShadowRadius = res.getDimensionPixelSize(
+                    com.android.internal.R.dimen.subtitle_shadow_radius);
+            mShadowOffset = res.getDimensionPixelSize(
+                    com.android.internal.R.dimen.subtitle_shadow_offset);
+        }
+
+        void setCaptionStyle(CaptionStyle captionStyle) {
+            mTextColor = captionStyle.foregroundColor;
+            mBgColor = captionStyle.backgroundColor;
+            mEdgeType = captionStyle.edgeType;
+            mEdgeColor = captionStyle.edgeColor;
+
+            setTextColor(mTextColor);
+            if (mEdgeType == CaptionStyle.EDGE_TYPE_DROP_SHADOW) {
+                setShadowLayer(mShadowRadius, mShadowOffset, mShadowOffset, mEdgeColor);
+            } else {
+                setShadowLayer(0, 0, 0, 0);
+            }
+            invalidate();
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            float fontSize = MeasureSpec.getSize(heightMeasureSpec) * FONT_PADDING_RATIO;
+            setTextSize(TypedValue.COMPLEX_UNIT_PX, fontSize);
+
+            mOutlineWidth = EDGE_OUTLINE_RATIO * fontSize + 1.0f;
+            mShadowRadius = EDGE_SHADOW_RATIO * fontSize + 1.0f;;
+            mShadowOffset = mShadowRadius;
+
+            // set font scale in the X direction to match the required width
+            setScaleX(1.0f);
+            getPaint().getTextBounds(mDummyText, 0, mDummyText.length(), mTextBounds);
+            float actualTextWidth = mTextBounds.width();
+            float requiredTextWidth = MeasureSpec.getSize(widthMeasureSpec);
+            setScaleX(requiredTextWidth / actualTextWidth);
+
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        }
+
+        @Override
+        protected void onDraw(Canvas c) {
+            if (mEdgeType == CaptionStyle.EDGE_TYPE_UNSPECIFIED
+                    || mEdgeType == CaptionStyle.EDGE_TYPE_NONE
+                    || mEdgeType == CaptionStyle.EDGE_TYPE_DROP_SHADOW) {
+                // these edge styles don't require a second pass
+                super.onDraw(c);
+                return;
+            }
+
+            if (mEdgeType == CaptionStyle.EDGE_TYPE_OUTLINE) {
+                drawEdgeOutline(c);
+            } else {
+                // Raised or depressed
+                drawEdgeRaisedOrDepressed(c);
+            }
+        }
+
+        private void drawEdgeOutline(Canvas c) {
+            TextPaint textPaint = getPaint();
+
+            Paint.Style previousStyle = textPaint.getStyle();
+            Paint.Join previousJoin = textPaint.getStrokeJoin();
+            float previousWidth = textPaint.getStrokeWidth();
+
+            setTextColor(mEdgeColor);
+            textPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+            textPaint.setStrokeJoin(Paint.Join.ROUND);
+            textPaint.setStrokeWidth(mOutlineWidth);
+
+            // Draw outline and background only.
+            super.onDraw(c);
+
+            // Restore original settings.
+            setTextColor(mTextColor);
+            textPaint.setStyle(previousStyle);
+            textPaint.setStrokeJoin(previousJoin);
+            textPaint.setStrokeWidth(previousWidth);
+
+            // Remove the background.
+            setBackgroundSpans(Color.TRANSPARENT);
+            // Draw foreground only.
+            super.onDraw(c);
+            // Restore the background.
+            setBackgroundSpans(mBgColor);
+        }
+
+        private void drawEdgeRaisedOrDepressed(Canvas c) {
+            TextPaint textPaint = getPaint();
+
+            Paint.Style previousStyle = textPaint.getStyle();
+            textPaint.setStyle(Paint.Style.FILL);
+
+            final boolean raised = mEdgeType == CaptionStyle.EDGE_TYPE_RAISED;
+            final int colorUp = raised ? Color.WHITE : mEdgeColor;
+            final int colorDown = raised ? mEdgeColor : Color.WHITE;
+            final float offset = mShadowRadius / 2f;
+
+            // Draw background and text with shadow up
+            setShadowLayer(mShadowRadius, -offset, -offset, colorUp);
+            super.onDraw(c);
+
+            // Remove the background.
+            setBackgroundSpans(Color.TRANSPARENT);
+
+            // Draw text with shadow down
+            setShadowLayer(mShadowRadius, +offset, +offset, colorDown);
+            super.onDraw(c);
+
+            // Restore settings
+            textPaint.setStyle(previousStyle);
+
+            // Restore the background.
+            setBackgroundSpans(mBgColor);
+        }
+
+        private void setBackgroundSpans(int color) {
+            CharSequence text = getText();
+            if (text instanceof Spannable) {
+                Spannable spannable = (Spannable) text;
+                Cea608CCParser.MutableBackgroundColorSpan[] bgSpans = spannable.getSpans(
+                        0, spannable.length(), Cea608CCParser.MutableBackgroundColorSpan.class);
+                for (int i = 0; i < bgSpans.length; i++) {
+                    bgSpans[i].setBackgroundColor(color);
+                }
+            }
+        }
+    }
+
+    private static class CCLayout extends LinearLayout implements ClosedCaptionLayout {
+        private static final int MAX_ROWS = Cea608CCParser.MAX_ROWS;
+        private static final float SAFE_AREA_RATIO = 0.9f;
+
+        private final CCLineBox[] mLineBoxes = new CCLineBox[MAX_ROWS];
+
+        CCLayout(Context context) {
+            super(context);
+            setGravity(Gravity.START);
+            setOrientation(LinearLayout.VERTICAL);
+            for (int i = 0; i < MAX_ROWS; i++) {
+                mLineBoxes[i] = new CCLineBox(getContext());
+                addView(mLineBoxes[i], LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+            }
+        }
+
+        @Override
+        public void setCaptionStyle(CaptionStyle captionStyle) {
+            for (int i = 0; i < MAX_ROWS; i++) {
+                mLineBoxes[i].setCaptionStyle(captionStyle);
+            }
+        }
+
+        @Override
+        public void setFontScale(float fontScale) {
+            // Ignores the font scale changes of the system wide CC preference.
+        }
+
+        void update(SpannableStringBuilder[] textBuffer) {
+            for (int i = 0; i < MAX_ROWS; i++) {
+                if (textBuffer[i] != null) {
+                    mLineBoxes[i].setText(textBuffer[i], TextView.BufferType.SPANNABLE);
+                    mLineBoxes[i].setVisibility(View.VISIBLE);
+                } else {
+                    mLineBoxes[i].setVisibility(View.INVISIBLE);
+                }
+            }
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+            int safeWidth = getMeasuredWidth();
+            int safeHeight = getMeasuredHeight();
+
+            // CEA-608 assumes 4:3 video
+            if (safeWidth * 3 >= safeHeight * 4) {
+                safeWidth = safeHeight * 4 / 3;
+            } else {
+                safeHeight = safeWidth * 3 / 4;
+            }
+            safeWidth *= SAFE_AREA_RATIO;
+            safeHeight *= SAFE_AREA_RATIO;
+
+            int lineHeight = safeHeight / MAX_ROWS;
+            int lineHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+                    lineHeight, MeasureSpec.EXACTLY);
+            int lineWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+                    safeWidth, MeasureSpec.EXACTLY);
+
+            for (int i = 0; i < MAX_ROWS; i++) {
+                mLineBoxes[i].measure(lineWidthMeasureSpec, lineHeightMeasureSpec);
+            }
+        }
+
+        @Override
+        protected void onLayout(boolean changed, int l, int t, int r, int b) {
+            // safe caption area
+            int viewPortWidth = r - l;
+            int viewPortHeight = b - t;
+            int safeWidth, safeHeight;
+            // CEA-608 assumes 4:3 video
+            if (viewPortWidth * 3 >= viewPortHeight * 4) {
+                safeWidth = viewPortHeight * 4 / 3;
+                safeHeight = viewPortHeight;
+            } else {
+                safeWidth = viewPortWidth;
+                safeHeight = viewPortWidth * 3 / 4;
+            }
+            safeWidth *= SAFE_AREA_RATIO;
+            safeHeight *= SAFE_AREA_RATIO;
+            int left = (viewPortWidth - safeWidth) / 2;
+            int top = (viewPortHeight - safeHeight) / 2;
+
+            for (int i = 0; i < MAX_ROWS; i++) {
+                mLineBoxes[i].layout(
+                        left,
+                        top + safeHeight * i / MAX_ROWS,
+                        left + safeWidth,
+                        top + safeHeight * (i + 1) / MAX_ROWS);
+            }
+        }
+    }
+}
diff --git a/android/media/Controller2Link.java b/android/media/Controller2Link.java
new file mode 100644
index 0000000..8eefec7
--- /dev/null
+++ b/android/media/Controller2Link.java
@@ -0,0 +1,216 @@
+/*
+ * 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.os.Binder;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+
+import java.util.Objects;
+
+/**
+ * Handles incoming commands from {@link MediaSession2} to {@link MediaController2}.
+ * @hide
+ */
+// @SystemApi
+public final class Controller2Link implements Parcelable {
+    private static final String TAG = "Controller2Link";
+    private static final boolean DEBUG = MediaController2.DEBUG;
+
+    public static final @android.annotation.NonNull Parcelable.Creator<Controller2Link> CREATOR =
+            new Parcelable.Creator<Controller2Link>() {
+                @Override
+                public Controller2Link createFromParcel(Parcel in) {
+                    return new Controller2Link(in);
+                }
+
+                @Override
+                public Controller2Link[] newArray(int size) {
+                    return new Controller2Link[size];
+                }
+            };
+
+
+    private final MediaController2 mController;
+    private final IMediaController2 mIController;
+
+    public Controller2Link(MediaController2 controller) {
+        mController = controller;
+        mIController = new Controller2Stub();
+    }
+
+    Controller2Link(Parcel in) {
+        mController = null;
+        mIController = IMediaController2.Stub.asInterface(in.readStrongBinder());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeStrongBinder(mIController.asBinder());
+    }
+
+    @Override
+    public int hashCode() {
+        return mIController.asBinder().hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Controller2Link)) {
+            return false;
+        }
+        Controller2Link other = (Controller2Link) obj;
+        return Objects.equals(mIController.asBinder(), other.mIController.asBinder());
+    }
+
+    /** Interface method for IMediaController2.notifyConnected */
+    public void notifyConnected(int seq, Bundle connectionResult) {
+        try {
+            mIController.notifyConnected(seq, connectionResult);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Interface method for IMediaController2.notifyDisonnected */
+    public void notifyDisconnected(int seq) {
+        try {
+            mIController.notifyDisconnected(seq);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Interface method for IMediaController2.notifyPlaybackActiveChanged */
+    public void notifyPlaybackActiveChanged(int seq, boolean playbackActive) {
+        try {
+            mIController.notifyPlaybackActiveChanged(seq, playbackActive);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Interface method for IMediaController2.sendSessionCommand */
+    public void sendSessionCommand(int seq, Session2Command command, Bundle args,
+            ResultReceiver resultReceiver) {
+        try {
+            mIController.sendSessionCommand(seq, command, args, resultReceiver);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Interface method for IMediaController2.cancelSessionCommand */
+    public void cancelSessionCommand(int seq) {
+        try {
+            mIController.cancelSessionCommand(seq);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Stub implementation for IMediaController2.notifyConnected */
+    public void onConnected(int seq, Bundle connectionResult) {
+        if (connectionResult == null) {
+            onDisconnected(seq);
+            return;
+        }
+        mController.onConnected(seq, connectionResult);
+    }
+
+    /** Stub implementation for IMediaController2.notifyDisonnected */
+    public void onDisconnected(int seq) {
+        mController.onDisconnected(seq);
+    }
+
+    /** Stub implementation for IMediaController2.notifyPlaybackActiveChanged */
+    public void onPlaybackActiveChanged(int seq, boolean playbackActive) {
+        mController.onPlaybackActiveChanged(seq, playbackActive);
+    }
+
+    /** Stub implementation for IMediaController2.sendSessionCommand */
+    public void onSessionCommand(int seq, Session2Command command, Bundle args,
+            ResultReceiver resultReceiver) {
+        mController.onSessionCommand(seq, command, args, resultReceiver);
+    }
+
+    /** Stub implementation for IMediaController2.cancelSessionCommand */
+    public void onCancelCommand(int seq) {
+        mController.onCancelCommand(seq);
+    }
+
+    private class Controller2Stub extends IMediaController2.Stub {
+        @Override
+        public void notifyConnected(int seq, Bundle connectionResult) {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                Controller2Link.this.onConnected(seq, connectionResult);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void notifyDisconnected(int seq) {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                Controller2Link.this.onDisconnected(seq);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void notifyPlaybackActiveChanged(int seq, boolean playbackActive) {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                Controller2Link.this.onPlaybackActiveChanged(seq, playbackActive);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void sendSessionCommand(int seq, Session2Command command, Bundle args,
+                ResultReceiver resultReceiver) {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                Controller2Link.this.onSessionCommand(seq, command, args, resultReceiver);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void cancelSessionCommand(int seq) {
+            final long token = Binder.clearCallingIdentity();
+            try {
+                Controller2Link.this.onCancelCommand(seq);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+    }
+}
diff --git a/android/media/DataSourceCallback.java b/android/media/DataSourceCallback.java
new file mode 100644
index 0000000..c297ecd
--- /dev/null
+++ b/android/media/DataSourceCallback.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2017 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.annotation.NonNull;
+
+import java.io.Closeable;
+import java.io.IOException;
+
+/**
+ * For supplying media data to the framework. Implement this if your app has
+ * special requirements for the way media data is obtained.
+ *
+ * <p class="note">Methods of this interface may be called on multiple different
+ * threads. There will be a thread synchronization point between each call to ensure that
+ * modifications to the state of your DataSourceCallback are visible to future calls. This means
+ * you don't need to do your own synchronization unless you're modifying the
+ * DataSourceCallback from another thread while it's being used by the framework.</p>
+ *
+ * @hide
+ */
+public abstract class DataSourceCallback implements Closeable {
+
+    public static final int END_OF_STREAM = -1;
+
+    /**
+     * Called to request data from the given position.
+     *
+     * Implementations should should write up to {@code size} bytes into
+     * {@code buffer}, and return the number of bytes written.
+     *
+     * Return {@code 0} if size is zero (thus no bytes are read).
+     *
+     * Return {@code -1} to indicate that end of stream is reached.
+     *
+     * @param position the position in the data source to read from.
+     * @param buffer the buffer to read the data into.
+     * @param offset the offset within buffer to read the data into.
+     * @param size the number of bytes to read.
+     * @throws IOException on fatal errors.
+     * @return the number of bytes read, or {@link #END_OF_STREAM} if end of stream is reached.
+     */
+    public abstract int readAt(long position, @NonNull byte[] buffer, int offset, int size)
+            throws IOException;
+
+    /**
+     * Called to get the size of the data source.
+     *
+     * @throws IOException on fatal errors
+     * @return the size of data source in bytes, or -1 if the size is unknown.
+     */
+    public abstract long getSize() throws IOException;
+}
diff --git a/android/media/DecoderCapabilities.java b/android/media/DecoderCapabilities.java
new file mode 100644
index 0000000..ebfc63b
--- /dev/null
+++ b/android/media/DecoderCapabilities.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2010 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.compat.annotation.UnsupportedAppUsage;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * {@hide}
+ *
+ * The DecoderCapabilities class is used to retrieve the types of the
+ * video and audio decoder(s) supported on a specific Android platform.
+ */
+public class DecoderCapabilities
+{
+    /**
+     * The VideoDecoder class represents the type of a video decoder
+     *
+     */
+    public enum VideoDecoder {
+        @UnsupportedAppUsage
+        VIDEO_DECODER_WMV,
+    };
+
+    /**
+     * The AudioDecoder class represents the type of an audio decoder
+     */
+    public enum AudioDecoder {
+        @UnsupportedAppUsage
+        AUDIO_DECODER_WMA,
+    };
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    /**
+     * Returns the list of video decoder types
+     * @see android.media.DecoderCapabilities.VideoDecoder
+     */
+    @UnsupportedAppUsage
+    public static List<VideoDecoder> getVideoDecoders() {
+        List<VideoDecoder> decoderList = new ArrayList<VideoDecoder>();
+        int nDecoders = native_get_num_video_decoders();
+        for (int i = 0; i < nDecoders; ++i) {
+            decoderList.add(VideoDecoder.values()[native_get_video_decoder_type(i)]);
+        }
+        return decoderList;
+    }
+
+    /**
+     * Returns the list of audio decoder types
+     * @see android.media.DecoderCapabilities.AudioDecoder
+     */
+    @UnsupportedAppUsage
+    public static List<AudioDecoder> getAudioDecoders() {
+        List<AudioDecoder> decoderList = new ArrayList<AudioDecoder>();
+        int nDecoders = native_get_num_audio_decoders();
+        for (int i = 0; i < nDecoders; ++i) {
+            decoderList.add(AudioDecoder.values()[native_get_audio_decoder_type(i)]);
+        }
+        return decoderList;
+    }
+
+    private DecoderCapabilities() {}  // Don't call me
+
+    // Implemented by JNI
+    private static native final void native_init();
+    private static native final int native_get_num_video_decoders();
+    private static native final int native_get_video_decoder_type(int index);
+    private static native final int native_get_num_audio_decoders();
+    private static native final int native_get_audio_decoder_type(int index);
+}
diff --git a/android/media/DeniedByServerException.java b/android/media/DeniedByServerException.java
new file mode 100644
index 0000000..9c1633a
--- /dev/null
+++ b/android/media/DeniedByServerException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 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;
+
+/**
+ * Exception thrown when the provisioning server or key server denies a
+ * certficate or license for a device.
+ */
+public final class DeniedByServerException extends MediaDrmException {
+    public DeniedByServerException(String detailMessage) {
+        super(detailMessage);
+    }
+}
diff --git a/android/media/DrmInitData.java b/android/media/DrmInitData.java
new file mode 100644
index 0000000..3c48f8f
--- /dev/null
+++ b/android/media/DrmInitData.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2016 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.annotation.NonNull;
+import android.media.MediaDrm;
+
+import java.util.Arrays;
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * Encapsulates initialization data required by a {@link MediaDrm} instance.
+ */
+public abstract class DrmInitData {
+
+    /**
+     * Prevent public constuctor access
+     */
+    /* package private */ DrmInitData() {
+    }
+
+    /**
+     * Retrieves initialization data for a given DRM scheme, specified by its UUID.
+     *
+     * @param schemeUuid The DRM scheme's UUID.
+     * @return The initialization data for the scheme, or null if the scheme is not supported.
+     * @deprecated Use {@link #getSchemeInitDataCount} and {@link #getSchemeInitDataAt} instead.
+     */
+    @Deprecated
+    public abstract SchemeInitData get(UUID schemeUuid);
+
+    /**
+     * Returns the number of {@link SchemeInitData} elements available through {@link
+     * #getSchemeInitDataAt}.
+     */
+    public int getSchemeInitDataCount() {
+        return 0;
+    }
+
+    /**
+     * Returns the {@link SchemeInitData} with the given {@code index}.
+     *
+     * @param index The index of the {@link SchemeInitData} to return.
+     * @return The {@link SchemeInitData} associated with the given {@code index}.
+     * @throws IndexOutOfBoundsException If the given {@code index} is negative or greater than
+     *         {@link #getSchemeInitDataCount}{@code - 1}.
+     */
+    @NonNull public SchemeInitData getSchemeInitDataAt(int index) {
+        throw new IndexOutOfBoundsException();
+    }
+
+    /**
+     * Scheme initialization data.
+     */
+    public static final class SchemeInitData {
+
+        /**
+         * The Nil UUID, as defined in RFC 4122, section 4.1.7.
+         */
+        @NonNull public static final UUID UUID_NIL = new UUID(0, 0);
+
+        /**
+         * The UUID associated with this scheme initialization data. May be {@link #UUID_NIL} if
+         * unknown or not applicable.
+         */
+        @NonNull public final UUID uuid;
+        /**
+         * The mimeType of {@link #data}.
+         */
+        public final String mimeType;
+        /**
+         * The initialization data.
+         */
+        public final byte[] data;
+
+        /**
+         * Creates a new instance with the given values.
+         *
+         * @param uuid The UUID associated with this scheme initialization data.
+         * @param mimeType The mimeType of the initialization data.
+         * @param data The initialization data.
+         */
+        public SchemeInitData(@NonNull UUID uuid, @NonNull String mimeType, @NonNull byte[] data) {
+            this.uuid = Objects.requireNonNull(uuid);
+            this.mimeType = Objects.requireNonNull(mimeType);
+            this.data = Objects.requireNonNull(data);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (!(obj instanceof SchemeInitData)) {
+                return false;
+            }
+            if (obj == this) {
+                return true;
+            }
+
+            SchemeInitData other = (SchemeInitData) obj;
+            return uuid.equals(other.uuid)
+                    && mimeType.equals(other.mimeType)
+                    && Arrays.equals(data, other.data);
+        }
+
+        @Override
+        public int hashCode() {
+            return uuid.hashCode() + 31 * (mimeType.hashCode() + 31 * Arrays.hashCode(data));
+        }
+
+    }
+
+}
diff --git a/android/media/EncoderCapabilities.java b/android/media/EncoderCapabilities.java
new file mode 100644
index 0000000..768b643
--- /dev/null
+++ b/android/media/EncoderCapabilities.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright (C) 2010 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.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The EncoderCapabilities class is used to retrieve the
+ * capabilities for different video and audio
+ * encoders supported on a specific Android platform.
+ * {@hide}
+ */
+public class EncoderCapabilities
+{
+    private static final String TAG = "EncoderCapabilities";
+
+    /**
+     * The VideoEncoderCap class represents a video encoder's
+     * supported parameter range in:
+     *
+     * <ul>
+     * <li>Resolution: the frame size (width/height) in pixels;
+     * <li>Bit rate: the compressed output bit rate in bits per second;
+     * <li>Frame rate: the output number of frames per second.
+     * </ul>
+     *
+     */
+    static public class VideoEncoderCap {
+        // These are not modifiable externally, thus are public accessible
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public final int mCodec;                // @see android.media.MediaRecorder.VideoEncoder
+        public final int mMinBitRate;           // min bit rate (bps)
+        public final int mMaxBitRate;           // max bit rate (bps)
+        public final int mMinFrameRate;         // min frame rate (fps)
+        public final int mMaxFrameRate;         // max frame rate (fps)
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public final int mMinFrameWidth;        // min frame width (pixel)
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public final int mMaxFrameWidth;        // max frame width (pixel)
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public final int mMinFrameHeight;       // min frame height (pixel)
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public final int mMaxFrameHeight;       // max frame height (pixel)
+
+        // Private constructor called by JNI
+        private VideoEncoderCap(int codec,
+                                int minBitRate, int maxBitRate,
+                                int minFrameRate, int maxFrameRate,
+                                int minFrameWidth, int maxFrameWidth,
+                                int minFrameHeight, int maxFrameHeight) {
+            mCodec = codec;
+            mMinBitRate = minBitRate;
+            mMaxBitRate = maxBitRate;
+            mMinFrameRate = minFrameRate;
+            mMaxFrameRate = maxFrameRate;
+            mMinFrameWidth = minFrameWidth;
+            mMaxFrameWidth = maxFrameWidth;
+            mMinFrameHeight = minFrameHeight;
+            mMaxFrameHeight = maxFrameHeight;
+        }
+    };
+
+    /**
+     * The AudioEncoderCap class represents an audio encoder's
+     * parameter range in:
+     *
+     * <ul>
+     * <li>Bit rate: the compressed output bit rate in bits per second;
+     * <li>Sample rate: the sampling rate used for recording the audio in samples per second;
+     * <li>Number of channels: the number of channels the audio is recorded.
+     * </ul>
+     *
+     */
+    static public class AudioEncoderCap {
+        // These are not modifiable externally, thus are public accessible
+        public final int mCodec;                         // @see android.media.MediaRecorder.AudioEncoder
+        public final int mMinChannels, mMaxChannels;     // min and max number of channels
+        public final int mMinSampleRate, mMaxSampleRate; // min and max sample rate (hz)
+        public final int mMinBitRate, mMaxBitRate;       // min and max bit rate (bps)
+
+        // Private constructor called by JNI
+        private AudioEncoderCap(int codec,
+                                int minBitRate, int maxBitRate,
+                                int minSampleRate, int maxSampleRate,
+                                int minChannels, int maxChannels) {
+           mCodec = codec;
+           mMinBitRate = minBitRate;
+           mMaxBitRate = maxBitRate;
+           mMinSampleRate = minSampleRate;
+           mMaxSampleRate = maxSampleRate;
+           mMinChannels = minChannels;
+           mMaxChannels = maxChannels;
+       }
+    };
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    /**
+     * Returns the array of supported output file formats.
+     * @see android.media.MediaRecorder.OutputFormat
+     */
+    public static int[] getOutputFileFormats() {
+        int nFormats = native_get_num_file_formats();
+        if (nFormats == 0) return null;
+
+        int[] formats = new int[nFormats];
+        for (int i = 0; i < nFormats; ++i) {
+            formats[i] = native_get_file_format(i);
+        }
+        return formats;
+    }
+
+    /**
+     * Returns the capabilities of the supported video encoders.
+     * @see android.media.EncoderCapabilities.VideoEncoderCap
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public static List<VideoEncoderCap> getVideoEncoders() {
+        int nEncoders = native_get_num_video_encoders();
+        if (nEncoders == 0) return null;
+
+        List<VideoEncoderCap> encoderList = new ArrayList<VideoEncoderCap>();
+        for (int i = 0; i < nEncoders; ++i) {
+            encoderList.add(native_get_video_encoder_cap(i));
+        }
+        return encoderList;
+    }
+
+    /**
+     * Returns the capabilities of the supported audio encoders.
+     * @see android.media.EncoderCapabilities.AudioEncoderCap
+     */
+    public static List<AudioEncoderCap> getAudioEncoders() {
+        int nEncoders = native_get_num_audio_encoders();
+        if (nEncoders == 0) return null;
+
+        List<AudioEncoderCap> encoderList = new ArrayList<AudioEncoderCap>();
+        for (int i = 0; i < nEncoders; ++i) {
+            encoderList.add(native_get_audio_encoder_cap(i));
+        }
+        return encoderList;
+    }
+
+
+    private EncoderCapabilities() {}  // Don't call me
+
+    // Implemented by JNI
+    private static native final void native_init();
+    private static native final int native_get_num_file_formats();
+    private static native final int native_get_file_format(int index);
+    private static native final int native_get_num_video_encoders();
+    private static native final VideoEncoderCap native_get_video_encoder_cap(int index);
+    private static native final int native_get_num_audio_encoders();
+    private static native final AudioEncoderCap native_get_audio_encoder_cap(int index);
+}
diff --git a/android/media/EncoderProfiles.java b/android/media/EncoderProfiles.java
new file mode 100644
index 0000000..ac8c65e
--- /dev/null
+++ b/android/media/EncoderProfiles.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright (C) 2021 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.annotation.NonNull;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Describes a set of encoding profiles for a given media (audio and/or video) profile.
+ * These settings are read-only.
+ *
+ * <p>Currently, this is used to describe camera recording profile with more detail than {@link
+ * CamcorderProfile}, by providing encoding parameters for more than just the default audio
+ * and/or video codec.
+ *
+ * <p>The compressed output from a camera recording session contains two tracks:
+ * one for audio and one for video.
+ * <p>In the future audio-only recording profiles may be defined.
+ *
+ * <p>Each media profile specifies a set of audio and a set of video specific settings.
+ * <ul>
+ * <li> The file output format
+ * <li> Default file duration
+ * <p>Video-specific settings are:
+ * <li> Video codec format
+ * <li> Video bit rate in bits per second
+ * <li> Video frame rate in frames per second
+ * <li> Video frame width and height,
+ * <li> Video encoder profile.
+ * <p>Audio-specific settings are:
+ * <li> Audio codec format
+ * <li> Audio bit rate in bits per second,
+ * <li> Audio sample rate
+ * <li> Number of audio channels for recording.
+ * </ul>
+ */
+public final class EncoderProfiles
+{
+    /**
+     * Default recording duration in seconds before the session is terminated.
+     * This is useful for applications like MMS that have a limited file size requirement.
+     * This could be 0 if there is no default recording duration.
+     */
+    public int getDefaultDurationSeconds() {
+        return durationSecs;
+    }
+
+    /**
+     * Recommended output file format
+     * @see android.media.MediaRecorder.OutputFormat
+     */
+    public @MediaRecorder.OutputFormatValues int getRecommendedFileFormat() {
+        return fileFormat;
+    }
+
+    /**
+     * Configuration for a video encoder.
+     */
+    public final static class VideoProfile {
+        /**
+         * The video encoder being used for the video track
+         * @see android.media.MediaRecorder.VideoEncoder
+         */
+        public @MediaRecorder.VideoEncoderValues int getCodec() {
+            return codec;
+        }
+
+        /**
+         * The media type of the video encoder being used for the video track
+         * @see android.media.MediaFormat#KEY_MIME
+         */
+        public @NonNull String getMediaType() {
+            if (codec == MediaRecorder.VideoEncoder.H263) {
+                return MediaFormat.MIMETYPE_VIDEO_H263;
+            } else if (codec == MediaRecorder.VideoEncoder.H264) {
+                return MediaFormat.MIMETYPE_VIDEO_AVC;
+            } else if (codec == MediaRecorder.VideoEncoder.MPEG_4_SP) {
+                return MediaFormat.MIMETYPE_VIDEO_MPEG4;
+            } else if (codec == MediaRecorder.VideoEncoder.VP8) {
+                return MediaFormat.MIMETYPE_VIDEO_VP8;
+            } else if (codec == MediaRecorder.VideoEncoder.HEVC) {
+                return MediaFormat.MIMETYPE_VIDEO_HEVC;
+            }
+            // we should never be here
+            throw new RuntimeException("Unknown codec");
+        }
+
+        /**
+         * The target video output bitrate in bits per second
+         * <p>
+         * This is the target recorded video output bitrate if the application configures the video
+         * recording via {@link MediaRecorder#setProfile} without specifying any other
+         * {@link MediaRecorder} encoding parameters. For example, for high speed quality profiles
+         * (from {@link CamcorderProfile#QUALITY_HIGH_SPEED_LOW} to {@link
+         * CamcorderProfile#QUALITY_HIGH_SPEED_2160P}), this is the bitrate where the video is
+         * recorded with. If the application intends to record slow motion videos with the high
+         * speed quality profiles, it must set a different video bitrate that is corresponding to
+         * the desired recording output bit rate (i.e., the encoded video bitrate during normal
+         * playback) via {@link MediaRecorder#setVideoEncodingBitRate}. For example, if {@link
+         * CamcorderProfile#QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #getFrameRate} and
+         * 64Mbps {@link #getBitrate} in the high speed VideoProfile, and the application
+         * intends to record 1/8 factor slow motion recording videos, the application must set 30fps
+         * via {@link MediaRecorder#setVideoFrameRate} and 8Mbps ( {@link #getBitrate} * slow motion
+         * factor) via {@link MediaRecorder#setVideoEncodingBitRate}. Failing to do so will result
+         * in videos with unexpected frame rate and bit rate, or {@link MediaRecorder} error if the
+         * output bit rate exceeds the encoder limit. If the application intends to do the video
+         * recording with {@link MediaCodec} encoder, it must set each individual field of {@link
+         * MediaFormat} similarly according to this VideoProfile.
+         * </p>
+         *
+         * @see #getFrameRate
+         * @see MediaRecorder
+         * @see MediaCodec
+         * @see MediaFormat
+         */
+        public int getBitrate() {
+            return bitrate;
+        }
+
+        /**
+         * The target video frame rate in frames per second.
+         * <p>
+         * This is the target recorded video output frame rate per second if the application
+         * configures the video recording via {@link MediaRecorder#setProfile} without specifying
+         * any other {@link MediaRecorder} encoding parameters. For example, for high speed quality
+         * profiles (from {@link CamcorderProfile#QUALITY_HIGH_SPEED_LOW} to {@link
+         * CamcorderProfile#QUALITY_HIGH_SPEED_2160P}), this is the frame rate where the video is
+         * recorded and played back with. If the application intends to create slow motion use case
+         * with the high speed quality profiles, it must set a different video frame rate that is
+         * corresponding to the desired output (playback) frame rate via {@link
+         * MediaRecorder#setVideoFrameRate}. For example, if {@link
+         * CamcorderProfile#QUALITY_HIGH_SPEED_720P} advertises 240fps {@link #getFrameRate}
+         * in the VideoProfile, and the application intends to create 1/8 factor slow motion
+         * recording videos, the application must set 30fps via {@link
+         * MediaRecorder#setVideoFrameRate}. Failing to do so will result in high speed videos with
+         * normal speed playback frame rate (240fps for above example). If the application intends
+         * to do the video recording with {@link MediaCodec} encoder, it must set each individual
+         * field of {@link MediaFormat} similarly according to this VideoProfile.
+         * </p>
+         *
+         * @see #getBitrate
+         * @see MediaRecorder
+         * @see MediaCodec
+         * @see MediaFormat
+         */
+        public int getFrameRate() {
+            return frameRate;
+        }
+
+        /**
+         * The target video frame width in pixels
+         */
+        public int getWidth() {
+            return width;
+        }
+
+        /**
+         * The target video frame height in pixels
+         */
+        public int getHeight() {
+            return height;
+        }
+
+        /**
+         * The video encoder profile being used for the video track.
+         * <p>
+         * This value is negative if there is no profile defined for the video codec.
+         *
+         * @see MediaRecorder#setVideoEncodingProfileLevel
+         * @see MediaFormat#KEY_PROFILE
+         */
+        public int getProfile() {
+            return profile;
+        }
+
+        // Constructor called by JNI and CamcorderProfile
+        /* package private */ VideoProfile(int codec,
+                             int width,
+                             int height,
+                             int frameRate,
+                             int bitrate,
+                             int profile) {
+            this.codec = codec;
+            this.width = width;
+            this.height = height;
+            this.frameRate = frameRate;
+            this.bitrate = bitrate;
+            this.profile = profile;
+        }
+
+        private int codec;
+        private int width;
+        private int height;
+        private int frameRate;
+        private int bitrate;
+        private int profile;
+    }
+
+    /**
+     * Returns the defined audio encoder profiles.
+     * <p>
+     * The list may be empty. This means there are no audio encoder
+     * profiles defined. Otherwise, the first profile is the default
+     * audio profile.
+     */
+    public @NonNull List<AudioProfile> getAudioProfiles() {
+        return audioProfiles;
+    }
+
+    /**
+     * Returns the defined video encoder profiles.
+     * <p>
+     * The list may be empty. This means there are no video encoder
+     * profiles defined. Otherwise, the first profile is the default
+     * video profile.
+     */
+    public @NonNull List<VideoProfile> getVideoProfiles() {
+        return videoProfiles;
+    }
+
+    /**
+     * Configuration for an audio encoder.
+     */
+    public final static class AudioProfile {
+        /**
+         * The audio encoder being used for the audio track.
+         * @see android.media.MediaRecorder.AudioEncoder
+         */
+        public @MediaRecorder.AudioEncoderValues int getCodec() {
+            return codec;
+        }
+
+        /**
+         * The media type of the audio encoder being used for the video track
+         * @see android.media.MediaFormat#KEY_MIME
+         */
+        public @NonNull String getMediaType() {
+            if (codec == MediaRecorder.AudioEncoder.AMR_NB) {
+                return MediaFormat.MIMETYPE_AUDIO_AMR_NB;
+            } else if (codec == MediaRecorder.AudioEncoder.AMR_WB) {
+                return MediaFormat.MIMETYPE_AUDIO_AMR_WB;
+            } else if (codec == MediaRecorder.AudioEncoder.AAC
+                    || codec == MediaRecorder.AudioEncoder.HE_AAC
+                    || codec == MediaRecorder.AudioEncoder.AAC_ELD) {
+                return MediaFormat.MIMETYPE_AUDIO_AAC;
+            } else if (codec == MediaRecorder.AudioEncoder.VORBIS) {
+                return MediaFormat.MIMETYPE_AUDIO_VORBIS;
+            } else if (codec == MediaRecorder.AudioEncoder.OPUS) {
+                return MediaFormat.MIMETYPE_AUDIO_OPUS;
+            }
+            // we should never be here
+            throw new RuntimeException("Unknown codec");
+        }
+
+        /**
+         * The target audio output bitrate in bits per second
+         */
+        public int getBitrate() {
+            return bitrate;
+        }
+
+        /**
+         * The audio sampling rate used for the audio track
+         */
+        public int getSampleRate() {
+            return sampleRate;
+        }
+
+        /**
+         * The number of audio channels used for the audio track
+         */
+        public int getChannels() {
+            return channels;
+        }
+
+        /**
+         * The audio encoder profile being used for the audio track
+         * <p>
+         * This value is negative if there is no profile defined for the audio codec.
+         * @see MediaFormat#KEY_PROFILE
+         */
+        public int getProfile() {
+            if (codec == MediaRecorder.AudioEncoder.AAC) {
+                return MediaCodecInfo.CodecProfileLevel.AACObjectMain;
+            } else if (codec == MediaRecorder.AudioEncoder.HE_AAC) {
+                return MediaCodecInfo.CodecProfileLevel.AACObjectHE;
+            } else if (codec == MediaRecorder.AudioEncoder.AAC_ELD) {
+                return MediaCodecInfo.CodecProfileLevel.AACObjectELD;
+            }
+            return profile;
+        }
+
+
+        // Constructor called by JNI and CamcorderProfile
+        /* package private */ AudioProfile(
+                int codec,
+                int channels,
+                int sampleRate,
+                int bitrate,
+                int profile) {
+            this.codec = codec;
+            this.channels = channels;
+            this.sampleRate = sampleRate;
+            this.bitrate = bitrate;
+            this.profile = profile;
+        }
+
+        private int codec;
+        private int channels;
+        private int sampleRate;
+        private int bitrate;
+        private int profile;  // this contains the profile if codec itself does not
+    }
+
+    private int durationSecs;
+    private int fileFormat;
+    // non-modifiable lists
+    private @NonNull List<AudioProfile> audioProfiles;
+    private @NonNull List<VideoProfile> videoProfiles;
+
+    // Constructor called by JNI and CamcorderProfile
+    /* package private */ EncoderProfiles(
+            int duration,
+            int fileFormat,
+            VideoProfile[] videoProfiles,
+            AudioProfile[] audioProfiles) {
+        this.durationSecs     = duration;
+        this.fileFormat       = fileFormat;
+        this.videoProfiles    = Collections.unmodifiableList(Arrays.asList(videoProfiles));
+        this.audioProfiles    = Collections.unmodifiableList(Arrays.asList(audioProfiles));
+    }
+}
diff --git a/android/media/ExifInterface.java b/android/media/ExifInterface.java
new file mode 100644
index 0000000..37054b8
--- /dev/null
+++ b/android/media/ExifInterface.java
@@ -0,0 +1,5223 @@
+/*
+ * Copyright (C) 2007 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.ExifInterfaceUtils.byteArrayToHexString;
+import static android.media.ExifInterfaceUtils.closeFileDescriptor;
+import static android.media.ExifInterfaceUtils.closeQuietly;
+import static android.media.ExifInterfaceUtils.convertToLongArray;
+import static android.media.ExifInterfaceUtils.copy;
+import static android.media.ExifInterfaceUtils.startsWith;
+
+import android.annotation.CurrentTimeMillisLong;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.res.AssetManager;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.FileUtils;
+import android.os.ParcelFileDescriptor;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInput;
+import java.io.DataInputStream;
+import java.io.EOFException;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.FilterOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+import java.text.ParsePosition;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+import java.util.TimeZone;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.CRC32;
+
+/**
+ * This is a class for reading and writing Exif tags in various image file formats.
+ * <p>
+ * Supported for reading: JPEG, PNG, WebP, HEIF, DNG, CR2, NEF, NRW, ARW, RW2, ORF, PEF, SRW, RAF,
+ * AVIF.
+ * <p>
+ * Supported for writing: JPEG, PNG, WebP.
+ * <p>
+ * Note: JPEG and HEIF files may contain XMP data either inside the Exif data chunk or outside of
+ * it. This class will search both locations for XMP data, but if XMP data exist both inside and
+ * outside Exif, will favor the XMP data inside Exif over the one outside.
+ * <p>
+ * Note: It is recommended to use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+ * <a href="{@docRoot}reference/androidx/exifinterface/media/ExifInterface.html">ExifInterface
+ * Library</a> since it is a superset of this class. In addition to the functionalities of this
+ * class, it supports parsing extra metadata such as exposure and data compression information
+ * as well as setting extra metadata such as GPS and datetime information.
+ */
+public class ExifInterface {
+    private static final String TAG = "ExifInterface";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    // The Exif tag names. See Tiff 6.0 Section 3 and Section 8.
+    /** Type is String. */
+    public static final String TAG_ARTIST = "Artist";
+    /** Type is int. */
+    public static final String TAG_BITS_PER_SAMPLE = "BitsPerSample";
+    /** Type is int. */
+    public static final String TAG_COMPRESSION = "Compression";
+    /** Type is String. */
+    public static final String TAG_COPYRIGHT = "Copyright";
+    /** Type is String. */
+    public static final String TAG_DATETIME = "DateTime";
+    /** Type is String. */
+    public static final String TAG_IMAGE_DESCRIPTION = "ImageDescription";
+    /** Type is int. */
+    public static final String TAG_IMAGE_LENGTH = "ImageLength";
+    /** Type is int. */
+    public static final String TAG_IMAGE_WIDTH = "ImageWidth";
+    /** Type is int. */
+    public static final String TAG_JPEG_INTERCHANGE_FORMAT = "JPEGInterchangeFormat";
+    /** Type is int. */
+    public static final String TAG_JPEG_INTERCHANGE_FORMAT_LENGTH = "JPEGInterchangeFormatLength";
+    /** Type is String. */
+    public static final String TAG_MAKE = "Make";
+    /** Type is String. */
+    public static final String TAG_MODEL = "Model";
+    /** Type is int. */
+    public static final String TAG_ORIENTATION = "Orientation";
+    /** Type is int. */
+    public static final String TAG_PHOTOMETRIC_INTERPRETATION = "PhotometricInterpretation";
+    /** Type is int. */
+    public static final String TAG_PLANAR_CONFIGURATION = "PlanarConfiguration";
+    /** Type is rational. */
+    public static final String TAG_PRIMARY_CHROMATICITIES = "PrimaryChromaticities";
+    /** Type is rational. */
+    public static final String TAG_REFERENCE_BLACK_WHITE = "ReferenceBlackWhite";
+    /** Type is int. */
+    public static final String TAG_RESOLUTION_UNIT = "ResolutionUnit";
+    /** Type is int. */
+    public static final String TAG_ROWS_PER_STRIP = "RowsPerStrip";
+    /** Type is int. */
+    public static final String TAG_SAMPLES_PER_PIXEL = "SamplesPerPixel";
+    /** Type is String. */
+    public static final String TAG_SOFTWARE = "Software";
+    /** Type is int. */
+    public static final String TAG_STRIP_BYTE_COUNTS = "StripByteCounts";
+    /** Type is int. */
+    public static final String TAG_STRIP_OFFSETS = "StripOffsets";
+    /** Type is int. */
+    public static final String TAG_TRANSFER_FUNCTION = "TransferFunction";
+    /** Type is rational. */
+    public static final String TAG_WHITE_POINT = "WhitePoint";
+    /** Type is rational. */
+    public static final String TAG_X_RESOLUTION = "XResolution";
+    /** Type is rational. */
+    public static final String TAG_Y_CB_CR_COEFFICIENTS = "YCbCrCoefficients";
+    /** Type is int. */
+    public static final String TAG_Y_CB_CR_POSITIONING = "YCbCrPositioning";
+    /** Type is int. */
+    public static final String TAG_Y_CB_CR_SUB_SAMPLING = "YCbCrSubSampling";
+    /** Type is rational. */
+    public static final String TAG_Y_RESOLUTION = "YResolution";
+    /** Type is rational. */
+    public static final String TAG_APERTURE_VALUE = "ApertureValue";
+    /** Type is rational. */
+    public static final String TAG_BRIGHTNESS_VALUE = "BrightnessValue";
+    /** Type is String. */
+    public static final String TAG_CFA_PATTERN = "CFAPattern";
+    /** Type is int. */
+    public static final String TAG_COLOR_SPACE = "ColorSpace";
+    /** Type is String. */
+    public static final String TAG_COMPONENTS_CONFIGURATION = "ComponentsConfiguration";
+    /** Type is rational. */
+    public static final String TAG_COMPRESSED_BITS_PER_PIXEL = "CompressedBitsPerPixel";
+    /** Type is int. */
+    public static final String TAG_CONTRAST = "Contrast";
+    /** Type is int. */
+    public static final String TAG_CUSTOM_RENDERED = "CustomRendered";
+    /** Type is String. */
+    public static final String TAG_DATETIME_DIGITIZED = "DateTimeDigitized";
+    /** Type is String. */
+    public static final String TAG_DATETIME_ORIGINAL = "DateTimeOriginal";
+    /** Type is String. */
+    public static final String TAG_DEVICE_SETTING_DESCRIPTION = "DeviceSettingDescription";
+    /** Type is double. */
+    public static final String TAG_DIGITAL_ZOOM_RATIO = "DigitalZoomRatio";
+    /** Type is String. */
+    public static final String TAG_EXIF_VERSION = "ExifVersion";
+    /** Type is double. */
+    public static final String TAG_EXPOSURE_BIAS_VALUE = "ExposureBiasValue";
+    /** Type is rational. */
+    public static final String TAG_EXPOSURE_INDEX = "ExposureIndex";
+    /** Type is int. */
+    public static final String TAG_EXPOSURE_MODE = "ExposureMode";
+    /** Type is int. */
+    public static final String TAG_EXPOSURE_PROGRAM = "ExposureProgram";
+    /** Type is double. */
+    public static final String TAG_EXPOSURE_TIME = "ExposureTime";
+    /** Type is double. */
+    public static final String TAG_F_NUMBER = "FNumber";
+    /**
+     * Type is double.
+     *
+     * @deprecated use {@link #TAG_F_NUMBER} instead
+     */
+    @Deprecated
+    public static final String TAG_APERTURE = "FNumber";
+    /** Type is String. */
+    public static final String TAG_FILE_SOURCE = "FileSource";
+    /** Type is int. */
+    public static final String TAG_FLASH = "Flash";
+    /** Type is rational. */
+    public static final String TAG_FLASH_ENERGY = "FlashEnergy";
+    /** Type is String. */
+    public static final String TAG_FLASHPIX_VERSION = "FlashpixVersion";
+    /** Type is rational. */
+    public static final String TAG_FOCAL_LENGTH = "FocalLength";
+    /** Type is int. */
+    public static final String TAG_FOCAL_LENGTH_IN_35MM_FILM = "FocalLengthIn35mmFilm";
+    /** Type is int. */
+    public static final String TAG_FOCAL_PLANE_RESOLUTION_UNIT = "FocalPlaneResolutionUnit";
+    /** Type is rational. */
+    public static final String TAG_FOCAL_PLANE_X_RESOLUTION = "FocalPlaneXResolution";
+    /** Type is rational. */
+    public static final String TAG_FOCAL_PLANE_Y_RESOLUTION = "FocalPlaneYResolution";
+    /** Type is int. */
+    public static final String TAG_GAIN_CONTROL = "GainControl";
+    /** Type is int. */
+    public static final String TAG_ISO_SPEED_RATINGS = "ISOSpeedRatings";
+    /**
+     * Type is int.
+     *
+     * @deprecated use {@link #TAG_ISO_SPEED_RATINGS} instead
+     */
+    @Deprecated
+    public static final String TAG_ISO = "ISOSpeedRatings";
+    /** Type is String. */
+    public static final String TAG_IMAGE_UNIQUE_ID = "ImageUniqueID";
+    /** Type is int. */
+    public static final String TAG_LIGHT_SOURCE = "LightSource";
+    /** Type is String. */
+    public static final String TAG_MAKER_NOTE = "MakerNote";
+    /** Type is rational. */
+    public static final String TAG_MAX_APERTURE_VALUE = "MaxApertureValue";
+    /** Type is int. */
+    public static final String TAG_METERING_MODE = "MeteringMode";
+    /** Type is int. */
+    public static final String TAG_NEW_SUBFILE_TYPE = "NewSubfileType";
+    /** Type is String. */
+    public static final String TAG_OECF = "OECF";
+    /**
+     *  <p>A tag used to record the offset from UTC (the time difference from Universal Time
+     *  Coordinated including daylight saving time) of the time of DateTime tag. The format when
+     *  recording the offset is "±HH:MM". The part of "±" shall be recorded as "+" or "-". When
+     *  the offsets are unknown, all the character spaces except colons (":") should be filled
+     *  with blank characters, or else the Interoperability field should be filled with blank
+     *  characters. The character string length is 7 Bytes including NULL for termination. When
+     *  the field is left blank, it is treated as unknown.</p>
+     *
+     *  <ul>
+     *      <li>Tag = 36880</li>
+     *      <li>Type = String</li>
+     *      <li>Length = 7</li>
+     *      <li>Default = None</li>
+     *  </ul>
+     */
+    public static final String TAG_OFFSET_TIME = "OffsetTime";
+    /**
+     *  <p>A tag used to record the offset from UTC (the time difference from Universal Time
+     *  Coordinated including daylight saving time) of the time of DateTimeOriginal tag. The format
+     *  when recording the offset is "±HH:MM". The part of "±" shall be recorded as "+" or "-". When
+     *  the offsets are unknown, all the character spaces except colons (":") should be filled
+     *  with blank characters, or else the Interoperability field should be filled with blank
+     *  characters. The character string length is 7 Bytes including NULL for termination. When
+     *  the field is left blank, it is treated as unknown.</p>
+     *
+     *  <ul>
+     *      <li>Tag = 36881</li>
+     *      <li>Type = String</li>
+     *      <li>Length = 7</li>
+     *      <li>Default = None</li>
+     *  </ul>
+     */
+    public static final String TAG_OFFSET_TIME_ORIGINAL = "OffsetTimeOriginal";
+    /**
+     *  <p>A tag used to record the offset from UTC (the time difference from Universal Time
+     *  Coordinated including daylight saving time) of the time of DateTimeDigitized tag. The format
+     *  when recording the offset is "±HH:MM". The part of "±" shall be recorded as "+" or "-". When
+     *  the offsets are unknown, all the character spaces except colons (":") should be filled
+     *  with blank characters, or else the Interoperability field should be filled with blank
+     *  characters. The character string length is 7 Bytes including NULL for termination. When
+     *  the field is left blank, it is treated as unknown.</p>
+     *
+     *  <ul>
+     *      <li>Tag = 36882</li>
+     *      <li>Type = String</li>
+     *      <li>Length = 7</li>
+     *      <li>Default = None</li>
+     *  </ul>
+     */
+    public static final String TAG_OFFSET_TIME_DIGITIZED = "OffsetTimeDigitized";
+    /** Type is int. */
+    public static final String TAG_PIXEL_X_DIMENSION = "PixelXDimension";
+    /** Type is int. */
+    public static final String TAG_PIXEL_Y_DIMENSION = "PixelYDimension";
+    /** Type is String. */
+    public static final String TAG_RELATED_SOUND_FILE = "RelatedSoundFile";
+    /** Type is int. */
+    public static final String TAG_SATURATION = "Saturation";
+    /** Type is int. */
+    public static final String TAG_SCENE_CAPTURE_TYPE = "SceneCaptureType";
+    /** Type is String. */
+    public static final String TAG_SCENE_TYPE = "SceneType";
+    /** Type is int. */
+    public static final String TAG_SENSING_METHOD = "SensingMethod";
+    /** Type is int. */
+    public static final String TAG_SHARPNESS = "Sharpness";
+    /** Type is rational. */
+    public static final String TAG_SHUTTER_SPEED_VALUE = "ShutterSpeedValue";
+    /** Type is String. */
+    public static final String TAG_SPATIAL_FREQUENCY_RESPONSE = "SpatialFrequencyResponse";
+    /** Type is String. */
+    public static final String TAG_SPECTRAL_SENSITIVITY = "SpectralSensitivity";
+    /** Type is int. */
+    public static final String TAG_SUBFILE_TYPE = "SubfileType";
+    /** Type is String. */
+    public static final String TAG_SUBSEC_TIME = "SubSecTime";
+    /**
+     * Type is String.
+     *
+     * @deprecated use {@link #TAG_SUBSEC_TIME_DIGITIZED} instead
+     */
+    public static final String TAG_SUBSEC_TIME_DIG = "SubSecTimeDigitized";
+    /** Type is String. */
+    public static final String TAG_SUBSEC_TIME_DIGITIZED = "SubSecTimeDigitized";
+    /**
+     * Type is String.
+     *
+     * @deprecated use {@link #TAG_SUBSEC_TIME_ORIGINAL} instead
+     */
+    public static final String TAG_SUBSEC_TIME_ORIG = "SubSecTimeOriginal";
+    /** Type is String. */
+    public static final String TAG_SUBSEC_TIME_ORIGINAL = "SubSecTimeOriginal";
+    /** Type is int. */
+    public static final String TAG_SUBJECT_AREA = "SubjectArea";
+    /** Type is double. */
+    public static final String TAG_SUBJECT_DISTANCE = "SubjectDistance";
+    /** Type is int. */
+    public static final String TAG_SUBJECT_DISTANCE_RANGE = "SubjectDistanceRange";
+    /** Type is int. */
+    public static final String TAG_SUBJECT_LOCATION = "SubjectLocation";
+    /** Type is String. */
+    public static final String TAG_USER_COMMENT = "UserComment";
+    /** Type is int. */
+    public static final String TAG_WHITE_BALANCE = "WhiteBalance";
+    /**
+     * The altitude (in meters) based on the reference in TAG_GPS_ALTITUDE_REF.
+     * Type is rational.
+     */
+    public static final String TAG_GPS_ALTITUDE = "GPSAltitude";
+    /**
+     * 0 if the altitude is above sea level. 1 if the altitude is below sea
+     * level. Type is int.
+     */
+    public static final String TAG_GPS_ALTITUDE_REF = "GPSAltitudeRef";
+    /** Type is String. */
+    public static final String TAG_GPS_AREA_INFORMATION = "GPSAreaInformation";
+    /** Type is rational. */
+    public static final String TAG_GPS_DOP = "GPSDOP";
+    /** Type is String. */
+    public static final String TAG_GPS_DATESTAMP = "GPSDateStamp";
+    /** Type is rational. */
+    public static final String TAG_GPS_DEST_BEARING = "GPSDestBearing";
+    /** Type is String. */
+    public static final String TAG_GPS_DEST_BEARING_REF = "GPSDestBearingRef";
+    /** Type is rational. */
+    public static final String TAG_GPS_DEST_DISTANCE = "GPSDestDistance";
+    /** Type is String. */
+    public static final String TAG_GPS_DEST_DISTANCE_REF = "GPSDestDistanceRef";
+    /** Type is rational. */
+    public static final String TAG_GPS_DEST_LATITUDE = "GPSDestLatitude";
+    /** Type is String. */
+    public static final String TAG_GPS_DEST_LATITUDE_REF = "GPSDestLatitudeRef";
+    /** Type is rational. */
+    public static final String TAG_GPS_DEST_LONGITUDE = "GPSDestLongitude";
+    /** Type is String. */
+    public static final String TAG_GPS_DEST_LONGITUDE_REF = "GPSDestLongitudeRef";
+    /** Type is int. */
+    public static final String TAG_GPS_DIFFERENTIAL = "GPSDifferential";
+    /** Type is rational. */
+    public static final String TAG_GPS_IMG_DIRECTION = "GPSImgDirection";
+    /** Type is String. */
+    public static final String TAG_GPS_IMG_DIRECTION_REF = "GPSImgDirectionRef";
+    /** Type is rational. Format is "num1/denom1,num2/denom2,num3/denom3". */
+    public static final String TAG_GPS_LATITUDE = "GPSLatitude";
+    /** Type is String. */
+    public static final String TAG_GPS_LATITUDE_REF = "GPSLatitudeRef";
+    /** Type is rational. Format is "num1/denom1,num2/denom2,num3/denom3". */
+    public static final String TAG_GPS_LONGITUDE = "GPSLongitude";
+    /** Type is String. */
+    public static final String TAG_GPS_LONGITUDE_REF = "GPSLongitudeRef";
+    /** Type is String. */
+    public static final String TAG_GPS_MAP_DATUM = "GPSMapDatum";
+    /** Type is String. */
+    public static final String TAG_GPS_MEASURE_MODE = "GPSMeasureMode";
+    /** Type is String. Name of GPS processing method used for location finding. */
+    public static final String TAG_GPS_PROCESSING_METHOD = "GPSProcessingMethod";
+    /** Type is String. */
+    public static final String TAG_GPS_SATELLITES = "GPSSatellites";
+    /** Type is rational. */
+    public static final String TAG_GPS_SPEED = "GPSSpeed";
+    /** Type is String. */
+    public static final String TAG_GPS_SPEED_REF = "GPSSpeedRef";
+    /** Type is String. */
+    public static final String TAG_GPS_STATUS = "GPSStatus";
+    /** Type is String. Format is "hh:mm:ss". */
+    public static final String TAG_GPS_TIMESTAMP = "GPSTimeStamp";
+    /** Type is rational. */
+    public static final String TAG_GPS_TRACK = "GPSTrack";
+    /** Type is String. */
+    public static final String TAG_GPS_TRACK_REF = "GPSTrackRef";
+    /** Type is String. */
+    public static final String TAG_GPS_VERSION_ID = "GPSVersionID";
+    /** Type is String. */
+    public static final String TAG_INTEROPERABILITY_INDEX = "InteroperabilityIndex";
+    /** Type is int. */
+    public static final String TAG_THUMBNAIL_IMAGE_LENGTH = "ThumbnailImageLength";
+    /** Type is int. */
+    public static final String TAG_THUMBNAIL_IMAGE_WIDTH = "ThumbnailImageWidth";
+    /** Type is int. */
+    public static final String TAG_THUMBNAIL_ORIENTATION = "ThumbnailOrientation";
+    /** Type is int. DNG Specification 1.4.0.0. Section 4 */
+    public static final String TAG_DNG_VERSION = "DNGVersion";
+    /** Type is int. DNG Specification 1.4.0.0. Section 4 */
+    public static final String TAG_DEFAULT_CROP_SIZE = "DefaultCropSize";
+    /** Type is undefined. See Olympus MakerNote tags in http://www.exiv2.org/tags-olympus.html. */
+    public static final String TAG_ORF_THUMBNAIL_IMAGE = "ThumbnailImage";
+    /** Type is int. See Olympus Camera Settings tags in http://www.exiv2.org/tags-olympus.html. */
+    public static final String TAG_ORF_PREVIEW_IMAGE_START = "PreviewImageStart";
+    /** Type is int. See Olympus Camera Settings tags in http://www.exiv2.org/tags-olympus.html. */
+    public static final String TAG_ORF_PREVIEW_IMAGE_LENGTH = "PreviewImageLength";
+    /** Type is int. See Olympus Image Processing tags in http://www.exiv2.org/tags-olympus.html. */
+    public static final String TAG_ORF_ASPECT_FRAME = "AspectFrame";
+    /**
+     * Type is int. See PanasonicRaw tags in
+     * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html
+     */
+    public static final String TAG_RW2_SENSOR_BOTTOM_BORDER = "SensorBottomBorder";
+    /**
+     * Type is int. See PanasonicRaw tags in
+     * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html
+     */
+    public static final String TAG_RW2_SENSOR_LEFT_BORDER = "SensorLeftBorder";
+    /**
+     * Type is int. See PanasonicRaw tags in
+     * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html
+     */
+    public static final String TAG_RW2_SENSOR_RIGHT_BORDER = "SensorRightBorder";
+    /**
+     * Type is int. See PanasonicRaw tags in
+     * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html
+     */
+    public static final String TAG_RW2_SENSOR_TOP_BORDER = "SensorTopBorder";
+    /**
+     * Type is int. See PanasonicRaw tags in
+     * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html
+     */
+    public static final String TAG_RW2_ISO = "ISO";
+    /**
+     * Type is undefined. See PanasonicRaw tags in
+     * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html
+     */
+    public static final String TAG_RW2_JPG_FROM_RAW = "JpgFromRaw";
+    /**
+     * Type is byte[]. See <a href=
+     * "https://en.wikipedia.org/wiki/Extensible_Metadata_Platform">Extensible
+     * Metadata Platform (XMP)</a> for details on contents.
+     */
+    public static final String TAG_XMP = "Xmp";
+
+    /**
+     * Private tags used for pointing the other IFD offsets.
+     * The types of the following tags are int.
+     * See JEITA CP-3451C Section 4.6.3: Exif-specific IFD.
+     * For SubIFD, see Note 1 of Adobe PageMaker® 6.0 TIFF Technical Notes.
+     */
+    private static final String TAG_EXIF_IFD_POINTER = "ExifIFDPointer";
+    private static final String TAG_GPS_INFO_IFD_POINTER = "GPSInfoIFDPointer";
+    private static final String TAG_INTEROPERABILITY_IFD_POINTER = "InteroperabilityIFDPointer";
+    private static final String TAG_SUB_IFD_POINTER = "SubIFDPointer";
+    // Proprietary pointer tags used for ORF files.
+    // See http://www.exiv2.org/tags-olympus.html
+    private static final String TAG_ORF_CAMERA_SETTINGS_IFD_POINTER = "CameraSettingsIFDPointer";
+    private static final String TAG_ORF_IMAGE_PROCESSING_IFD_POINTER = "ImageProcessingIFDPointer";
+
+    // Private tags used for thumbnail information.
+    private static final String TAG_HAS_THUMBNAIL = "HasThumbnail";
+    private static final String TAG_THUMBNAIL_OFFSET = "ThumbnailOffset";
+    private static final String TAG_THUMBNAIL_LENGTH = "ThumbnailLength";
+    private static final String TAG_THUMBNAIL_DATA = "ThumbnailData";
+    private static final int MAX_THUMBNAIL_SIZE = 512;
+
+    // Constants used for the Orientation Exif tag.
+    public static final int ORIENTATION_UNDEFINED = 0;
+    public static final int ORIENTATION_NORMAL = 1;
+    public static final int ORIENTATION_FLIP_HORIZONTAL = 2;  // left right reversed mirror
+    public static final int ORIENTATION_ROTATE_180 = 3;
+    public static final int ORIENTATION_FLIP_VERTICAL = 4;  // upside down mirror
+    // flipped about top-left <--> bottom-right axis
+    public static final int ORIENTATION_TRANSPOSE = 5;
+    public static final int ORIENTATION_ROTATE_90 = 6;  // rotate 90 cw to right it
+    // flipped about top-right <--> bottom-left axis
+    public static final int ORIENTATION_TRANSVERSE = 7;
+    public static final int ORIENTATION_ROTATE_270 = 8;  // rotate 270 to right it
+
+    // Constants used for white balance
+    public static final int WHITEBALANCE_AUTO = 0;
+    public static final int WHITEBALANCE_MANUAL = 1;
+
+    /**
+     * Constant used to indicate that the input stream contains the full image data.
+     * <p>
+     * The format of the image data should follow one of the image formats supported by this class.
+     */
+    public static final int STREAM_TYPE_FULL_IMAGE_DATA = 0;
+    /**
+     * Constant used to indicate that the input stream contains only Exif data.
+     * <p>
+     * The format of the Exif-only data must follow the below structure:
+     *     Exif Identifier Code ("Exif\0\0") + TIFF header + IFD data
+     * See JEITA CP-3451C Section 4.5.2 and 4.5.4 specifications for more details.
+     */
+    public static final int STREAM_TYPE_EXIF_DATA_ONLY = 1;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({STREAM_TYPE_FULL_IMAGE_DATA, STREAM_TYPE_EXIF_DATA_ONLY})
+    public @interface ExifStreamType {}
+
+    // Maximum size for checking file type signature (see image_type_recognition_lite.cc)
+    private static final int SIGNATURE_CHECK_SIZE = 5000;
+
+    private static final byte[] JPEG_SIGNATURE = new byte[] {(byte) 0xff, (byte) 0xd8, (byte) 0xff};
+    private static final String RAF_SIGNATURE = "FUJIFILMCCD-RAW";
+    private static final int RAF_OFFSET_TO_JPEG_IMAGE_OFFSET = 84;
+    private static final int RAF_INFO_SIZE = 160;
+    private static final int RAF_JPEG_LENGTH_VALUE_SIZE = 4;
+
+    private static final byte[] HEIF_TYPE_FTYP = new byte[] {'f', 't', 'y', 'p'};
+    private static final byte[] HEIF_BRAND_MIF1 = new byte[] {'m', 'i', 'f', '1'};
+    private static final byte[] HEIF_BRAND_HEIC = new byte[] {'h', 'e', 'i', 'c'};
+    private static final byte[] HEIF_BRAND_AVIF = new byte[] {'a', 'v', 'i', 'f'};
+    private static final byte[] HEIF_BRAND_AVIS = new byte[] {'a', 'v', 'i', 's'};
+
+    // See http://fileformats.archiveteam.org/wiki/Olympus_ORF
+    private static final short ORF_SIGNATURE_1 = 0x4f52;
+    private static final short ORF_SIGNATURE_2 = 0x5352;
+    // There are two formats for Olympus Makernote Headers. Each has different identifiers and
+    // offsets to the actual data.
+    // See http://www.exiv2.org/makernote.html#R1
+    private static final byte[] ORF_MAKER_NOTE_HEADER_1 = new byte[] {(byte) 0x4f, (byte) 0x4c,
+            (byte) 0x59, (byte) 0x4d, (byte) 0x50, (byte) 0x00}; // "OLYMP\0"
+    private static final byte[] ORF_MAKER_NOTE_HEADER_2 = new byte[] {(byte) 0x4f, (byte) 0x4c,
+            (byte) 0x59, (byte) 0x4d, (byte) 0x50, (byte) 0x55, (byte) 0x53, (byte) 0x00,
+            (byte) 0x49, (byte) 0x49}; // "OLYMPUS\0II"
+    private static final int ORF_MAKER_NOTE_HEADER_1_SIZE = 8;
+    private static final int ORF_MAKER_NOTE_HEADER_2_SIZE = 12;
+
+    // See http://fileformats.archiveteam.org/wiki/RW2
+    private static final short RW2_SIGNATURE = 0x0055;
+
+    // See http://fileformats.archiveteam.org/wiki/Pentax_PEF
+    private static final String PEF_SIGNATURE = "PENTAX";
+    // See http://www.exiv2.org/makernote.html#R11
+    private static final int PEF_MAKER_NOTE_SKIP_SIZE = 6;
+
+    // See PNG (Portable Network Graphics) Specification, Version 1.2,
+    // 3.1. PNG file signature
+    private static final byte[] PNG_SIGNATURE = new byte[] {(byte) 0x89, (byte) 0x50, (byte) 0x4e,
+            (byte) 0x47, (byte) 0x0d, (byte) 0x0a, (byte) 0x1a, (byte) 0x0a};
+    // See PNG (Portable Network Graphics) Specification, Version 1.2,
+    // 3.7. eXIf Exchangeable Image File (Exif) Profile
+    private static final byte[] PNG_CHUNK_TYPE_EXIF = new byte[]{(byte) 0x65, (byte) 0x58,
+            (byte) 0x49, (byte) 0x66};
+    private static final byte[] PNG_CHUNK_TYPE_IHDR = new byte[]{(byte) 0x49, (byte) 0x48,
+            (byte) 0x44, (byte) 0x52};
+    private static final byte[] PNG_CHUNK_TYPE_IEND = new byte[]{(byte) 0x49, (byte) 0x45,
+            (byte) 0x4e, (byte) 0x44};
+    private static final int PNG_CHUNK_TYPE_BYTE_LENGTH = 4;
+    private static final int PNG_CHUNK_CRC_BYTE_LENGTH = 4;
+
+    // See https://developers.google.com/speed/webp/docs/riff_container, Section "WebP File Header"
+    private static final byte[] WEBP_SIGNATURE_1 = new byte[] {'R', 'I', 'F', 'F'};
+    private static final byte[] WEBP_SIGNATURE_2 = new byte[] {'W', 'E', 'B', 'P'};
+    private static final int WEBP_FILE_SIZE_BYTE_LENGTH = 4;
+    private static final byte[] WEBP_CHUNK_TYPE_EXIF = new byte[]{(byte) 0x45, (byte) 0x58,
+            (byte) 0x49, (byte) 0x46};
+    private static final byte[] WEBP_VP8_SIGNATURE = new byte[]{(byte) 0x9d, (byte) 0x01,
+            (byte) 0x2a};
+    private static final byte WEBP_VP8L_SIGNATURE = (byte) 0x2f;
+    private static final byte[] WEBP_CHUNK_TYPE_VP8X = "VP8X".getBytes(Charset.defaultCharset());
+    private static final byte[] WEBP_CHUNK_TYPE_VP8L = "VP8L".getBytes(Charset.defaultCharset());
+    private static final byte[] WEBP_CHUNK_TYPE_VP8 = "VP8 ".getBytes(Charset.defaultCharset());
+    private static final byte[] WEBP_CHUNK_TYPE_ANIM = "ANIM".getBytes(Charset.defaultCharset());
+    private static final byte[] WEBP_CHUNK_TYPE_ANMF = "ANMF".getBytes(Charset.defaultCharset());
+    private static final int WEBP_CHUNK_TYPE_VP8X_DEFAULT_LENGTH = 10;
+    private static final int WEBP_CHUNK_TYPE_BYTE_LENGTH = 4;
+    private static final int WEBP_CHUNK_SIZE_BYTE_LENGTH = 4;
+
+    @GuardedBy("sFormatter")
+    private static SimpleDateFormat sFormatter;
+    @GuardedBy("sFormatterTz")
+    private static SimpleDateFormat sFormatterTz;
+
+    // See Exchangeable image file format for digital still cameras: Exif version 2.2.
+    // The following values are for parsing EXIF data area. There are tag groups in EXIF data area.
+    // They are called "Image File Directory". They have multiple data formats to cover various
+    // image metadata from GPS longitude to camera model name.
+
+    // Types of Exif byte alignments (see JEITA CP-3451C Section 4.5.2)
+    private static final short BYTE_ALIGN_II = 0x4949;  // II: Intel order
+    private static final short BYTE_ALIGN_MM = 0x4d4d;  // MM: Motorola order
+
+    // TIFF Header Fixed Constant (see JEITA CP-3451C Section 4.5.2)
+    private static final byte START_CODE = 0x2a; // 42
+    private static final int IFD_OFFSET = 8;
+
+    // Formats for the value in IFD entry (See TIFF 6.0 Section 2, "Image File Directory".)
+    private static final int IFD_FORMAT_BYTE = 1;
+    private static final int IFD_FORMAT_STRING = 2;
+    private static final int IFD_FORMAT_USHORT = 3;
+    private static final int IFD_FORMAT_ULONG = 4;
+    private static final int IFD_FORMAT_URATIONAL = 5;
+    private static final int IFD_FORMAT_SBYTE = 6;
+    private static final int IFD_FORMAT_UNDEFINED = 7;
+    private static final int IFD_FORMAT_SSHORT = 8;
+    private static final int IFD_FORMAT_SLONG = 9;
+    private static final int IFD_FORMAT_SRATIONAL = 10;
+    private static final int IFD_FORMAT_SINGLE = 11;
+    private static final int IFD_FORMAT_DOUBLE = 12;
+    // Format indicating a new IFD entry (See Adobe PageMaker® 6.0 TIFF Technical Notes, "New Tag")
+    private static final int IFD_FORMAT_IFD = 13;
+    // Names for the data formats for debugging purpose.
+    private static final String[] IFD_FORMAT_NAMES = new String[] {
+            "", "BYTE", "STRING", "USHORT", "ULONG", "URATIONAL", "SBYTE", "UNDEFINED", "SSHORT",
+            "SLONG", "SRATIONAL", "SINGLE", "DOUBLE", "IFD"
+    };
+    // Sizes of the components of each IFD value format
+    private static final int[] IFD_FORMAT_BYTES_PER_FORMAT = new int[] {
+            0, 1, 1, 2, 4, 8, 1, 1, 2, 4, 8, 4, 8, 1
+    };
+    private static final byte[] EXIF_ASCII_PREFIX = new byte[] {
+            0x41, 0x53, 0x43, 0x49, 0x49, 0x0, 0x0, 0x0
+    };
+
+    /**
+     * Constants used for Compression tag.
+     * For Value 1, 2, 32773, see TIFF 6.0 Spec Section 3: Bilevel Images, Compression
+     * For Value 6, see TIFF 6.0 Spec Section 22: JPEG Compression, Extensions to Existing Fields
+     * For Value 7, 8, 34892, see DNG Specification 1.4.0.0. Section 3, Compression
+     */
+    private static final int DATA_UNCOMPRESSED = 1;
+    private static final int DATA_HUFFMAN_COMPRESSED = 2;
+    private static final int DATA_JPEG = 6;
+    private static final int DATA_JPEG_COMPRESSED = 7;
+    private static final int DATA_DEFLATE_ZIP = 8;
+    private static final int DATA_PACK_BITS_COMPRESSED = 32773;
+    private static final int DATA_LOSSY_JPEG = 34892;
+
+    /**
+     * Constants used for BitsPerSample tag.
+     * For RGB, see TIFF 6.0 Spec Section 6, Differences from Palette Color Images
+     * For Greyscale, see TIFF 6.0 Spec Section 4, Differences from Bilevel Images
+     */
+    private static final int[] BITS_PER_SAMPLE_RGB = new int[] { 8, 8, 8 };
+    private static final int[] BITS_PER_SAMPLE_GREYSCALE_1 = new int[] { 4 };
+    private static final int[] BITS_PER_SAMPLE_GREYSCALE_2 = new int[] { 8 };
+
+    /**
+     * Constants used for PhotometricInterpretation tag.
+     * For White/Black, see Section 3, Color.
+     * See TIFF 6.0 Spec Section 22, Minimum Requirements for TIFF with JPEG Compression.
+     */
+    private static final int PHOTOMETRIC_INTERPRETATION_WHITE_IS_ZERO = 0;
+    private static final int PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO = 1;
+    private static final int PHOTOMETRIC_INTERPRETATION_RGB = 2;
+    private static final int PHOTOMETRIC_INTERPRETATION_YCBCR = 6;
+
+    /**
+     * Constants used for NewSubfileType tag.
+     * See TIFF 6.0 Spec Section 8
+     * */
+    private static final int ORIGINAL_RESOLUTION_IMAGE = 0;
+    private static final int REDUCED_RESOLUTION_IMAGE = 1;
+
+    // A class for indicating EXIF rational type.
+    private static class Rational {
+        public final long numerator;
+        public final long denominator;
+
+        private Rational(long numerator, long denominator) {
+            // Handle erroneous case
+            if (denominator == 0) {
+                this.numerator = 0;
+                this.denominator = 1;
+                return;
+            }
+            this.numerator = numerator;
+            this.denominator = denominator;
+        }
+
+        @Override
+        public String toString() {
+            return numerator + "/" + denominator;
+        }
+
+        public double calculate() {
+            return (double) numerator / denominator;
+        }
+    }
+
+    // A class for indicating EXIF attribute.
+    private static class ExifAttribute {
+        public final int format;
+        public final int numberOfComponents;
+        public final long bytesOffset;
+        public final byte[] bytes;
+
+        public static final long BYTES_OFFSET_UNKNOWN = -1;
+
+        private ExifAttribute(int format, int numberOfComponents, byte[] bytes) {
+            this(format, numberOfComponents, BYTES_OFFSET_UNKNOWN, bytes);
+        }
+
+        private ExifAttribute(int format, int numberOfComponents, long bytesOffset, byte[] bytes) {
+            this.format = format;
+            this.numberOfComponents = numberOfComponents;
+            this.bytesOffset = bytesOffset;
+            this.bytes = bytes;
+        }
+
+        public static ExifAttribute createUShort(int[] values, ByteOrder byteOrder) {
+            final ByteBuffer buffer = ByteBuffer.wrap(
+                    new byte[IFD_FORMAT_BYTES_PER_FORMAT[IFD_FORMAT_USHORT] * values.length]);
+            buffer.order(byteOrder);
+            for (int value : values) {
+                buffer.putShort((short) value);
+            }
+            return new ExifAttribute(IFD_FORMAT_USHORT, values.length, buffer.array());
+        }
+
+        public static ExifAttribute createUShort(int value, ByteOrder byteOrder) {
+            return createUShort(new int[] {value}, byteOrder);
+        }
+
+        public static ExifAttribute createULong(long[] values, ByteOrder byteOrder) {
+            final ByteBuffer buffer = ByteBuffer.wrap(
+                    new byte[IFD_FORMAT_BYTES_PER_FORMAT[IFD_FORMAT_ULONG] * values.length]);
+            buffer.order(byteOrder);
+            for (long value : values) {
+                buffer.putInt((int) value);
+            }
+            return new ExifAttribute(IFD_FORMAT_ULONG, values.length, buffer.array());
+        }
+
+        public static ExifAttribute createULong(long value, ByteOrder byteOrder) {
+            return createULong(new long[] {value}, byteOrder);
+        }
+
+        public static ExifAttribute createSLong(int[] values, ByteOrder byteOrder) {
+            final ByteBuffer buffer = ByteBuffer.wrap(
+                    new byte[IFD_FORMAT_BYTES_PER_FORMAT[IFD_FORMAT_SLONG] * values.length]);
+            buffer.order(byteOrder);
+            for (int value : values) {
+                buffer.putInt(value);
+            }
+            return new ExifAttribute(IFD_FORMAT_SLONG, values.length, buffer.array());
+        }
+
+        public static ExifAttribute createSLong(int value, ByteOrder byteOrder) {
+            return createSLong(new int[] {value}, byteOrder);
+        }
+
+        public static ExifAttribute createByte(String value) {
+            // Exception for GPSAltitudeRef tag
+            if (value.length() == 1 && value.charAt(0) >= '0' && value.charAt(0) <= '1') {
+                final byte[] bytes = new byte[] { (byte) (value.charAt(0) - '0') };
+                return new ExifAttribute(IFD_FORMAT_BYTE, bytes.length, bytes);
+            }
+            final byte[] ascii = value.getBytes(ASCII);
+            return new ExifAttribute(IFD_FORMAT_BYTE, ascii.length, ascii);
+        }
+
+        public static ExifAttribute createString(String value) {
+            final byte[] ascii = (value + '\0').getBytes(ASCII);
+            return new ExifAttribute(IFD_FORMAT_STRING, ascii.length, ascii);
+        }
+
+        public static ExifAttribute createURational(Rational[] values, ByteOrder byteOrder) {
+            final ByteBuffer buffer = ByteBuffer.wrap(
+                    new byte[IFD_FORMAT_BYTES_PER_FORMAT[IFD_FORMAT_URATIONAL] * values.length]);
+            buffer.order(byteOrder);
+            for (Rational value : values) {
+                buffer.putInt((int) value.numerator);
+                buffer.putInt((int) value.denominator);
+            }
+            return new ExifAttribute(IFD_FORMAT_URATIONAL, values.length, buffer.array());
+        }
+
+        public static ExifAttribute createURational(Rational value, ByteOrder byteOrder) {
+            return createURational(new Rational[] {value}, byteOrder);
+        }
+
+        public static ExifAttribute createSRational(Rational[] values, ByteOrder byteOrder) {
+            final ByteBuffer buffer = ByteBuffer.wrap(
+                    new byte[IFD_FORMAT_BYTES_PER_FORMAT[IFD_FORMAT_SRATIONAL] * values.length]);
+            buffer.order(byteOrder);
+            for (Rational value : values) {
+                buffer.putInt((int) value.numerator);
+                buffer.putInt((int) value.denominator);
+            }
+            return new ExifAttribute(IFD_FORMAT_SRATIONAL, values.length, buffer.array());
+        }
+
+        public static ExifAttribute createSRational(Rational value, ByteOrder byteOrder) {
+            return createSRational(new Rational[] {value}, byteOrder);
+        }
+
+        public static ExifAttribute createDouble(double[] values, ByteOrder byteOrder) {
+            final ByteBuffer buffer = ByteBuffer.wrap(
+                    new byte[IFD_FORMAT_BYTES_PER_FORMAT[IFD_FORMAT_DOUBLE] * values.length]);
+            buffer.order(byteOrder);
+            for (double value : values) {
+                buffer.putDouble(value);
+            }
+            return new ExifAttribute(IFD_FORMAT_DOUBLE, values.length, buffer.array());
+        }
+
+        public static ExifAttribute createDouble(double value, ByteOrder byteOrder) {
+            return createDouble(new double[] {value}, byteOrder);
+        }
+
+        @Override
+        public String toString() {
+            return "(" + IFD_FORMAT_NAMES[format] + ", data length:" + bytes.length + ")";
+        }
+
+        private Object getValue(ByteOrder byteOrder) {
+            try {
+                ByteOrderedDataInputStream inputStream =
+                        new ByteOrderedDataInputStream(bytes);
+                inputStream.setByteOrder(byteOrder);
+                switch (format) {
+                    case IFD_FORMAT_BYTE:
+                    case IFD_FORMAT_SBYTE: {
+                        // Exception for GPSAltitudeRef tag
+                        if (bytes.length == 1 && bytes[0] >= 0 && bytes[0] <= 1) {
+                            return new String(new char[] { (char) (bytes[0] + '0') });
+                        }
+                        return new String(bytes, ASCII);
+                    }
+                    case IFD_FORMAT_UNDEFINED:
+                    case IFD_FORMAT_STRING: {
+                        int index = 0;
+                        if (numberOfComponents >= EXIF_ASCII_PREFIX.length) {
+                            boolean same = true;
+                            for (int i = 0; i < EXIF_ASCII_PREFIX.length; ++i) {
+                                if (bytes[i] != EXIF_ASCII_PREFIX[i]) {
+                                    same = false;
+                                    break;
+                                }
+                            }
+                            if (same) {
+                                index = EXIF_ASCII_PREFIX.length;
+                            }
+                        }
+
+                        StringBuilder stringBuilder = new StringBuilder();
+                        while (index < numberOfComponents) {
+                            int ch = bytes[index];
+                            if (ch == 0) {
+                                break;
+                            }
+                            if (ch >= 32) {
+                                stringBuilder.append((char) ch);
+                            } else {
+                                stringBuilder.append('?');
+                            }
+                            ++index;
+                        }
+                        return stringBuilder.toString();
+                    }
+                    case IFD_FORMAT_USHORT: {
+                        final int[] values = new int[numberOfComponents];
+                        for (int i = 0; i < numberOfComponents; ++i) {
+                            values[i] = inputStream.readUnsignedShort();
+                        }
+                        return values;
+                    }
+                    case IFD_FORMAT_ULONG: {
+                        final long[] values = new long[numberOfComponents];
+                        for (int i = 0; i < numberOfComponents; ++i) {
+                            values[i] = inputStream.readUnsignedInt();
+                        }
+                        return values;
+                    }
+                    case IFD_FORMAT_URATIONAL: {
+                        final Rational[] values = new Rational[numberOfComponents];
+                        for (int i = 0; i < numberOfComponents; ++i) {
+                            final long numerator = inputStream.readUnsignedInt();
+                            final long denominator = inputStream.readUnsignedInt();
+                            values[i] = new Rational(numerator, denominator);
+                        }
+                        return values;
+                    }
+                    case IFD_FORMAT_SSHORT: {
+                        final int[] values = new int[numberOfComponents];
+                        for (int i = 0; i < numberOfComponents; ++i) {
+                            values[i] = inputStream.readShort();
+                        }
+                        return values;
+                    }
+                    case IFD_FORMAT_SLONG: {
+                        final int[] values = new int[numberOfComponents];
+                        for (int i = 0; i < numberOfComponents; ++i) {
+                            values[i] = inputStream.readInt();
+                        }
+                        return values;
+                    }
+                    case IFD_FORMAT_SRATIONAL: {
+                        final Rational[] values = new Rational[numberOfComponents];
+                        for (int i = 0; i < numberOfComponents; ++i) {
+                            final long numerator = inputStream.readInt();
+                            final long denominator = inputStream.readInt();
+                            values[i] = new Rational(numerator, denominator);
+                        }
+                        return values;
+                    }
+                    case IFD_FORMAT_SINGLE: {
+                        final double[] values = new double[numberOfComponents];
+                        for (int i = 0; i < numberOfComponents; ++i) {
+                            values[i] = inputStream.readFloat();
+                        }
+                        return values;
+                    }
+                    case IFD_FORMAT_DOUBLE: {
+                        final double[] values = new double[numberOfComponents];
+                        for (int i = 0; i < numberOfComponents; ++i) {
+                            values[i] = inputStream.readDouble();
+                        }
+                        return values;
+                    }
+                    default:
+                        return null;
+                }
+            } catch (IOException e) {
+                Log.w(TAG, "IOException occurred during reading a value", e);
+                return null;
+            }
+        }
+
+        public double getDoubleValue(ByteOrder byteOrder) {
+            Object value = getValue(byteOrder);
+            if (value == null) {
+                throw new NumberFormatException("NULL can't be converted to a double value");
+            }
+            if (value instanceof String) {
+                return Double.parseDouble((String) value);
+            }
+            if (value instanceof long[]) {
+                long[] array = (long[]) value;
+                if (array.length == 1) {
+                    return array[0];
+                }
+                throw new NumberFormatException("There are more than one component");
+            }
+            if (value instanceof int[]) {
+                int[] array = (int[]) value;
+                if (array.length == 1) {
+                    return array[0];
+                }
+                throw new NumberFormatException("There are more than one component");
+            }
+            if (value instanceof double[]) {
+                double[] array = (double[]) value;
+                if (array.length == 1) {
+                    return array[0];
+                }
+                throw new NumberFormatException("There are more than one component");
+            }
+            if (value instanceof Rational[]) {
+                Rational[] array = (Rational[]) value;
+                if (array.length == 1) {
+                    return array[0].calculate();
+                }
+                throw new NumberFormatException("There are more than one component");
+            }
+            throw new NumberFormatException("Couldn't find a double value");
+        }
+
+        public int getIntValue(ByteOrder byteOrder) {
+            Object value = getValue(byteOrder);
+            if (value == null) {
+                throw new NumberFormatException("NULL can't be converted to a integer value");
+            }
+            if (value instanceof String) {
+                return Integer.parseInt((String) value);
+            }
+            if (value instanceof long[]) {
+                long[] array = (long[]) value;
+                if (array.length == 1) {
+                    return (int) array[0];
+                }
+                throw new NumberFormatException("There are more than one component");
+            }
+            if (value instanceof int[]) {
+                int[] array = (int[]) value;
+                if (array.length == 1) {
+                    return array[0];
+                }
+                throw new NumberFormatException("There are more than one component");
+            }
+            throw new NumberFormatException("Couldn't find a integer value");
+        }
+
+        public String getStringValue(ByteOrder byteOrder) {
+            Object value = getValue(byteOrder);
+            if (value == null) {
+                return null;
+            }
+            if (value instanceof String) {
+                return (String) value;
+            }
+
+            final StringBuilder stringBuilder = new StringBuilder();
+            if (value instanceof long[]) {
+                long[] array = (long[]) value;
+                for (int i = 0; i < array.length; ++i) {
+                    stringBuilder.append(array[i]);
+                    if (i + 1 != array.length) {
+                        stringBuilder.append(",");
+                    }
+                }
+                return stringBuilder.toString();
+            }
+            if (value instanceof int[]) {
+                int[] array = (int[]) value;
+                for (int i = 0; i < array.length; ++i) {
+                    stringBuilder.append(array[i]);
+                    if (i + 1 != array.length) {
+                        stringBuilder.append(",");
+                    }
+                }
+                return stringBuilder.toString();
+            }
+            if (value instanceof double[]) {
+                double[] array = (double[]) value;
+                for (int i = 0; i < array.length; ++i) {
+                    stringBuilder.append(array[i]);
+                    if (i + 1 != array.length) {
+                        stringBuilder.append(",");
+                    }
+                }
+                return stringBuilder.toString();
+            }
+            if (value instanceof Rational[]) {
+                Rational[] array = (Rational[]) value;
+                for (int i = 0; i < array.length; ++i) {
+                    stringBuilder.append(array[i].numerator);
+                    stringBuilder.append('/');
+                    stringBuilder.append(array[i].denominator);
+                    if (i + 1 != array.length) {
+                        stringBuilder.append(",");
+                    }
+                }
+                return stringBuilder.toString();
+            }
+            return null;
+        }
+
+        public int size() {
+            return IFD_FORMAT_BYTES_PER_FORMAT[format] * numberOfComponents;
+        }
+    }
+
+    // A class for indicating EXIF tag.
+    private static class ExifTag {
+        public final int number;
+        public final String name;
+        public final int primaryFormat;
+        public final int secondaryFormat;
+
+        private ExifTag(String name, int number, int format) {
+            this.name = name;
+            this.number = number;
+            this.primaryFormat = format;
+            this.secondaryFormat = -1;
+        }
+
+        private ExifTag(String name, int number, int primaryFormat, int secondaryFormat) {
+            this.name = name;
+            this.number = number;
+            this.primaryFormat = primaryFormat;
+            this.secondaryFormat = secondaryFormat;
+        }
+    }
+
+    // Primary image IFD TIFF tags (See JEITA CP-3451C Section 4.6.8 Tag Support Levels)
+    private static final ExifTag[] IFD_TIFF_TAGS = new ExifTag[] {
+            // For below two, see TIFF 6.0 Spec Section 3: Bilevel Images.
+            new ExifTag(TAG_NEW_SUBFILE_TYPE, 254, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_SUBFILE_TYPE, 255, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_IMAGE_WIDTH, 256, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_IMAGE_LENGTH, 257, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_BITS_PER_SAMPLE, 258, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_COMPRESSION, 259, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_PHOTOMETRIC_INTERPRETATION, 262, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_IMAGE_DESCRIPTION, 270, IFD_FORMAT_STRING),
+            new ExifTag(TAG_MAKE, 271, IFD_FORMAT_STRING),
+            new ExifTag(TAG_MODEL, 272, IFD_FORMAT_STRING),
+            new ExifTag(TAG_STRIP_OFFSETS, 273, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_ORIENTATION, 274, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_SAMPLES_PER_PIXEL, 277, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_ROWS_PER_STRIP, 278, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_STRIP_BYTE_COUNTS, 279, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_X_RESOLUTION, 282, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_Y_RESOLUTION, 283, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_PLANAR_CONFIGURATION, 284, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_RESOLUTION_UNIT, 296, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_TRANSFER_FUNCTION, 301, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_SOFTWARE, 305, IFD_FORMAT_STRING),
+            new ExifTag(TAG_DATETIME, 306, IFD_FORMAT_STRING),
+            new ExifTag(TAG_ARTIST, 315, IFD_FORMAT_STRING),
+            new ExifTag(TAG_WHITE_POINT, 318, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_PRIMARY_CHROMATICITIES, 319, IFD_FORMAT_URATIONAL),
+            // See Adobe PageMaker® 6.0 TIFF Technical Notes, Note 1.
+            new ExifTag(TAG_SUB_IFD_POINTER, 330, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT, 513, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, 514, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_Y_CB_CR_COEFFICIENTS, 529, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_Y_CB_CR_SUB_SAMPLING, 530, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_Y_CB_CR_POSITIONING, 531, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_REFERENCE_BLACK_WHITE, 532, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_COPYRIGHT, 33432, IFD_FORMAT_STRING),
+            new ExifTag(TAG_EXIF_IFD_POINTER, 34665, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_GPS_INFO_IFD_POINTER, 34853, IFD_FORMAT_ULONG),
+            // RW2 file tags
+            // See http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/PanasonicRaw.html)
+            new ExifTag(TAG_RW2_SENSOR_TOP_BORDER, 4, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_RW2_SENSOR_LEFT_BORDER, 5, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_RW2_SENSOR_BOTTOM_BORDER, 6, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_RW2_SENSOR_RIGHT_BORDER, 7, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_RW2_ISO, 23, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_RW2_JPG_FROM_RAW, 46, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_XMP, 700, IFD_FORMAT_BYTE),
+    };
+
+    // Primary image IFD Exif Private tags (See JEITA CP-3451C Section 4.6.8 Tag Support Levels)
+    private static final ExifTag[] IFD_EXIF_TAGS = new ExifTag[] {
+            new ExifTag(TAG_EXPOSURE_TIME, 33434, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_F_NUMBER, 33437, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_EXPOSURE_PROGRAM, 34850, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_SPECTRAL_SENSITIVITY, 34852, IFD_FORMAT_STRING),
+            new ExifTag(TAG_ISO_SPEED_RATINGS, 34855, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_OECF, 34856, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_EXIF_VERSION, 36864, IFD_FORMAT_STRING),
+            new ExifTag(TAG_DATETIME_ORIGINAL, 36867, IFD_FORMAT_STRING),
+            new ExifTag(TAG_DATETIME_DIGITIZED, 36868, IFD_FORMAT_STRING),
+            new ExifTag(TAG_OFFSET_TIME, 36880, IFD_FORMAT_STRING),
+            new ExifTag(TAG_OFFSET_TIME_ORIGINAL, 36881, IFD_FORMAT_STRING),
+            new ExifTag(TAG_OFFSET_TIME_DIGITIZED, 36882, IFD_FORMAT_STRING),
+            new ExifTag(TAG_COMPONENTS_CONFIGURATION, 37121, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_COMPRESSED_BITS_PER_PIXEL, 37122, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_SHUTTER_SPEED_VALUE, 37377, IFD_FORMAT_SRATIONAL),
+            new ExifTag(TAG_APERTURE_VALUE, 37378, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_BRIGHTNESS_VALUE, 37379, IFD_FORMAT_SRATIONAL),
+            new ExifTag(TAG_EXPOSURE_BIAS_VALUE, 37380, IFD_FORMAT_SRATIONAL),
+            new ExifTag(TAG_MAX_APERTURE_VALUE, 37381, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_SUBJECT_DISTANCE, 37382, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_METERING_MODE, 37383, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_LIGHT_SOURCE, 37384, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_FLASH, 37385, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_FOCAL_LENGTH, 37386, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_SUBJECT_AREA, 37396, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_MAKER_NOTE, 37500, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_USER_COMMENT, 37510, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_SUBSEC_TIME, 37520, IFD_FORMAT_STRING),
+            new ExifTag(TAG_SUBSEC_TIME_ORIG, 37521, IFD_FORMAT_STRING),
+            new ExifTag(TAG_SUBSEC_TIME_DIG, 37522, IFD_FORMAT_STRING),
+            new ExifTag(TAG_FLASHPIX_VERSION, 40960, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_COLOR_SPACE, 40961, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_PIXEL_X_DIMENSION, 40962, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_PIXEL_Y_DIMENSION, 40963, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_RELATED_SOUND_FILE, 40964, IFD_FORMAT_STRING),
+            new ExifTag(TAG_INTEROPERABILITY_IFD_POINTER, 40965, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_FLASH_ENERGY, 41483, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_SPATIAL_FREQUENCY_RESPONSE, 41484, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_FOCAL_PLANE_X_RESOLUTION, 41486, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_FOCAL_PLANE_Y_RESOLUTION, 41487, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_FOCAL_PLANE_RESOLUTION_UNIT, 41488, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_SUBJECT_LOCATION, 41492, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_EXPOSURE_INDEX, 41493, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_SENSING_METHOD, 41495, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_FILE_SOURCE, 41728, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_SCENE_TYPE, 41729, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_CFA_PATTERN, 41730, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_CUSTOM_RENDERED, 41985, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_EXPOSURE_MODE, 41986, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_WHITE_BALANCE, 41987, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_DIGITAL_ZOOM_RATIO, 41988, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_FOCAL_LENGTH_IN_35MM_FILM, 41989, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_SCENE_CAPTURE_TYPE, 41990, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_GAIN_CONTROL, 41991, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_CONTRAST, 41992, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_SATURATION, 41993, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_SHARPNESS, 41994, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_DEVICE_SETTING_DESCRIPTION, 41995, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_SUBJECT_DISTANCE_RANGE, 41996, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_IMAGE_UNIQUE_ID, 42016, IFD_FORMAT_STRING),
+            new ExifTag(TAG_DNG_VERSION, 50706, IFD_FORMAT_BYTE),
+            new ExifTag(TAG_DEFAULT_CROP_SIZE, 50720, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG)
+    };
+
+    // Primary image IFD GPS Info tags (See JEITA CP-3451C Section 4.6.8 Tag Support Levels)
+    private static final ExifTag[] IFD_GPS_TAGS = new ExifTag[] {
+            new ExifTag(TAG_GPS_VERSION_ID, 0, IFD_FORMAT_BYTE),
+            new ExifTag(TAG_GPS_LATITUDE_REF, 1, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_LATITUDE, 2, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_GPS_LONGITUDE_REF, 3, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_LONGITUDE, 4, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_GPS_ALTITUDE_REF, 5, IFD_FORMAT_BYTE),
+            new ExifTag(TAG_GPS_ALTITUDE, 6, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_GPS_TIMESTAMP, 7, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_GPS_SATELLITES, 8, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_STATUS, 9, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_MEASURE_MODE, 10, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_DOP, 11, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_GPS_SPEED_REF, 12, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_SPEED, 13, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_GPS_TRACK_REF, 14, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_TRACK, 15, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_GPS_IMG_DIRECTION_REF, 16, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_IMG_DIRECTION, 17, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_GPS_MAP_DATUM, 18, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_DEST_LATITUDE_REF, 19, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_DEST_LATITUDE, 20, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_GPS_DEST_LONGITUDE_REF, 21, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_DEST_LONGITUDE, 22, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_GPS_DEST_BEARING_REF, 23, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_DEST_BEARING, 24, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_GPS_DEST_DISTANCE_REF, 25, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_DEST_DISTANCE, 26, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_GPS_PROCESSING_METHOD, 27, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_GPS_AREA_INFORMATION, 28, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_GPS_DATESTAMP, 29, IFD_FORMAT_STRING),
+            new ExifTag(TAG_GPS_DIFFERENTIAL, 30, IFD_FORMAT_USHORT)
+    };
+    // Primary image IFD Interoperability tag (See JEITA CP-3451C Section 4.6.8 Tag Support Levels)
+    private static final ExifTag[] IFD_INTEROPERABILITY_TAGS = new ExifTag[] {
+            new ExifTag(TAG_INTEROPERABILITY_INDEX, 1, IFD_FORMAT_STRING)
+    };
+    // IFD Thumbnail tags (See JEITA CP-3451C Section 4.6.8 Tag Support Levels)
+    private static final ExifTag[] IFD_THUMBNAIL_TAGS = new ExifTag[] {
+            // For below two, see TIFF 6.0 Spec Section 3: Bilevel Images.
+            new ExifTag(TAG_NEW_SUBFILE_TYPE, 254, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_SUBFILE_TYPE, 255, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_THUMBNAIL_IMAGE_WIDTH, 256, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_THUMBNAIL_IMAGE_LENGTH, 257, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_BITS_PER_SAMPLE, 258, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_COMPRESSION, 259, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_PHOTOMETRIC_INTERPRETATION, 262, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_IMAGE_DESCRIPTION, 270, IFD_FORMAT_STRING),
+            new ExifTag(TAG_MAKE, 271, IFD_FORMAT_STRING),
+            new ExifTag(TAG_MODEL, 272, IFD_FORMAT_STRING),
+            new ExifTag(TAG_STRIP_OFFSETS, 273, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_THUMBNAIL_ORIENTATION, 274, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_SAMPLES_PER_PIXEL, 277, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_ROWS_PER_STRIP, 278, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_STRIP_BYTE_COUNTS, 279, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_X_RESOLUTION, 282, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_Y_RESOLUTION, 283, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_PLANAR_CONFIGURATION, 284, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_RESOLUTION_UNIT, 296, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_TRANSFER_FUNCTION, 301, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_SOFTWARE, 305, IFD_FORMAT_STRING),
+            new ExifTag(TAG_DATETIME, 306, IFD_FORMAT_STRING),
+            new ExifTag(TAG_ARTIST, 315, IFD_FORMAT_STRING),
+            new ExifTag(TAG_WHITE_POINT, 318, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_PRIMARY_CHROMATICITIES, 319, IFD_FORMAT_URATIONAL),
+            // See Adobe PageMaker® 6.0 TIFF Technical Notes, Note 1.
+            new ExifTag(TAG_SUB_IFD_POINTER, 330, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT, 513, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, 514, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_Y_CB_CR_COEFFICIENTS, 529, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_Y_CB_CR_SUB_SAMPLING, 530, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_Y_CB_CR_POSITIONING, 531, IFD_FORMAT_USHORT),
+            new ExifTag(TAG_REFERENCE_BLACK_WHITE, 532, IFD_FORMAT_URATIONAL),
+            new ExifTag(TAG_COPYRIGHT, 33432, IFD_FORMAT_STRING),
+            new ExifTag(TAG_EXIF_IFD_POINTER, 34665, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_GPS_INFO_IFD_POINTER, 34853, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_DNG_VERSION, 50706, IFD_FORMAT_BYTE),
+            new ExifTag(TAG_DEFAULT_CROP_SIZE, 50720, IFD_FORMAT_USHORT, IFD_FORMAT_ULONG)
+    };
+
+    // RAF file tag (See piex.cc line 372)
+    private static final ExifTag TAG_RAF_IMAGE_SIZE =
+            new ExifTag(TAG_STRIP_OFFSETS, 273, IFD_FORMAT_USHORT);
+
+    // ORF file tags (See http://www.exiv2.org/tags-olympus.html)
+    private static final ExifTag[] ORF_MAKER_NOTE_TAGS = new ExifTag[] {
+            new ExifTag(TAG_ORF_THUMBNAIL_IMAGE, 256, IFD_FORMAT_UNDEFINED),
+            new ExifTag(TAG_ORF_CAMERA_SETTINGS_IFD_POINTER, 8224, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_ORF_IMAGE_PROCESSING_IFD_POINTER, 8256, IFD_FORMAT_ULONG)
+    };
+    private static final ExifTag[] ORF_CAMERA_SETTINGS_TAGS = new ExifTag[] {
+            new ExifTag(TAG_ORF_PREVIEW_IMAGE_START, 257, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_ORF_PREVIEW_IMAGE_LENGTH, 258, IFD_FORMAT_ULONG)
+    };
+    private static final ExifTag[] ORF_IMAGE_PROCESSING_TAGS = new ExifTag[] {
+            new ExifTag(TAG_ORF_ASPECT_FRAME, 4371, IFD_FORMAT_USHORT)
+    };
+    // PEF file tag (See http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Pentax.html)
+    private static final ExifTag[] PEF_TAGS = new ExifTag[] {
+            new ExifTag(TAG_COLOR_SPACE, 55, IFD_FORMAT_USHORT)
+    };
+
+    // See JEITA CP-3451C Section 4.6.3: Exif-specific IFD.
+    // The following values are used for indicating pointers to the other Image File Directories.
+
+    // Indices of Exif Ifd tag groups
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({IFD_TYPE_PRIMARY, IFD_TYPE_EXIF, IFD_TYPE_GPS, IFD_TYPE_INTEROPERABILITY,
+            IFD_TYPE_THUMBNAIL, IFD_TYPE_PREVIEW, IFD_TYPE_ORF_MAKER_NOTE,
+            IFD_TYPE_ORF_CAMERA_SETTINGS, IFD_TYPE_ORF_IMAGE_PROCESSING, IFD_TYPE_PEF})
+    public @interface IfdType {}
+
+    private static final int IFD_TYPE_PRIMARY = 0;
+    private static final int IFD_TYPE_EXIF = 1;
+    private static final int IFD_TYPE_GPS = 2;
+    private static final int IFD_TYPE_INTEROPERABILITY = 3;
+    private static final int IFD_TYPE_THUMBNAIL = 4;
+    private static final int IFD_TYPE_PREVIEW = 5;
+    private static final int IFD_TYPE_ORF_MAKER_NOTE = 6;
+    private static final int IFD_TYPE_ORF_CAMERA_SETTINGS = 7;
+    private static final int IFD_TYPE_ORF_IMAGE_PROCESSING = 8;
+    private static final int IFD_TYPE_PEF = 9;
+
+    // List of Exif tag groups
+    private static final ExifTag[][] EXIF_TAGS = new ExifTag[][] {
+            IFD_TIFF_TAGS, IFD_EXIF_TAGS, IFD_GPS_TAGS, IFD_INTEROPERABILITY_TAGS,
+            IFD_THUMBNAIL_TAGS, IFD_TIFF_TAGS, ORF_MAKER_NOTE_TAGS, ORF_CAMERA_SETTINGS_TAGS,
+            ORF_IMAGE_PROCESSING_TAGS, PEF_TAGS
+    };
+    // List of tags for pointing to the other image file directory offset.
+    private static final ExifTag[] EXIF_POINTER_TAGS = new ExifTag[] {
+            new ExifTag(TAG_SUB_IFD_POINTER, 330, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_EXIF_IFD_POINTER, 34665, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_GPS_INFO_IFD_POINTER, 34853, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_INTEROPERABILITY_IFD_POINTER, 40965, IFD_FORMAT_ULONG),
+            new ExifTag(TAG_ORF_CAMERA_SETTINGS_IFD_POINTER, 8224, IFD_FORMAT_BYTE),
+            new ExifTag(TAG_ORF_IMAGE_PROCESSING_IFD_POINTER, 8256, IFD_FORMAT_BYTE)
+    };
+
+    // Tags for indicating the thumbnail offset and length
+    private static final ExifTag JPEG_INTERCHANGE_FORMAT_TAG =
+            new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT, 513, IFD_FORMAT_ULONG);
+    private static final ExifTag JPEG_INTERCHANGE_FORMAT_LENGTH_TAG =
+            new ExifTag(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH, 514, IFD_FORMAT_ULONG);
+
+    // Mappings from tag number to tag name and each item represents one IFD tag group.
+    private static final HashMap[] sExifTagMapsForReading = new HashMap[EXIF_TAGS.length];
+    // Mappings from tag name to tag number and each item represents one IFD tag group.
+    private static final HashMap[] sExifTagMapsForWriting = new HashMap[EXIF_TAGS.length];
+    private static final HashSet<String> sTagSetForCompatibility = new HashSet<>(Arrays.asList(
+            TAG_F_NUMBER, TAG_DIGITAL_ZOOM_RATIO, TAG_EXPOSURE_TIME, TAG_SUBJECT_DISTANCE,
+            TAG_GPS_TIMESTAMP));
+    // Mappings from tag number to IFD type for pointer tags.
+    private static final HashMap<Integer, Integer> sExifPointerTagMap = new HashMap();
+
+    // See JPEG File Interchange Format Version 1.02.
+    // The following values are defined for handling JPEG streams. In this implementation, we are
+    // not only getting information from EXIF but also from some JPEG special segments such as
+    // MARKER_COM for user comment and MARKER_SOFx for image width and height.
+
+    private static final Charset ASCII = Charset.forName("US-ASCII");
+    // Identifier for EXIF APP1 segment in JPEG
+    private static final byte[] IDENTIFIER_EXIF_APP1 = "Exif\0\0".getBytes(ASCII);
+    // Identifier for XMP APP1 segment in JPEG
+    private static final byte[] IDENTIFIER_XMP_APP1 = "http://ns.adobe.com/xap/1.0/\0".getBytes(ASCII);
+    // JPEG segment markers, that each marker consumes two bytes beginning with 0xff and ending with
+    // the indicator. There is no SOF4, SOF8, SOF16 markers in JPEG and SOFx markers indicates start
+    // of frame(baseline DCT) and the image size info exists in its beginning part.
+    private static final byte MARKER = (byte) 0xff;
+    private static final byte MARKER_SOI = (byte) 0xd8;
+    private static final byte MARKER_SOF0 = (byte) 0xc0;
+    private static final byte MARKER_SOF1 = (byte) 0xc1;
+    private static final byte MARKER_SOF2 = (byte) 0xc2;
+    private static final byte MARKER_SOF3 = (byte) 0xc3;
+    private static final byte MARKER_SOF5 = (byte) 0xc5;
+    private static final byte MARKER_SOF6 = (byte) 0xc6;
+    private static final byte MARKER_SOF7 = (byte) 0xc7;
+    private static final byte MARKER_SOF9 = (byte) 0xc9;
+    private static final byte MARKER_SOF10 = (byte) 0xca;
+    private static final byte MARKER_SOF11 = (byte) 0xcb;
+    private static final byte MARKER_SOF13 = (byte) 0xcd;
+    private static final byte MARKER_SOF14 = (byte) 0xce;
+    private static final byte MARKER_SOF15 = (byte) 0xcf;
+    private static final byte MARKER_SOS = (byte) 0xda;
+    private static final byte MARKER_APP1 = (byte) 0xe1;
+    private static final byte MARKER_COM = (byte) 0xfe;
+    private static final byte MARKER_EOI = (byte) 0xd9;
+
+    // Supported Image File Types
+    private static final int IMAGE_TYPE_UNKNOWN = 0;
+    private static final int IMAGE_TYPE_ARW = 1;
+    private static final int IMAGE_TYPE_CR2 = 2;
+    private static final int IMAGE_TYPE_DNG = 3;
+    private static final int IMAGE_TYPE_JPEG = 4;
+    private static final int IMAGE_TYPE_NEF = 5;
+    private static final int IMAGE_TYPE_NRW = 6;
+    private static final int IMAGE_TYPE_ORF = 7;
+    private static final int IMAGE_TYPE_PEF = 8;
+    private static final int IMAGE_TYPE_RAF = 9;
+    private static final int IMAGE_TYPE_RW2 = 10;
+    private static final int IMAGE_TYPE_SRW = 11;
+    private static final int IMAGE_TYPE_HEIF = 12;
+    private static final int IMAGE_TYPE_PNG = 13;
+    private static final int IMAGE_TYPE_WEBP = 14;
+
+    static {
+        sFormatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.US);
+        sFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
+        sFormatterTz = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss XXX", Locale.US);
+        sFormatterTz.setTimeZone(TimeZone.getTimeZone("UTC"));
+
+        // Build up the hash tables to look up Exif tags for reading Exif tags.
+        for (int ifdType = 0; ifdType < EXIF_TAGS.length; ++ifdType) {
+            sExifTagMapsForReading[ifdType] = new HashMap();
+            sExifTagMapsForWriting[ifdType] = new HashMap();
+            for (ExifTag tag : EXIF_TAGS[ifdType]) {
+                sExifTagMapsForReading[ifdType].put(tag.number, tag);
+                sExifTagMapsForWriting[ifdType].put(tag.name, tag);
+            }
+        }
+
+        // Build up the hash table to look up Exif pointer tags.
+        sExifPointerTagMap.put(EXIF_POINTER_TAGS[0].number, IFD_TYPE_PREVIEW); // 330
+        sExifPointerTagMap.put(EXIF_POINTER_TAGS[1].number, IFD_TYPE_EXIF); // 34665
+        sExifPointerTagMap.put(EXIF_POINTER_TAGS[2].number, IFD_TYPE_GPS); // 34853
+        sExifPointerTagMap.put(EXIF_POINTER_TAGS[3].number, IFD_TYPE_INTEROPERABILITY); // 40965
+        sExifPointerTagMap.put(EXIF_POINTER_TAGS[4].number, IFD_TYPE_ORF_CAMERA_SETTINGS); // 8224
+        sExifPointerTagMap.put(EXIF_POINTER_TAGS[5].number, IFD_TYPE_ORF_IMAGE_PROCESSING); // 8256
+    }
+
+    private String mFilename;
+    private FileDescriptor mSeekableFileDescriptor;
+    private AssetManager.AssetInputStream mAssetInputStream;
+    private boolean mIsInputStream;
+    private int mMimeType;
+    private boolean mIsExifDataOnly;
+    @UnsupportedAppUsage(publicAlternatives = "Use {@link #getAttribute(java.lang.String)} "
+            + "instead.")
+    private final HashMap[] mAttributes = new HashMap[EXIF_TAGS.length];
+    private Set<Integer> mHandledIfdOffsets = new HashSet<>(EXIF_TAGS.length);
+    private ByteOrder mExifByteOrder = ByteOrder.BIG_ENDIAN;
+    private boolean mHasThumbnail;
+    private boolean mHasThumbnailStrips;
+    private boolean mAreThumbnailStripsConsecutive;
+    // Used to indicate the position of the thumbnail (includes offset to EXIF data segment).
+    private int mThumbnailOffset;
+    private int mThumbnailLength;
+    private byte[] mThumbnailBytes;
+    private int mThumbnailCompression;
+    private int mExifOffset;
+    private int mOrfMakerNoteOffset;
+    private int mOrfThumbnailOffset;
+    private int mOrfThumbnailLength;
+    private int mRw2JpgFromRawOffset;
+    private boolean mIsSupportedFile;
+    private boolean mModified;
+    // XMP data can be contained as either part of the EXIF data (tag number 700), or as a
+    // separate data marker (a separate MARKER_APP1).
+    private boolean mXmpIsFromSeparateMarker;
+
+    // Pattern to check non zero timestamp
+    private static final Pattern sNonZeroTimePattern = Pattern.compile(".*[1-9].*");
+    // Pattern to check gps timestamp
+    private static final Pattern sGpsTimestampPattern =
+            Pattern.compile("^([0-9][0-9]):([0-9][0-9]):([0-9][0-9])$");
+
+    /**
+     * Reads Exif tags from the specified image file.
+     *
+     * @param file the file of the image data
+     * @throws NullPointerException if file is null
+     * @throws IOException if an I/O error occurs while retrieving file descriptor via
+     *         {@link FileInputStream#getFD()}.
+     */
+    public ExifInterface(@NonNull File file) throws IOException {
+        if (file == null) {
+            throw new NullPointerException("file cannot be null");
+        }
+        initForFilename(file.getAbsolutePath());
+    }
+
+    /**
+     * Reads Exif tags from the specified image file.
+     *
+     * @param filename the name of the file of the image data
+     * @throws NullPointerException if file name is null
+     * @throws IOException if an I/O error occurs while retrieving file descriptor via
+     *         {@link FileInputStream#getFD()}.
+     */
+    public ExifInterface(@NonNull String filename) throws IOException {
+        if (filename == null) {
+            throw new NullPointerException("filename cannot be null");
+        }
+        initForFilename(filename);
+    }
+
+    /**
+     * Reads Exif tags from the specified image file descriptor. Attribute mutation is supported
+     * for writable and seekable file descriptors only. This constructor will not rewind the offset
+     * of the given file descriptor. Developers should close the file descriptor after use.
+     *
+     * @param fileDescriptor the file descriptor of the image data
+     * @throws NullPointerException if file descriptor is null
+     * @throws IOException if an error occurs while duplicating the file descriptor via
+     *         {@link Os#dup(FileDescriptor)}.
+     */
+    public ExifInterface(@NonNull FileDescriptor fileDescriptor) throws IOException {
+        if (fileDescriptor == null) {
+            throw new NullPointerException("fileDescriptor cannot be null");
+        }
+        // If a file descriptor has a modern file descriptor, this means that the file can be
+        // transcoded and not using the modern file descriptor will trigger the transcoding
+        // operation. Thus, to avoid unnecessary transcoding, need to convert to modern file
+        // descriptor if it exists. As of Android S, transcoding is not supported for image files,
+        // so this is for protecting against non-image files sent to ExifInterface, but support may
+        // be added in the future.
+        ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fileDescriptor);
+        if (modernFd != null) {
+            fileDescriptor = modernFd.getFileDescriptor();
+        }
+
+        mAssetInputStream = null;
+        mFilename = null;
+
+        boolean isFdDuped = false;
+        // Can't save attributes to files with transcoding because apps get a different copy of
+        // that file when they're not using it through framework libraries like ExifInterface.
+        if (isSeekableFD(fileDescriptor) && modernFd == null) {
+            mSeekableFileDescriptor = fileDescriptor;
+            // Keep the original file descriptor in order to save attributes when it's seekable.
+            // Otherwise, just close the given file descriptor after reading it because the save
+            // feature won't be working.
+            try {
+                fileDescriptor = Os.dup(fileDescriptor);
+                isFdDuped = true;
+            } catch (ErrnoException e) {
+                throw e.rethrowAsIOException();
+            }
+        } else {
+            mSeekableFileDescriptor = null;
+        }
+        mIsInputStream = false;
+        FileInputStream in = null;
+        try {
+            in = new FileInputStream(fileDescriptor);
+            loadAttributes(in);
+        } finally {
+            closeQuietly(in);
+            if (isFdDuped) {
+                closeFileDescriptor(fileDescriptor);
+            }
+            if (modernFd != null) {
+                modernFd.close();
+            }
+        }
+    }
+
+    /**
+     * Reads Exif tags from the specified image input stream. Attribute mutation is not supported
+     * for input streams. The given input stream will proceed from its current position. Developers
+     * should close the input stream after use. This constructor is not intended to be used with an
+     * input stream that performs any networking operations.
+     *
+     * @param inputStream the input stream that contains the image data
+     * @throws NullPointerException if the input stream is null
+     */
+    public ExifInterface(@NonNull InputStream inputStream) throws IOException {
+        this(inputStream, false);
+    }
+
+    /**
+     * Reads Exif tags from the specified image input stream based on the stream type. Attribute
+     * mutation is not supported for input streams. The given input stream will proceed from its
+     * current position. Developers should close the input stream after use. This constructor is not
+     * intended to be used with an input stream that performs any networking operations.
+     *
+     * @param inputStream the input stream that contains the image data
+     * @param streamType the type of input stream
+     * @throws NullPointerException if the input stream is null
+     * @throws IOException if an I/O error occurs while retrieving file descriptor via
+     *         {@link FileInputStream#getFD()}.
+     */
+    public ExifInterface(@NonNull InputStream inputStream, @ExifStreamType int streamType)
+            throws IOException {
+        this(inputStream, (streamType == STREAM_TYPE_EXIF_DATA_ONLY) ? true : false);
+    }
+
+    private ExifInterface(@NonNull InputStream inputStream, boolean shouldBeExifDataOnly)
+            throws IOException {
+        if (inputStream == null) {
+            throw new NullPointerException("inputStream cannot be null");
+        }
+        mFilename = null;
+
+        if (shouldBeExifDataOnly) {
+            inputStream = new BufferedInputStream(inputStream, SIGNATURE_CHECK_SIZE);
+            if (!isExifDataOnly((BufferedInputStream) inputStream)) {
+                Log.w(TAG, "Given data does not follow the structure of an Exif-only data.");
+                return;
+            }
+            mIsExifDataOnly = true;
+            mAssetInputStream = null;
+            mSeekableFileDescriptor = null;
+        } else {
+            if (inputStream instanceof AssetManager.AssetInputStream) {
+                mAssetInputStream = (AssetManager.AssetInputStream) inputStream;
+                mSeekableFileDescriptor = null;
+            } else if (inputStream instanceof FileInputStream
+                    && (isSeekableFD(((FileInputStream) inputStream).getFD()))) {
+                mAssetInputStream = null;
+                mSeekableFileDescriptor = ((FileInputStream) inputStream).getFD();
+            } else {
+                mAssetInputStream = null;
+                mSeekableFileDescriptor = null;
+            }
+        }
+        loadAttributes(inputStream);
+    }
+
+    /**
+     * Returns whether ExifInterface currently supports reading data from the specified mime type
+     * or not.
+     *
+     * @param mimeType the string value of mime type
+     */
+    public static boolean isSupportedMimeType(@NonNull String mimeType) {
+        if (mimeType == null) {
+            throw new NullPointerException("mimeType shouldn't be null");
+        }
+
+        switch (mimeType.toLowerCase(Locale.ROOT)) {
+            case "image/jpeg":
+            case "image/x-adobe-dng":
+            case "image/x-canon-cr2":
+            case "image/x-nikon-nef":
+            case "image/x-nikon-nrw":
+            case "image/x-sony-arw":
+            case "image/x-panasonic-rw2":
+            case "image/x-olympus-orf":
+            case "image/x-pentax-pef":
+            case "image/x-samsung-srw":
+            case "image/x-fuji-raf":
+            case "image/heic":
+            case "image/heif":
+            case "image/png":
+            case "image/webp":
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Returns the EXIF attribute of the specified tag or {@code null} if there is no such tag in
+     * the image file.
+     *
+     * @param tag the name of the tag.
+     */
+    private @Nullable ExifAttribute getExifAttribute(@NonNull String tag) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
+        // Retrieves all tag groups. The value from primary image tag group has a higher priority
+        // than the value from the thumbnail tag group if there are more than one candidates.
+        for (int i = 0; i < EXIF_TAGS.length; ++i) {
+            Object value = mAttributes[i].get(tag);
+            if (value != null) {
+                return (ExifAttribute) value;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the value of the specified tag or {@code null} if there
+     * is no such tag in the image file.
+     *
+     * @param tag the name of the tag.
+     */
+    public @Nullable String getAttribute(@NonNull String tag) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
+        ExifAttribute attribute = getExifAttribute(tag);
+        if (attribute != null) {
+            if (!sTagSetForCompatibility.contains(tag)) {
+                return attribute.getStringValue(mExifByteOrder);
+            }
+            if (tag.equals(TAG_GPS_TIMESTAMP)) {
+                // Convert the rational values to the custom formats for backwards compatibility.
+                if (attribute.format != IFD_FORMAT_URATIONAL
+                        && attribute.format != IFD_FORMAT_SRATIONAL) {
+                    return null;
+                }
+                Rational[] array = (Rational[]) attribute.getValue(mExifByteOrder);
+                if (array.length != 3) {
+                    return null;
+                }
+                return String.format("%02d:%02d:%02d",
+                        (int) ((float) array[0].numerator / array[0].denominator),
+                        (int) ((float) array[1].numerator / array[1].denominator),
+                        (int) ((float) array[2].numerator / array[2].denominator));
+            }
+            try {
+                return Double.toString(attribute.getDoubleValue(mExifByteOrder));
+            } catch (NumberFormatException e) {
+                return null;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns the integer value of the specified tag. If there is no such tag
+     * in the image file or the value cannot be parsed as integer, return
+     * <var>defaultValue</var>.
+     *
+     * @param tag the name of the tag.
+     * @param defaultValue the value to return if the tag is not available.
+     */
+    public int getAttributeInt(@NonNull String tag, int defaultValue) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
+        ExifAttribute exifAttribute = getExifAttribute(tag);
+        if (exifAttribute == null) {
+            return defaultValue;
+        }
+
+        try {
+            return exifAttribute.getIntValue(mExifByteOrder);
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the double value of the tag that is specified as rational or contains a
+     * double-formatted value. If there is no such tag in the image file or the value cannot be
+     * parsed as double, return <var>defaultValue</var>.
+     *
+     * @param tag the name of the tag.
+     * @param defaultValue the value to return if the tag is not available.
+     */
+    public double getAttributeDouble(@NonNull String tag, double defaultValue) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
+        ExifAttribute exifAttribute = getExifAttribute(tag);
+        if (exifAttribute == null) {
+            return defaultValue;
+        }
+
+        try {
+            return exifAttribute.getDoubleValue(mExifByteOrder);
+        } catch (NumberFormatException e) {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Set the value of the specified tag.
+     *
+     * @param tag the name of the tag.
+     * @param value the value of the tag.
+     */
+    public void setAttribute(@NonNull String tag, @Nullable String value) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
+        // Convert the given value to rational values for backwards compatibility.
+        if (value != null && sTagSetForCompatibility.contains(tag)) {
+            if (tag.equals(TAG_GPS_TIMESTAMP)) {
+                Matcher m = sGpsTimestampPattern.matcher(value);
+                if (!m.find()) {
+                    Log.w(TAG, "Invalid value for " + tag + " : " + value);
+                    return;
+                }
+                value = Integer.parseInt(m.group(1)) + "/1," + Integer.parseInt(m.group(2)) + "/1,"
+                        + Integer.parseInt(m.group(3)) + "/1";
+            } else {
+                try {
+                    double doubleValue = Double.parseDouble(value);
+                    value = (long) (doubleValue * 10000L) + "/10000";
+                } catch (NumberFormatException e) {
+                    Log.w(TAG, "Invalid value for " + tag + " : " + value);
+                    return;
+                }
+            }
+        }
+
+        for (int i = 0 ; i < EXIF_TAGS.length; ++i) {
+            if (i == IFD_TYPE_THUMBNAIL && !mHasThumbnail) {
+                continue;
+            }
+            final Object obj = sExifTagMapsForWriting[i].get(tag);
+            if (obj != null) {
+                if (value == null) {
+                    mAttributes[i].remove(tag);
+                    continue;
+                }
+                final ExifTag exifTag = (ExifTag) obj;
+                Pair<Integer, Integer> guess = guessDataFormat(value);
+                int dataFormat;
+                if (exifTag.primaryFormat == guess.first || exifTag.primaryFormat == guess.second) {
+                    dataFormat = exifTag.primaryFormat;
+                } else if (exifTag.secondaryFormat != -1 && (exifTag.secondaryFormat == guess.first
+                        || exifTag.secondaryFormat == guess.second)) {
+                    dataFormat = exifTag.secondaryFormat;
+                } else if (exifTag.primaryFormat == IFD_FORMAT_BYTE
+                        || exifTag.primaryFormat == IFD_FORMAT_UNDEFINED
+                        || exifTag.primaryFormat == IFD_FORMAT_STRING) {
+                    dataFormat = exifTag.primaryFormat;
+                } else {
+                    if (DEBUG) {
+                        Log.d(TAG, "Given tag (" + tag
+                                + ") value didn't match with one of expected "
+                                + "formats: " + IFD_FORMAT_NAMES[exifTag.primaryFormat]
+                                + (exifTag.secondaryFormat == -1 ? "" : ", "
+                                + IFD_FORMAT_NAMES[exifTag.secondaryFormat]) + " (guess: "
+                                + IFD_FORMAT_NAMES[guess.first] + (guess.second == -1 ? "" : ", "
+                                + IFD_FORMAT_NAMES[guess.second]) + ")");
+                    }
+                    continue;
+                }
+                switch (dataFormat) {
+                    case IFD_FORMAT_BYTE: {
+                        mAttributes[i].put(tag, ExifAttribute.createByte(value));
+                        break;
+                    }
+                    case IFD_FORMAT_UNDEFINED:
+                    case IFD_FORMAT_STRING: {
+                        mAttributes[i].put(tag, ExifAttribute.createString(value));
+                        break;
+                    }
+                    case IFD_FORMAT_USHORT: {
+                        final String[] values = value.split(",");
+                        final int[] intArray = new int[values.length];
+                        for (int j = 0; j < values.length; ++j) {
+                            intArray[j] = Integer.parseInt(values[j]);
+                        }
+                        mAttributes[i].put(tag,
+                                ExifAttribute.createUShort(intArray, mExifByteOrder));
+                        break;
+                    }
+                    case IFD_FORMAT_SLONG: {
+                        final String[] values = value.split(",");
+                        final int[] intArray = new int[values.length];
+                        for (int j = 0; j < values.length; ++j) {
+                            intArray[j] = Integer.parseInt(values[j]);
+                        }
+                        mAttributes[i].put(tag,
+                                ExifAttribute.createSLong(intArray, mExifByteOrder));
+                        break;
+                    }
+                    case IFD_FORMAT_ULONG: {
+                        final String[] values = value.split(",");
+                        final long[] longArray = new long[values.length];
+                        for (int j = 0; j < values.length; ++j) {
+                            longArray[j] = Long.parseLong(values[j]);
+                        }
+                        mAttributes[i].put(tag,
+                                ExifAttribute.createULong(longArray, mExifByteOrder));
+                        break;
+                    }
+                    case IFD_FORMAT_URATIONAL: {
+                        final String[] values = value.split(",");
+                        final Rational[] rationalArray = new Rational[values.length];
+                        for (int j = 0; j < values.length; ++j) {
+                            final String[] numbers = values[j].split("/");
+                            rationalArray[j] = new Rational((long) Double.parseDouble(numbers[0]),
+                                    (long) Double.parseDouble(numbers[1]));
+                        }
+                        mAttributes[i].put(tag,
+                                ExifAttribute.createURational(rationalArray, mExifByteOrder));
+                        break;
+                    }
+                    case IFD_FORMAT_SRATIONAL: {
+                        final String[] values = value.split(",");
+                        final Rational[] rationalArray = new Rational[values.length];
+                        for (int j = 0; j < values.length; ++j) {
+                            final String[] numbers = values[j].split("/");
+                            rationalArray[j] = new Rational((long) Double.parseDouble(numbers[0]),
+                                    (long) Double.parseDouble(numbers[1]));
+                        }
+                        mAttributes[i].put(tag,
+                                ExifAttribute.createSRational(rationalArray, mExifByteOrder));
+                        break;
+                    }
+                    case IFD_FORMAT_DOUBLE: {
+                        final String[] values = value.split(",");
+                        final double[] doubleArray = new double[values.length];
+                        for (int j = 0; j < values.length; ++j) {
+                            doubleArray[j] = Double.parseDouble(values[j]);
+                        }
+                        mAttributes[i].put(tag,
+                                ExifAttribute.createDouble(doubleArray, mExifByteOrder));
+                        break;
+                    }
+                    default:
+                        if (DEBUG) {
+                            Log.d(TAG, "Data format isn't one of expected formats: " + dataFormat);
+                        }
+                        continue;
+                }
+            }
+        }
+    }
+
+    /**
+     * Update the values of the tags in the tag groups if any value for the tag already was stored.
+     *
+     * @param tag the name of the tag.
+     * @param value the value of the tag in a form of {@link ExifAttribute}.
+     * @return Returns {@code true} if updating is placed.
+     */
+    private boolean updateAttribute(String tag, ExifAttribute value) {
+        boolean updated = false;
+        for (int i = 0 ; i < EXIF_TAGS.length; ++i) {
+            if (mAttributes[i].containsKey(tag)) {
+                mAttributes[i].put(tag, value);
+                updated = true;
+            }
+        }
+        return updated;
+    }
+
+    /**
+     * Remove any values of the specified tag.
+     *
+     * @param tag the name of the tag.
+     */
+    private void removeAttribute(String tag) {
+        for (int i = 0 ; i < EXIF_TAGS.length; ++i) {
+            mAttributes[i].remove(tag);
+        }
+    }
+
+    /**
+     * This function decides which parser to read the image data according to the given input stream
+     * type and the content of the input stream.
+     */
+    private void loadAttributes(@NonNull InputStream in) {
+        if (in == null) {
+            throw new NullPointerException("inputstream shouldn't be null");
+        }
+        try {
+            // Initialize mAttributes.
+            for (int i = 0; i < EXIF_TAGS.length; ++i) {
+                mAttributes[i] = new HashMap();
+            }
+
+            // Check file type
+            if (!mIsExifDataOnly) {
+                in = new BufferedInputStream(in, SIGNATURE_CHECK_SIZE);
+                mMimeType = getMimeType((BufferedInputStream) in);
+            }
+
+            // Create byte-ordered input stream
+            ByteOrderedDataInputStream inputStream = new ByteOrderedDataInputStream(in);
+
+            if (!mIsExifDataOnly) {
+                switch (mMimeType) {
+                    case IMAGE_TYPE_JPEG: {
+                        getJpegAttributes(inputStream, 0, IFD_TYPE_PRIMARY); // 0 is offset
+                        break;
+                    }
+                    case IMAGE_TYPE_RAF: {
+                        getRafAttributes(inputStream);
+                        break;
+                    }
+                    case IMAGE_TYPE_HEIF: {
+                        getHeifAttributes(inputStream);
+                        break;
+                    }
+                    case IMAGE_TYPE_ORF: {
+                        getOrfAttributes(inputStream);
+                        break;
+                    }
+                    case IMAGE_TYPE_RW2: {
+                        getRw2Attributes(inputStream);
+                        break;
+                    }
+                    case IMAGE_TYPE_PNG: {
+                        getPngAttributes(inputStream);
+                        break;
+                    }
+                    case IMAGE_TYPE_WEBP: {
+                        getWebpAttributes(inputStream);
+                        break;
+                    }
+                    case IMAGE_TYPE_ARW:
+                    case IMAGE_TYPE_CR2:
+                    case IMAGE_TYPE_DNG:
+                    case IMAGE_TYPE_NEF:
+                    case IMAGE_TYPE_NRW:
+                    case IMAGE_TYPE_PEF:
+                    case IMAGE_TYPE_SRW:
+                    case IMAGE_TYPE_UNKNOWN: {
+                        getRawAttributes(inputStream);
+                        break;
+                    }
+                    default: {
+                        break;
+                    }
+                }
+            } else {
+                getStandaloneAttributes(inputStream);
+            }
+            // Set thumbnail image offset and length
+            setThumbnailData(inputStream);
+            mIsSupportedFile = true;
+        } catch (IOException | OutOfMemoryError e) {
+            // Ignore exceptions in order to keep the compatibility with the old versions of
+            // ExifInterface.
+            mIsSupportedFile = false;
+            Log.w(TAG, "Invalid image: ExifInterface got an unsupported image format file"
+                    + "(ExifInterface supports JPEG and some RAW image formats only) "
+                    + "or a corrupted JPEG file to ExifInterface.", e);
+        } finally {
+            addDefaultValuesForCompatibility();
+
+            if (DEBUG) {
+                printAttributes();
+            }
+        }
+    }
+
+    private static boolean isSeekableFD(FileDescriptor fd) {
+        try {
+            Os.lseek(fd, 0, OsConstants.SEEK_CUR);
+            return true;
+        } catch (ErrnoException e) {
+            if (DEBUG) {
+                Log.d(TAG, "The file descriptor for the given input is not seekable");
+            }
+            return false;
+        }
+    }
+
+    // Prints out attributes for debugging.
+    private void printAttributes() {
+        for (int i = 0; i < mAttributes.length; ++i) {
+            Log.d(TAG, "The size of tag group[" + i + "]: " + mAttributes[i].size());
+            for (Map.Entry entry : (Set<Map.Entry>) mAttributes[i].entrySet()) {
+                final ExifAttribute tagValue = (ExifAttribute) entry.getValue();
+                Log.d(TAG, "tagName: " + entry.getKey() + ", tagType: " + tagValue.toString()
+                        + ", tagValue: '" + tagValue.getStringValue(mExifByteOrder) + "'");
+            }
+        }
+    }
+
+    /**
+     * Save the tag data into the original image file. This is expensive because
+     * it involves copying all the data from one file to another and deleting
+     * the old file and renaming the other. It's best to use
+     * {@link #setAttribute(String,String)} to set all attributes to write and
+     * make a single call rather than multiple calls for each attribute.
+     * <p>
+     * This method is supported for JPEG, PNG and WebP files.
+     * <p class="note">
+     * Note: after calling this method, any attempts to obtain range information
+     * from {@link #getAttributeRange(String)} or {@link #getThumbnailRange()}
+     * will throw {@link IllegalStateException}, since the offsets may have
+     * changed in the newly written file.
+     * <p>
+     * For WebP format, the Exif data will be stored as an Extended File Format, and it may not be
+     * supported for older readers.
+     * </p>
+     */
+    public void saveAttributes() throws IOException {
+        if (!isSupportedFormatForSavingAttributes()) {
+            throw new IOException("ExifInterface only supports saving attributes on JPEG, PNG, "
+                    + "or WebP formats.");
+        }
+        if (mIsInputStream || (mSeekableFileDescriptor == null && mFilename == null)) {
+            throw new IOException(
+                    "ExifInterface does not support saving attributes for the current input.");
+        }
+
+        // Remember the fact that we've changed the file on disk from what was
+        // originally parsed, meaning we can't answer range questions
+        mModified = true;
+
+        // Keep the thumbnail in memory
+        mThumbnailBytes = getThumbnail();
+
+        FileInputStream in = null;
+        FileOutputStream out = null;
+        File tempFile = null;
+        try {
+            // Copy the original file to temporary file.
+            tempFile = File.createTempFile("temp", "tmp");
+            if (mFilename != null) {
+                in = new FileInputStream(mFilename);
+            } else if (mSeekableFileDescriptor != null) {
+                Os.lseek(mSeekableFileDescriptor, 0, OsConstants.SEEK_SET);
+                in = new FileInputStream(mSeekableFileDescriptor);
+            }
+            out = new FileOutputStream(tempFile);
+            copy(in, out);
+        } catch (Exception e) {
+            throw new IOException("Failed to copy original file to temp file", e);
+        } finally {
+            closeQuietly(in);
+            closeQuietly(out);
+        }
+
+        in = null;
+        out = null;
+        try {
+            // Save the new file.
+            in = new FileInputStream(tempFile);
+            if (mFilename != null) {
+                out = new FileOutputStream(mFilename);
+            } else if (mSeekableFileDescriptor != null) {
+                Os.lseek(mSeekableFileDescriptor, 0, OsConstants.SEEK_SET);
+                out = new FileOutputStream(mSeekableFileDescriptor);
+            }
+            try (BufferedInputStream bufferedIn = new BufferedInputStream(in);
+                 BufferedOutputStream bufferedOut = new BufferedOutputStream(out)) {
+                if (mMimeType == IMAGE_TYPE_JPEG) {
+                    saveJpegAttributes(bufferedIn, bufferedOut);
+                } else if (mMimeType == IMAGE_TYPE_PNG) {
+                    savePngAttributes(bufferedIn, bufferedOut);
+                } else if (mMimeType == IMAGE_TYPE_WEBP) {
+                    saveWebpAttributes(bufferedIn, bufferedOut);
+                }
+            }
+        } catch (Exception e) {
+            // Restore original file
+            in = new FileInputStream(tempFile);
+            if (mFilename != null) {
+                out = new FileOutputStream(mFilename);
+            } else if (mSeekableFileDescriptor != null) {
+                try {
+                    Os.lseek(mSeekableFileDescriptor, 0, OsConstants.SEEK_SET);
+                } catch (ErrnoException exception) {
+                    throw new IOException("Failed to save new file. Original file may be "
+                            + "corrupted since error occurred while trying to restore it.",
+                            exception);
+                }
+                out = new FileOutputStream(mSeekableFileDescriptor);
+            }
+            copy(in, out);
+            closeQuietly(in);
+            closeQuietly(out);
+            throw new IOException("Failed to save new file", e);
+        } finally {
+            closeQuietly(in);
+            closeQuietly(out);
+            tempFile.delete();
+        }
+
+        // Discard the thumbnail in memory
+        mThumbnailBytes = null;
+    }
+
+    /**
+     * Returns true if the image file has a thumbnail.
+     */
+    public boolean hasThumbnail() {
+        return mHasThumbnail;
+    }
+
+    /**
+     * Returns true if the image file has the given attribute defined.
+     *
+     * @param tag the name of the tag.
+     */
+    public boolean hasAttribute(@NonNull String tag) {
+        return (getExifAttribute(tag) != null);
+    }
+
+    /**
+     * Returns the JPEG compressed thumbnail inside the image file, or {@code null} if there is no
+     * JPEG compressed thumbnail.
+     * The returned data can be decoded using
+     * {@link android.graphics.BitmapFactory#decodeByteArray(byte[],int,int)}
+     */
+    public byte[] getThumbnail() {
+        if (mThumbnailCompression == DATA_JPEG || mThumbnailCompression == DATA_JPEG_COMPRESSED) {
+            return getThumbnailBytes();
+        }
+        return null;
+    }
+
+    /**
+     * Returns the thumbnail bytes inside the image file, regardless of the compression type of the
+     * thumbnail image.
+     */
+    public byte[] getThumbnailBytes() {
+        if (!mHasThumbnail) {
+            return null;
+        }
+        if (mThumbnailBytes != null) {
+            return mThumbnailBytes;
+        }
+
+        // Read the thumbnail.
+        InputStream in = null;
+        FileDescriptor newFileDescriptor = null;
+        try {
+            if (mAssetInputStream != null) {
+                in = mAssetInputStream;
+                if (in.markSupported()) {
+                    in.reset();
+                } else {
+                    Log.d(TAG, "Cannot read thumbnail from inputstream without mark/reset support");
+                    return null;
+                }
+            } else if (mFilename != null) {
+                in = new FileInputStream(mFilename);
+            } else if (mSeekableFileDescriptor != null) {
+                newFileDescriptor = Os.dup(mSeekableFileDescriptor);
+                Os.lseek(newFileDescriptor, 0, OsConstants.SEEK_SET);
+                in = new FileInputStream(newFileDescriptor);
+            }
+            if (in == null) {
+                // Should not be reached this.
+                throw new FileNotFoundException();
+            }
+            if (in.skip(mThumbnailOffset) != mThumbnailOffset) {
+                throw new IOException("Corrupted image");
+            }
+            // TODO: Need to handle potential OutOfMemoryError
+            byte[] buffer = new byte[mThumbnailLength];
+            if (in.read(buffer) != mThumbnailLength) {
+                throw new IOException("Corrupted image");
+            }
+            mThumbnailBytes = buffer;
+            return buffer;
+        } catch (IOException | ErrnoException e) {
+            // Couldn't get a thumbnail image.
+            Log.d(TAG, "Encountered exception while getting thumbnail", e);
+        } finally {
+            closeQuietly(in);
+            if (newFileDescriptor != null) {
+                closeFileDescriptor(newFileDescriptor);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Creates and returns a Bitmap object of the thumbnail image based on the byte array and the
+     * thumbnail compression value, or {@code null} if the compression type is unsupported.
+     */
+    public Bitmap getThumbnailBitmap() {
+        if (!mHasThumbnail) {
+            return null;
+        } else if (mThumbnailBytes == null) {
+            mThumbnailBytes = getThumbnailBytes();
+        }
+
+        if (mThumbnailCompression == DATA_JPEG || mThumbnailCompression == DATA_JPEG_COMPRESSED) {
+            return BitmapFactory.decodeByteArray(mThumbnailBytes, 0, mThumbnailLength);
+        } else if (mThumbnailCompression == DATA_UNCOMPRESSED) {
+            int[] rgbValues = new int[mThumbnailBytes.length / 3];
+            byte alpha = (byte) 0xff000000;
+            for (int i = 0; i < rgbValues.length; i++) {
+                rgbValues[i] = alpha + (mThumbnailBytes[3 * i] << 16)
+                        + (mThumbnailBytes[3 * i + 1] << 8) + mThumbnailBytes[3 * i + 2];
+            }
+
+            ExifAttribute imageLengthAttribute =
+                    (ExifAttribute) mAttributes[IFD_TYPE_THUMBNAIL].get(TAG_IMAGE_LENGTH);
+            ExifAttribute imageWidthAttribute =
+                    (ExifAttribute) mAttributes[IFD_TYPE_THUMBNAIL].get(TAG_IMAGE_WIDTH);
+            if (imageLengthAttribute != null && imageWidthAttribute != null) {
+                int imageLength = imageLengthAttribute.getIntValue(mExifByteOrder);
+                int imageWidth = imageWidthAttribute.getIntValue(mExifByteOrder);
+                return Bitmap.createBitmap(
+                        rgbValues, imageWidth, imageLength, Bitmap.Config.ARGB_8888);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Returns true if thumbnail image is JPEG Compressed, or false if either thumbnail image does
+     * not exist or thumbnail image is uncompressed.
+     */
+    public boolean isThumbnailCompressed() {
+        if (!mHasThumbnail) {
+            return false;
+        }
+        if (mThumbnailCompression == DATA_JPEG || mThumbnailCompression == DATA_JPEG_COMPRESSED) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * Returns the offset and length of thumbnail inside the image file, or
+     * {@code null} if either there is no thumbnail or the thumbnail bytes are stored
+     * non-consecutively.
+     *
+     * @return two-element array, the offset in the first value, and length in
+     *         the second, or {@code null} if no thumbnail was found or the thumbnail strips are
+     *         not placed consecutively.
+     * @throws IllegalStateException if {@link #saveAttributes()} has been
+     *             called since the underlying file was initially parsed, since
+     *             that means offsets may have changed.
+     */
+    public @Nullable long[] getThumbnailRange() {
+        if (mModified) {
+            throw new IllegalStateException(
+                    "The underlying file has been modified since being parsed");
+        }
+
+        if (mHasThumbnail) {
+            if (mHasThumbnailStrips && !mAreThumbnailStripsConsecutive) {
+                return null;
+            }
+            return new long[] { mThumbnailOffset, mThumbnailLength };
+        }
+        return null;
+    }
+
+    /**
+     * Returns the offset and length of the requested tag inside the image file,
+     * or {@code null} if the tag is not contained.
+     *
+     * @return two-element array, the offset in the first value, and length in
+     *         the second, or {@code null} if no tag was found.
+     * @throws IllegalStateException if {@link #saveAttributes()} has been
+     *             called since the underlying file was initially parsed, since
+     *             that means offsets may have changed.
+     */
+    public @Nullable long[] getAttributeRange(@NonNull String tag) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
+        if (mModified) {
+            throw new IllegalStateException(
+                    "The underlying file has been modified since being parsed");
+        }
+
+        final ExifAttribute attribute = getExifAttribute(tag);
+        if (attribute != null) {
+            return new long[] { attribute.bytesOffset, attribute.bytes.length };
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the raw bytes for the value of the requested tag inside the image
+     * file, or {@code null} if the tag is not contained.
+     *
+     * @return raw bytes for the value of the requested tag, or {@code null} if
+     *         no tag was found.
+     */
+    public @Nullable byte[] getAttributeBytes(@NonNull String tag) {
+        if (tag == null) {
+            throw new NullPointerException("tag shouldn't be null");
+        }
+        final ExifAttribute attribute = getExifAttribute(tag);
+        if (attribute != null) {
+            return attribute.bytes;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Stores the latitude and longitude value in a float array. The first element is
+     * the latitude, and the second element is the longitude. Returns false if the
+     * Exif tags are not available.
+     */
+    public boolean getLatLong(float output[]) {
+        String latValue = getAttribute(TAG_GPS_LATITUDE);
+        String latRef = getAttribute(TAG_GPS_LATITUDE_REF);
+        String lngValue = getAttribute(TAG_GPS_LONGITUDE);
+        String lngRef = getAttribute(TAG_GPS_LONGITUDE_REF);
+
+        if (latValue != null && latRef != null && lngValue != null && lngRef != null) {
+            try {
+                output[0] = convertRationalLatLonToFloat(latValue, latRef);
+                output[1] = convertRationalLatLonToFloat(lngValue, lngRef);
+                return true;
+            } catch (IllegalArgumentException e) {
+                // if values are not parseable
+            }
+        }
+
+        return false;
+    }
+
+    /**
+     * Return the altitude in meters. If the exif tag does not exist, return
+     * <var>defaultValue</var>.
+     *
+     * @param defaultValue the value to return if the tag is not available.
+     */
+    public double getAltitude(double defaultValue) {
+        double altitude = getAttributeDouble(TAG_GPS_ALTITUDE, -1);
+        int ref = getAttributeInt(TAG_GPS_ALTITUDE_REF, -1);
+
+        if (altitude >= 0 && ref >= 0) {
+            return (altitude * ((ref == 1) ? -1 : 1));
+        } else {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns parsed {@link #TAG_DATETIME} value, or -1 if unavailable or invalid.
+     */
+    public @CurrentTimeMillisLong long getDateTime() {
+        return parseDateTime(getAttribute(TAG_DATETIME),
+                getAttribute(TAG_SUBSEC_TIME),
+                getAttribute(TAG_OFFSET_TIME));
+    }
+
+    /**
+     * Returns parsed {@link #TAG_DATETIME_DIGITIZED} value, or -1 if unavailable or invalid.
+     */
+    public @CurrentTimeMillisLong long getDateTimeDigitized() {
+        return parseDateTime(getAttribute(TAG_DATETIME_DIGITIZED),
+                getAttribute(TAG_SUBSEC_TIME_DIGITIZED),
+                getAttribute(TAG_OFFSET_TIME_DIGITIZED));
+    }
+
+    /**
+     * Returns parsed {@link #TAG_DATETIME_ORIGINAL} value, or -1 if unavailable or invalid.
+     */
+    public @CurrentTimeMillisLong long getDateTimeOriginal() {
+        return parseDateTime(getAttribute(TAG_DATETIME_ORIGINAL),
+                getAttribute(TAG_SUBSEC_TIME_ORIGINAL),
+                getAttribute(TAG_OFFSET_TIME_ORIGINAL));
+    }
+
+    private static @CurrentTimeMillisLong long parseDateTime(@Nullable String dateTimeString,
+            @Nullable String subSecs, @Nullable String offsetString) {
+        if (dateTimeString == null
+                || !sNonZeroTimePattern.matcher(dateTimeString).matches()) return -1;
+
+        ParsePosition pos = new ParsePosition(0);
+        try {
+            // The exif field is in local time. Parsing it as if it is UTC will yield time
+            // since 1/1/1970 local time
+            Date datetime;
+            synchronized (sFormatter) {
+                datetime = sFormatter.parse(dateTimeString, pos);
+            }
+
+            if (offsetString != null) {
+                dateTimeString = dateTimeString + " " + offsetString;
+                ParsePosition position = new ParsePosition(0);
+                synchronized (sFormatterTz) {
+                    datetime = sFormatterTz.parse(dateTimeString, position);
+                }
+            }
+
+            if (datetime == null) return -1;
+            long msecs = datetime.getTime();
+
+            if (subSecs != null) {
+                try {
+                    long sub = Long.parseLong(subSecs);
+                    while (sub > 1000) {
+                        sub /= 10;
+                    }
+                    msecs += sub;
+                } catch (NumberFormatException e) {
+                    // Ignored
+                }
+            }
+            return msecs;
+        } catch (IllegalArgumentException e) {
+            return -1;
+        }
+    }
+
+    /**
+     * Returns number of milliseconds since Jan. 1, 1970, midnight UTC.
+     * Returns -1 if the date time information if not available.
+     */
+    public long getGpsDateTime() {
+        String date = getAttribute(TAG_GPS_DATESTAMP);
+        String time = getAttribute(TAG_GPS_TIMESTAMP);
+        if (date == null || time == null
+                || (!sNonZeroTimePattern.matcher(date).matches()
+                && !sNonZeroTimePattern.matcher(time).matches())) {
+            return -1;
+        }
+
+        String dateTimeString = date + ' ' + time;
+
+        ParsePosition pos = new ParsePosition(0);
+        try {
+            final Date datetime;
+            synchronized (sFormatter) {
+                datetime = sFormatter.parse(dateTimeString, pos);
+            }
+            if (datetime == null) return -1;
+            return datetime.getTime();
+        } catch (IllegalArgumentException e) {
+            return -1;
+        }
+    }
+
+    /** {@hide} */
+    public static float convertRationalLatLonToFloat(String rationalString, String ref) {
+        try {
+            String [] parts = rationalString.split(",");
+
+            String [] pair;
+            pair = parts[0].split("/");
+            double degrees = Double.parseDouble(pair[0].trim())
+                    / Double.parseDouble(pair[1].trim());
+
+            pair = parts[1].split("/");
+            double minutes = Double.parseDouble(pair[0].trim())
+                    / Double.parseDouble(pair[1].trim());
+
+            pair = parts[2].split("/");
+            double seconds = Double.parseDouble(pair[0].trim())
+                    / Double.parseDouble(pair[1].trim());
+
+            double result = degrees + (minutes / 60.0) + (seconds / 3600.0);
+            if ((ref.equals("S") || ref.equals("W"))) {
+                return (float) -result;
+            }
+            return (float) result;
+        } catch (NumberFormatException | ArrayIndexOutOfBoundsException e) {
+            // Not valid
+            throw new IllegalArgumentException();
+        }
+    }
+
+    private void initForFilename(String filename) throws IOException {
+        FileInputStream in = null;
+        ParcelFileDescriptor modernFd = null;
+        mAssetInputStream = null;
+        mFilename = filename;
+        mIsInputStream = false;
+        try {
+            in = new FileInputStream(filename);
+            modernFd = FileUtils.convertToModernFd(in.getFD());
+            if (modernFd != null) {
+                closeQuietly(in);
+                in = new FileInputStream(modernFd.getFileDescriptor());
+                mSeekableFileDescriptor = null;
+            } else if (isSeekableFD(in.getFD())) {
+                mSeekableFileDescriptor = in.getFD();
+            }
+            loadAttributes(in);
+        } finally {
+            closeQuietly(in);
+            if (modernFd != null) {
+                modernFd.close();
+            }
+        }
+    }
+
+    // Checks the type of image file
+    private int getMimeType(BufferedInputStream in) throws IOException {
+        // TODO (b/142218289): Need to handle case where input stream does not support mark
+        in.mark(SIGNATURE_CHECK_SIZE);
+        byte[] signatureCheckBytes = new byte[SIGNATURE_CHECK_SIZE];
+        in.read(signatureCheckBytes);
+        in.reset();
+        if (isJpegFormat(signatureCheckBytes)) {
+            return IMAGE_TYPE_JPEG;
+        } else if (isRafFormat(signatureCheckBytes)) {
+            return IMAGE_TYPE_RAF;
+        } else if (isHeifFormat(signatureCheckBytes)) {
+            return IMAGE_TYPE_HEIF;
+        } else if (isOrfFormat(signatureCheckBytes)) {
+            return IMAGE_TYPE_ORF;
+        } else if (isRw2Format(signatureCheckBytes)) {
+            return IMAGE_TYPE_RW2;
+        } else if (isPngFormat(signatureCheckBytes)) {
+            return IMAGE_TYPE_PNG;
+        } else if (isWebpFormat(signatureCheckBytes)) {
+            return IMAGE_TYPE_WEBP;
+        }
+        // Certain file formats (PEF) are identified in readImageFileDirectory()
+        return IMAGE_TYPE_UNKNOWN;
+    }
+
+    /**
+     * This method looks at the first 3 bytes to determine if this file is a JPEG file.
+     * See http://www.media.mit.edu/pia/Research/deepview/exif.html, "JPEG format and Marker"
+     */
+    private static boolean isJpegFormat(byte[] signatureCheckBytes) throws IOException {
+        for (int i = 0; i < JPEG_SIGNATURE.length; i++) {
+            if (signatureCheckBytes[i] != JPEG_SIGNATURE[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * This method looks at the first 15 bytes to determine if this file is a RAF file.
+     * There is no official specification for RAF files from Fuji, but there is an online archive of
+     * image file specifications:
+     * http://fileformats.archiveteam.org/wiki/Fujifilm_RAF
+     */
+    private boolean isRafFormat(byte[] signatureCheckBytes) throws IOException {
+        byte[] rafSignatureBytes = RAF_SIGNATURE.getBytes();
+        for (int i = 0; i < rafSignatureBytes.length; i++) {
+            if (signatureCheckBytes[i] != rafSignatureBytes[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private boolean isHeifFormat(byte[] signatureCheckBytes) throws IOException {
+        ByteOrderedDataInputStream signatureInputStream = null;
+        try {
+            signatureInputStream = new ByteOrderedDataInputStream(signatureCheckBytes);
+
+            long chunkSize = signatureInputStream.readInt();
+            byte[] chunkType = new byte[4];
+            signatureInputStream.read(chunkType);
+
+            if (!Arrays.equals(chunkType, HEIF_TYPE_FTYP)) {
+                return false;
+            }
+
+            long chunkDataOffset = 8;
+            if (chunkSize == 1) {
+                // This indicates that the next 8 bytes represent the chunk size,
+                // and chunk data comes after that.
+                chunkSize = signatureInputStream.readLong();
+                if (chunkSize < 16) {
+                    // The smallest valid chunk is 16 bytes long in this case.
+                    return false;
+                }
+                chunkDataOffset += 8;
+            }
+
+            // only sniff up to signatureCheckBytes.length
+            if (chunkSize > signatureCheckBytes.length) {
+                chunkSize = signatureCheckBytes.length;
+            }
+
+            long chunkDataSize = chunkSize - chunkDataOffset;
+
+            // It should at least have major brand (4-byte) and minor version (4-byte).
+            // The rest of the chunk (if any) is a list of (4-byte) compatible brands.
+            if (chunkDataSize < 8) {
+                return false;
+            }
+
+            byte[] brand = new byte[4];
+            boolean isMif1 = false;
+            boolean isHeic = false;
+            boolean isAvif = false;
+            for (long i = 0; i < chunkDataSize / 4;  ++i) {
+                if (signatureInputStream.read(brand) != brand.length) {
+                    return false;
+                }
+                if (i == 1) {
+                    // Skip this index, it refers to the minorVersion, not a brand.
+                    continue;
+                }
+                if (Arrays.equals(brand, HEIF_BRAND_MIF1)) {
+                    isMif1 = true;
+                } else if (Arrays.equals(brand, HEIF_BRAND_HEIC)) {
+                    isHeic = true;
+                } else if (Arrays.equals(brand, HEIF_BRAND_AVIF)
+                        || Arrays.equals(brand, HEIF_BRAND_AVIS)) {
+                    isAvif = true;
+                }
+                if (isMif1 && (isHeic || isAvif)) {
+                    return true;
+                }
+            }
+        } catch (Exception e) {
+            if (DEBUG) {
+                Log.d(TAG, "Exception parsing HEIF file type box.", e);
+            }
+        } finally {
+            if (signatureInputStream != null) {
+                signatureInputStream.close();
+                signatureInputStream = null;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * ORF has a similar structure to TIFF but it contains a different signature at the TIFF Header.
+     * This method looks at the 2 bytes following the Byte Order bytes to determine if this file is
+     * an ORF file.
+     * There is no official specification for ORF files from Olympus, but there is an online archive
+     * of image file specifications:
+     * http://fileformats.archiveteam.org/wiki/Olympus_ORF
+     */
+    private boolean isOrfFormat(byte[] signatureCheckBytes) throws IOException {
+        ByteOrderedDataInputStream signatureInputStream = null;
+
+        try {
+            signatureInputStream = new ByteOrderedDataInputStream(signatureCheckBytes);
+
+            // Read byte order
+            mExifByteOrder = readByteOrder(signatureInputStream);
+            // Set byte order
+            signatureInputStream.setByteOrder(mExifByteOrder);
+
+            short orfSignature = signatureInputStream.readShort();
+            return orfSignature == ORF_SIGNATURE_1 || orfSignature == ORF_SIGNATURE_2;
+        } catch (Exception e) {
+            // Do nothing
+        } finally {
+            if (signatureInputStream != null) {
+                signatureInputStream.close();
+            }
+        }
+        return false;
+    }
+
+    /**
+     * RW2 is TIFF-based, but stores 0x55 signature byte instead of 0x42 at the header
+     * See http://lclevy.free.fr/raw/
+     */
+    private boolean isRw2Format(byte[] signatureCheckBytes) throws IOException {
+        ByteOrderedDataInputStream signatureInputStream = null;
+
+        try {
+            signatureInputStream = new ByteOrderedDataInputStream(signatureCheckBytes);
+
+            // Read byte order
+            mExifByteOrder = readByteOrder(signatureInputStream);
+            // Set byte order
+            signatureInputStream.setByteOrder(mExifByteOrder);
+
+            short signatureByte = signatureInputStream.readShort();
+            signatureInputStream.close();
+            return signatureByte == RW2_SIGNATURE;
+        } catch (Exception e) {
+            // Do nothing
+        } finally {
+            if (signatureInputStream != null) {
+                signatureInputStream.close();
+            }
+        }
+        return false;
+    }
+
+    /**
+     * PNG's file signature is first 8 bytes.
+     * See PNG (Portable Network Graphics) Specification, Version 1.2, 3.1. PNG file signature
+     */
+    private boolean isPngFormat(byte[] signatureCheckBytes) throws IOException {
+        for (int i = 0; i < PNG_SIGNATURE.length; i++) {
+            if (signatureCheckBytes[i] != PNG_SIGNATURE[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * WebP's file signature is composed of 12 bytes:
+     *   'RIFF' (4 bytes) + file length value (4 bytes) + 'WEBP' (4 bytes)
+     * See https://developers.google.com/speed/webp/docs/riff_container, Section "WebP File Header"
+     */
+    private boolean isWebpFormat(byte[] signatureCheckBytes) throws IOException {
+        for (int i = 0; i < WEBP_SIGNATURE_1.length; i++) {
+            if (signatureCheckBytes[i] != WEBP_SIGNATURE_1[i]) {
+                return false;
+            }
+        }
+        for (int i = 0; i < WEBP_SIGNATURE_2.length; i++) {
+            if (signatureCheckBytes[i + WEBP_SIGNATURE_1.length + WEBP_FILE_SIZE_BYTE_LENGTH]
+                    != WEBP_SIGNATURE_2[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    private static boolean isExifDataOnly(BufferedInputStream in) throws IOException {
+        in.mark(IDENTIFIER_EXIF_APP1.length);
+        byte[] signatureCheckBytes = new byte[IDENTIFIER_EXIF_APP1.length];
+        in.read(signatureCheckBytes);
+        in.reset();
+        for (int i = 0; i < IDENTIFIER_EXIF_APP1.length; i++) {
+            if (signatureCheckBytes[i] != IDENTIFIER_EXIF_APP1[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Loads EXIF attributes from a JPEG input stream.
+     *
+     * @param in The input stream that starts with the JPEG data.
+     * @param jpegOffset The offset value in input stream for JPEG data.
+     * @param imageType The image type from which to retrieve metadata. Use IFD_TYPE_PRIMARY for
+     *                   primary image, IFD_TYPE_PREVIEW for preview image, and
+     *                   IFD_TYPE_THUMBNAIL for thumbnail image.
+     * @throws IOException If the data contains invalid JPEG markers, offsets, or length values.
+     */
+    private void getJpegAttributes(ByteOrderedDataInputStream in, int jpegOffset, int imageType)
+            throws IOException {
+        // See JPEG File Interchange Format Specification, "JFIF Specification"
+        if (DEBUG) {
+            Log.d(TAG, "getJpegAttributes starting with: " + in);
+        }
+
+        // JPEG uses Big Endian by default. See https://people.cs.umass.edu/~verts/cs32/endian.html
+        in.setByteOrder(ByteOrder.BIG_ENDIAN);
+
+        // Skip to JPEG data
+        in.seek(jpegOffset);
+        int bytesRead = jpegOffset;
+
+        byte marker;
+        if ((marker = in.readByte()) != MARKER) {
+            throw new IOException("Invalid marker: " + Integer.toHexString(marker & 0xff));
+        }
+        ++bytesRead;
+        if (in.readByte() != MARKER_SOI) {
+            throw new IOException("Invalid marker: " + Integer.toHexString(marker & 0xff));
+        }
+        ++bytesRead;
+        while (true) {
+            marker = in.readByte();
+            if (marker != MARKER) {
+                throw new IOException("Invalid marker:" + Integer.toHexString(marker & 0xff));
+            }
+            ++bytesRead;
+            marker = in.readByte();
+            if (DEBUG) {
+                Log.d(TAG, "Found JPEG segment indicator: " + Integer.toHexString(marker & 0xff));
+            }
+            ++bytesRead;
+
+            // EOI indicates the end of an image and in case of SOS, JPEG image stream starts and
+            // the image data will terminate right after.
+            if (marker == MARKER_EOI || marker == MARKER_SOS) {
+                break;
+            }
+            int length = in.readUnsignedShort() - 2;
+            bytesRead += 2;
+            if (DEBUG) {
+                Log.d(TAG, "JPEG segment: " + Integer.toHexString(marker & 0xff) + " (length: "
+                        + (length + 2) + ")");
+            }
+            if (length < 0) {
+                throw new IOException("Invalid length");
+            }
+            switch (marker) {
+                case MARKER_APP1: {
+                    final int start = bytesRead;
+                    final byte[] bytes = new byte[length];
+                    in.readFully(bytes);
+                    bytesRead += length;
+                    length = 0;
+
+                    if (startsWith(bytes, IDENTIFIER_EXIF_APP1)) {
+                        final long offset = start + IDENTIFIER_EXIF_APP1.length;
+                        final byte[] value = Arrays.copyOfRange(bytes,
+                                IDENTIFIER_EXIF_APP1.length, bytes.length);
+                        // Save offset values for handleThumbnailFromJfif() function
+                        mExifOffset = (int) offset;
+                        readExifSegment(value, imageType);
+                    } else if (startsWith(bytes, IDENTIFIER_XMP_APP1)) {
+                        // See XMP Specification Part 3: Storage in Files, 1.1.3 JPEG, Table 6
+                        final long offset = start + IDENTIFIER_XMP_APP1.length;
+                        final byte[] value = Arrays.copyOfRange(bytes,
+                                IDENTIFIER_XMP_APP1.length, bytes.length);
+                        // TODO: check if ignoring separate XMP data when tag 700 already exists is
+                        //  valid.
+                        if (getAttribute(TAG_XMP) == null) {
+                            mAttributes[IFD_TYPE_PRIMARY].put(TAG_XMP, new ExifAttribute(
+                                    IFD_FORMAT_BYTE, value.length, offset, value));
+                            mXmpIsFromSeparateMarker = true;
+                        }
+                    }
+                    break;
+                }
+
+                case MARKER_COM: {
+                    byte[] bytes = new byte[length];
+                    if (in.read(bytes) != length) {
+                        throw new IOException("Invalid exif");
+                    }
+                    length = 0;
+                    if (getAttribute(TAG_USER_COMMENT) == null) {
+                        mAttributes[IFD_TYPE_EXIF].put(TAG_USER_COMMENT, ExifAttribute.createString(
+                                new String(bytes, ASCII)));
+                    }
+                    break;
+                }
+
+                case MARKER_SOF0:
+                case MARKER_SOF1:
+                case MARKER_SOF2:
+                case MARKER_SOF3:
+                case MARKER_SOF5:
+                case MARKER_SOF6:
+                case MARKER_SOF7:
+                case MARKER_SOF9:
+                case MARKER_SOF10:
+                case MARKER_SOF11:
+                case MARKER_SOF13:
+                case MARKER_SOF14:
+                case MARKER_SOF15: {
+                    if (in.skipBytes(1) != 1) {
+                        throw new IOException("Invalid SOFx");
+                    }
+                    mAttributes[imageType].put(TAG_IMAGE_LENGTH, ExifAttribute.createULong(
+                            in.readUnsignedShort(), mExifByteOrder));
+                    mAttributes[imageType].put(TAG_IMAGE_WIDTH, ExifAttribute.createULong(
+                            in.readUnsignedShort(), mExifByteOrder));
+                    length -= 5;
+                    break;
+                }
+
+                default: {
+                    break;
+                }
+            }
+            if (length < 0) {
+                throw new IOException("Invalid length");
+            }
+            if (in.skipBytes(length) != length) {
+                throw new IOException("Invalid JPEG segment");
+            }
+            bytesRead += length;
+        }
+        // Restore original byte order
+        in.setByteOrder(mExifByteOrder);
+    }
+
+    private void getRawAttributes(ByteOrderedDataInputStream in) throws IOException {
+        // Parse TIFF Headers. See JEITA CP-3451C Section 4.5.2. Table 1.
+        parseTiffHeaders(in, in.available());
+
+        // Read TIFF image file directories. See JEITA CP-3451C Section 4.5.2. Figure 6.
+        readImageFileDirectory(in, IFD_TYPE_PRIMARY);
+
+        // Update ImageLength/Width tags for all image data.
+        updateImageSizeValues(in, IFD_TYPE_PRIMARY);
+        updateImageSizeValues(in, IFD_TYPE_PREVIEW);
+        updateImageSizeValues(in, IFD_TYPE_THUMBNAIL);
+
+        // Check if each image data is in valid position.
+        validateImages();
+
+        if (mMimeType == IMAGE_TYPE_PEF) {
+            // PEF files contain a MakerNote data, which contains the data for ColorSpace tag.
+            // See http://lclevy.free.fr/raw/ and piex.cc PefGetPreviewData()
+            ExifAttribute makerNoteAttribute =
+                    (ExifAttribute) mAttributes[IFD_TYPE_EXIF].get(TAG_MAKER_NOTE);
+            if (makerNoteAttribute != null) {
+                // Create an ordered DataInputStream for MakerNote
+                ByteOrderedDataInputStream makerNoteDataInputStream =
+                        new ByteOrderedDataInputStream(makerNoteAttribute.bytes);
+                makerNoteDataInputStream.setByteOrder(mExifByteOrder);
+
+                // Seek to MakerNote data
+                makerNoteDataInputStream.seek(PEF_MAKER_NOTE_SKIP_SIZE);
+
+                // Read IFD data from MakerNote
+                readImageFileDirectory(makerNoteDataInputStream, IFD_TYPE_PEF);
+
+                // Update ColorSpace tag
+                ExifAttribute colorSpaceAttribute =
+                        (ExifAttribute) mAttributes[IFD_TYPE_PEF].get(TAG_COLOR_SPACE);
+                if (colorSpaceAttribute != null) {
+                    mAttributes[IFD_TYPE_EXIF].put(TAG_COLOR_SPACE, colorSpaceAttribute);
+                }
+            }
+        }
+    }
+
+    /**
+     * RAF files contains a JPEG and a CFA data.
+     * The JPEG contains two images, a preview and a thumbnail, while the CFA contains a RAW image.
+     * This method looks at the first 160 bytes of a RAF file to retrieve the offset and length
+     * values for the JPEG and CFA data.
+     * Using that data, it parses the JPEG data to retrieve the preview and thumbnail image data,
+     * then parses the CFA metadata to retrieve the primary image length/width values.
+     * For data format details, see http://fileformats.archiveteam.org/wiki/Fujifilm_RAF
+     */
+    private void getRafAttributes(ByteOrderedDataInputStream in) throws IOException {
+        // Retrieve offset & length values
+        in.skipBytes(RAF_OFFSET_TO_JPEG_IMAGE_OFFSET);
+        byte[] jpegOffsetBytes = new byte[4];
+        byte[] cfaHeaderOffsetBytes = new byte[4];
+        in.read(jpegOffsetBytes);
+        // Skip JPEG length value since it is not needed
+        in.skipBytes(RAF_JPEG_LENGTH_VALUE_SIZE);
+        in.read(cfaHeaderOffsetBytes);
+        int rafJpegOffset = ByteBuffer.wrap(jpegOffsetBytes).getInt();
+        int rafCfaHeaderOffset = ByteBuffer.wrap(cfaHeaderOffsetBytes).getInt();
+
+        // Retrieve JPEG image metadata
+        getJpegAttributes(in, rafJpegOffset, IFD_TYPE_PREVIEW);
+
+        // Skip to CFA header offset.
+        in.seek(rafCfaHeaderOffset);
+
+        // Retrieve primary image length/width values, if TAG_RAF_IMAGE_SIZE exists
+        in.setByteOrder(ByteOrder.BIG_ENDIAN);
+        int numberOfDirectoryEntry = in.readInt();
+        if (DEBUG) {
+            Log.d(TAG, "numberOfDirectoryEntry: " + numberOfDirectoryEntry);
+        }
+        // CFA stores some metadata about the RAW image. Since CFA uses proprietary tags, can only
+        // find and retrieve image size information tags, while skipping others.
+        // See piex.cc RafGetDimension()
+        for (int i = 0; i < numberOfDirectoryEntry; ++i) {
+            int tagNumber = in.readUnsignedShort();
+            int numberOfBytes = in.readUnsignedShort();
+            if (tagNumber == TAG_RAF_IMAGE_SIZE.number) {
+                int imageLength = in.readShort();
+                int imageWidth = in.readShort();
+                ExifAttribute imageLengthAttribute =
+                        ExifAttribute.createUShort(imageLength, mExifByteOrder);
+                ExifAttribute imageWidthAttribute =
+                        ExifAttribute.createUShort(imageWidth, mExifByteOrder);
+                mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_LENGTH, imageLengthAttribute);
+                mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_WIDTH, imageWidthAttribute);
+                if (DEBUG) {
+                    Log.d(TAG, "Updated to length: " + imageLength + ", width: " + imageWidth);
+                }
+                return;
+            }
+            in.skipBytes(numberOfBytes);
+        }
+    }
+
+    private void getHeifAttributes(ByteOrderedDataInputStream in) throws IOException {
+        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+        try {
+            retriever.setDataSource(new MediaDataSource() {
+                long mPosition;
+
+                @Override
+                public void close() throws IOException {}
+
+                @Override
+                public int readAt(long position, byte[] buffer, int offset, int size)
+                        throws IOException {
+                    if (size == 0) {
+                        return 0;
+                    }
+                    if (position < 0) {
+                        return -1;
+                    }
+                    try {
+                        if (mPosition != position) {
+                            // We don't allow seek to positions after the available bytes,
+                            // the input stream won't be able to seek back then.
+                            // However, if we hit an exception before (mPosition set to -1),
+                            // let it try the seek in hope it might recover.
+                            if (mPosition >= 0 && position >= mPosition + in.available()) {
+                                return -1;
+                            }
+                            in.seek(position);
+                            mPosition = position;
+                        }
+
+                        // If the read will cause us to go over the available bytes,
+                        // reduce the size so that we stay in the available range.
+                        // Otherwise the input stream may not be able to seek back.
+                        if (size > in.available()) {
+                            size = in.available();
+                        }
+
+                        int bytesRead = in.read(buffer, offset, size);
+                        if (bytesRead >= 0) {
+                            mPosition += bytesRead;
+                            return bytesRead;
+                        }
+                    } catch (IOException e) {}
+                    mPosition = -1; // need to seek on next read
+                    return -1;
+                }
+
+                @Override
+                public long getSize() throws IOException {
+                    return -1;
+                }
+            });
+
+            String exifOffsetStr = retriever.extractMetadata(
+                    MediaMetadataRetriever.METADATA_KEY_EXIF_OFFSET);
+            String exifLengthStr = retriever.extractMetadata(
+                    MediaMetadataRetriever.METADATA_KEY_EXIF_LENGTH);
+            String hasImage = retriever.extractMetadata(
+                    MediaMetadataRetriever.METADATA_KEY_HAS_IMAGE);
+            String hasVideo = retriever.extractMetadata(
+                    MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO);
+
+            String width = null;
+            String height = null;
+            String rotation = null;
+            final String METADATA_VALUE_YES = "yes";
+            // If the file has both image and video, prefer image info over video info.
+            // App querying ExifInterface is most likely using the bitmap path which
+            // picks the image first.
+            if (METADATA_VALUE_YES.equals(hasImage)) {
+                width = retriever.extractMetadata(
+                        MediaMetadataRetriever.METADATA_KEY_IMAGE_WIDTH);
+                height = retriever.extractMetadata(
+                        MediaMetadataRetriever.METADATA_KEY_IMAGE_HEIGHT);
+                rotation = retriever.extractMetadata(
+                        MediaMetadataRetriever.METADATA_KEY_IMAGE_ROTATION);
+            } else if (METADATA_VALUE_YES.equals(hasVideo)) {
+                width = retriever.extractMetadata(
+                        MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH);
+                height = retriever.extractMetadata(
+                        MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT);
+                rotation = retriever.extractMetadata(
+                        MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION);
+            }
+
+            if (width != null) {
+                mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_WIDTH,
+                        ExifAttribute.createUShort(Integer.parseInt(width), mExifByteOrder));
+            }
+
+            if (height != null) {
+                mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_LENGTH,
+                        ExifAttribute.createUShort(Integer.parseInt(height), mExifByteOrder));
+            }
+
+            if (rotation != null) {
+                int orientation = ExifInterface.ORIENTATION_NORMAL;
+
+                // all rotation angles in CW
+                switch (Integer.parseInt(rotation)) {
+                    case 90:
+                        orientation = ExifInterface.ORIENTATION_ROTATE_90;
+                        break;
+                    case 180:
+                        orientation = ExifInterface.ORIENTATION_ROTATE_180;
+                        break;
+                    case 270:
+                        orientation = ExifInterface.ORIENTATION_ROTATE_270;
+                        break;
+                }
+
+                mAttributes[IFD_TYPE_PRIMARY].put(TAG_ORIENTATION,
+                        ExifAttribute.createUShort(orientation, mExifByteOrder));
+            }
+
+            if (exifOffsetStr != null && exifLengthStr != null) {
+                int offset = Integer.parseInt(exifOffsetStr);
+                int length = Integer.parseInt(exifLengthStr);
+                if (length <= 6) {
+                    throw new IOException("Invalid exif length");
+                }
+                in.seek(offset);
+                byte[] identifier = new byte[6];
+                if (in.read(identifier) != 6) {
+                    throw new IOException("Can't read identifier");
+                }
+                offset += 6;
+                length -= 6;
+                if (!Arrays.equals(identifier, IDENTIFIER_EXIF_APP1)) {
+                    throw new IOException("Invalid identifier");
+                }
+
+                // TODO: Need to handle potential OutOfMemoryError
+                byte[] bytes = new byte[length];
+                if (in.read(bytes) != length) {
+                    throw new IOException("Can't read exif");
+                }
+                // Save offset values for handling thumbnail and attribute offsets.
+                mExifOffset = offset;
+                readExifSegment(bytes, IFD_TYPE_PRIMARY);
+            }
+
+            String xmpOffsetStr = retriever.extractMetadata(
+                    MediaMetadataRetriever.METADATA_KEY_XMP_OFFSET);
+            String xmpLengthStr = retriever.extractMetadata(
+                    MediaMetadataRetriever.METADATA_KEY_XMP_LENGTH);
+            if (xmpOffsetStr != null && xmpLengthStr != null) {
+                int offset = Integer.parseInt(xmpOffsetStr);
+                int length = Integer.parseInt(xmpLengthStr);
+                in.seek(offset);
+                byte[] xmpBytes = new byte[length];
+                if (in.read(xmpBytes) != length) {
+                    throw new IOException("Failed to read XMP from HEIF");
+                }
+                if (getAttribute(TAG_XMP) == null) {
+                    mAttributes[IFD_TYPE_PRIMARY].put(TAG_XMP, new ExifAttribute(
+                            IFD_FORMAT_BYTE, xmpBytes.length, offset, xmpBytes));
+                }
+            }
+
+            if (DEBUG) {
+                Log.d(TAG, "Heif meta: " + width + "x" + height + ", rotation " + rotation);
+            }
+        } finally {
+            retriever.release();
+        }
+    }
+
+    private void getStandaloneAttributes(ByteOrderedDataInputStream in) throws IOException {
+        in.skipBytes(IDENTIFIER_EXIF_APP1.length);
+        // TODO: Need to handle potential OutOfMemoryError
+        byte[] data = new byte[in.available()];
+        in.readFully(data);
+        // Save offset values for handling thumbnail and attribute offsets.
+        mExifOffset = IDENTIFIER_EXIF_APP1.length;
+        readExifSegment(data, IFD_TYPE_PRIMARY);
+    }
+
+    /**
+     * ORF files contains a primary image data and a MakerNote data that contains preview/thumbnail
+     * images. Both data takes the form of IFDs and can therefore be read with the
+     * readImageFileDirectory() method.
+     * This method reads all the necessary data and updates the primary/preview/thumbnail image
+     * information according to the GetOlympusPreviewImage() method in piex.cc.
+     * For data format details, see the following:
+     * http://fileformats.archiveteam.org/wiki/Olympus_ORF
+     * https://libopenraw.freedesktop.org/wiki/Olympus_ORF
+     */
+    private void getOrfAttributes(ByteOrderedDataInputStream in) throws IOException {
+        // Retrieve primary image data
+        // Other Exif data will be located in the Makernote.
+        getRawAttributes(in);
+
+        // Additionally retrieve preview/thumbnail information from MakerNote tag, which contains
+        // proprietary tags and therefore does not have offical documentation
+        // See GetOlympusPreviewImage() in piex.cc & http://www.exiv2.org/tags-olympus.html
+        ExifAttribute makerNoteAttribute =
+                (ExifAttribute) mAttributes[IFD_TYPE_EXIF].get(TAG_MAKER_NOTE);
+        if (makerNoteAttribute != null) {
+            // Create an ordered DataInputStream for MakerNote
+            ByteOrderedDataInputStream makerNoteDataInputStream =
+                    new ByteOrderedDataInputStream(makerNoteAttribute.bytes);
+            makerNoteDataInputStream.setByteOrder(mExifByteOrder);
+
+            // There are two types of headers for Olympus MakerNotes
+            // See http://www.exiv2.org/makernote.html#R1
+            byte[] makerNoteHeader1Bytes = new byte[ORF_MAKER_NOTE_HEADER_1.length];
+            makerNoteDataInputStream.readFully(makerNoteHeader1Bytes);
+            makerNoteDataInputStream.seek(0);
+            byte[] makerNoteHeader2Bytes = new byte[ORF_MAKER_NOTE_HEADER_2.length];
+            makerNoteDataInputStream.readFully(makerNoteHeader2Bytes);
+            // Skip the corresponding amount of bytes for each header type
+            if (Arrays.equals(makerNoteHeader1Bytes, ORF_MAKER_NOTE_HEADER_1)) {
+                makerNoteDataInputStream.seek(ORF_MAKER_NOTE_HEADER_1_SIZE);
+            } else if (Arrays.equals(makerNoteHeader2Bytes, ORF_MAKER_NOTE_HEADER_2)) {
+                makerNoteDataInputStream.seek(ORF_MAKER_NOTE_HEADER_2_SIZE);
+            }
+
+            // Read IFD data from MakerNote
+            readImageFileDirectory(makerNoteDataInputStream, IFD_TYPE_ORF_MAKER_NOTE);
+
+            // Retrieve & update preview image offset & length values
+            ExifAttribute imageLengthAttribute = (ExifAttribute)
+                    mAttributes[IFD_TYPE_ORF_CAMERA_SETTINGS].get(TAG_ORF_PREVIEW_IMAGE_START);
+            ExifAttribute bitsPerSampleAttribute = (ExifAttribute)
+                    mAttributes[IFD_TYPE_ORF_CAMERA_SETTINGS].get(TAG_ORF_PREVIEW_IMAGE_LENGTH);
+
+            if (imageLengthAttribute != null && bitsPerSampleAttribute != null) {
+                mAttributes[IFD_TYPE_PREVIEW].put(TAG_JPEG_INTERCHANGE_FORMAT,
+                        imageLengthAttribute);
+                mAttributes[IFD_TYPE_PREVIEW].put(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH,
+                        bitsPerSampleAttribute);
+            }
+
+            // TODO: Check this behavior in other ORF files
+            // Retrieve primary image length & width values
+            // See piex.cc GetOlympusPreviewImage()
+            ExifAttribute aspectFrameAttribute = (ExifAttribute)
+                    mAttributes[IFD_TYPE_ORF_IMAGE_PROCESSING].get(TAG_ORF_ASPECT_FRAME);
+            if (aspectFrameAttribute != null) {
+                int[] aspectFrameValues = new int[4];
+                aspectFrameValues = (int[]) aspectFrameAttribute.getValue(mExifByteOrder);
+                if (aspectFrameValues[2] > aspectFrameValues[0] &&
+                        aspectFrameValues[3] > aspectFrameValues[1]) {
+                    int primaryImageWidth = aspectFrameValues[2] - aspectFrameValues[0] + 1;
+                    int primaryImageLength = aspectFrameValues[3] - aspectFrameValues[1] + 1;
+                    // Swap width & length values
+                    if (primaryImageWidth < primaryImageLength) {
+                        primaryImageWidth += primaryImageLength;
+                        primaryImageLength = primaryImageWidth - primaryImageLength;
+                        primaryImageWidth -= primaryImageLength;
+                    }
+                    ExifAttribute primaryImageWidthAttribute =
+                            ExifAttribute.createUShort(primaryImageWidth, mExifByteOrder);
+                    ExifAttribute primaryImageLengthAttribute =
+                            ExifAttribute.createUShort(primaryImageLength, mExifByteOrder);
+
+                    mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_WIDTH, primaryImageWidthAttribute);
+                    mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_LENGTH, primaryImageLengthAttribute);
+                }
+            }
+        }
+    }
+
+    // RW2 contains the primary image data in IFD0 and the preview and/or thumbnail image data in
+    // the JpgFromRaw tag
+    // See https://libopenraw.freedesktop.org/wiki/Panasonic_RAW/ and piex.cc Rw2GetPreviewData()
+    private void getRw2Attributes(ByteOrderedDataInputStream in) throws IOException {
+        // Retrieve primary image data
+        getRawAttributes(in);
+
+        // Retrieve preview and/or thumbnail image data
+        ExifAttribute jpgFromRawAttribute =
+                (ExifAttribute) mAttributes[IFD_TYPE_PRIMARY].get(TAG_RW2_JPG_FROM_RAW);
+        if (jpgFromRawAttribute != null) {
+            getJpegAttributes(in, mRw2JpgFromRawOffset, IFD_TYPE_PREVIEW);
+        }
+
+        // Set ISO tag value if necessary
+        ExifAttribute rw2IsoAttribute =
+                (ExifAttribute) mAttributes[IFD_TYPE_PRIMARY].get(TAG_RW2_ISO);
+        ExifAttribute exifIsoAttribute =
+                (ExifAttribute) mAttributes[IFD_TYPE_EXIF].get(TAG_ISO_SPEED_RATINGS);
+        if (rw2IsoAttribute != null && exifIsoAttribute == null) {
+            // Place this attribute only if it doesn't exist
+            mAttributes[IFD_TYPE_EXIF].put(TAG_ISO_SPEED_RATINGS, rw2IsoAttribute);
+        }
+    }
+
+    // PNG contains the EXIF data as a Special-Purpose Chunk
+    private void getPngAttributes(ByteOrderedDataInputStream in) throws IOException {
+        if (DEBUG) {
+            Log.d(TAG, "getPngAttributes starting with: " + in);
+        }
+
+        // PNG uses Big Endian by default.
+        // See PNG (Portable Network Graphics) Specification, Version 1.2,
+        // 2.1. Integers and byte order
+        in.setByteOrder(ByteOrder.BIG_ENDIAN);
+
+        int bytesRead = 0;
+
+        // Skip the signature bytes
+        in.skipBytes(PNG_SIGNATURE.length);
+        bytesRead += PNG_SIGNATURE.length;
+
+        // Each chunk is made up of four parts:
+        //   1) Length: 4-byte unsigned integer indicating the number of bytes in the
+        //   Chunk Data field. Excludes Chunk Type and CRC bytes.
+        //   2) Chunk Type: 4-byte chunk type code.
+        //   3) Chunk Data: The data bytes. Can be zero-length.
+        //   4) CRC: 4-byte data calculated on the preceding bytes in the chunk. Always
+        //   present.
+        // --> 4 (length bytes) + 4 (type bytes) + X (data bytes) + 4 (CRC bytes)
+        // See PNG (Portable Network Graphics) Specification, Version 1.2,
+        // 3.2. Chunk layout
+        try {
+            while (true) {
+                int length = in.readInt();
+                bytesRead += 4;
+
+                byte[] type = new byte[PNG_CHUNK_TYPE_BYTE_LENGTH];
+                if (in.read(type) != type.length) {
+                    throw new IOException("Encountered invalid length while parsing PNG chunk"
+                            + "type");
+                }
+                bytesRead += PNG_CHUNK_TYPE_BYTE_LENGTH;
+
+                // The first chunk must be the IHDR chunk
+                if (bytesRead == 16 && !Arrays.equals(type, PNG_CHUNK_TYPE_IHDR)) {
+                    throw new IOException("Encountered invalid PNG file--IHDR chunk should appear"
+                            + "as the first chunk");
+                }
+
+                if (Arrays.equals(type, PNG_CHUNK_TYPE_IEND)) {
+                    // IEND marks the end of the image.
+                    break;
+                } else if (Arrays.equals(type, PNG_CHUNK_TYPE_EXIF)) {
+                    // TODO: Need to handle potential OutOfMemoryError
+                    byte[] data = new byte[length];
+                    if (in.read(data) != length) {
+                        throw new IOException("Failed to read given length for given PNG chunk "
+                                + "type: " + byteArrayToHexString(type));
+                    }
+
+                    // Compare CRC values for potential data corruption.
+                    int dataCrcValue = in.readInt();
+                    // Cyclic Redundancy Code used to check for corruption of the data
+                    CRC32 crc = new CRC32();
+                    crc.update(type);
+                    crc.update(data);
+                    if ((int) crc.getValue() != dataCrcValue) {
+                        throw new IOException("Encountered invalid CRC value for PNG-EXIF chunk."
+                                + "\n recorded CRC value: " + dataCrcValue + ", calculated CRC "
+                                + "value: " + crc.getValue());
+                    }
+                    // Save offset values for handleThumbnailFromJfif() function
+                    mExifOffset = bytesRead;
+                    readExifSegment(data, IFD_TYPE_PRIMARY);
+
+                    validateImages();
+                    break;
+                } else {
+                    // Skip to next chunk
+                    in.skipBytes(length + PNG_CHUNK_CRC_BYTE_LENGTH);
+                    bytesRead += length + PNG_CHUNK_CRC_BYTE_LENGTH;
+                }
+            }
+        } catch (EOFException e) {
+            // Should not reach here. Will only reach here if the file is corrupted or
+            // does not follow the PNG specifications
+            throw new IOException("Encountered corrupt PNG file.");
+        }
+    }
+
+    // WebP contains EXIF data as a RIFF File Format Chunk
+    // All references below can be found in the following link.
+    // https://developers.google.com/speed/webp/docs/riff_container
+    private void getWebpAttributes(ByteOrderedDataInputStream in) throws IOException {
+        if (DEBUG) {
+            Log.d(TAG, "getWebpAttributes starting with: " + in);
+        }
+        // WebP uses little-endian by default.
+        // See Section "Terminology & Basics"
+        in.setByteOrder(ByteOrder.LITTLE_ENDIAN);
+        in.skipBytes(WEBP_SIGNATURE_1.length);
+        // File size corresponds to the size of the entire file from offset 8.
+        // See Section "WebP File Header"
+        int fileSize = in.readInt() + 8;
+        int bytesRead = 8;
+        bytesRead += in.skipBytes(WEBP_SIGNATURE_2.length);
+        try {
+            while (true) {
+                // TODO: Check the first Chunk Type, and if it is VP8X, check if the chunks are
+                // ordered properly.
+
+                // Each chunk is made up of three parts:
+                //   1) Chunk FourCC: 4-byte concatenating four ASCII characters.
+                //   2) Chunk Size: 4-byte unsigned integer indicating the size of the chunk.
+                //                  Excludes Chunk FourCC and Chunk Size bytes.
+                //   3) Chunk Payload: data payload. A single padding byte ('0') is added if
+                //                     Chunk Size is odd.
+                // See Section "RIFF File Format"
+                byte[] code = new byte[WEBP_CHUNK_TYPE_BYTE_LENGTH];
+                if (in.read(code) != code.length) {
+                    throw new IOException("Encountered invalid length while parsing WebP chunk"
+                            + "type");
+                }
+                bytesRead += 4;
+                int chunkSize = in.readInt();
+                bytesRead += 4;
+                if (Arrays.equals(WEBP_CHUNK_TYPE_EXIF, code)) {
+                    // TODO: Need to handle potential OutOfMemoryError
+                    byte[] payload = new byte[chunkSize];
+                    if (in.read(payload) != chunkSize) {
+                        throw new IOException("Failed to read given length for given PNG chunk "
+                                + "type: " + byteArrayToHexString(code));
+                    }
+                    // Save offset values for handling thumbnail and attribute offsets.
+                    mExifOffset = bytesRead;
+                    readExifSegment(payload, IFD_TYPE_PRIMARY);
+
+                    // Save offset values for handleThumbnailFromJfif() function
+                    mExifOffset = bytesRead;
+                    break;
+                } else {
+                    // Add a single padding byte at end if chunk size is odd
+                    chunkSize = (chunkSize % 2 == 1) ? chunkSize + 1 : chunkSize;
+                    // Check if skipping to next chunk is necessary
+                    if (bytesRead + chunkSize == fileSize) {
+                        // Reached end of file
+                        break;
+                    } else if (bytesRead + chunkSize > fileSize) {
+                        throw new IOException("Encountered WebP file with invalid chunk size");
+                    }
+                    // Skip to next chunk
+                    int skipped = in.skipBytes(chunkSize);
+                    if (skipped != chunkSize) {
+                        throw new IOException("Encountered WebP file with invalid chunk size");
+                    }
+                    bytesRead += skipped;
+                }
+            }
+        } catch (EOFException e) {
+            // Should not reach here. Will only reach here if the file is corrupted or
+            // does not follow the WebP specifications
+            throw new IOException("Encountered corrupt WebP file.");
+        }
+    }
+
+    // Stores a new JPEG image with EXIF attributes into a given output stream.
+    private void saveJpegAttributes(InputStream inputStream, OutputStream outputStream)
+            throws IOException {
+        // See JPEG File Interchange Format Specification, "JFIF Specification"
+        if (DEBUG) {
+            Log.d(TAG, "saveJpegAttributes starting with (inputStream: " + inputStream
+                    + ", outputStream: " + outputStream + ")");
+        }
+        DataInputStream dataInputStream = new DataInputStream(inputStream);
+        ByteOrderedDataOutputStream dataOutputStream =
+                new ByteOrderedDataOutputStream(outputStream, ByteOrder.BIG_ENDIAN);
+        if (dataInputStream.readByte() != MARKER) {
+            throw new IOException("Invalid marker");
+        }
+        dataOutputStream.writeByte(MARKER);
+        if (dataInputStream.readByte() != MARKER_SOI) {
+            throw new IOException("Invalid marker");
+        }
+        dataOutputStream.writeByte(MARKER_SOI);
+
+        // Remove XMP data if it is from a separate marker (IDENTIFIER_XMP_APP1, not
+        // IDENTIFIER_EXIF_APP1)
+        // Will re-add it later after the rest of the file is written
+        ExifAttribute xmpAttribute = null;
+        if (getAttribute(TAG_XMP) != null && mXmpIsFromSeparateMarker) {
+            xmpAttribute = (ExifAttribute) mAttributes[IFD_TYPE_PRIMARY].remove(TAG_XMP);
+        }
+
+        // Write EXIF APP1 segment
+        dataOutputStream.writeByte(MARKER);
+        dataOutputStream.writeByte(MARKER_APP1);
+        writeExifSegment(dataOutputStream);
+
+        // Re-add previously removed XMP data.
+        if (xmpAttribute != null) {
+            mAttributes[IFD_TYPE_PRIMARY].put(TAG_XMP, xmpAttribute);
+        }
+
+        byte[] bytes = new byte[4096];
+
+        while (true) {
+            byte marker = dataInputStream.readByte();
+            if (marker != MARKER) {
+                throw new IOException("Invalid marker");
+            }
+            marker = dataInputStream.readByte();
+            switch (marker) {
+                case MARKER_APP1: {
+                    int length = dataInputStream.readUnsignedShort() - 2;
+                    if (length < 0) {
+                        throw new IOException("Invalid length");
+                    }
+                    byte[] identifier = new byte[6];
+                    if (length >= 6) {
+                        if (dataInputStream.read(identifier) != 6) {
+                            throw new IOException("Invalid exif");
+                        }
+                        if (Arrays.equals(identifier, IDENTIFIER_EXIF_APP1)) {
+                            // Skip the original EXIF APP1 segment.
+                            if (dataInputStream.skipBytes(length - 6) != length - 6) {
+                                throw new IOException("Invalid length");
+                            }
+                            break;
+                        }
+                    }
+                    // Copy non-EXIF APP1 segment.
+                    dataOutputStream.writeByte(MARKER);
+                    dataOutputStream.writeByte(marker);
+                    dataOutputStream.writeUnsignedShort(length + 2);
+                    if (length >= 6) {
+                        length -= 6;
+                        dataOutputStream.write(identifier);
+                    }
+                    int read;
+                    while (length > 0 && (read = dataInputStream.read(
+                            bytes, 0, Math.min(length, bytes.length))) >= 0) {
+                        dataOutputStream.write(bytes, 0, read);
+                        length -= read;
+                    }
+                    break;
+                }
+                case MARKER_EOI:
+                case MARKER_SOS: {
+                    dataOutputStream.writeByte(MARKER);
+                    dataOutputStream.writeByte(marker);
+                    // Copy all the remaining data
+                    copy(dataInputStream, dataOutputStream);
+                    return;
+                }
+                default: {
+                    // Copy JPEG segment
+                    dataOutputStream.writeByte(MARKER);
+                    dataOutputStream.writeByte(marker);
+                    int length = dataInputStream.readUnsignedShort();
+                    dataOutputStream.writeUnsignedShort(length);
+                    length -= 2;
+                    if (length < 0) {
+                        throw new IOException("Invalid length");
+                    }
+                    int read;
+                    while (length > 0 && (read = dataInputStream.read(
+                            bytes, 0, Math.min(length, bytes.length))) >= 0) {
+                        dataOutputStream.write(bytes, 0, read);
+                        length -= read;
+                    }
+                    break;
+                }
+            }
+        }
+    }
+
+    private void savePngAttributes(InputStream inputStream, OutputStream outputStream)
+            throws IOException {
+        if (DEBUG) {
+            Log.d(TAG, "savePngAttributes starting with (inputStream: " + inputStream
+                    + ", outputStream: " + outputStream + ")");
+        }
+        DataInputStream dataInputStream = new DataInputStream(inputStream);
+        ByteOrderedDataOutputStream dataOutputStream =
+                new ByteOrderedDataOutputStream(outputStream, ByteOrder.BIG_ENDIAN);
+        // Copy PNG signature bytes
+        copy(dataInputStream, dataOutputStream, PNG_SIGNATURE.length);
+        // EXIF chunk can appear anywhere between the first (IHDR) and last (IEND) chunks, except
+        // between IDAT chunks.
+        // Adhering to these rules,
+        //   1) if EXIF chunk did not exist in the original file, it will be stored right after the
+        //      first chunk,
+        //   2) if EXIF chunk existed in the original file, it will be stored in the same location.
+        if (mExifOffset == 0) {
+            // Copy IHDR chunk bytes
+            int ihdrChunkLength = dataInputStream.readInt();
+            dataOutputStream.writeInt(ihdrChunkLength);
+            copy(dataInputStream, dataOutputStream, PNG_CHUNK_TYPE_BYTE_LENGTH
+                    + ihdrChunkLength + PNG_CHUNK_CRC_BYTE_LENGTH);
+        } else {
+            // Copy up until the point where EXIF chunk length information is stored.
+            int copyLength = mExifOffset - PNG_SIGNATURE.length
+                    - 4 /* PNG EXIF chunk length bytes */
+                    - PNG_CHUNK_TYPE_BYTE_LENGTH;
+            copy(dataInputStream, dataOutputStream, copyLength);
+            // Skip to the start of the chunk after the EXIF chunk
+            int exifChunkLength = dataInputStream.readInt();
+            dataInputStream.skipBytes(PNG_CHUNK_TYPE_BYTE_LENGTH + exifChunkLength
+                    + PNG_CHUNK_CRC_BYTE_LENGTH);
+        }
+        // Write EXIF data
+        try (ByteArrayOutputStream exifByteArrayOutputStream = new ByteArrayOutputStream()) {
+            // A byte array is needed to calculate the CRC value of this chunk which requires
+            // the chunk type bytes and the chunk data bytes.
+            ByteOrderedDataOutputStream exifDataOutputStream =
+                    new ByteOrderedDataOutputStream(exifByteArrayOutputStream,
+                            ByteOrder.BIG_ENDIAN);
+            // Store Exif data in separate byte array
+            writeExifSegment(exifDataOutputStream);
+            byte[] exifBytes =
+                    ((ByteArrayOutputStream) exifDataOutputStream.mOutputStream).toByteArray();
+            // Write EXIF chunk data
+            dataOutputStream.write(exifBytes);
+            // Write EXIF chunk CRC
+            CRC32 crc = new CRC32();
+            crc.update(exifBytes, 4 /* skip length bytes */, exifBytes.length - 4);
+            dataOutputStream.writeInt((int) crc.getValue());
+        }
+        // Copy the rest of the file
+        copy(dataInputStream, dataOutputStream);
+    }
+
+    // A WebP file has a header and a series of chunks.
+    // The header is composed of:
+    //   "RIFF" + File Size + "WEBP"
+    //
+    // The structure of the chunks can be divided largely into two categories:
+    //   1) Contains only image data,
+    //   2) Contains image data and extra data.
+    // In the first category, there is only one chunk: type "VP8" (compression with loss) or "VP8L"
+    // (lossless compression).
+    // In the second category, the first chunk will be of type "VP8X", which contains flags
+    // indicating which extra data exist in later chunks. The proceeding chunks must conform to
+    // the following order based on type (if they exist):
+    //   Color Profile ("ICCP") + Animation Control Data ("ANIM") + Image Data ("VP8"/"VP8L")
+    //   + Exif metadata ("EXIF") + XMP metadata ("XMP")
+    //
+    // And in order to have EXIF data, a WebP file must be of the second structure and thus follow
+    // the following rules:
+    //   1) "VP8X" chunk as the first chunk,
+    //   2) flag for EXIF inside "VP8X" chunk set to 1, and
+    //   3) contain the "EXIF" chunk in the correct order amongst other chunks.
+    //
+    // Based on these rules, this API will support three different cases depending on the contents
+    // of the original file:
+    //   1) "EXIF" chunk already exists
+    //     -> replace it with the new "EXIF" chunk
+    //   2) "EXIF" chunk does not exist and the first chunk is "VP8" or "VP8L"
+    //     -> add "VP8X" before the "VP8"/"VP8L" chunk (with EXIF flag set to 1), and add new
+    //     "EXIF" chunk after the "VP8"/"VP8L" chunk.
+    //   3) "EXIF" chunk does not exist and the first chunk is "VP8X"
+    //     -> set EXIF flag in "VP8X" chunk to 1, and add new "EXIF" chunk at the proper location.
+    //
+    // See https://developers.google.com/speed/webp/docs/riff_container for more details.
+    private void saveWebpAttributes(InputStream inputStream, OutputStream outputStream)
+            throws IOException {
+        if (DEBUG) {
+            Log.d(TAG, "saveWebpAttributes starting with (inputStream: " + inputStream
+                    + ", outputStream: " + outputStream + ")");
+        }
+        ByteOrderedDataInputStream totalInputStream =
+                new ByteOrderedDataInputStream(inputStream, ByteOrder.LITTLE_ENDIAN);
+        ByteOrderedDataOutputStream totalOutputStream =
+                new ByteOrderedDataOutputStream(outputStream, ByteOrder.LITTLE_ENDIAN);
+
+        // WebP signature
+        copy(totalInputStream, totalOutputStream, WEBP_SIGNATURE_1.length);
+        // File length will be written after all the chunks have been written
+        totalInputStream.skipBytes(WEBP_FILE_SIZE_BYTE_LENGTH + WEBP_SIGNATURE_2.length);
+
+        // Create a separate byte array to calculate file length
+        ByteArrayOutputStream nonHeaderByteArrayOutputStream = null;
+        try {
+            nonHeaderByteArrayOutputStream = new ByteArrayOutputStream();
+            ByteOrderedDataOutputStream nonHeaderOutputStream =
+                    new ByteOrderedDataOutputStream(nonHeaderByteArrayOutputStream,
+                            ByteOrder.LITTLE_ENDIAN);
+
+            if (mExifOffset != 0) {
+                // EXIF chunk exists in the original file
+                // Tested by webp_with_exif.webp
+                int bytesRead = WEBP_SIGNATURE_1.length + WEBP_FILE_SIZE_BYTE_LENGTH
+                        + WEBP_SIGNATURE_2.length;
+                copy(totalInputStream, nonHeaderOutputStream,
+                        mExifOffset - bytesRead - WEBP_CHUNK_TYPE_BYTE_LENGTH
+                                - WEBP_CHUNK_SIZE_BYTE_LENGTH);
+
+                // Skip input stream to the end of the EXIF chunk
+                totalInputStream.skipBytes(WEBP_CHUNK_TYPE_BYTE_LENGTH);
+                int exifChunkLength = totalInputStream.readInt();
+                totalInputStream.skipBytes(exifChunkLength);
+
+                // Write new EXIF chunk to output stream
+                int exifSize = writeExifSegment(nonHeaderOutputStream);
+            } else {
+                // EXIF chunk does not exist in the original file
+                byte[] firstChunkType = new byte[WEBP_CHUNK_TYPE_BYTE_LENGTH];
+                if (totalInputStream.read(firstChunkType) != firstChunkType.length) {
+                    throw new IOException("Encountered invalid length while parsing WebP chunk "
+                            + "type");
+                }
+
+                if (Arrays.equals(firstChunkType, WEBP_CHUNK_TYPE_VP8X)) {
+                    // Original file already includes other extra data
+                    int size = totalInputStream.readInt();
+                    // WebP files have a single padding byte at the end if the chunk size is odd.
+                    byte[] data = new byte[(size % 2) == 1 ? size + 1 : size];
+                    totalInputStream.read(data);
+
+                    // Set the EXIF flag to 1
+                    data[0] = (byte) (data[0] | (1 << 3));
+
+                    // Retrieve Animation flag--in order to check where EXIF data should start
+                    boolean containsAnimation = ((data[0] >> 1) & 1) == 1;
+
+                    // Write the original VP8X chunk
+                    nonHeaderOutputStream.write(WEBP_CHUNK_TYPE_VP8X);
+                    nonHeaderOutputStream.writeInt(size);
+                    nonHeaderOutputStream.write(data);
+
+                    // Animation control data is composed of 1 ANIM chunk and multiple ANMF
+                    // chunks and since the image data (VP8/VP8L) chunks are included in the ANMF
+                    // chunks, EXIF data should come after the last ANMF chunk.
+                    // Also, because there is no value indicating the amount of ANMF chunks, we need
+                    // to keep iterating through chunks until we either reach the end of the file or
+                    // the XMP chunk (if it exists).
+                    // Tested by webp_with_anim_without_exif.webp
+                    if (containsAnimation) {
+                        copyChunksUpToGivenChunkType(totalInputStream, nonHeaderOutputStream,
+                                WEBP_CHUNK_TYPE_ANIM, null);
+
+                        while (true) {
+                            byte[] type = new byte[WEBP_CHUNK_TYPE_BYTE_LENGTH];
+                            int read = inputStream.read(type);
+                            if (!Arrays.equals(type, WEBP_CHUNK_TYPE_ANMF)) {
+                                // Either we have reached EOF or the start of a non-ANMF chunk
+                                writeExifSegment(nonHeaderOutputStream);
+                                break;
+                            }
+                            copyWebPChunk(totalInputStream, nonHeaderOutputStream, type);
+                        }
+                    } else {
+                        // Skip until we find the VP8 or VP8L chunk
+                        copyChunksUpToGivenChunkType(totalInputStream, nonHeaderOutputStream,
+                                WEBP_CHUNK_TYPE_VP8, WEBP_CHUNK_TYPE_VP8L);
+                        writeExifSegment(nonHeaderOutputStream);
+                    }
+                } else if (Arrays.equals(firstChunkType, WEBP_CHUNK_TYPE_VP8)
+                        || Arrays.equals(firstChunkType, WEBP_CHUNK_TYPE_VP8L)) {
+                    int size = totalInputStream.readInt();
+                    int bytesToRead = size;
+                    // WebP files have a single padding byte at the end if the chunk size is odd.
+                    if (size % 2 == 1) {
+                        bytesToRead += 1;
+                    }
+
+                    // Retrieve image width/height
+                    int widthAndHeight = 0;
+                    int width = 0;
+                    int height = 0;
+                    int alpha = 0;
+                    // Save VP8 frame data for later
+                    byte[] vp8Frame = new byte[3];
+
+                    if (Arrays.equals(firstChunkType, WEBP_CHUNK_TYPE_VP8)) {
+                        totalInputStream.read(vp8Frame);
+
+                        // Check signature
+                        byte[] vp8Signature = new byte[3];
+                        if (totalInputStream.read(vp8Signature) != vp8Signature.length
+                                || !Arrays.equals(WEBP_VP8_SIGNATURE, vp8Signature)) {
+                            throw new IOException("Encountered error while checking VP8 "
+                                    + "signature");
+                        }
+
+                        // Retrieve image width/height
+                        widthAndHeight = totalInputStream.readInt();
+                        width = (widthAndHeight << 18) >> 18;
+                        height = (widthAndHeight << 2) >> 18;
+                        bytesToRead -= (vp8Frame.length + vp8Signature.length + 4);
+                    } else if (Arrays.equals(firstChunkType, WEBP_CHUNK_TYPE_VP8L)) {
+                        // Check signature
+                        byte vp8lSignature = totalInputStream.readByte();
+                        if (vp8lSignature != WEBP_VP8L_SIGNATURE) {
+                            throw new IOException("Encountered error while checking VP8L "
+                                    + "signature");
+                        }
+
+                        // Retrieve image width/height
+                        widthAndHeight = totalInputStream.readInt();
+                        // VP8L stores width - 1 and height - 1 values. See "2 RIFF Header" of
+                        // "WebP Lossless Bitstream Specification"
+                        width = ((widthAndHeight << 18) >> 18) + 1;
+                        height = ((widthAndHeight << 4) >> 18) + 1;
+                        // Retrieve alpha bit
+                        alpha = widthAndHeight & (1 << 3);
+                        bytesToRead -= (1 /* VP8L signature */ + 4);
+                    }
+
+                    // Create VP8X with Exif flag set to 1
+                    nonHeaderOutputStream.write(WEBP_CHUNK_TYPE_VP8X);
+                    nonHeaderOutputStream.writeInt(WEBP_CHUNK_TYPE_VP8X_DEFAULT_LENGTH);
+                    byte[] data = new byte[WEBP_CHUNK_TYPE_VP8X_DEFAULT_LENGTH];
+                    // EXIF flag
+                    data[0] = (byte) (data[0] | (1 << 3));
+                    // ALPHA flag
+                    data[0] = (byte) (data[0] | (alpha << 4));
+                    // VP8X stores Width - 1 and Height - 1 values
+                    width -= 1;
+                    height -= 1;
+                    data[4] = (byte) width;
+                    data[5] = (byte) (width >> 8);
+                    data[6] = (byte) (width >> 16);
+                    data[7] = (byte) height;
+                    data[8] = (byte) (height >> 8);
+                    data[9] = (byte) (height >> 16);
+                    nonHeaderOutputStream.write(data);
+
+                    // Write VP8 or VP8L data
+                    nonHeaderOutputStream.write(firstChunkType);
+                    nonHeaderOutputStream.writeInt(size);
+                    if (Arrays.equals(firstChunkType, WEBP_CHUNK_TYPE_VP8)) {
+                        nonHeaderOutputStream.write(vp8Frame);
+                        nonHeaderOutputStream.write(WEBP_VP8_SIGNATURE);
+                        nonHeaderOutputStream.writeInt(widthAndHeight);
+                    } else if (Arrays.equals(firstChunkType, WEBP_CHUNK_TYPE_VP8L)) {
+                        nonHeaderOutputStream.write(WEBP_VP8L_SIGNATURE);
+                        nonHeaderOutputStream.writeInt(widthAndHeight);
+                    }
+                    copy(totalInputStream, nonHeaderOutputStream, bytesToRead);
+
+                    // Write EXIF chunk
+                    writeExifSegment(nonHeaderOutputStream);
+                }
+            }
+
+            // Copy the rest of the file
+            copy(totalInputStream, nonHeaderOutputStream);
+
+            // Write file length + second signature
+            totalOutputStream.writeInt(nonHeaderByteArrayOutputStream.size()
+                    + WEBP_SIGNATURE_2.length);
+            totalOutputStream.write(WEBP_SIGNATURE_2);
+            nonHeaderByteArrayOutputStream.writeTo(totalOutputStream);
+        } catch (Exception e) {
+            throw new IOException("Failed to save WebP file", e);
+        } finally {
+            closeQuietly(nonHeaderByteArrayOutputStream);
+        }
+    }
+
+    private void copyChunksUpToGivenChunkType(ByteOrderedDataInputStream inputStream,
+            ByteOrderedDataOutputStream outputStream, byte[] firstGivenType,
+            byte[] secondGivenType) throws IOException {
+        while (true) {
+            byte[] type = new byte[WEBP_CHUNK_TYPE_BYTE_LENGTH];
+            if (inputStream.read(type) != type.length) {
+                throw new IOException("Encountered invalid length while copying WebP chunks up to"
+                        + "chunk type " + new String(firstGivenType, ASCII)
+                        + ((secondGivenType == null) ? "" : " or " + new String(secondGivenType,
+                        ASCII)));
+            }
+            copyWebPChunk(inputStream, outputStream, type);
+            if (Arrays.equals(type, firstGivenType)
+                    || (secondGivenType != null && Arrays.equals(type, secondGivenType))) {
+                break;
+            }
+        }
+    }
+
+    private void copyWebPChunk(ByteOrderedDataInputStream inputStream,
+            ByteOrderedDataOutputStream outputStream, byte[] type) throws IOException {
+        int size = inputStream.readInt();
+        outputStream.write(type);
+        outputStream.writeInt(size);
+        // WebP files have a single padding byte at the end if the chunk size is odd.
+        copy(inputStream, outputStream, (size % 2) == 1 ? size + 1 : size);
+    }
+
+    // Reads the given EXIF byte area and save its tag data into attributes.
+    private void readExifSegment(byte[] exifBytes, int imageType) throws IOException {
+        ByteOrderedDataInputStream dataInputStream =
+                new ByteOrderedDataInputStream(exifBytes);
+
+        // Parse TIFF Headers. See JEITA CP-3451C Section 4.5.2. Table 1.
+        parseTiffHeaders(dataInputStream, exifBytes.length);
+
+        // Read TIFF image file directories. See JEITA CP-3451C Section 4.5.2. Figure 6.
+        readImageFileDirectory(dataInputStream, imageType);
+    }
+
+    private void addDefaultValuesForCompatibility() {
+        // If DATETIME tag has no value, then set the value to DATETIME_ORIGINAL tag's.
+        String valueOfDateTimeOriginal = getAttribute(TAG_DATETIME_ORIGINAL);
+        if (valueOfDateTimeOriginal != null && getAttribute(TAG_DATETIME) == null) {
+            mAttributes[IFD_TYPE_PRIMARY].put(TAG_DATETIME,
+                    ExifAttribute.createString(valueOfDateTimeOriginal));
+        }
+
+        // Add the default value.
+        if (getAttribute(TAG_IMAGE_WIDTH) == null) {
+            mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_WIDTH,
+                    ExifAttribute.createULong(0, mExifByteOrder));
+        }
+        if (getAttribute(TAG_IMAGE_LENGTH) == null) {
+            mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_LENGTH,
+                    ExifAttribute.createULong(0, mExifByteOrder));
+        }
+        if (getAttribute(TAG_ORIENTATION) == null) {
+            mAttributes[IFD_TYPE_PRIMARY].put(TAG_ORIENTATION,
+                    ExifAttribute.createUShort(0, mExifByteOrder));
+        }
+        if (getAttribute(TAG_LIGHT_SOURCE) == null) {
+            mAttributes[IFD_TYPE_EXIF].put(TAG_LIGHT_SOURCE,
+                    ExifAttribute.createULong(0, mExifByteOrder));
+        }
+    }
+
+    private ByteOrder readByteOrder(ByteOrderedDataInputStream dataInputStream)
+            throws IOException {
+        // Read byte order.
+        short byteOrder = dataInputStream.readShort();
+        switch (byteOrder) {
+            case BYTE_ALIGN_II:
+                if (DEBUG) {
+                    Log.d(TAG, "readExifSegment: Byte Align II");
+                }
+                return ByteOrder.LITTLE_ENDIAN;
+            case BYTE_ALIGN_MM:
+                if (DEBUG) {
+                    Log.d(TAG, "readExifSegment: Byte Align MM");
+                }
+                return ByteOrder.BIG_ENDIAN;
+            default:
+                throw new IOException("Invalid byte order: " + Integer.toHexString(byteOrder));
+        }
+    }
+
+    private void parseTiffHeaders(ByteOrderedDataInputStream dataInputStream,
+            int exifBytesLength) throws IOException {
+        // Read byte order
+        mExifByteOrder = readByteOrder(dataInputStream);
+        // Set byte order
+        dataInputStream.setByteOrder(mExifByteOrder);
+
+        // Check start code
+        int startCode = dataInputStream.readUnsignedShort();
+        if (mMimeType != IMAGE_TYPE_ORF && mMimeType != IMAGE_TYPE_RW2 && startCode != START_CODE) {
+            throw new IOException("Invalid start code: " + Integer.toHexString(startCode));
+        }
+
+        // Read and skip to first ifd offset
+        int firstIfdOffset = dataInputStream.readInt();
+        if (firstIfdOffset < 8 || firstIfdOffset >= exifBytesLength) {
+            throw new IOException("Invalid first Ifd offset: " + firstIfdOffset);
+        }
+        firstIfdOffset -= 8;
+        if (firstIfdOffset > 0) {
+            if (dataInputStream.skipBytes(firstIfdOffset) != firstIfdOffset) {
+                throw new IOException("Couldn't jump to first Ifd: " + firstIfdOffset);
+            }
+        }
+    }
+
+    // Reads image file directory, which is a tag group in EXIF.
+    private void readImageFileDirectory(ByteOrderedDataInputStream dataInputStream,
+            @IfdType int ifdType) throws IOException {
+        // Save offset of current IFD to prevent reading an IFD that is already read.
+        mHandledIfdOffsets.add(dataInputStream.mPosition);
+
+        if (dataInputStream.mPosition + 2 > dataInputStream.mLength) {
+            // Return if there is no data from the offset.
+            return;
+        }
+        // See TIFF 6.0 Section 2: TIFF Structure, Figure 1.
+        short numberOfDirectoryEntry = dataInputStream.readShort();
+        if (dataInputStream.mPosition + 12 * numberOfDirectoryEntry > dataInputStream.mLength
+                || numberOfDirectoryEntry <= 0) {
+            // Return if the size of entries is either too big or negative.
+            return;
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "numberOfDirectoryEntry: " + numberOfDirectoryEntry);
+        }
+
+        // See TIFF 6.0 Section 2: TIFF Structure, "Image File Directory".
+        for (short i = 0; i < numberOfDirectoryEntry; ++i) {
+            int tagNumber = dataInputStream.readUnsignedShort();
+            int dataFormat = dataInputStream.readUnsignedShort();
+            int numberOfComponents = dataInputStream.readInt();
+            // Next four bytes is for data offset or value.
+            long nextEntryOffset = dataInputStream.peek() + 4;
+
+            // Look up a corresponding tag from tag number
+            ExifTag tag = (ExifTag) sExifTagMapsForReading[ifdType].get(tagNumber);
+
+            if (DEBUG) {
+                Log.d(TAG, String.format("ifdType: %d, tagNumber: %d, tagName: %s, dataFormat: %d, "
+                        + "numberOfComponents: %d", ifdType, tagNumber,
+                        tag != null ? tag.name : null, dataFormat, numberOfComponents));
+            }
+
+            long byteCount = 0;
+            boolean valid = false;
+            if (tag == null) {
+                if (DEBUG) {
+                    Log.d(TAG, "Skip the tag entry since tag number is not defined: " + tagNumber);
+                }
+            } else if (dataFormat <= 0 || dataFormat >= IFD_FORMAT_BYTES_PER_FORMAT.length) {
+                if (DEBUG) {
+                    Log.d(TAG, "Skip the tag entry since data format is invalid: " + dataFormat);
+                }
+            } else {
+                byteCount = (long) numberOfComponents * IFD_FORMAT_BYTES_PER_FORMAT[dataFormat];
+                if (byteCount < 0 || byteCount > Integer.MAX_VALUE) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Skip the tag entry since the number of components is invalid: "
+                                + numberOfComponents);
+                    }
+                } else {
+                    valid = true;
+                }
+            }
+            if (!valid) {
+                dataInputStream.seek(nextEntryOffset);
+                continue;
+            }
+
+            // Read a value from data field or seek to the value offset which is stored in data
+            // field if the size of the entry value is bigger than 4.
+            if (byteCount > 4) {
+                int offset = dataInputStream.readInt();
+                if (DEBUG) {
+                    Log.d(TAG, "seek to data offset: " + offset);
+                }
+                if (mMimeType == IMAGE_TYPE_ORF) {
+                    if (tag.name == TAG_MAKER_NOTE) {
+                        // Save offset value for reading thumbnail
+                        mOrfMakerNoteOffset = offset;
+                    } else if (ifdType == IFD_TYPE_ORF_MAKER_NOTE
+                            && tag.name == TAG_ORF_THUMBNAIL_IMAGE) {
+                        // Retrieve & update values for thumbnail offset and length values for ORF
+                        mOrfThumbnailOffset = offset;
+                        mOrfThumbnailLength = numberOfComponents;
+
+                        ExifAttribute compressionAttribute =
+                                ExifAttribute.createUShort(DATA_JPEG, mExifByteOrder);
+                        ExifAttribute jpegInterchangeFormatAttribute =
+                                ExifAttribute.createULong(mOrfThumbnailOffset, mExifByteOrder);
+                        ExifAttribute jpegInterchangeFormatLengthAttribute =
+                                ExifAttribute.createULong(mOrfThumbnailLength, mExifByteOrder);
+
+                        mAttributes[IFD_TYPE_THUMBNAIL].put(TAG_COMPRESSION, compressionAttribute);
+                        mAttributes[IFD_TYPE_THUMBNAIL].put(TAG_JPEG_INTERCHANGE_FORMAT,
+                                jpegInterchangeFormatAttribute);
+                        mAttributes[IFD_TYPE_THUMBNAIL].put(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH,
+                                jpegInterchangeFormatLengthAttribute);
+                    }
+                } else if (mMimeType == IMAGE_TYPE_RW2) {
+                    if (tag.name == TAG_RW2_JPG_FROM_RAW) {
+                        mRw2JpgFromRawOffset = offset;
+                    }
+                }
+                if (offset + byteCount <= dataInputStream.mLength) {
+                    dataInputStream.seek(offset);
+                } else {
+                    // Skip if invalid data offset.
+                    if (DEBUG) {
+                        Log.d(TAG, "Skip the tag entry since data offset is invalid: " + offset);
+                    }
+                    dataInputStream.seek(nextEntryOffset);
+                    continue;
+                }
+            }
+
+            // Recursively parse IFD when a IFD pointer tag appears.
+            Integer nextIfdType = sExifPointerTagMap.get(tagNumber);
+            if (DEBUG) {
+                Log.d(TAG, "nextIfdType: " + nextIfdType + " byteCount: " + byteCount);
+            }
+
+            if (nextIfdType != null) {
+                long offset = -1L;
+                // Get offset from data field
+                switch (dataFormat) {
+                    case IFD_FORMAT_USHORT: {
+                        offset = dataInputStream.readUnsignedShort();
+                        break;
+                    }
+                    case IFD_FORMAT_SSHORT: {
+                        offset = dataInputStream.readShort();
+                        break;
+                    }
+                    case IFD_FORMAT_ULONG: {
+                        offset = dataInputStream.readUnsignedInt();
+                        break;
+                    }
+                    case IFD_FORMAT_SLONG:
+                    case IFD_FORMAT_IFD: {
+                        offset = dataInputStream.readInt();
+                        break;
+                    }
+                    default: {
+                        // Nothing to do
+                        break;
+                    }
+                }
+                if (DEBUG) {
+                    Log.d(TAG, String.format("Offset: %d, tagName: %s", offset, tag.name));
+                }
+
+                // Check if the next IFD offset
+                // 1. Exists within the boundaries of the input stream
+                // 2. Does not point to a previously read IFD.
+                if (offset > 0L && offset < dataInputStream.mLength) {
+                    if (!mHandledIfdOffsets.contains((int) offset)) {
+                        dataInputStream.seek(offset);
+                        readImageFileDirectory(dataInputStream, nextIfdType);
+                    } else {
+                        if (DEBUG) {
+                            Log.d(TAG, "Skip jump into the IFD since it has already been read: "
+                                    + "IfdType " + nextIfdType + " (at " + offset + ")");
+                        }
+                    }
+                } else {
+                    if (DEBUG) {
+                        Log.d(TAG, "Skip jump into the IFD since its offset is invalid: " + offset);
+                    }
+                }
+
+                dataInputStream.seek(nextEntryOffset);
+                continue;
+            }
+
+            final int bytesOffset = dataInputStream.peek() + mExifOffset;
+            final byte[] bytes = new byte[(int) byteCount];
+            dataInputStream.readFully(bytes);
+            ExifAttribute attribute = new ExifAttribute(dataFormat, numberOfComponents,
+                    bytesOffset, bytes);
+            mAttributes[ifdType].put(tag.name, attribute);
+
+            // DNG files have a DNG Version tag specifying the version of specifications that the
+            // image file is following.
+            // See http://fileformats.archiveteam.org/wiki/DNG
+            if (tag.name == TAG_DNG_VERSION) {
+                mMimeType = IMAGE_TYPE_DNG;
+            }
+
+            // PEF files have a Make or Model tag that begins with "PENTAX" or a compression tag
+            // that is 65535.
+            // See http://fileformats.archiveteam.org/wiki/Pentax_PEF
+            if (((tag.name == TAG_MAKE || tag.name == TAG_MODEL)
+                    && attribute.getStringValue(mExifByteOrder).contains(PEF_SIGNATURE))
+                    || (tag.name == TAG_COMPRESSION
+                    && attribute.getIntValue(mExifByteOrder) == 65535)) {
+                mMimeType = IMAGE_TYPE_PEF;
+            }
+
+            // Seek to next tag offset
+            if (dataInputStream.peek() != nextEntryOffset) {
+                dataInputStream.seek(nextEntryOffset);
+            }
+        }
+
+        if (dataInputStream.peek() + 4 <= dataInputStream.mLength) {
+            int nextIfdOffset = dataInputStream.readInt();
+            if (DEBUG) {
+                Log.d(TAG, String.format("nextIfdOffset: %d", nextIfdOffset));
+            }
+            // Check if the next IFD offset
+            // 1. Exists within the boundaries of the input stream
+            // 2. Does not point to a previously read IFD.
+            if (nextIfdOffset > 0L && nextIfdOffset < dataInputStream.mLength) {
+                if (!mHandledIfdOffsets.contains(nextIfdOffset)) {
+                    dataInputStream.seek(nextIfdOffset);
+                    // Do not overwrite thumbnail IFD data if it alreay exists.
+                    if (mAttributes[IFD_TYPE_THUMBNAIL].isEmpty()) {
+                        readImageFileDirectory(dataInputStream, IFD_TYPE_THUMBNAIL);
+                    } else if (mAttributes[IFD_TYPE_PREVIEW].isEmpty()) {
+                        readImageFileDirectory(dataInputStream, IFD_TYPE_PREVIEW);
+                    }
+                } else {
+                    if (DEBUG) {
+                        Log.d(TAG, "Stop reading file since re-reading an IFD may cause an "
+                                + "infinite loop: " + nextIfdOffset);
+                    }
+                }
+            } else {
+                if (DEBUG) {
+                    Log.d(TAG, "Stop reading file since a wrong offset may cause an infinite loop: "
+                            + nextIfdOffset);
+                }
+            }
+        }
+    }
+
+    /**
+     * JPEG compressed images do not contain IMAGE_LENGTH & IMAGE_WIDTH tags.
+     * This value uses JpegInterchangeFormat(JPEG data offset) value, and calls getJpegAttributes()
+     * to locate SOF(Start of Frame) marker and update the image length & width values.
+     * See JEITA CP-3451C Table 5 and Section 4.8.1. B.
+     */
+    private void retrieveJpegImageSize(ByteOrderedDataInputStream in, int imageType)
+            throws IOException {
+        // Check if image already has IMAGE_LENGTH & IMAGE_WIDTH values
+        ExifAttribute imageLengthAttribute =
+                (ExifAttribute) mAttributes[imageType].get(TAG_IMAGE_LENGTH);
+        ExifAttribute imageWidthAttribute =
+                (ExifAttribute) mAttributes[imageType].get(TAG_IMAGE_WIDTH);
+
+        if (imageLengthAttribute == null || imageWidthAttribute == null) {
+            // Find if offset for JPEG data exists
+            ExifAttribute jpegInterchangeFormatAttribute =
+                    (ExifAttribute) mAttributes[imageType].get(TAG_JPEG_INTERCHANGE_FORMAT);
+            if (jpegInterchangeFormatAttribute != null) {
+                int jpegInterchangeFormat =
+                        jpegInterchangeFormatAttribute.getIntValue(mExifByteOrder);
+
+                // Searches for SOF marker in JPEG data and updates IMAGE_LENGTH & IMAGE_WIDTH tags
+                getJpegAttributes(in, jpegInterchangeFormat, imageType);
+            }
+        }
+    }
+
+    // Sets thumbnail offset & length attributes based on JpegInterchangeFormat or StripOffsets tags
+    private void setThumbnailData(ByteOrderedDataInputStream in) throws IOException {
+        HashMap thumbnailData = mAttributes[IFD_TYPE_THUMBNAIL];
+
+        ExifAttribute compressionAttribute =
+                (ExifAttribute) thumbnailData.get(TAG_COMPRESSION);
+        if (compressionAttribute != null) {
+            mThumbnailCompression = compressionAttribute.getIntValue(mExifByteOrder);
+            switch (mThumbnailCompression) {
+                case DATA_JPEG: {
+                    handleThumbnailFromJfif(in, thumbnailData);
+                    break;
+                }
+                case DATA_UNCOMPRESSED:
+                case DATA_JPEG_COMPRESSED: {
+                    if (isSupportedDataType(thumbnailData)) {
+                        handleThumbnailFromStrips(in, thumbnailData);
+                    }
+                    break;
+                }
+            }
+        } else {
+            // Thumbnail data may not contain Compression tag value
+            handleThumbnailFromJfif(in, thumbnailData);
+        }
+    }
+
+    // Check JpegInterchangeFormat(JFIF) tags to retrieve thumbnail offset & length values
+    // and reads the corresponding bytes if stream does not support seek function
+    private void handleThumbnailFromJfif(ByteOrderedDataInputStream in, HashMap thumbnailData)
+            throws IOException {
+        ExifAttribute jpegInterchangeFormatAttribute =
+                (ExifAttribute) thumbnailData.get(TAG_JPEG_INTERCHANGE_FORMAT);
+        ExifAttribute jpegInterchangeFormatLengthAttribute =
+                (ExifAttribute) thumbnailData.get(TAG_JPEG_INTERCHANGE_FORMAT_LENGTH);
+        if (jpegInterchangeFormatAttribute != null
+                && jpegInterchangeFormatLengthAttribute != null) {
+            int thumbnailOffset = jpegInterchangeFormatAttribute.getIntValue(mExifByteOrder);
+            int thumbnailLength = jpegInterchangeFormatLengthAttribute.getIntValue(mExifByteOrder);
+
+            if (mMimeType == IMAGE_TYPE_ORF) {
+                // Update offset value since RAF files have IFD data preceding MakerNote data.
+                thumbnailOffset += mOrfMakerNoteOffset;
+            }
+            // The following code limits the size of thumbnail size not to overflow EXIF data area.
+            thumbnailLength = Math.min(thumbnailLength, in.getLength() - thumbnailOffset);
+
+            if (thumbnailOffset > 0 && thumbnailLength > 0) {
+                mHasThumbnail = true;
+                // Need to add mExifOffset, which is the offset to the EXIF data segment
+                mThumbnailOffset = thumbnailOffset + mExifOffset;
+                mThumbnailLength = thumbnailLength;
+                mThumbnailCompression = DATA_JPEG;
+
+                if (mFilename == null && mAssetInputStream == null
+                        && mSeekableFileDescriptor == null) {
+                    // TODO: Need to handle potential OutOfMemoryError
+                    // Save the thumbnail in memory if the input doesn't support reading again.
+                    byte[] thumbnailBytes = new byte[mThumbnailLength];
+                    in.seek(mThumbnailOffset);
+                    in.readFully(thumbnailBytes);
+                    mThumbnailBytes = thumbnailBytes;
+                }
+            }
+            if (DEBUG) {
+                Log.d(TAG, "Setting thumbnail attributes with offset: " + thumbnailOffset
+                        + ", length: " + thumbnailLength);
+            }
+        }
+    }
+
+    // Check StripOffsets & StripByteCounts tags to retrieve thumbnail offset & length values
+    private void handleThumbnailFromStrips(ByteOrderedDataInputStream in, HashMap thumbnailData)
+            throws IOException {
+        ExifAttribute stripOffsetsAttribute =
+                (ExifAttribute) thumbnailData.get(TAG_STRIP_OFFSETS);
+        ExifAttribute stripByteCountsAttribute =
+                (ExifAttribute) thumbnailData.get(TAG_STRIP_BYTE_COUNTS);
+
+        if (stripOffsetsAttribute != null && stripByteCountsAttribute != null) {
+            long[] stripOffsets =
+                    convertToLongArray(stripOffsetsAttribute.getValue(mExifByteOrder));
+            long[] stripByteCounts =
+                    convertToLongArray(stripByteCountsAttribute.getValue(mExifByteOrder));
+
+            if (stripOffsets == null || stripOffsets.length == 0) {
+                Log.w(TAG, "stripOffsets should not be null or have zero length.");
+                return;
+            }
+            if (stripByteCounts == null || stripByteCounts.length == 0) {
+                Log.w(TAG, "stripByteCounts should not be null or have zero length.");
+                return;
+            }
+            if (stripOffsets.length != stripByteCounts.length) {
+                Log.w(TAG, "stripOffsets and stripByteCounts should have same length.");
+                return;
+            }
+
+            // TODO: Need to handle potential OutOfMemoryError
+            // Set thumbnail byte array data for non-consecutive strip bytes
+            byte[] totalStripBytes =
+                    new byte[(int) Arrays.stream(stripByteCounts).sum()];
+
+            int bytesRead = 0;
+            int bytesAdded = 0;
+            mHasThumbnail = mHasThumbnailStrips = mAreThumbnailStripsConsecutive = true;
+            for (int i = 0; i < stripOffsets.length; i++) {
+                int stripOffset = (int) stripOffsets[i];
+                int stripByteCount = (int) stripByteCounts[i];
+
+                // Check if strips are consecutive
+                // TODO: Add test for non-consecutive thumbnail image
+                if (i < stripOffsets.length - 1
+                        && stripOffset + stripByteCount != stripOffsets[i + 1]) {
+                    mAreThumbnailStripsConsecutive = false;
+                }
+
+                // Skip to offset
+                int skipBytes = stripOffset - bytesRead;
+                if (skipBytes < 0) {
+                    Log.d(TAG, "Invalid strip offset value");
+                }
+                in.seek(skipBytes);
+                bytesRead += skipBytes;
+
+                // TODO: Need to handle potential OutOfMemoryError
+                // Read strip bytes
+                byte[] stripBytes = new byte[stripByteCount];
+                in.read(stripBytes);
+                bytesRead += stripByteCount;
+
+                // Add bytes to array
+                System.arraycopy(stripBytes, 0, totalStripBytes, bytesAdded,
+                        stripBytes.length);
+                bytesAdded += stripBytes.length;
+            }
+            mThumbnailBytes = totalStripBytes;
+
+            if (mAreThumbnailStripsConsecutive) {
+                // Need to add mExifOffset, which is the offset to the EXIF data segment
+                mThumbnailOffset = (int) stripOffsets[0] + mExifOffset;
+                mThumbnailLength = totalStripBytes.length;
+            }
+        }
+    }
+
+    // Check if thumbnail data type is currently supported or not
+    private boolean isSupportedDataType(HashMap thumbnailData) throws IOException {
+        ExifAttribute bitsPerSampleAttribute =
+                (ExifAttribute) thumbnailData.get(TAG_BITS_PER_SAMPLE);
+        if (bitsPerSampleAttribute != null) {
+            int[] bitsPerSampleValue = (int[]) bitsPerSampleAttribute.getValue(mExifByteOrder);
+
+            if (Arrays.equals(BITS_PER_SAMPLE_RGB, bitsPerSampleValue)) {
+                return true;
+            }
+
+            // See DNG Specification 1.4.0.0. Section 3, Compression.
+            if (mMimeType == IMAGE_TYPE_DNG) {
+                ExifAttribute photometricInterpretationAttribute =
+                        (ExifAttribute) thumbnailData.get(TAG_PHOTOMETRIC_INTERPRETATION);
+                if (photometricInterpretationAttribute != null) {
+                    int photometricInterpretationValue
+                            = photometricInterpretationAttribute.getIntValue(mExifByteOrder);
+                    if ((photometricInterpretationValue == PHOTOMETRIC_INTERPRETATION_BLACK_IS_ZERO
+                            && Arrays.equals(bitsPerSampleValue, BITS_PER_SAMPLE_GREYSCALE_2))
+                            || ((photometricInterpretationValue == PHOTOMETRIC_INTERPRETATION_YCBCR)
+                            && (Arrays.equals(bitsPerSampleValue, BITS_PER_SAMPLE_RGB)))) {
+                        return true;
+                    } else {
+                        // TODO: Add support for lossless Huffman JPEG data
+                    }
+                }
+            }
+        }
+        if (DEBUG) {
+            Log.d(TAG, "Unsupported data type value");
+        }
+        return false;
+    }
+
+    // Returns true if the image length and width values are <= 512.
+    // See Section 4.8 of http://standardsproposals.bsigroup.com/Home/getPDF/567
+    private boolean isThumbnail(HashMap map) throws IOException {
+        ExifAttribute imageLengthAttribute = (ExifAttribute) map.get(TAG_IMAGE_LENGTH);
+        ExifAttribute imageWidthAttribute = (ExifAttribute) map.get(TAG_IMAGE_WIDTH);
+
+        if (imageLengthAttribute != null && imageWidthAttribute != null) {
+            int imageLengthValue = imageLengthAttribute.getIntValue(mExifByteOrder);
+            int imageWidthValue = imageWidthAttribute.getIntValue(mExifByteOrder);
+            if (imageLengthValue <= MAX_THUMBNAIL_SIZE && imageWidthValue <= MAX_THUMBNAIL_SIZE) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // Validate primary, preview, thumbnail image data by comparing image size
+    private void validateImages() throws IOException {
+        // Swap images based on size (primary > preview > thumbnail)
+        swapBasedOnImageSize(IFD_TYPE_PRIMARY, IFD_TYPE_PREVIEW);
+        swapBasedOnImageSize(IFD_TYPE_PRIMARY, IFD_TYPE_THUMBNAIL);
+        swapBasedOnImageSize(IFD_TYPE_PREVIEW, IFD_TYPE_THUMBNAIL);
+
+        // TODO (b/142296453): Revise image width/height setting logic
+        // Check if image has PixelXDimension/PixelYDimension tags, which contain valid image
+        // sizes, excluding padding at the right end or bottom end of the image to make sure that
+        // the values are multiples of 64. See JEITA CP-3451C Table 5 and Section 4.8.1. B.
+        ExifAttribute pixelXDimAttribute =
+                (ExifAttribute) mAttributes[IFD_TYPE_EXIF].get(TAG_PIXEL_X_DIMENSION);
+        ExifAttribute pixelYDimAttribute =
+                (ExifAttribute) mAttributes[IFD_TYPE_EXIF].get(TAG_PIXEL_Y_DIMENSION);
+        if (pixelXDimAttribute != null && pixelYDimAttribute != null) {
+            mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_WIDTH, pixelXDimAttribute);
+            mAttributes[IFD_TYPE_PRIMARY].put(TAG_IMAGE_LENGTH, pixelYDimAttribute);
+        }
+
+        // Check whether thumbnail image exists and whether preview image satisfies the thumbnail
+        // image requirements
+        if (mAttributes[IFD_TYPE_THUMBNAIL].isEmpty()) {
+            if (isThumbnail(mAttributes[IFD_TYPE_PREVIEW])) {
+                mAttributes[IFD_TYPE_THUMBNAIL] = mAttributes[IFD_TYPE_PREVIEW];
+                mAttributes[IFD_TYPE_PREVIEW] = new HashMap();
+            }
+        }
+
+        // Check if the thumbnail image satisfies the thumbnail size requirements
+        if (!isThumbnail(mAttributes[IFD_TYPE_THUMBNAIL])) {
+            Log.d(TAG, "No image meets the size requirements of a thumbnail image.");
+        }
+    }
+
+    /**
+     * If image is uncompressed, ImageWidth/Length tags are used to store size info.
+     * However, uncompressed images often store extra pixels around the edges of the final image,
+     * which results in larger values for TAG_IMAGE_WIDTH and TAG_IMAGE_LENGTH tags.
+     * This method corrects those tag values by checking first the values of TAG_DEFAULT_CROP_SIZE
+     * See DNG Specification 1.4.0.0. Section 4. (DefaultCropSize)
+     *
+     * If image is a RW2 file, valid image sizes are stored in SensorBorder tags.
+     * See tiff_parser.cc GetFullDimension32()
+     * */
+    private void updateImageSizeValues(ByteOrderedDataInputStream in, int imageType)
+            throws IOException {
+        // Uncompressed image valid image size values
+        ExifAttribute defaultCropSizeAttribute =
+                (ExifAttribute) mAttributes[imageType].get(TAG_DEFAULT_CROP_SIZE);
+        // RW2 image valid image size values
+        ExifAttribute topBorderAttribute =
+                (ExifAttribute) mAttributes[imageType].get(TAG_RW2_SENSOR_TOP_BORDER);
+        ExifAttribute leftBorderAttribute =
+                (ExifAttribute) mAttributes[imageType].get(TAG_RW2_SENSOR_LEFT_BORDER);
+        ExifAttribute bottomBorderAttribute =
+                (ExifAttribute) mAttributes[imageType].get(TAG_RW2_SENSOR_BOTTOM_BORDER);
+        ExifAttribute rightBorderAttribute =
+                (ExifAttribute) mAttributes[imageType].get(TAG_RW2_SENSOR_RIGHT_BORDER);
+
+        if (defaultCropSizeAttribute != null) {
+            // Update for uncompressed image
+            ExifAttribute defaultCropSizeXAttribute, defaultCropSizeYAttribute;
+            if (defaultCropSizeAttribute.format == IFD_FORMAT_URATIONAL) {
+                Rational[] defaultCropSizeValue =
+                        (Rational[]) defaultCropSizeAttribute.getValue(mExifByteOrder);
+                defaultCropSizeXAttribute =
+                        ExifAttribute.createURational(defaultCropSizeValue[0], mExifByteOrder);
+                defaultCropSizeYAttribute =
+                        ExifAttribute.createURational(defaultCropSizeValue[1], mExifByteOrder);
+            } else {
+                int[] defaultCropSizeValue =
+                        (int[]) defaultCropSizeAttribute.getValue(mExifByteOrder);
+                defaultCropSizeXAttribute =
+                        ExifAttribute.createUShort(defaultCropSizeValue[0], mExifByteOrder);
+                defaultCropSizeYAttribute =
+                        ExifAttribute.createUShort(defaultCropSizeValue[1], mExifByteOrder);
+            }
+            mAttributes[imageType].put(TAG_IMAGE_WIDTH, defaultCropSizeXAttribute);
+            mAttributes[imageType].put(TAG_IMAGE_LENGTH, defaultCropSizeYAttribute);
+        } else if (topBorderAttribute != null && leftBorderAttribute != null &&
+                bottomBorderAttribute != null && rightBorderAttribute != null) {
+            // Update for RW2 image
+            int topBorderValue = topBorderAttribute.getIntValue(mExifByteOrder);
+            int bottomBorderValue = bottomBorderAttribute.getIntValue(mExifByteOrder);
+            int rightBorderValue = rightBorderAttribute.getIntValue(mExifByteOrder);
+            int leftBorderValue = leftBorderAttribute.getIntValue(mExifByteOrder);
+            if (bottomBorderValue > topBorderValue && rightBorderValue > leftBorderValue) {
+                int length = bottomBorderValue - topBorderValue;
+                int width = rightBorderValue - leftBorderValue;
+                ExifAttribute imageLengthAttribute =
+                        ExifAttribute.createUShort(length, mExifByteOrder);
+                ExifAttribute imageWidthAttribute =
+                        ExifAttribute.createUShort(width, mExifByteOrder);
+                mAttributes[imageType].put(TAG_IMAGE_LENGTH, imageLengthAttribute);
+                mAttributes[imageType].put(TAG_IMAGE_WIDTH, imageWidthAttribute);
+            }
+        } else {
+            retrieveJpegImageSize(in, imageType);
+        }
+    }
+
+    // Writes an Exif segment into the given output stream.
+    private int writeExifSegment(ByteOrderedDataOutputStream dataOutputStream) throws IOException {
+        // The following variables are for calculating each IFD tag group size in bytes.
+        int[] ifdOffsets = new int[EXIF_TAGS.length];
+        int[] ifdDataSizes = new int[EXIF_TAGS.length];
+
+        // Remove IFD pointer tags (we'll re-add it later.)
+        for (ExifTag tag : EXIF_POINTER_TAGS) {
+            removeAttribute(tag.name);
+        }
+        // Remove old thumbnail data
+        removeAttribute(JPEG_INTERCHANGE_FORMAT_TAG.name);
+        removeAttribute(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name);
+
+        // Remove null value tags.
+        for (int ifdType = 0; ifdType < EXIF_TAGS.length; ++ifdType) {
+            for (Object obj : mAttributes[ifdType].entrySet().toArray()) {
+                final Map.Entry entry = (Map.Entry) obj;
+                if (entry.getValue() == null) {
+                    mAttributes[ifdType].remove(entry.getKey());
+                }
+            }
+        }
+
+        // Add IFD pointer tags. The next offset of primary image TIFF IFD will have thumbnail IFD
+        // offset when there is one or more tags in the thumbnail IFD.
+        if (!mAttributes[IFD_TYPE_EXIF].isEmpty()) {
+            mAttributes[IFD_TYPE_PRIMARY].put(EXIF_POINTER_TAGS[1].name,
+                    ExifAttribute.createULong(0, mExifByteOrder));
+        }
+        if (!mAttributes[IFD_TYPE_GPS].isEmpty()) {
+            mAttributes[IFD_TYPE_PRIMARY].put(EXIF_POINTER_TAGS[2].name,
+                    ExifAttribute.createULong(0, mExifByteOrder));
+        }
+        if (!mAttributes[IFD_TYPE_INTEROPERABILITY].isEmpty()) {
+            mAttributes[IFD_TYPE_EXIF].put(EXIF_POINTER_TAGS[3].name,
+                    ExifAttribute.createULong(0, mExifByteOrder));
+        }
+        if (mHasThumbnail) {
+            mAttributes[IFD_TYPE_THUMBNAIL].put(JPEG_INTERCHANGE_FORMAT_TAG.name,
+                    ExifAttribute.createULong(0, mExifByteOrder));
+            mAttributes[IFD_TYPE_THUMBNAIL].put(JPEG_INTERCHANGE_FORMAT_LENGTH_TAG.name,
+                    ExifAttribute.createULong(mThumbnailLength, mExifByteOrder));
+        }
+
+        // Calculate IFD group data area sizes. IFD group data area is assigned to save the entry
+        // value which has a bigger size than 4 bytes.
+        for (int i = 0; i < EXIF_TAGS.length; ++i) {
+            int sum = 0;
+            for (Map.Entry entry : (Set<Map.Entry>) mAttributes[i].entrySet()) {
+                final ExifAttribute exifAttribute = (ExifAttribute) entry.getValue();
+                final int size = exifAttribute.size();
+                if (size > 4) {
+                    sum += size;
+                }
+            }
+            ifdDataSizes[i] += sum;
+        }
+
+        // Calculate IFD offsets.
+        // 8 bytes are for TIFF headers: 2 bytes (byte order) + 2 bytes (identifier) + 4 bytes
+        // (offset of IFDs)
+        int position = 8;
+        for (int ifdType = 0; ifdType < EXIF_TAGS.length; ++ifdType) {
+            if (!mAttributes[ifdType].isEmpty()) {
+                ifdOffsets[ifdType] = position;
+                position += 2 + mAttributes[ifdType].size() * 12 + 4 + ifdDataSizes[ifdType];
+            }
+        }
+        if (mHasThumbnail) {
+            int thumbnailOffset = position;
+            mAttributes[IFD_TYPE_THUMBNAIL].put(JPEG_INTERCHANGE_FORMAT_TAG.name,
+                    ExifAttribute.createULong(thumbnailOffset, mExifByteOrder));
+            // Need to add mExifOffset, which is the offset to the EXIF data segment
+            mThumbnailOffset = thumbnailOffset + mExifOffset;
+            position += mThumbnailLength;
+        }
+
+        int totalSize = position;
+        if (mMimeType == IMAGE_TYPE_JPEG) {
+            // Add 8 bytes for APP1 size and identifier data
+            totalSize += 8;
+        }
+        if (DEBUG) {
+            for (int i = 0; i < EXIF_TAGS.length; ++i) {
+                Log.d(TAG, String.format("index: %d, offsets: %d, tag count: %d, data sizes: %d, "
+                                + "total size: %d", i, ifdOffsets[i], mAttributes[i].size(),
+                        ifdDataSizes[i], totalSize));
+            }
+        }
+
+        // Update IFD pointer tags with the calculated offsets.
+        if (!mAttributes[IFD_TYPE_EXIF].isEmpty()) {
+            mAttributes[IFD_TYPE_PRIMARY].put(EXIF_POINTER_TAGS[1].name,
+                    ExifAttribute.createULong(ifdOffsets[IFD_TYPE_EXIF], mExifByteOrder));
+        }
+        if (!mAttributes[IFD_TYPE_GPS].isEmpty()) {
+            mAttributes[IFD_TYPE_PRIMARY].put(EXIF_POINTER_TAGS[2].name,
+                    ExifAttribute.createULong(ifdOffsets[IFD_TYPE_GPS], mExifByteOrder));
+        }
+        if (!mAttributes[IFD_TYPE_INTEROPERABILITY].isEmpty()) {
+            mAttributes[IFD_TYPE_EXIF].put(EXIF_POINTER_TAGS[3].name, ExifAttribute.createULong(
+                    ifdOffsets[IFD_TYPE_INTEROPERABILITY], mExifByteOrder));
+        }
+
+        switch (mMimeType) {
+            case IMAGE_TYPE_JPEG:
+                // Write JPEG specific data (APP1 size, APP1 identifier)
+                dataOutputStream.writeUnsignedShort(totalSize);
+                dataOutputStream.write(IDENTIFIER_EXIF_APP1);
+                break;
+            case IMAGE_TYPE_PNG:
+                // Write PNG specific data (chunk size, chunk type)
+                dataOutputStream.writeInt(totalSize);
+                dataOutputStream.write(PNG_CHUNK_TYPE_EXIF);
+                break;
+            case IMAGE_TYPE_WEBP:
+                // Write WebP specific data (chunk type, chunk size)
+                dataOutputStream.write(WEBP_CHUNK_TYPE_EXIF);
+                dataOutputStream.writeInt(totalSize);
+                break;
+        }
+
+        // Write TIFF Headers. See JEITA CP-3451C Section 4.5.2. Table 1.
+        dataOutputStream.writeShort(mExifByteOrder == ByteOrder.BIG_ENDIAN
+                ? BYTE_ALIGN_MM : BYTE_ALIGN_II);
+        dataOutputStream.setByteOrder(mExifByteOrder);
+        dataOutputStream.writeUnsignedShort(START_CODE);
+        dataOutputStream.writeUnsignedInt(IFD_OFFSET);
+
+        // Write IFD groups. See JEITA CP-3451C Section 4.5.8. Figure 9.
+        for (int ifdType = 0; ifdType < EXIF_TAGS.length; ++ifdType) {
+            if (!mAttributes[ifdType].isEmpty()) {
+                // See JEITA CP-3451C Section 4.6.2: IFD structure.
+                // Write entry count
+                dataOutputStream.writeUnsignedShort(mAttributes[ifdType].size());
+
+                // Write entry info
+                int dataOffset = ifdOffsets[ifdType] + 2 + mAttributes[ifdType].size() * 12 + 4;
+                for (Map.Entry entry : (Set<Map.Entry>) mAttributes[ifdType].entrySet()) {
+                    // Convert tag name to tag number.
+                    final ExifTag tag =
+                            (ExifTag) sExifTagMapsForWriting[ifdType].get(entry.getKey());
+                    final int tagNumber = tag.number;
+                    final ExifAttribute attribute = (ExifAttribute) entry.getValue();
+                    final int size = attribute.size();
+
+                    dataOutputStream.writeUnsignedShort(tagNumber);
+                    dataOutputStream.writeUnsignedShort(attribute.format);
+                    dataOutputStream.writeInt(attribute.numberOfComponents);
+                    if (size > 4) {
+                        dataOutputStream.writeUnsignedInt(dataOffset);
+                        dataOffset += size;
+                    } else {
+                        dataOutputStream.write(attribute.bytes);
+                        // Fill zero up to 4 bytes
+                        if (size < 4) {
+                            for (int i = size; i < 4; ++i) {
+                                dataOutputStream.writeByte(0);
+                            }
+                        }
+                    }
+                }
+
+                // Write the next offset. It writes the offset of thumbnail IFD if there is one or
+                // more tags in the thumbnail IFD when the current IFD is the primary image TIFF
+                // IFD; Otherwise 0.
+                if (ifdType == 0 && !mAttributes[IFD_TYPE_THUMBNAIL].isEmpty()) {
+                    dataOutputStream.writeUnsignedInt(ifdOffsets[IFD_TYPE_THUMBNAIL]);
+                } else {
+                    dataOutputStream.writeUnsignedInt(0);
+                }
+
+                // Write values of data field exceeding 4 bytes after the next offset.
+                for (Map.Entry entry : (Set<Map.Entry>) mAttributes[ifdType].entrySet()) {
+                    ExifAttribute attribute = (ExifAttribute) entry.getValue();
+
+                    if (attribute.bytes.length > 4) {
+                        dataOutputStream.write(attribute.bytes, 0, attribute.bytes.length);
+                    }
+                }
+            }
+        }
+
+        // Write thumbnail
+        if (mHasThumbnail) {
+            dataOutputStream.write(getThumbnailBytes());
+        }
+
+        // For WebP files, add a single padding byte at end if chunk size is odd
+        if (mMimeType == IMAGE_TYPE_WEBP && totalSize % 2 == 1) {
+            dataOutputStream.writeByte(0);
+        }
+
+        // Reset the byte order to big endian in order to write remaining parts of the JPEG file.
+        dataOutputStream.setByteOrder(ByteOrder.BIG_ENDIAN);
+
+        return totalSize;
+    }
+
+    /**
+     * Determines the data format of EXIF entry value.
+     *
+     * @param entryValue The value to be determined.
+     * @return Returns two data formats guessed as a pair in integer. If there is no two candidate
+               data formats for the given entry value, returns {@code -1} in the second of the pair.
+     */
+    private static Pair<Integer, Integer> guessDataFormat(String entryValue) {
+        // See TIFF 6.0 Section 2, "Image File Directory".
+        // Take the first component if there are more than one component.
+        if (entryValue.contains(",")) {
+            String[] entryValues = entryValue.split(",");
+            Pair<Integer, Integer> dataFormat = guessDataFormat(entryValues[0]);
+            if (dataFormat.first == IFD_FORMAT_STRING) {
+                return dataFormat;
+            }
+            for (int i = 1; i < entryValues.length; ++i) {
+                final Pair<Integer, Integer> guessDataFormat = guessDataFormat(entryValues[i]);
+                int first = -1, second = -1;
+                if (guessDataFormat.first == dataFormat.first
+                        || guessDataFormat.second == dataFormat.first) {
+                    first = dataFormat.first;
+                }
+                if (dataFormat.second != -1 && (guessDataFormat.first == dataFormat.second
+                        || guessDataFormat.second == dataFormat.second)) {
+                    second = dataFormat.second;
+                }
+                if (first == -1 && second == -1) {
+                    return new Pair<>(IFD_FORMAT_STRING, -1);
+                }
+                if (first == -1) {
+                    dataFormat = new Pair<>(second, -1);
+                    continue;
+                }
+                if (second == -1) {
+                    dataFormat = new Pair<>(first, -1);
+                    continue;
+                }
+            }
+            return dataFormat;
+        }
+
+        if (entryValue.contains("/")) {
+            String[] rationalNumber = entryValue.split("/");
+            if (rationalNumber.length == 2) {
+                try {
+                    long numerator = (long) Double.parseDouble(rationalNumber[0]);
+                    long denominator = (long) Double.parseDouble(rationalNumber[1]);
+                    if (numerator < 0L || denominator < 0L) {
+                        return new Pair<>(IFD_FORMAT_SRATIONAL, -1);
+                    }
+                    if (numerator > Integer.MAX_VALUE || denominator > Integer.MAX_VALUE) {
+                        return new Pair<>(IFD_FORMAT_URATIONAL, -1);
+                    }
+                    return new Pair<>(IFD_FORMAT_SRATIONAL, IFD_FORMAT_URATIONAL);
+                } catch (NumberFormatException e)  {
+                    // Ignored
+                }
+            }
+            return new Pair<>(IFD_FORMAT_STRING, -1);
+        }
+        try {
+            Long longValue = Long.parseLong(entryValue);
+            if (longValue >= 0 && longValue <= 65535) {
+                return new Pair<>(IFD_FORMAT_USHORT, IFD_FORMAT_ULONG);
+            }
+            if (longValue < 0) {
+                return new Pair<>(IFD_FORMAT_SLONG, -1);
+            }
+            return new Pair<>(IFD_FORMAT_ULONG, -1);
+        } catch (NumberFormatException e) {
+            // Ignored
+        }
+        try {
+            Double.parseDouble(entryValue);
+            return new Pair<>(IFD_FORMAT_DOUBLE, -1);
+        } catch (NumberFormatException e) {
+            // Ignored
+        }
+        return new Pair<>(IFD_FORMAT_STRING, -1);
+    }
+
+    // An input stream to parse EXIF data area, which can be written in either little or big endian
+    // order.
+    private static class ByteOrderedDataInputStream extends InputStream implements DataInput {
+        private static final ByteOrder LITTLE_ENDIAN = ByteOrder.LITTLE_ENDIAN;
+        private static final ByteOrder BIG_ENDIAN = ByteOrder.BIG_ENDIAN;
+
+        private DataInputStream mDataInputStream;
+        private InputStream mInputStream;
+        private ByteOrder mByteOrder = ByteOrder.BIG_ENDIAN;
+        private final int mLength;
+        private int mPosition;
+
+        public ByteOrderedDataInputStream(InputStream in) throws IOException {
+            this(in, ByteOrder.BIG_ENDIAN);
+        }
+
+        ByteOrderedDataInputStream(InputStream in, ByteOrder byteOrder) throws IOException {
+            mInputStream = in;
+            mDataInputStream = new DataInputStream(in);
+            mLength = mDataInputStream.available();
+            mPosition = 0;
+            // TODO (b/142218289): Need to handle case where input stream does not support mark
+            mDataInputStream.mark(mLength);
+            mByteOrder = byteOrder;
+        }
+
+        public ByteOrderedDataInputStream(byte[] bytes) throws IOException {
+            this(new ByteArrayInputStream(bytes));
+        }
+
+        public void setByteOrder(ByteOrder byteOrder) {
+            mByteOrder = byteOrder;
+        }
+
+        public void seek(long byteCount) throws IOException {
+            if (mPosition > byteCount) {
+                mPosition = 0;
+                mDataInputStream.reset();
+                // TODO (b/142218289): Need to handle case where input stream does not support mark
+                mDataInputStream.mark(mLength);
+            } else {
+                byteCount -= mPosition;
+            }
+
+            if (skipBytes((int) byteCount) != (int) byteCount) {
+                throw new IOException("Couldn't seek up to the byteCount");
+            }
+        }
+
+        public int peek() {
+            return mPosition;
+        }
+
+        @Override
+        public int available() throws IOException {
+            return mDataInputStream.available();
+        }
+
+        @Override
+        public int read() throws IOException {
+            ++mPosition;
+            return mDataInputStream.read();
+        }
+
+        @Override
+        public int readUnsignedByte() throws IOException {
+            ++mPosition;
+            return mDataInputStream.readUnsignedByte();
+        }
+
+        @Override
+        public String readLine() throws IOException {
+            Log.d(TAG, "Currently unsupported");
+            return null;
+        }
+
+        @Override
+        public boolean readBoolean() throws IOException {
+            ++mPosition;
+            return mDataInputStream.readBoolean();
+        }
+
+        @Override
+        public char readChar() throws IOException {
+            mPosition += 2;
+            return mDataInputStream.readChar();
+        }
+
+        @Override
+        public String readUTF() throws IOException {
+            mPosition += 2;
+            return mDataInputStream.readUTF();
+        }
+
+        @Override
+        public void readFully(byte[] buffer, int offset, int length) throws IOException {
+            mPosition += length;
+            if (mPosition > mLength) {
+                throw new EOFException();
+            }
+            if (mDataInputStream.read(buffer, offset, length) != length) {
+                throw new IOException("Couldn't read up to the length of buffer");
+            }
+        }
+
+        @Override
+        public void readFully(byte[] buffer) throws IOException {
+            mPosition += buffer.length;
+            if (mPosition > mLength) {
+                throw new EOFException();
+            }
+            if (mDataInputStream.read(buffer, 0, buffer.length) != buffer.length) {
+                throw new IOException("Couldn't read up to the length of buffer");
+            }
+        }
+
+        @Override
+        public byte readByte() throws IOException {
+            ++mPosition;
+            if (mPosition > mLength) {
+                throw new EOFException();
+            }
+            int ch = mDataInputStream.read();
+            if (ch < 0) {
+                throw new EOFException();
+            }
+            return (byte) ch;
+        }
+
+        @Override
+        public short readShort() throws IOException {
+            mPosition += 2;
+            if (mPosition > mLength) {
+                throw new EOFException();
+            }
+            int ch1 = mDataInputStream.read();
+            int ch2 = mDataInputStream.read();
+            if ((ch1 | ch2) < 0) {
+                throw new EOFException();
+            }
+            if (mByteOrder == LITTLE_ENDIAN) {
+                return (short) ((ch2 << 8) + (ch1));
+            } else if (mByteOrder == BIG_ENDIAN) {
+                return (short) ((ch1 << 8) + (ch2));
+            }
+            throw new IOException("Invalid byte order: " + mByteOrder);
+        }
+
+        @Override
+        public int readInt() throws IOException {
+            mPosition += 4;
+            if (mPosition > mLength) {
+                throw new EOFException();
+            }
+            int ch1 = mDataInputStream.read();
+            int ch2 = mDataInputStream.read();
+            int ch3 = mDataInputStream.read();
+            int ch4 = mDataInputStream.read();
+            if ((ch1 | ch2 | ch3 | ch4) < 0) {
+                throw new EOFException();
+            }
+            if (mByteOrder == LITTLE_ENDIAN) {
+                return ((ch4 << 24) + (ch3 << 16) + (ch2 << 8) + ch1);
+            } else if (mByteOrder == BIG_ENDIAN) {
+                return ((ch1 << 24) + (ch2 << 16) + (ch3 << 8) + ch4);
+            }
+            throw new IOException("Invalid byte order: " + mByteOrder);
+        }
+
+        @Override
+        public int skipBytes(int byteCount) throws IOException {
+            int totalBytesToSkip = Math.min(byteCount, mLength - mPosition);
+            int totalSkipped = 0;
+            while (totalSkipped < totalBytesToSkip) {
+                int skipped = mDataInputStream.skipBytes(totalBytesToSkip - totalSkipped);
+                if (skipped > 0) {
+                    totalSkipped += skipped;
+                } else {
+                    break;
+                }
+            }
+            mPosition += totalSkipped;
+            return totalSkipped;
+        }
+
+        public int readUnsignedShort() throws IOException {
+            mPosition += 2;
+            if (mPosition > mLength) {
+                throw new EOFException();
+            }
+            int ch1 = mDataInputStream.read();
+            int ch2 = mDataInputStream.read();
+            if ((ch1 | ch2) < 0) {
+                throw new EOFException();
+            }
+            if (mByteOrder == LITTLE_ENDIAN) {
+                return ((ch2 << 8) + (ch1));
+            } else if (mByteOrder == BIG_ENDIAN) {
+                return ((ch1 << 8) + (ch2));
+            }
+            throw new IOException("Invalid byte order: " + mByteOrder);
+        }
+
+        public long readUnsignedInt() throws IOException {
+            return readInt() & 0xffffffffL;
+        }
+
+        @Override
+        public long readLong() throws IOException {
+            mPosition += 8;
+            if (mPosition > mLength) {
+                throw new EOFException();
+            }
+            int ch1 = mDataInputStream.read();
+            int ch2 = mDataInputStream.read();
+            int ch3 = mDataInputStream.read();
+            int ch4 = mDataInputStream.read();
+            int ch5 = mDataInputStream.read();
+            int ch6 = mDataInputStream.read();
+            int ch7 = mDataInputStream.read();
+            int ch8 = mDataInputStream.read();
+            if ((ch1 | ch2 | ch3 | ch4 | ch5 | ch6 | ch7 | ch8) < 0) {
+                throw new EOFException();
+            }
+            if (mByteOrder == LITTLE_ENDIAN) {
+                return (((long) ch8 << 56) + ((long) ch7 << 48) + ((long) ch6 << 40)
+                        + ((long) ch5 << 32) + ((long) ch4 << 24) + ((long) ch3 << 16)
+                        + ((long) ch2 << 8) + (long) ch1);
+            } else if (mByteOrder == BIG_ENDIAN) {
+                return (((long) ch1 << 56) + ((long) ch2 << 48) + ((long) ch3 << 40)
+                        + ((long) ch4 << 32) + ((long) ch5 << 24) + ((long) ch6 << 16)
+                        + ((long) ch7 << 8) + (long) ch8);
+            }
+            throw new IOException("Invalid byte order: " + mByteOrder);
+        }
+
+        @Override
+        public float readFloat() throws IOException {
+            return Float.intBitsToFloat(readInt());
+        }
+
+        @Override
+        public double readDouble() throws IOException {
+            return Double.longBitsToDouble(readLong());
+        }
+
+        public int getLength() {
+            return mLength;
+        }
+    }
+
+    // An output stream to write EXIF data area, which can be written in either little or big endian
+    // order.
+    private static class ByteOrderedDataOutputStream extends FilterOutputStream {
+        final OutputStream mOutputStream;
+        private ByteOrder mByteOrder;
+
+        public ByteOrderedDataOutputStream(OutputStream out, ByteOrder byteOrder) {
+            super(out);
+            mOutputStream = out;
+            mByteOrder = byteOrder;
+        }
+
+        public void setByteOrder(ByteOrder byteOrder) {
+            mByteOrder = byteOrder;
+        }
+
+        public void write(byte[] bytes) throws IOException {
+            mOutputStream.write(bytes);
+        }
+
+        public void write(byte[] bytes, int offset, int length) throws IOException {
+            mOutputStream.write(bytes, offset, length);
+        }
+
+        public void writeByte(int val) throws IOException {
+            mOutputStream.write(val);
+        }
+
+        public void writeShort(short val) throws IOException {
+            if (mByteOrder == ByteOrder.LITTLE_ENDIAN) {
+                mOutputStream.write((val >>> 0) & 0xFF);
+                mOutputStream.write((val >>> 8) & 0xFF);
+            } else if (mByteOrder == ByteOrder.BIG_ENDIAN) {
+                mOutputStream.write((val >>> 8) & 0xFF);
+                mOutputStream.write((val >>> 0) & 0xFF);
+            }
+        }
+
+        public void writeInt(int val) throws IOException {
+            if (mByteOrder == ByteOrder.LITTLE_ENDIAN) {
+                mOutputStream.write((val >>> 0) & 0xFF);
+                mOutputStream.write((val >>> 8) & 0xFF);
+                mOutputStream.write((val >>> 16) & 0xFF);
+                mOutputStream.write((val >>> 24) & 0xFF);
+            } else if (mByteOrder == ByteOrder.BIG_ENDIAN) {
+                mOutputStream.write((val >>> 24) & 0xFF);
+                mOutputStream.write((val >>> 16) & 0xFF);
+                mOutputStream.write((val >>> 8) & 0xFF);
+                mOutputStream.write((val >>> 0) & 0xFF);
+            }
+        }
+
+        public void writeUnsignedShort(int val) throws IOException {
+            writeShort((short) val);
+        }
+
+        public void writeUnsignedInt(long val) throws IOException {
+            writeInt((int) val);
+        }
+    }
+
+    // Swaps image data based on image size
+    private void swapBasedOnImageSize(@IfdType int firstIfdType, @IfdType int secondIfdType)
+            throws IOException {
+        if (mAttributes[firstIfdType].isEmpty() || mAttributes[secondIfdType].isEmpty()) {
+            if (DEBUG) {
+                Log.d(TAG, "Cannot perform swap since only one image data exists");
+            }
+            return;
+        }
+
+        ExifAttribute firstImageLengthAttribute =
+                (ExifAttribute) mAttributes[firstIfdType].get(TAG_IMAGE_LENGTH);
+        ExifAttribute firstImageWidthAttribute =
+                (ExifAttribute) mAttributes[firstIfdType].get(TAG_IMAGE_WIDTH);
+        ExifAttribute secondImageLengthAttribute =
+                (ExifAttribute) mAttributes[secondIfdType].get(TAG_IMAGE_LENGTH);
+        ExifAttribute secondImageWidthAttribute =
+                (ExifAttribute) mAttributes[secondIfdType].get(TAG_IMAGE_WIDTH);
+
+        if (firstImageLengthAttribute == null || firstImageWidthAttribute == null) {
+            if (DEBUG) {
+                Log.d(TAG, "First image does not contain valid size information");
+            }
+        } else if (secondImageLengthAttribute == null || secondImageWidthAttribute == null) {
+            if (DEBUG) {
+                Log.d(TAG, "Second image does not contain valid size information");
+            }
+        } else {
+            int firstImageLengthValue = firstImageLengthAttribute.getIntValue(mExifByteOrder);
+            int firstImageWidthValue = firstImageWidthAttribute.getIntValue(mExifByteOrder);
+            int secondImageLengthValue = secondImageLengthAttribute.getIntValue(mExifByteOrder);
+            int secondImageWidthValue = secondImageWidthAttribute.getIntValue(mExifByteOrder);
+
+            if (firstImageLengthValue < secondImageLengthValue &&
+                    firstImageWidthValue < secondImageWidthValue) {
+                HashMap tempMap = mAttributes[firstIfdType];
+                mAttributes[firstIfdType] = mAttributes[secondIfdType];
+                mAttributes[secondIfdType] = tempMap;
+            }
+        }
+    }
+
+    private boolean isSupportedFormatForSavingAttributes() {
+        if (mIsSupportedFile && (mMimeType == IMAGE_TYPE_JPEG || mMimeType == IMAGE_TYPE_PNG
+                || mMimeType == IMAGE_TYPE_WEBP)) {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/android/media/ExifInterfaceUtils.java b/android/media/ExifInterfaceUtils.java
new file mode 100644
index 0000000..491fe1d
--- /dev/null
+++ b/android/media/ExifInterfaceUtils.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2020 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.system.ErrnoException;
+import android.system.Os;
+import android.util.Log;
+
+import java.io.Closeable;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+/**
+ * Package private utility class for ExifInterface.
+ */
+class ExifInterfaceUtils {
+    private static final String TAG = "ExifInterface";
+
+    /**
+     * Copies all of the bytes from {@code in} to {@code out}. Neither stream is closed.
+     * Returns the total number of bytes transferred.
+     */
+    public static int copy(InputStream in, OutputStream out) throws IOException {
+        int total = 0;
+        byte[] buffer = new byte[8192];
+        int c;
+        while ((c = in.read(buffer)) != -1) {
+            total += c;
+            out.write(buffer, 0, c);
+        }
+        return total;
+    }
+
+    /**
+     * Copies the given number of the bytes from {@code in} to {@code out}. Neither stream is
+     * closed.
+     */
+    public static void copy(InputStream in, OutputStream out, int numBytes) throws IOException {
+        int remainder = numBytes;
+        byte[] buffer = new byte[8192];
+        while (remainder > 0) {
+            int bytesToRead = Math.min(remainder, 8192);
+            int bytesRead = in.read(buffer, 0, bytesToRead);
+            if (bytesRead != bytesToRead) {
+                throw new IOException("Failed to copy the given amount of bytes from the input"
+                        + "stream to the output stream.");
+            }
+            remainder -= bytesRead;
+            out.write(buffer, 0, bytesRead);
+        }
+    }
+
+    /**
+     * Convert given int[] to long[]. If long[] is given, just return it.
+     * Return null for other types of input.
+     */
+    public static long[] convertToLongArray(Object inputObj) {
+        if (inputObj instanceof int[]) {
+            int[] input = (int[]) inputObj;
+            long[] result = new long[input.length];
+            for (int i = 0; i < input.length; i++) {
+                result[i] = input[i];
+            }
+            return result;
+        } else if (inputObj instanceof long[]) {
+            return (long[]) inputObj;
+        }
+        return null;
+    }
+
+    /**
+     * Convert given byte array to hex string.
+     */
+    public static String byteArrayToHexString(byte[] bytes) {
+        StringBuilder sb = new StringBuilder(bytes.length * 2);
+        for (int i = 0; i < bytes.length; i++) {
+            sb.append(String.format("%02x", bytes[i]));
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Checks if the start of the first byte array is equal to the second byte array.
+     */
+    public static boolean startsWith(byte[] cur, byte[] val) {
+        if (cur == null || val == null) return false;
+        if (cur.length < val.length) return false;
+        if (cur.length == 0 || val.length == 0) return false;
+        for (int i = 0; i < val.length; i++) {
+            if (cur[i] != val[i]) return false;
+        }
+        return true;
+    }
+
+    /**
+     * Closes 'closeable', ignoring any checked exceptions. Does nothing if 'closeable' is null.
+     */
+    public static void closeQuietly(Closeable closeable) {
+        if (closeable != null) {
+            try {
+                closeable.close();
+            } catch (RuntimeException rethrown) {
+                throw rethrown;
+            } catch (Exception ignored) {
+            }
+        }
+    }
+
+    /**
+     * Closes a file descriptor that has been duplicated.
+     */
+    public static void closeFileDescriptor(FileDescriptor fd) {
+        try {
+            Os.close(fd);
+        } catch (ErrnoException ex) {
+            Log.e(TAG, "Error closing fd.", ex);
+        }
+    }
+}
diff --git a/android/media/ExternalRingtonesCursorWrapper.java b/android/media/ExternalRingtonesCursorWrapper.java
new file mode 100644
index 0000000..ea63a3a
--- /dev/null
+++ b/android/media/ExternalRingtonesCursorWrapper.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2016 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.database.Cursor;
+import android.database.CursorWrapper;
+import android.net.Uri;
+
+/**
+ * Cursor that adds the user id to fetched URIs. This is especially useful for {@link getCursor} as
+ * a managed profile should also list its parent's ringtones
+ *
+ * @hide
+ */
+public class ExternalRingtonesCursorWrapper extends CursorWrapper {
+    private Uri mUri;
+
+    public ExternalRingtonesCursorWrapper(Cursor cursor, Uri uri) {
+        super(cursor);
+        mUri = uri;
+    }
+
+    public String getString(int index) {
+        if (index == RingtoneManager.URI_COLUMN_INDEX) {
+            return mUri.toString();
+        } else {
+            return super.getString(index);
+        }
+    }
+}
diff --git a/android/media/FaceDetector.java b/android/media/FaceDetector.java
new file mode 100644
index 0000000..61991e3
--- /dev/null
+++ b/android/media/FaceDetector.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2006 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.graphics.Bitmap;
+import android.graphics.PointF;
+import android.util.Log;
+
+import java.lang.IllegalArgumentException;
+
+/**
+ * Identifies the faces of people in a 
+ * {@link android.graphics.Bitmap} graphic object.
+ */
+public class FaceDetector {
+
+    /**
+     * A Face contains all the information identifying the location
+     * of a face in a bitmap.
+     */
+    public class Face {
+        /** The minimum confidence factor of good face recognition */
+        public static final float CONFIDENCE_THRESHOLD = 0.4f;
+        /** The x-axis Euler angle of a face. */
+        public static final int EULER_X = 0;
+        /** The y-axis Euler angle of a face. */
+        public static final int EULER_Y = 1;
+        /** The z-axis Euler angle of a face. */
+        public static final int EULER_Z = 2;
+
+        /** 
+         * Returns a confidence factor between 0 and 1. This indicates how
+         * certain what has been found is actually a face. A confidence
+         * factor above 0.3 is usually good enough.
+         */
+        public float confidence() {
+            return mConfidence;
+        }
+        /**
+         * Sets the position of the mid-point between the eyes.
+         * @param point the PointF coordinates (float values) of the 
+         *              face's mid-point
+         */
+        public void getMidPoint(PointF point) {
+            // don't return a PointF to avoid allocations
+            point.set(mMidPointX, mMidPointY);
+        }
+        /**
+         * Returns the distance between the eyes.
+         */
+        public float eyesDistance() {
+            return mEyesDist;
+        }
+        /**
+         * Returns the face's pose. That is, the rotations around either 
+         * the X, Y or Z axis (the positions in 3-dimensional Euclidean space).
+         * 
+         * @param euler the Euler axis to retrieve an angle from 
+         *              (<var>EULER_X</var>, <var>EULER_Y</var> or 
+         *              <var>EULER_Z</var>)
+         * @return the Euler angle of the of the face, for the given axis
+         */
+        public float pose(int euler) {
+            // don't use an array to avoid allocations
+            if (euler == EULER_X)
+                return mPoseEulerX;
+            else if (euler == EULER_Y)
+                return mPoseEulerY;
+            else if (euler == EULER_Z)
+                return mPoseEulerZ;
+           throw new IllegalArgumentException();
+        }
+
+        // private ctor, user not supposed to build this object
+        private Face() {
+        }
+        private float   mConfidence;
+        private float   mMidPointX;
+        private float   mMidPointY;
+        private float   mEyesDist;
+        private float   mPoseEulerX;
+        private float   mPoseEulerY;
+        private float   mPoseEulerZ;
+    }
+
+
+    /**
+     * Creates a FaceDetector, configured with the size of the images to
+     * be analysed and the maximum number of faces that can be detected.
+     * These parameters cannot be changed once the object is constructed.
+     * Note that the width of the image must be even.
+     * 
+     * @param width  the width of the image
+     * @param height the height of the image
+     * @param maxFaces the maximum number of faces to identify
+     *
+     */
+    public FaceDetector(int width, int height, int maxFaces)
+    {
+        if (!sInitialized) {
+            return;
+        }
+        fft_initialize(width, height, maxFaces);
+        mWidth = width;
+        mHeight = height;
+        mMaxFaces = maxFaces;
+        mBWBuffer = new byte[width * height];
+    }
+
+    /**
+     * Finds all the faces found in a given {@link android.graphics.Bitmap}. 
+     * The supplied array is populated with {@link FaceDetector.Face}s for each
+     * face found. The bitmap must be in 565 format (for now).
+     * 
+     * @param bitmap the {@link android.graphics.Bitmap} graphic to be analyzed
+     * @param faces  an array in which to place all found 
+     *               {@link FaceDetector.Face}s. The array must be sized equal
+     *               to the <var>maxFaces</var> value set at initialization
+     * @return the number of faces found
+     * @throws IllegalArgumentException if the Bitmap dimensions don't match
+     *               the dimensions defined at initialization or the given array 
+     *               is not sized equal to the <var>maxFaces</var> value defined
+     *               at initialization
+     */
+    public int findFaces(Bitmap bitmap, Face[] faces)
+    {
+        if (!sInitialized) {
+            return 0;
+        }
+        if (bitmap.getWidth() != mWidth || bitmap.getHeight() != mHeight) {
+            throw new IllegalArgumentException(
+                    "bitmap size doesn't match initialization");
+        }
+        if (faces.length < mMaxFaces) {
+            throw new IllegalArgumentException(
+                    "faces[] smaller than maxFaces");
+        }
+        
+        int numFaces = fft_detect(bitmap);
+        if (numFaces >= mMaxFaces)
+            numFaces = mMaxFaces;
+        for (int i=0 ; i<numFaces ; i++) {
+            if (faces[i] == null)
+                faces[i] = new Face();
+            fft_get_face(faces[i], i);
+        }
+        return numFaces;
+    }
+
+
+    /* no user serviceable parts here ... */
+    @Override
+    protected void finalize() throws Throwable {
+        fft_destroy();
+    }
+
+    /*
+     * We use a class initializer to allow the native code to cache some
+     * field offsets.
+     */
+    private static boolean sInitialized;
+    native private static void nativeClassInit();
+
+    static {
+        sInitialized = false;
+        try {
+            System.loadLibrary("FFTEm");
+            nativeClassInit();
+            sInitialized = true;
+        } catch (UnsatisfiedLinkError e) {
+            Log.d("FFTEm", "face detection library not found!");
+        }
+    }
+
+    native private int  fft_initialize(int width, int height, int maxFaces);
+    native private int  fft_detect(Bitmap bitmap);
+    native private void fft_get_face(Face face, int i);
+    native private void fft_destroy();
+
+    private long    mFD;
+    private long    mSDK;
+    private long    mDCR;
+    private int     mWidth;
+    private int     mHeight;
+    private int     mMaxFaces;    
+    private byte    mBWBuffer[];
+}
+
diff --git a/android/media/HwAudioSource.java b/android/media/HwAudioSource.java
new file mode 100644
index 0000000..167ab65
--- /dev/null
+++ b/android/media/HwAudioSource.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2019 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+
+/**
+ * The HwAudioSource represents the audio playback directly from a source audio device.
+ * It currently supports {@link HwAudioSource#start()} and {@link HwAudioSource#stop()} only
+ * corresponding to {@link AudioSystem#startAudioSource(AudioPortConfig, AudioAttributes)}
+ * and {@link AudioSystem#stopAudioSource(int)}.
+ *
+ * @hide
+ */
+@SystemApi
+public class HwAudioSource extends PlayerBase {
+    private final AudioDeviceInfo mAudioDeviceInfo;
+    private final AudioAttributes mAudioAttributes;
+
+    /**
+     * The value of the native handle encodes the HwAudioSource state.
+     * The native handle returned by {@link AudioSystem#startAudioSource} is either valid
+     * (aka > 0, so successfully started) or hosting an error code (negative).
+     * 0 corresponds to an untialized or stopped HwAudioSource.
+     */
+    private int mNativeHandle = 0;
+
+    /**
+     * Class constructor for a hardware audio source based player.
+     *
+     * Use the {@link Builder} class to construct a {@link HwAudioSource} instance.
+     *
+     * @param device {@link AudioDeviceInfo} instance of the source audio device.
+     * @param attributes {@link AudioAttributes} instance for this player.
+     */
+    private HwAudioSource(@NonNull AudioDeviceInfo device, @NonNull AudioAttributes attributes) {
+        super(attributes, AudioPlaybackConfiguration.PLAYER_TYPE_HW_SOURCE);
+        Preconditions.checkNotNull(device);
+        Preconditions.checkNotNull(attributes);
+        Preconditions.checkArgument(device.isSource(), "Requires a source device");
+        mAudioDeviceInfo = device;
+        mAudioAttributes = attributes;
+        baseRegisterPlayer(AudioSystem.AUDIO_SESSION_ALLOCATE);
+    }
+
+    /**
+     * TODO: sets the gain on {@link #mAudioDeviceInfo}.
+     *
+     * @param muting if true, the player is to be muted, and the volume values can be ignored
+     * @param leftVolume the left volume to use if muting is false
+     * @param rightVolume the right volume to use if muting is false
+     */
+    @Override
+    void playerSetVolume(boolean muting, float leftVolume, float rightVolume) {
+    }
+
+    /**
+     * TODO: applies {@link VolumeShaper} on {@link #mAudioDeviceInfo}.
+     *
+     * @param configuration a {@code VolumeShaper.Configuration} object
+     *        created by {@link VolumeShaper.Configuration.Builder} or
+     *        an created from a {@code VolumeShaper} id
+     *        by the {@link VolumeShaper.Configuration} constructor.
+     * @param operation a {@code VolumeShaper.Operation}.
+     * @return
+     */
+    @Override
+    int playerApplyVolumeShaper(
+            @NonNull VolumeShaper.Configuration configuration,
+            @NonNull VolumeShaper.Operation operation) {
+        return 0;
+    }
+
+    /**
+     * TODO: gets the {@link VolumeShaper} by a given id.
+     *
+     * @param id the {@code VolumeShaper} id returned from
+     *           sending a fully specified {@code VolumeShaper.Configuration}
+     *           through {@link #playerApplyVolumeShaper}
+     * @return
+     */
+    @Override
+    @Nullable
+    VolumeShaper.State playerGetVolumeShaperState(int id) {
+        return new VolumeShaper.State(1f, 1f);
+    }
+
+    /**
+     * TODO: sets the level on {@link #mAudioDeviceInfo}.
+     *
+     * @param muting
+     * @param level
+     * @return
+     */
+    @Override
+    int playerSetAuxEffectSendLevel(boolean muting, float level) {
+        return AudioSystem.SUCCESS;
+    }
+
+    @Override
+    void playerStart() {
+        start();
+    }
+
+    @Override
+    void playerPause() {
+        // Pause is equivalent to stop for hardware audio source based players.
+        stop();
+    }
+
+    @Override
+    void playerStop() {
+        stop();
+    }
+
+    /**
+     * Starts the playback from {@link AudioDeviceInfo}.
+     * Starts does not return any error code, caller must check {@link HwAudioSource#isPlaying} to
+     * ensure the state of the HwAudioSource encoded in {@link mNativeHandle}.
+     */
+    public void start() {
+        Preconditions.checkState(!isPlaying(), "HwAudioSource is currently playing");
+        mNativeHandle = AudioSystem.startAudioSource(
+                mAudioDeviceInfo.getPort().activeConfig(),
+                mAudioAttributes);
+        if (isPlaying()) {
+            // FIXME: b/174876389 clean up device id reporting
+            baseStart(getDeviceId());
+        }
+    }
+
+    private int getDeviceId() {
+        ArrayList<AudioPatch> patches = new ArrayList<AudioPatch>();
+        if (AudioManager.listAudioPatches(patches) != AudioManager.SUCCESS) {
+            return 0;
+        }
+
+        for (int i = 0; i < patches.size(); i++) {
+            AudioPatch patch = patches.get(i);
+            AudioPortConfig[] sources = patch.sources();
+            AudioPortConfig[] sinks = patch.sinks();
+            if ((sources != null) && (sources.length > 0)) {
+                for (int c = 0;  c < sources.length; c++) {
+                    if (sources[c].port().id() == mAudioDeviceInfo.getId()) {
+                        return sinks[c].port().id();
+                    }
+                }
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Checks whether the HwAudioSource player is playing.
+     * It checks the state of the HwAudioSource encoded in {@link HwAudioSource#isPlaying}.
+     * 0 corresponds to a stopped or uninitialized HwAudioSource.
+     * Negative value corresponds to a status reported by {@link AudioSystem#startAudioSource} to
+     * indicate a failure when trying to start the HwAudioSource.
+     *
+     * @return true if currently playing, false otherwise
+     */
+    public boolean isPlaying() {
+        return mNativeHandle > 0;
+    }
+
+    /**
+     * Stops the playback from {@link AudioDeviceInfo}.
+     */
+    public void stop() {
+        if (mNativeHandle > 0) {
+            baseStop();
+            AudioSystem.stopAudioSource(mNativeHandle);
+            mNativeHandle = 0;
+        }
+    }
+
+    /**
+     * Builder class for {@link HwAudioSource} objects.
+     * Use this class to configure and create a <code>HwAudioSource</code> instance.
+     * <p>Here is an example where <code>Builder</code> is used to specify an audio
+     * playback directly from a source device as media usage, to be used by a new
+     * <code>HwAudioSource</code> instance:
+     *
+     * <pre class="prettyprint">
+     * HwAudioSource player = new HwAudioSource.Builder()
+     *              .setAudioAttributes(new AudioAttributes.Builder()
+     *                       .setUsage(AudioAttributes.USAGE_MEDIA)
+     *                       .build())
+     *              .setAudioDeviceInfo(device)
+     *              .build()
+     * </pre>
+     * <p>
+     * If the audio attributes are not set with {@link #setAudioAttributes(AudioAttributes)},
+     * attributes comprising {@link AudioAttributes#USAGE_MEDIA} will be used.
+     */
+    public static final class Builder {
+        private AudioAttributes mAudioAttributes;
+        private AudioDeviceInfo mAudioDeviceInfo;
+
+        /**
+         * Constructs a new Builder with default values.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Sets the {@link AudioAttributes}.
+         * @param attributes a non-null {@link AudioAttributes} instance that describes the audio
+         *     data to be played.
+         * @return the same Builder instance.
+         */
+        public @NonNull Builder setAudioAttributes(@NonNull AudioAttributes attributes) {
+            Preconditions.checkNotNull(attributes);
+            mAudioAttributes = attributes;
+            return this;
+        }
+
+        /**
+         * Sets the {@link AudioDeviceInfo}.
+         * @param info a non-null {@link AudioDeviceInfo} instance that describes the audio
+         *     data come from.
+         * @return the same Builder instance.
+         */
+        public @NonNull Builder setAudioDeviceInfo(@NonNull AudioDeviceInfo info) {
+            Preconditions.checkNotNull(info);
+            Preconditions.checkArgument(info.isSource());
+            mAudioDeviceInfo = info;
+            return this;
+        }
+
+        /**
+         * Builds an {@link HwAudioSource} instance initialized with all the parameters set
+         * on this <code>Builder</code>.
+         * @return a new successfully initialized {@link HwAudioSource} instance.
+         */
+        public @NonNull HwAudioSource build() {
+            Preconditions.checkNotNull(mAudioDeviceInfo);
+            if (mAudioAttributes == null) {
+                mAudioAttributes = new AudioAttributes.Builder()
+                        .setUsage(AudioAttributes.USAGE_MEDIA)
+                        .build();
+            }
+            return new HwAudioSource(mAudioDeviceInfo, mAudioAttributes);
+        }
+    }
+}
diff --git a/android/media/Image.java b/android/media/Image.java
new file mode 100644
index 0000000..1616c03
--- /dev/null
+++ b/android/media/Image.java
@@ -0,0 +1,462 @@
+/*
+ * Copyright (C) 2013 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.annotation.Nullable;
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.graphics.Rect;
+import android.hardware.HardwareBuffer;
+
+import java.nio.ByteBuffer;
+
+/**
+ * <p>A single complete image buffer to use with a media source such as a
+ * {@link MediaCodec} or a
+ * {@link android.hardware.camera2.CameraDevice CameraDevice}.</p>
+ *
+ * <p>This class allows for efficient direct application access to the pixel
+ * data of the Image through one or more
+ * {@link java.nio.ByteBuffer ByteBuffers}. Each buffer is encapsulated in a
+ * {@link Plane} that describes the layout of the pixel data in that plane. Due
+ * to this direct access, and unlike the {@link android.graphics.Bitmap Bitmap} class,
+ * Images are not directly usable as UI resources.</p>
+ *
+ * <p>Since Images are often directly produced or consumed by hardware
+ * components, they are a limited resource shared across the system, and should
+ * be closed as soon as they are no longer needed.</p>
+ *
+ * <p>For example, when using the {@link ImageReader} class to read out Images
+ * from various media sources, not closing old Image objects will prevent the
+ * availability of new Images once
+ * {@link ImageReader#getMaxImages the maximum outstanding image count} is
+ * reached. When this happens, the function acquiring new Images will typically
+ * throw an {@link IllegalStateException}.</p>
+ *
+ * @see ImageReader
+ */
+public abstract class Image implements AutoCloseable {
+    /**
+     * @hide
+     */
+    protected boolean mIsImageValid = false;
+
+    /**
+     * @hide
+     */
+    @UnsupportedAppUsage
+    @TestApi
+    protected Image() {
+    }
+
+    /**
+     * Throw IllegalStateException if the image is invalid (already closed).
+     *
+     * @hide
+     */
+    protected void throwISEIfImageIsInvalid() {
+        if (!mIsImageValid) {
+            throw new IllegalStateException("Image is already closed");
+        }
+    }
+    /**
+     * Get the format for this image. This format determines the number of
+     * ByteBuffers needed to represent the image, and the general layout of the
+     * pixel data in each ByteBuffer.
+     *
+     * <p>
+     * The format is one of the values from
+     * {@link android.graphics.ImageFormat ImageFormat}. The mapping between the
+     * formats and the planes is as follows:
+     * </p>
+     *
+     * <table>
+     * <tr>
+     *   <th>Format</th>
+     *   <th>Plane count</th>
+     *   <th>Layout details</th>
+     * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#JPEG JPEG}</td>
+     *   <td>1</td>
+     *   <td>Compressed data, so row and pixel strides are 0. To uncompress, use
+     *      {@link android.graphics.BitmapFactory#decodeByteArray BitmapFactory#decodeByteArray}.
+     *   </td>
+     * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#YUV_420_888 YUV_420_888}</td>
+     *   <td>3</td>
+     *   <td>A luminance plane followed by the Cb and Cr chroma planes.
+     *     The chroma planes have half the width and height of the luminance
+     *     plane (4:2:0 subsampling). Each pixel sample in each plane has 8 bits.
+     *     Each plane has its own row stride and pixel stride.</td>
+     * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#YUV_422_888 YUV_422_888}</td>
+     *   <td>3</td>
+     *   <td>A luminance plane followed by the Cb and Cr chroma planes.
+     *     The chroma planes have half the width and the full height of the luminance
+     *     plane (4:2:2 subsampling). Each pixel sample in each plane has 8 bits.
+     *     Each plane has its own row stride and pixel stride.</td>
+     * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#YUV_444_888 YUV_444_888}</td>
+     *   <td>3</td>
+     *   <td>A luminance plane followed by the Cb and Cr chroma planes.
+     *     The chroma planes have the same width and height as that of the luminance
+     *     plane (4:4:4 subsampling). Each pixel sample in each plane has 8 bits.
+     *     Each plane has its own row stride and pixel stride.</td>
+     * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#FLEX_RGB_888 FLEX_RGB_888}</td>
+     *   <td>3</td>
+     *   <td>A R (red) plane followed by the G (green) and B (blue) planes.
+     *     All planes have the same widths and heights.
+     *     Each pixel sample in each plane has 8 bits.
+     *     Each plane has its own row stride and pixel stride.</td>
+     * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#FLEX_RGBA_8888 FLEX_RGBA_8888}</td>
+     *   <td>4</td>
+     *   <td>A R (red) plane followed by the G (green), B (blue), and
+     *     A (alpha) planes. All planes have the same widths and heights.
+     *     Each pixel sample in each plane has 8 bits.
+     *     Each plane has its own row stride and pixel stride.</td>
+     * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#RAW_SENSOR RAW_SENSOR}</td>
+     *   <td>1</td>
+     *   <td>A single plane of raw sensor image data, with 16 bits per color
+     *     sample. The details of the layout need to be queried from the source of
+     *     the raw sensor data, such as
+     *     {@link android.hardware.camera2.CameraDevice CameraDevice}.
+     *   </td>
+     * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE}</td>
+     *   <td>1</td>
+     *   <td>A single plane of raw sensor image data of private layout.
+     *   The details of the layout is implementation specific. Row stride and
+     *   pixel stride are undefined for this format. Calling {@link Plane#getRowStride()}
+     *   or {@link Plane#getPixelStride()} on RAW_PRIVATE image will cause
+     *   UnSupportedOperationException being thrown.
+     *   </td>
+     * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#HEIC HEIC}</td>
+     *   <td>1</td>
+     *   <td>Compressed data, so row and pixel strides are 0. To uncompress, use
+     *      {@link android.graphics.BitmapFactory#decodeByteArray BitmapFactory#decodeByteArray}.
+     *   </td>
+     * </tr>
+     * </table>
+     *
+     * @see android.graphics.ImageFormat
+     */
+    public abstract int getFormat();
+
+    /**
+     * The width of the image in pixels. For formats where some color channels
+     * are subsampled, this is the width of the largest-resolution plane.
+     */
+    public abstract int getWidth();
+
+    /**
+     * The height of the image in pixels. For formats where some color channels
+     * are subsampled, this is the height of the largest-resolution plane.
+     */
+    public abstract int getHeight();
+
+    /**
+     * Get the timestamp associated with this frame.
+     * <p>
+     * The timestamp is measured in nanoseconds, and is normally monotonically
+     * increasing. The timestamps for the images from different sources may have
+     * different timebases therefore may not be comparable. The specific meaning and
+     * timebase of the timestamp depend on the source providing images. See
+     * {@link android.hardware.Camera Camera},
+     * {@link android.hardware.camera2.CameraDevice CameraDevice},
+     * {@link MediaPlayer} and {@link MediaCodec} for more details.
+     * </p>
+     */
+    public abstract long getTimestamp();
+
+    /**
+     * Get the transformation associated with this frame.
+     * @return The window transformation that needs to be applied for this frame.
+     * @hide
+     */
+    @SuppressWarnings("HiddenAbstractMethod")
+    public abstract int getTransform();
+
+    /**
+     * Get the scaling mode associated with this frame.
+     * @return The scaling mode that needs to be applied for this frame.
+     * @hide
+     */
+    @SuppressWarnings("HiddenAbstractMethod")
+    public abstract int getScalingMode();
+
+    /**
+     * Get the fence file descriptor associated with this frame.
+     * @return The fence file descriptor for this frame.
+     * @hide
+     */
+    public int getFenceFd() {
+        return -1;
+    }
+
+    /**
+     * Get the number of planes.
+     * @return The number of expected planes.
+     * @hide
+     */
+    public int getPlaneCount() {
+        return -1;
+    }
+    /**
+     * Get the {@link android.hardware.HardwareBuffer HardwareBuffer} handle of the input image
+     * intended for GPU and/or hardware access.
+     * <p>
+     * The returned {@link android.hardware.HardwareBuffer HardwareBuffer} shall not be used
+     * after  {@link Image#close Image.close()} has been called.
+     * </p>
+     * @return the HardwareBuffer associated with this Image or null if this Image doesn't support
+     * this feature. (Unsupported use cases include Image instances obtained through
+     * {@link android.media.MediaCodec MediaCodec}, and on versions prior to Android P,
+     * {@link android.media.ImageWriter ImageWriter}).
+     */
+    @Nullable
+    public HardwareBuffer getHardwareBuffer() {
+        throwISEIfImageIsInvalid();
+        return null;
+    }
+
+    /**
+     * Set the timestamp associated with this frame.
+     * <p>
+     * The timestamp is measured in nanoseconds, and is normally monotonically
+     * increasing. The timestamps for the images from different sources may have
+     * different timebases therefore may not be comparable. The specific meaning and
+     * timebase of the timestamp depend on the source providing images. See
+     * {@link android.hardware.Camera Camera},
+     * {@link android.hardware.camera2.CameraDevice CameraDevice},
+     * {@link MediaPlayer} and {@link MediaCodec} for more details.
+     * </p>
+     * <p>
+     * For images dequeued from {@link ImageWriter} via
+     * {@link ImageWriter#dequeueInputImage()}, it's up to the application to
+     * set the timestamps correctly before sending them back to the
+     * {@link ImageWriter}, or the timestamp will be generated automatically when
+     * {@link ImageWriter#queueInputImage queueInputImage()} is called.
+     * </p>
+     *
+     * @param timestamp The timestamp to be set for this image.
+     */
+    public void setTimestamp(long timestamp) {
+        throwISEIfImageIsInvalid();
+        return;
+    }
+
+    private Rect mCropRect;
+
+    /**
+     * Get the crop rectangle associated with this frame.
+     * <p>
+     * The crop rectangle specifies the region of valid pixels in the image,
+     * using coordinates in the largest-resolution plane.
+     */
+    public Rect getCropRect() {
+        throwISEIfImageIsInvalid();
+
+        if (mCropRect == null) {
+            return new Rect(0, 0, getWidth(), getHeight());
+        } else {
+            return new Rect(mCropRect); // return a copy
+        }
+    }
+
+    /**
+     * Set the crop rectangle associated with this frame.
+     * <p>
+     * The crop rectangle specifies the region of valid pixels in the image,
+     * using coordinates in the largest-resolution plane.
+     */
+    public void setCropRect(Rect cropRect) {
+        throwISEIfImageIsInvalid();
+
+        if (cropRect != null) {
+            cropRect = new Rect(cropRect);  // make a copy
+            if (!cropRect.intersect(0, 0, getWidth(), getHeight())) {
+                cropRect.setEmpty();
+            }
+        }
+        mCropRect = cropRect;
+    }
+
+    /**
+     * Get the array of pixel planes for this Image. The number of planes is
+     * determined by the format of the Image. The application will get an empty
+     * array if the image format is {@link android.graphics.ImageFormat#PRIVATE
+     * PRIVATE}, because the image pixel data is not directly accessible. The
+     * application can check the image format by calling
+     * {@link Image#getFormat()}.
+     */
+    public abstract Plane[] getPlanes();
+
+    /**
+     * Free up this frame for reuse.
+     * <p>
+     * After calling this method, calling any methods on this {@code Image} will
+     * result in an {@link IllegalStateException}, and attempting to read from
+     * or write to {@link ByteBuffer ByteBuffers} returned by an earlier
+     * {@link Plane#getBuffer} call will have undefined behavior. If the image
+     * was obtained from {@link ImageWriter} via
+     * {@link ImageWriter#dequeueInputImage()}, after calling this method, any
+     * image data filled by the application will be lost and the image will be
+     * returned to {@link ImageWriter} for reuse. Images given to
+     * {@link ImageWriter#queueInputImage queueInputImage()} are automatically
+     * closed.
+     * </p>
+     */
+    @Override
+    public abstract void close();
+
+    /**
+     * <p>
+     * Check if the image can be attached to a new owner (e.g. {@link ImageWriter}).
+     * </p>
+     * <p>
+     * This is a package private method that is only used internally.
+     * </p>
+     *
+     * @return true if the image is attachable to a new owner, false if the image is still attached
+     *         to its current owner, or the image is a stand-alone image and is not attachable to
+     *         a new owner.
+     * @hide
+     */
+    public boolean isAttachable() {
+        throwISEIfImageIsInvalid();
+
+        return false;
+    }
+
+    /**
+     * <p>
+     * Get the owner of the {@link Image}.
+     * </p>
+     * <p>
+     * The owner of an {@link Image} could be {@link ImageReader}, {@link ImageWriter},
+     * {@link MediaCodec} etc. This method returns the owner that produces this image, or null
+     * if the image is stand-alone image or the owner is unknown.
+     * </p>
+     * <p>
+     * This is a package private method that is only used internally.
+     * </p>
+     *
+     * @return The owner of the Image.
+     */
+    Object getOwner() {
+        throwISEIfImageIsInvalid();
+
+        return null;
+    }
+
+    /**
+     * Get native context (buffer pointer) associated with this image.
+     * <p>
+     * This is a package private method that is only used internally. It can be
+     * used to get the native buffer pointer and passed to native, which may be
+     * passed to {@link ImageWriter#attachAndQueueInputImage} to avoid a reverse
+     * JNI call.
+     * </p>
+     *
+     * @return native context associated with this Image.
+     */
+    long getNativeContext() {
+        throwISEIfImageIsInvalid();
+
+        return 0;
+    }
+
+    /**
+     * <p>A single color plane of image data.</p>
+     *
+     * <p>The number and meaning of the planes in an Image are determined by the
+     * format of the Image.</p>
+     *
+     * <p>Once the Image has been closed, any access to the the plane's
+     * ByteBuffer will fail.</p>
+     *
+     * @see #getFormat
+     */
+    public static abstract class Plane {
+        /**
+         * @hide
+         */
+        @UnsupportedAppUsage
+        @TestApi
+        protected Plane() {
+        }
+
+        /**
+         * <p>The row stride for this color plane, in bytes.</p>
+         *
+         * <p>This is the distance between the start of two consecutive rows of
+         * pixels in the image. Note that row stride is undefined for some formats
+         * such as
+         * {@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE},
+         * and calling getRowStride on images of these formats will
+         * cause an UnsupportedOperationException being thrown.
+         * For formats where row stride is well defined, the row stride
+         * is always greater than 0.</p>
+         */
+        public abstract int getRowStride();
+        /**
+         * <p>The distance between adjacent pixel samples, in bytes.</p>
+         *
+         * <p>This is the distance between two consecutive pixel values in a row
+         * of pixels. It may be larger than the size of a single pixel to
+         * account for interleaved image data or padded formats.
+         * Note that pixel stride is undefined for some formats such as
+         * {@link android.graphics.ImageFormat#RAW_PRIVATE RAW_PRIVATE},
+         * and calling getPixelStride on images of these formats will
+         * cause an UnsupportedOperationException being thrown.
+         * For formats where pixel stride is well defined, the pixel stride
+         * is always greater than 0.</p>
+         */
+        public abstract int getPixelStride();
+        /**
+         * <p>Get a direct {@link java.nio.ByteBuffer ByteBuffer}
+         * containing the frame data.</p>
+         *
+         * <p>In particular, the buffer returned will always have
+         * {@link java.nio.ByteBuffer#isDirect isDirect} return {@code true}, so
+         * the underlying data could be mapped as a pointer in JNI without doing
+         * any copies with {@code GetDirectBufferAddress}.</p>
+         *
+         * <p>For raw formats, each plane is only guaranteed to contain data
+         * up to the last pixel in the last row. In other words, the stride
+         * after the last row may not be mapped into the buffer. This is a
+         * necessary requirement for any interleaved format.</p>
+         *
+         * @return the byte buffer containing the image data for this plane.
+         */
+        public abstract ByteBuffer getBuffer();
+    }
+
+}
diff --git a/android/media/ImageReader.java b/android/media/ImageReader.java
new file mode 100644
index 0000000..5656dff
--- /dev/null
+++ b/android/media/ImageReader.java
@@ -0,0 +1,1229 @@
+/*
+ * Copyright (C) 2013 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.annotation.CallbackExecutor;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.graphics.GraphicBuffer;
+import android.graphics.ImageFormat;
+import android.graphics.ImageFormat.Format;
+import android.graphics.Rect;
+import android.hardware.HardwareBuffer;
+import android.hardware.HardwareBuffer.Usage;
+import android.hardware.camera2.MultiResolutionImageReader;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.view.Surface;
+
+import dalvik.system.VMRuntime;
+
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.NioUtils;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * <p>The ImageReader class allows direct application access to image data
+ * rendered into a {@link android.view.Surface}</p>
+ *
+ * <p>Several Android media API classes accept Surface objects as targets to
+ * render to, including {@link MediaPlayer}, {@link MediaCodec},
+ * {@link android.hardware.camera2.CameraDevice}, {@link ImageWriter} and
+ * {@link android.renderscript.Allocation RenderScript Allocations}. The image
+ * sizes and formats that can be used with each source vary, and should be
+ * checked in the documentation for the specific API.</p>
+ *
+ * <p>The image data is encapsulated in {@link Image} objects, and multiple such
+ * objects can be accessed at the same time, up to the number specified by the
+ * {@code maxImages} constructor parameter. New images sent to an ImageReader
+ * through its {@link Surface} are queued until accessed through the {@link #acquireLatestImage}
+ * or {@link #acquireNextImage} call. Due to memory limits, an image source will
+ * eventually stall or drop Images in trying to render to the Surface if the
+ * ImageReader does not obtain and release Images at a rate equal to the
+ * production rate.</p>
+ */
+public class ImageReader implements AutoCloseable {
+
+    /**
+     * Returned by nativeImageSetup when acquiring the image was successful.
+     */
+    private static final int ACQUIRE_SUCCESS = 0;
+    /**
+     * Returned by nativeImageSetup when we couldn't acquire the buffer,
+     * because there were no buffers available to acquire.
+     */
+    private static final int ACQUIRE_NO_BUFS = 1;
+    /**
+     * Returned by nativeImageSetup when we couldn't acquire the buffer
+     * because the consumer has already acquired {@maxImages} and cannot
+     * acquire more than that.
+     */
+    private static final int ACQUIRE_MAX_IMAGES = 2;
+
+    /**
+     * <p>
+     * Create a new reader for images of the desired size and format.
+     * </p>
+     * <p>
+     * The {@code maxImages} parameter determines the maximum number of
+     * {@link Image} objects that can be be acquired from the
+     * {@code ImageReader} simultaneously. Requesting more buffers will use up
+     * more memory, so it is important to use only the minimum number necessary
+     * for the use case.
+     * </p>
+     * <p>
+     * The valid sizes and formats depend on the source of the image data.
+     * </p>
+     * <p>
+     * If the {@code format} is {@link ImageFormat#PRIVATE PRIVATE}, the created
+     * {@link ImageReader} will produce images that are not directly accessible
+     * by the application. The application can still acquire images from this
+     * {@link ImageReader}, and send them to the
+     * {@link android.hardware.camera2.CameraDevice camera} for reprocessing via
+     * {@link ImageWriter} interface. However, the {@link Image#getPlanes()
+     * getPlanes()} will return an empty array for {@link ImageFormat#PRIVATE
+     * PRIVATE} format images. The application can check if an existing reader's
+     * format by calling {@link #getImageFormat()}.
+     * </p>
+     * <p>
+     * {@link ImageFormat#PRIVATE PRIVATE} format {@link ImageReader
+     * ImageReaders} are more efficient to use when application access to image
+     * data is not necessary, compared to ImageReaders using other format such
+     * as {@link ImageFormat#YUV_420_888 YUV_420_888}.
+     * </p>
+     *
+     * @param width The default width in pixels of the Images that this reader
+     *            will produce.
+     * @param height The default height in pixels of the Images that this reader
+     *            will produce.
+     * @param format The format of the Image that this reader will produce. This
+     *            must be one of the {@link android.graphics.ImageFormat} or
+     *            {@link android.graphics.PixelFormat} constants. Note that not
+     *            all formats are supported, like ImageFormat.NV21.
+     * @param maxImages The maximum number of images the user will want to
+     *            access simultaneously. This should be as small as possible to
+     *            limit memory use. Once maxImages Images are obtained by the
+     *            user, one of them has to be released before a new Image will
+     *            become available for access through
+     *            {@link #acquireLatestImage()} or {@link #acquireNextImage()}.
+     *            Must be greater than 0.
+     * @see Image
+     */
+    public static @NonNull ImageReader newInstance(
+            @IntRange(from = 1) int width,
+            @IntRange(from = 1) int height,
+            @Format             int format,
+            @IntRange(from = 1) int maxImages) {
+        // If the format is private don't default to USAGE_CPU_READ_OFTEN since it may not
+        // work, and is inscrutable anyway
+        return new ImageReader(width, height, format, maxImages,
+                format == ImageFormat.PRIVATE ? 0 : HardwareBuffer.USAGE_CPU_READ_OFTEN,
+                /*parent*/ null);
+    }
+
+    /**
+     * <p>
+     * Create a new reader for images of the desired size, format and consumer usage flag.
+     * </p>
+     * <p>
+     * The {@code maxImages} parameter determines the maximum number of {@link Image} objects that
+     * can be be acquired from the {@code ImageReader} simultaneously. Requesting more buffers will
+     * use up more memory, so it is important to use only the minimum number necessary for the use
+     * case.
+     * </p>
+     * <p>
+     * The valid sizes and formats depend on the source of the image data.
+     * </p>
+     * <p>
+     * The format and usage flag combination describes how the buffer will be used by
+     * consumer end-points. For example, if the application intends to send the images to
+     * {@link android.media.MediaCodec} or {@link android.media.MediaRecorder} for hardware video
+     * encoding, the format and usage flag combination needs to be
+     * {@link ImageFormat#PRIVATE PRIVATE} and {@link HardwareBuffer#USAGE_VIDEO_ENCODE}. When an
+     * {@link ImageReader} object is created with a valid size and such format/usage flag
+     * combination, the application can send the {@link Image images} to an {@link ImageWriter} that
+     * is created with the input {@link android.view.Surface} provided by the
+     * {@link android.media.MediaCodec} or {@link android.media.MediaRecorder}.
+     * </p>
+     * <p>
+     * If the {@code format} is {@link ImageFormat#PRIVATE PRIVATE}, the created {@link ImageReader}
+     * will produce images that are not directly accessible by the application. The application can
+     * still acquire images from this {@link ImageReader}, and send them to the
+     * {@link android.hardware.camera2.CameraDevice camera} for reprocessing, or to the
+     * {@link android.media.MediaCodec} / {@link android.media.MediaRecorder} for hardware video
+     * encoding via {@link ImageWriter} interface. However, the {@link Image#getPlanes()
+     * getPlanes()} will return an empty array for {@link ImageFormat#PRIVATE PRIVATE} format
+     * images. The application can check if an existing reader's format by calling
+     * {@link #getImageFormat()}.
+     * </p>
+     * <p>
+     * {@link ImageFormat#PRIVATE PRIVATE} format {@link ImageReader ImageReaders} are more
+     * efficient to use when application access to image data is not necessary, compared to
+     * ImageReaders using other format such as {@link ImageFormat#YUV_420_888 YUV_420_888}.
+     * </p>
+     * <p>
+     * Note that not all format and usage flag combinations are supported by the
+     * {@link ImageReader}. Below are the supported combinations by the {@link ImageReader}
+     * (assuming the consumer end-points support the such image consumption, e.g., hardware video
+     * encoding).
+     * <table>
+     * <tr>
+     *   <th>Format</th>
+     *   <th>Compatible usage flags</th>
+     * </tr>
+     * <tr>
+     *   <td>non-{@link android.graphics.ImageFormat#PRIVATE PRIVATE} formats defined by
+     *   {@link android.graphics.ImageFormat ImageFormat} or
+     *   {@link android.graphics.PixelFormat PixelFormat}</td>
+     *   <td>{@link HardwareBuffer#USAGE_CPU_READ_RARELY} or
+     *   {@link HardwareBuffer#USAGE_CPU_READ_OFTEN}</td>
+     * </tr>
+     * <tr>
+     *   <td>{@link android.graphics.ImageFormat#PRIVATE}</td>
+     *   <td>{@link HardwareBuffer#USAGE_VIDEO_ENCODE} or
+     *   {@link HardwareBuffer#USAGE_GPU_SAMPLED_IMAGE}, or combined</td>
+     * </tr>
+     * </table>
+     * Using other combinations may result in {@link IllegalArgumentException}. Additionally,
+     * specifying {@link HardwareBuffer#USAGE_CPU_WRITE_RARELY} or
+     * {@link HardwareBuffer#USAGE_CPU_WRITE_OFTEN} and writing to the ImageReader's buffers
+     * might break assumptions made by some producers, and should be used with caution.
+     * </p>
+     * <p>
+     * If the {@link ImageReader} is used as an output target for a {@link
+     * android.hardware.camera2.CameraDevice}, and if the usage flag contains
+     * {@link HardwareBuffer#USAGE_VIDEO_ENCODE}, the timestamps of the
+     * {@link Image images} produced by the {@link ImageReader} won't be in the same timebase as
+     * {@link android.os.SystemClock#elapsedRealtimeNanos}, even if
+     * {@link android.hardware.camera2.CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE} is
+     * {@link android.hardware.camera2.CameraCharacteristics#SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME}.
+     * Instead, the timestamps will be roughly in the same timebase as in
+     * {@link android.os.SystemClock#uptimeMillis}, so that A/V synchronization could work for
+     * video recording. In this case, the timestamps from the {@link ImageReader} with
+     * {@link HardwareBuffer#USAGE_VIDEO_ENCODE} usage flag may not be directly comparable with
+     * timestamps of other streams or capture result metadata.
+     * </p>
+     * @param width The default width in pixels of the Images that this reader will produce.
+     * @param height The default height in pixels of the Images that this reader will produce.
+     * @param format The format of the Image that this reader will produce. This must be one of the
+     *            {@link android.graphics.ImageFormat} or {@link android.graphics.PixelFormat}
+     *            constants. Note that not all formats are supported, like ImageFormat.NV21.
+     * @param maxImages The maximum number of images the user will want to access simultaneously.
+     *            This should be as small as possible to limit memory use. Once maxImages Images are
+     *            obtained by the user, one of them has to be released before a new Image will
+     *            become available for access through {@link #acquireLatestImage()} or
+     *            {@link #acquireNextImage()}. Must be greater than 0.
+     * @param usage The intended usage of the images produced by this ImageReader. See the usages
+     *              on {@link HardwareBuffer} for a list of valid usage bits. See also
+     *              {@link HardwareBuffer#isSupported(int, int, int, int, long)} for checking
+     *              if a combination is supported. If it's not supported this will throw
+     *              an {@link IllegalArgumentException}.
+     * @see Image
+     * @see HardwareBuffer
+     */
+    public static @NonNull ImageReader newInstance(
+            @IntRange(from = 1) int width,
+            @IntRange(from = 1) int height,
+            @Format             int format,
+            @IntRange(from = 1) int maxImages,
+            @Usage              long usage) {
+        // TODO: Check this - can't do it just yet because format support is different
+        // Unify formats! The only reliable way to validate usage is to just try it and see.
+
+//        if (!HardwareBuffer.isSupported(width, height, format, 1, usage)) {
+//            throw new IllegalArgumentException("The given format=" + Integer.toHexString(format)
+//                + " & usage=" + Long.toHexString(usage) + " is not supported");
+//        }
+        return new ImageReader(width, height, format, maxImages, usage, /*parent*/ null);
+    }
+
+     /**
+      * @hide
+      */
+     public static @NonNull ImageReader newInstance(
+            @IntRange(from = 1) int width,
+            @IntRange(from = 1) int height,
+            @Format             int format,
+            @IntRange(from = 1) int maxImages,
+            @NonNull            MultiResolutionImageReader parent) {
+        // If the format is private don't default to USAGE_CPU_READ_OFTEN since it may not
+        // work, and is inscrutable anyway
+        return new ImageReader(width, height, format, maxImages,
+                format == ImageFormat.PRIVATE ? 0 : HardwareBuffer.USAGE_CPU_READ_OFTEN,
+                parent);
+    }
+
+
+    /**
+     * @hide
+     */
+    protected ImageReader(int width, int height, int format, int maxImages, long usage,
+            MultiResolutionImageReader parent) {
+        mWidth = width;
+        mHeight = height;
+        mFormat = format;
+        mUsage = usage;
+        mMaxImages = maxImages;
+        mParent = parent;
+
+        if (width < 1 || height < 1) {
+            throw new IllegalArgumentException(
+                "The image dimensions must be positive");
+        }
+        if (mMaxImages < 1) {
+            throw new IllegalArgumentException(
+                "Maximum outstanding image count must be at least 1");
+        }
+
+        if (format == ImageFormat.NV21) {
+            throw new IllegalArgumentException(
+                    "NV21 format is not supported");
+        }
+
+        mNumPlanes = ImageUtils.getNumPlanesForFormat(mFormat);
+
+        nativeInit(new WeakReference<>(this), width, height, format, maxImages, usage);
+
+        mSurface = nativeGetSurface();
+
+        mIsReaderValid = true;
+        // Estimate the native buffer allocation size and register it so it gets accounted for
+        // during GC. Note that this doesn't include the buffers required by the buffer queue
+        // itself and the buffers requested by the producer.
+        // Only include memory for 1 buffer, since actually accounting for the memory used is
+        // complex, and 1 buffer is enough for the VM to treat the ImageReader as being of some
+        // size.
+        mEstimatedNativeAllocBytes = ImageUtils.getEstimatedNativeAllocBytes(
+                width, height, format, /*buffer count*/ 1);
+        VMRuntime.getRuntime().registerNativeAllocation(mEstimatedNativeAllocBytes);
+    }
+
+    /**
+     * The default width of {@link Image Images}, in pixels.
+     *
+     * <p>The width may be overridden by the producer sending buffers to this
+     * ImageReader's Surface. If so, the actual width of the images can be
+     * found using {@link Image#getWidth}.</p>
+     *
+     * @return the expected width of an Image
+     */
+    public int getWidth() {
+        return mWidth;
+    }
+
+    /**
+     * The default height of {@link Image Images}, in pixels.
+     *
+     * <p>The height may be overridden by the producer sending buffers to this
+     * ImageReader's Surface. If so, the actual height of the images can be
+     * found using {@link Image#getHeight}.</p>
+     *
+     * @return the expected height of an Image
+     */
+    public int getHeight() {
+        return mHeight;
+    }
+
+    /**
+     * The default {@link ImageFormat image format} of {@link Image Images}.
+     *
+     * <p>Some color formats may be overridden by the producer sending buffers to
+     * this ImageReader's Surface if the default color format allows. ImageReader
+     * guarantees that all {@link Image Images} acquired from ImageReader
+     * (for example, with {@link #acquireNextImage}) will have a "compatible"
+     * format to what was specified in {@link #newInstance}.
+     * As of now, each format is only compatible to itself.
+     * The actual format of the images can be found using {@link Image#getFormat}.</p>
+     *
+     * @return the expected format of an Image
+     *
+     * @see ImageFormat
+     */
+    public int getImageFormat() {
+        return mFormat;
+    }
+
+    /**
+     * Maximum number of images that can be acquired from the ImageReader by any time (for example,
+     * with {@link #acquireNextImage}).
+     *
+     * <p>An image is considered acquired after it's returned by a function from ImageReader, and
+     * until the Image is {@link Image#close closed} to release the image back to the ImageReader.
+     * </p>
+     *
+     * <p>Attempting to acquire more than {@code maxImages} concurrently will result in the
+     * acquire function throwing a {@link IllegalStateException}. Furthermore,
+     * while the max number of images have been acquired by the ImageReader user, the producer
+     * enqueueing additional images may stall until at least one image has been released. </p>
+     *
+     * @return Maximum number of images for this ImageReader.
+     *
+     * @see Image#close
+     */
+    public int getMaxImages() {
+        return mMaxImages;
+    }
+
+    /**
+     * <p>Get a {@link Surface} that can be used to produce {@link Image Images} for this
+     * {@code ImageReader}.</p>
+     *
+     * <p>Until valid image data is rendered into this {@link Surface}, the
+     * {@link #acquireNextImage} method will return {@code null}. Only one source
+     * can be producing data into this Surface at the same time, although the
+     * same {@link Surface} can be reused with a different API once the first source is
+     * disconnected from the {@link Surface}.</p>
+     *
+     * <p>Please note that holding on to the Surface object returned by this method is not enough
+     * to keep its parent ImageReader from being reclaimed. In that sense, a Surface acts like a
+     * {@link java.lang.ref.WeakReference weak reference} to the ImageReader that provides it.</p>
+     *
+     * @return A {@link Surface} to use for a drawing target for various APIs.
+     */
+    public Surface getSurface() {
+        return mSurface;
+    }
+
+    /**
+     * <p>
+     * Acquire the latest {@link Image} from the ImageReader's queue, dropping older
+     * {@link Image images}. Returns {@code null} if no new image is available.
+     * </p>
+     * <p>
+     * This operation will acquire all the images possible from the ImageReader,
+     * but {@link #close} all images that aren't the latest. This function is
+     * recommended to use over {@link #acquireNextImage} for most use-cases, as it's
+     * more suited for real-time processing.
+     * </p>
+     * <p>
+     * Note that {@link #getMaxImages maxImages} should be at least 2 for
+     * {@link #acquireLatestImage} to be any different than {@link #acquireNextImage} -
+     * discarding all-but-the-newest {@link Image} requires temporarily acquiring two
+     * {@link Image Images} at once. Or more generally, calling {@link #acquireLatestImage}
+     * with less than two images of margin, that is
+     * {@code (maxImages - currentAcquiredImages < 2)} will not discard as expected.
+     * </p>
+     * <p>
+     * This operation will fail by throwing an {@link IllegalStateException} if
+     * {@code maxImages} have been acquired with {@link #acquireLatestImage} or
+     * {@link #acquireNextImage}. In particular a sequence of {@link #acquireLatestImage}
+     * calls greater than {@link #getMaxImages} without calling {@link Image#close} in-between
+     * will exhaust the underlying queue. At such a time, {@link IllegalStateException}
+     * will be thrown until more images are
+     * released with {@link Image#close}.
+     * </p>
+     *
+     * @return latest frame of image data, or {@code null} if no image data is available.
+     * @throws IllegalStateException if too many images are currently acquired
+     */
+    public Image acquireLatestImage() {
+        Image image = acquireNextImage();
+        if (image == null) {
+            return null;
+        }
+        try {
+            for (;;) {
+                Image next = acquireNextImageNoThrowISE();
+                if (next == null) {
+                    Image result = image;
+                    image = null;
+                    return result;
+                }
+                image.close();
+                image = next;
+            }
+        } finally {
+            if (image != null) {
+                image.close();
+            }
+            if (mParent != null) {
+                mParent.flushOther(this);
+            }
+        }
+    }
+
+    /**
+     * Don't throw IllegalStateException if there are too many images acquired.
+     *
+     * @return Image if acquiring succeeded, or null otherwise.
+     *
+     * @hide
+     */
+    public Image acquireNextImageNoThrowISE() {
+        SurfaceImage si = new SurfaceImage(mFormat);
+        return acquireNextSurfaceImage(si) == ACQUIRE_SUCCESS ? si : null;
+    }
+
+    /**
+     * Attempts to acquire the next image from the underlying native implementation.
+     *
+     * <p>
+     * Note that unexpected failures will throw at the JNI level.
+     * </p>
+     *
+     * @param si A blank SurfaceImage.
+     * @return One of the {@code ACQUIRE_*} codes that determine success or failure.
+     *
+     * @see #ACQUIRE_MAX_IMAGES
+     * @see #ACQUIRE_NO_BUFS
+     * @see #ACQUIRE_SUCCESS
+     */
+    private int acquireNextSurfaceImage(SurfaceImage si) {
+        synchronized (mCloseLock) {
+            // A null image will eventually be returned if ImageReader is already closed.
+            int status = ACQUIRE_NO_BUFS;
+            if (mIsReaderValid) {
+                status = nativeImageSetup(si);
+            }
+
+            switch (status) {
+                case ACQUIRE_SUCCESS:
+                    si.mIsImageValid = true;
+                case ACQUIRE_NO_BUFS:
+                case ACQUIRE_MAX_IMAGES:
+                    break;
+                default:
+                    throw new AssertionError("Unknown nativeImageSetup return code " + status);
+            }
+
+            // Only keep track the successfully acquired image, as the native buffer is only mapped
+            // for such case.
+            if (status == ACQUIRE_SUCCESS) {
+                mAcquiredImages.add(si);
+            }
+            return status;
+        }
+    }
+
+    /**
+     * <p>
+     * Acquire the next Image from the ImageReader's queue. Returns {@code null} if
+     * no new image is available.
+     * </p>
+     *
+     * <p><i>Warning:</i> Consider using {@link #acquireLatestImage()} instead, as it will
+     * automatically release older images, and allow slower-running processing routines to catch
+     * up to the newest frame. Usage of {@link #acquireNextImage} is recommended for
+     * batch/background processing. Incorrectly using this function can cause images to appear
+     * with an ever-increasing delay, followed by a complete stall where no new images seem to
+     * appear.
+     * </p>
+     *
+     * <p>
+     * This operation will fail by throwing an {@link IllegalStateException} if
+     * {@code maxImages} have been acquired with {@link #acquireNextImage} or
+     * {@link #acquireLatestImage}. In particular a sequence of {@link #acquireNextImage} or
+     * {@link #acquireLatestImage} calls greater than {@link #getMaxImages maxImages} without
+     * calling {@link Image#close} in-between will exhaust the underlying queue. At such a time,
+     * {@link IllegalStateException} will be thrown until more images are released with
+     * {@link Image#close}.
+     * </p>
+     *
+     * @return a new frame of image data, or {@code null} if no image data is available.
+     * @throws IllegalStateException if {@code maxImages} images are currently acquired
+     * @see #acquireLatestImage
+     */
+    public Image acquireNextImage() {
+        // Initialize with reader format, but can be overwritten by native if the image
+        // format is different from the reader format.
+        SurfaceImage si = new SurfaceImage(mFormat);
+        int status = acquireNextSurfaceImage(si);
+
+        switch (status) {
+            case ACQUIRE_SUCCESS:
+                return si;
+            case ACQUIRE_NO_BUFS:
+                return null;
+            case ACQUIRE_MAX_IMAGES:
+                throw new IllegalStateException(
+                        String.format(
+                                "maxImages (%d) has already been acquired, " +
+                                "call #close before acquiring more.", mMaxImages));
+            default:
+                throw new AssertionError("Unknown nativeImageSetup return code " + status);
+        }
+    }
+
+    /**
+     * <p>Return the frame to the ImageReader for reuse.</p>
+     */
+    private void releaseImage(Image i) {
+        if (! (i instanceof SurfaceImage) ) {
+            throw new IllegalArgumentException(
+                "This image was not produced by an ImageReader");
+        }
+        SurfaceImage si = (SurfaceImage) i;
+        if (si.mIsImageValid == false) {
+            return;
+        }
+
+        if (si.getReader() != this || !mAcquiredImages.contains(i)) {
+            throw new IllegalArgumentException(
+                "This image was not produced by this ImageReader");
+        }
+
+        si.clearSurfacePlanes();
+        nativeReleaseImage(i);
+        si.mIsImageValid = false;
+        mAcquiredImages.remove(i);
+    }
+
+    /**
+     * Register a listener to be invoked when a new image becomes available
+     * from the ImageReader.
+     *
+     * @param listener
+     *            The listener that will be run.
+     * @param handler
+     *            The handler on which the listener should be invoked, or null
+     *            if the listener should be invoked on the calling thread's looper.
+     * @throws IllegalArgumentException
+     *            If no handler specified and the calling thread has no looper.
+     */
+    public void setOnImageAvailableListener(OnImageAvailableListener listener, Handler handler) {
+        synchronized (mListenerLock) {
+            if (listener != null) {
+                Looper looper = handler != null ? handler.getLooper() : Looper.myLooper();
+                if (looper == null) {
+                    throw new IllegalArgumentException(
+                            "handler is null but the current thread is not a looper");
+                }
+                if (mListenerHandler == null || mListenerHandler.getLooper() != looper) {
+                    mListenerHandler = new ListenerHandler(looper);
+                    mListenerExecutor = new HandlerExecutor(mListenerHandler);
+                }
+            } else {
+                mListenerHandler = null;
+                mListenerExecutor = null;
+            }
+            mListener = listener;
+        }
+    }
+
+    /**
+     * Register a listener to be invoked when a new image becomes available
+     * from the ImageReader.
+     *
+     * @param listener
+     *            The listener that will be run.
+     * @param executor
+     *            The executor which will be used to invoke the listener.
+     * @throws IllegalArgumentException
+     *            If no handler specified and the calling thread has no looper.
+     *
+     * @hide
+     */
+    public void setOnImageAvailableListenerWithExecutor(@NonNull OnImageAvailableListener listener,
+            @NonNull Executor executor) {
+        if (executor == null) {
+            throw new IllegalArgumentException("executor must not be null");
+        }
+
+        synchronized (mListenerLock) {
+            mListenerExecutor = executor;
+            mListener = listener;
+        }
+    }
+
+    /**
+     * Callback interface for being notified that a new image is available.
+     *
+     * <p>
+     * The onImageAvailable is called per image basis, that is, callback fires for every new frame
+     * available from ImageReader.
+     * </p>
+     */
+    public interface OnImageAvailableListener {
+        /**
+         * Callback that is called when a new image is available from ImageReader.
+         *
+         * @param reader the ImageReader the callback is associated with.
+         * @see ImageReader
+         * @see Image
+         */
+        void onImageAvailable(ImageReader reader);
+    }
+
+    /**
+     * Free up all the resources associated with this ImageReader.
+     *
+     * <p>
+     * After calling this method, this ImageReader can not be used. Calling
+     * any methods on this ImageReader and Images previously provided by
+     * {@link #acquireNextImage} or {@link #acquireLatestImage}
+     * will result in an {@link IllegalStateException}, and attempting to read from
+     * {@link ByteBuffer ByteBuffers} returned by an earlier
+     * {@link Image.Plane#getBuffer Plane#getBuffer} call will
+     * have undefined behavior.
+     * </p>
+     */
+    @Override
+    public void close() {
+        setOnImageAvailableListener(null, null);
+        if (mSurface != null) mSurface.release();
+
+        /**
+         * Close all outstanding acquired images before closing the ImageReader. It is a good
+         * practice to close all the images as soon as it is not used to reduce system instantaneous
+         * memory pressure. CopyOnWrite list will use a copy of current list content. For the images
+         * being closed by other thread (e.g., GC thread), doubling the close call is harmless. For
+         * the image being acquired by other threads, mCloseLock is used to synchronize close and
+         * acquire operations.
+         */
+        synchronized (mCloseLock) {
+            mIsReaderValid = false;
+            for (Image image : mAcquiredImages) {
+                image.close();
+            }
+            mAcquiredImages.clear();
+
+            nativeClose();
+
+            if (mEstimatedNativeAllocBytes > 0) {
+                VMRuntime.getRuntime().registerNativeFree(mEstimatedNativeAllocBytes);
+                mEstimatedNativeAllocBytes = 0;
+            }
+        }
+    }
+
+    /**
+     * Discard any free buffers owned by this ImageReader.
+     *
+     * <p>
+     * Generally, the ImageReader caches buffers for reuse once they have been
+     * allocated, for best performance. However, sometimes it may be important to
+     * release all the cached, unused buffers to save on memory.
+     * </p>
+     * <p>
+     * Calling this method will discard all free cached buffers. This does not include any buffers
+     * associated with Images acquired from the ImageReader, any filled buffers waiting to be
+     * acquired, and any buffers currently in use by the source rendering buffers into the
+     * ImageReader's Surface.
+     * <p>
+     * The ImageReader continues to be usable after this call, but may need to reallocate buffers
+     * when more buffers are needed for rendering.
+     * </p>
+     */
+    public void discardFreeBuffers() {
+        synchronized (mCloseLock) {
+            nativeDiscardFreeBuffers();
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * <p>
+     * Remove the ownership of this image from the ImageReader.
+     * </p>
+     * <p>
+     * After this call, the ImageReader no longer owns this image, and the image
+     * ownership can be transfered to another entity like {@link ImageWriter}
+     * via {@link ImageWriter#queueInputImage}. It's up to the new owner to
+     * release the resources held by this image. For example, if the ownership
+     * of this image is transfered to an {@link ImageWriter}, the image will be
+     * freed by the ImageWriter after the image data consumption is done.
+     * </p>
+     * <p>
+     * This method can be used to achieve zero buffer copy for use cases like
+     * {@link android.hardware.camera2.CameraDevice Camera2 API} PRIVATE and YUV
+     * reprocessing, where the application can select an output image from
+     * {@link ImageReader} and transfer this image directly to
+     * {@link ImageWriter}, where this image can be consumed by camera directly.
+     * For PRIVATE reprocessing, this is the only way to send input buffers to
+     * the {@link android.hardware.camera2.CameraDevice camera} for
+     * reprocessing.
+     * </p>
+     * <p>
+     * This is a package private method that is only used internally.
+     * </p>
+     *
+     * @param image The image to be detached from this ImageReader.
+     * @throws IllegalStateException If the ImageReader or image have been
+     *             closed, or the has been detached, or has not yet been
+     *             acquired.
+     * @hide
+     */
+     public void detachImage(Image image) {
+       if (image == null) {
+           throw new IllegalArgumentException("input image must not be null");
+       }
+       if (!isImageOwnedbyMe(image)) {
+           throw new IllegalArgumentException("Trying to detach an image that is not owned by"
+                   + " this ImageReader");
+       }
+
+        SurfaceImage si = (SurfaceImage) image;
+        si.throwISEIfImageIsInvalid();
+
+        if (si.isAttachable()) {
+            throw new IllegalStateException("Image was already detached from this ImageReader");
+        }
+
+        nativeDetachImage(image);
+        si.clearSurfacePlanes();
+        si.mPlanes = null;
+        si.setDetached(true);
+    }
+
+    private boolean isImageOwnedbyMe(Image image) {
+        if (!(image instanceof SurfaceImage)) {
+            return false;
+        }
+        SurfaceImage si = (SurfaceImage) image;
+        return si.getReader() == this;
+    }
+
+    /**
+     * Called from Native code when an Event happens.
+     *
+     * This may be called from an arbitrary Binder thread, so access to the ImageReader must be
+     * synchronized appropriately.
+     */
+    private static void postEventFromNative(Object selfRef) {
+        @SuppressWarnings("unchecked")
+        WeakReference<ImageReader> weakSelf = (WeakReference<ImageReader>)selfRef;
+        final ImageReader ir = weakSelf.get();
+        if (ir == null) {
+            return;
+        }
+
+        final Executor executor;
+        final OnImageAvailableListener listener;
+        synchronized (ir.mListenerLock) {
+            executor = ir.mListenerExecutor;
+            listener = ir.mListener;
+        }
+        final boolean isReaderValid;
+        synchronized (ir.mCloseLock) {
+            isReaderValid = ir.mIsReaderValid;
+        }
+
+        // It's dangerous to fire onImageAvailable() callback when the ImageReader
+        // is being closed, as application could acquire next image in the
+        // onImageAvailable() callback.
+        if (executor != null && listener != null && isReaderValid) {
+            executor.execute(new Runnable() {
+                @Override
+                public void run() {
+                    listener.onImageAvailable(ir);
+                }
+            });
+        }
+    }
+
+    private final int mWidth;
+    private final int mHeight;
+    private final int mFormat;
+    private final long mUsage;
+    private final int mMaxImages;
+    private final int mNumPlanes;
+    private final Surface mSurface;
+    private int mEstimatedNativeAllocBytes;
+
+    private final Object mListenerLock = new Object();
+    private final Object mCloseLock = new Object();
+    private boolean mIsReaderValid = false;
+    private OnImageAvailableListener mListener;
+    private Executor mListenerExecutor;
+    private ListenerHandler mListenerHandler;
+    // Keep track of the successfully acquired Images. This need to be thread safe as the images
+    // could be closed by different threads (e.g., application thread and GC thread).
+    private List<Image> mAcquiredImages = new CopyOnWriteArrayList<>();
+
+    // Applicable if this isn't a standalone ImageReader, but belongs to a
+    // MultiResolutionImageReader.
+    private final MultiResolutionImageReader mParent;
+
+    /**
+     * This field is used by native code, do not access or modify.
+     */
+    private long mNativeContext;
+
+    /**
+     * This custom handler runs asynchronously so callbacks don't get queued behind UI messages.
+     */
+    private final class ListenerHandler extends Handler {
+        public ListenerHandler(Looper looper) {
+            super(looper, null, true /*async*/);
+        }
+    }
+
+    /**
+     * An adapter {@link Executor} that posts all executed tasks onto the
+     * given {@link Handler}.
+     **/
+    private final class HandlerExecutor implements Executor {
+        private final Handler mHandler;
+
+        public HandlerExecutor(@NonNull Handler handler) {
+            mHandler = Objects.requireNonNull(handler);
+        }
+
+        @Override
+        public void execute(Runnable command) {
+            mHandler.post(command);
+        }
+    }
+
+    private class SurfaceImage extends android.media.Image {
+        public SurfaceImage(int format) {
+            mFormat = format;
+        }
+
+        @Override
+        public void close() {
+            ImageReader.this.releaseImage(this);
+        }
+
+        public ImageReader getReader() {
+            return ImageReader.this;
+        }
+
+        @Override
+        public int getFormat() {
+            throwISEIfImageIsInvalid();
+            int readerFormat = ImageReader.this.getImageFormat();
+            // Assume opaque reader always produce opaque images.
+            mFormat = (readerFormat == ImageFormat.PRIVATE) ? readerFormat :
+                nativeGetFormat(readerFormat);
+            return mFormat;
+        }
+
+        @Override
+        public int getWidth() {
+            throwISEIfImageIsInvalid();
+            int width;
+            switch(getFormat()) {
+                case ImageFormat.JPEG:
+                case ImageFormat.DEPTH_POINT_CLOUD:
+                case ImageFormat.RAW_PRIVATE:
+                case ImageFormat.DEPTH_JPEG:
+                case ImageFormat.HEIC:
+                    width = ImageReader.this.getWidth();
+                    break;
+                default:
+                    width = nativeGetWidth();
+            }
+            return width;
+        }
+
+        @Override
+        public int getHeight() {
+            throwISEIfImageIsInvalid();
+            int height;
+            switch(getFormat()) {
+                case ImageFormat.JPEG:
+                case ImageFormat.DEPTH_POINT_CLOUD:
+                case ImageFormat.RAW_PRIVATE:
+                case ImageFormat.DEPTH_JPEG:
+                case ImageFormat.HEIC:
+                    height = ImageReader.this.getHeight();
+                    break;
+                default:
+                    height = nativeGetHeight();
+            }
+            return height;
+        }
+
+        @Override
+        public long getTimestamp() {
+            throwISEIfImageIsInvalid();
+            return mTimestamp;
+        }
+
+        @Override
+        public int getTransform() {
+            throwISEIfImageIsInvalid();
+            return mTransform;
+        }
+
+        @Override
+        public int getScalingMode() {
+            throwISEIfImageIsInvalid();
+            return mScalingMode;
+        }
+
+        @Override
+        public int getPlaneCount() {
+            throwISEIfImageIsInvalid();
+            return ImageReader.this.mNumPlanes;
+        }
+
+        @Override
+        public int getFenceFd() {
+            throwISEIfImageIsInvalid();
+            return nativeGetFenceFd();
+        }
+
+        @Override
+        public HardwareBuffer getHardwareBuffer() {
+            throwISEIfImageIsInvalid();
+            return nativeGetHardwareBuffer();
+        }
+
+        @Override
+        public void setTimestamp(long timestampNs) {
+            throwISEIfImageIsInvalid();
+            mTimestamp = timestampNs;
+        }
+
+        @Override
+        public Plane[] getPlanes() {
+            throwISEIfImageIsInvalid();
+
+            if (mPlanes == null) {
+                mPlanes = nativeCreatePlanes(ImageReader.this.mNumPlanes, ImageReader.this.mFormat,
+                        ImageReader.this.mUsage);
+            }
+            // Shallow copy is fine.
+            return mPlanes.clone();
+        }
+
+        @Override
+        protected final void finalize() throws Throwable {
+            try {
+                close();
+            } finally {
+                super.finalize();
+            }
+        }
+
+        @Override
+        public boolean isAttachable() {
+            throwISEIfImageIsInvalid();
+            return mIsDetached.get();
+        }
+
+        @Override
+        ImageReader getOwner() {
+            throwISEIfImageIsInvalid();
+            return ImageReader.this;
+        }
+
+        @Override
+        long getNativeContext() {
+            throwISEIfImageIsInvalid();
+            return mNativeBuffer;
+        }
+
+        private void setDetached(boolean detached) {
+            throwISEIfImageIsInvalid();
+            mIsDetached.getAndSet(detached);
+        }
+
+        private void clearSurfacePlanes() {
+            // Image#getPlanes may not be called before the image is closed.
+            if (mIsImageValid && mPlanes != null) {
+                for (int i = 0; i < mPlanes.length; i++) {
+                    if (mPlanes[i] != null) {
+                        mPlanes[i].clearBuffer();
+                        mPlanes[i] = null;
+                    }
+                }
+            }
+        }
+
+        private class SurfacePlane extends android.media.Image.Plane {
+            // SurfacePlane instance is created by native code when SurfaceImage#getPlanes() is
+            // called
+            private SurfacePlane(int rowStride, int pixelStride, ByteBuffer buffer) {
+                mRowStride = rowStride;
+                mPixelStride = pixelStride;
+                mBuffer = buffer;
+                /**
+                 * Set the byteBuffer order according to host endianness (native
+                 * order), otherwise, the byteBuffer order defaults to
+                 * ByteOrder.BIG_ENDIAN.
+                 */
+                mBuffer.order(ByteOrder.nativeOrder());
+            }
+
+            @Override
+            public ByteBuffer getBuffer() {
+                throwISEIfImageIsInvalid();
+                return mBuffer;
+            }
+
+            @Override
+            public int getPixelStride() {
+                SurfaceImage.this.throwISEIfImageIsInvalid();
+                if (ImageReader.this.mFormat == ImageFormat.RAW_PRIVATE) {
+                    throw new UnsupportedOperationException(
+                            "getPixelStride is not supported for RAW_PRIVATE plane");
+                }
+                return mPixelStride;
+            }
+
+            @Override
+            public int getRowStride() {
+                SurfaceImage.this.throwISEIfImageIsInvalid();
+                if (ImageReader.this.mFormat == ImageFormat.RAW_PRIVATE) {
+                    throw new UnsupportedOperationException(
+                            "getRowStride is not supported for RAW_PRIVATE plane");
+                }
+                return mRowStride;
+            }
+
+            private void clearBuffer() {
+                // Need null check first, as the getBuffer() may not be called before an image
+                // is closed.
+                if (mBuffer == null) {
+                    return;
+                }
+
+                if (mBuffer.isDirect()) {
+                    NioUtils.freeDirectBuffer(mBuffer);
+                }
+                mBuffer = null;
+            }
+
+            final private int mPixelStride;
+            final private int mRowStride;
+
+            private ByteBuffer mBuffer;
+        }
+
+        /**
+         * This field is used to keep track of native object and used by native code only.
+         * Don't modify.
+         */
+        private long mNativeBuffer;
+
+        /**
+         * These fields are set by native code during nativeImageSetup().
+         */
+        private long mTimestamp;
+        private int mTransform;
+        private int mScalingMode;
+
+        private SurfacePlane[] mPlanes;
+        private int mFormat = ImageFormat.UNKNOWN;
+        // If this image is detached from the ImageReader.
+        private AtomicBoolean mIsDetached = new AtomicBoolean(false);
+
+        private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes,
+                int readerFormat, long readerUsage);
+        private synchronized native int nativeGetWidth();
+        private synchronized native int nativeGetHeight();
+        private synchronized native int nativeGetFormat(int readerFormat);
+        private synchronized native int nativeGetFenceFd();
+        private synchronized native HardwareBuffer nativeGetHardwareBuffer();
+    }
+
+    private synchronized native void nativeInit(Object weakSelf, int w, int h,
+                                                    int fmt, int maxImgs, long consumerUsage);
+    private synchronized native void nativeClose();
+    private synchronized native void nativeReleaseImage(Image i);
+    private synchronized native Surface nativeGetSurface();
+    private synchronized native int nativeDetachImage(Image i);
+    private synchronized native void nativeDiscardFreeBuffers();
+
+    /**
+     * @return A return code {@code ACQUIRE_*}
+     *
+     * @see #ACQUIRE_SUCCESS
+     * @see #ACQUIRE_NO_BUFS
+     * @see #ACQUIRE_MAX_IMAGES
+     */
+    private synchronized native int nativeImageSetup(Image i);
+
+    /**
+     * @hide
+     */
+    public static class ImagePlane extends android.media.Image.Plane {
+        private ImagePlane(int rowStride, int pixelStride, ByteBuffer buffer) {
+            mRowStride = rowStride;
+            mPixelStride = pixelStride;
+            mBuffer = buffer;
+            /**
+             * Set the byteBuffer order according to host endianness (native
+             * order), otherwise, the byteBuffer order defaults to
+             * ByteOrder.BIG_ENDIAN.
+             */
+            mBuffer.order(ByteOrder.nativeOrder());
+        }
+
+        @Override
+        public ByteBuffer getBuffer() {
+            return mBuffer;
+        }
+
+        @Override
+        public int getPixelStride() {
+            return mPixelStride;
+        }
+
+        @Override
+        public int getRowStride() {
+            return mRowStride;
+        }
+
+        final private int mPixelStride;
+        final private int mRowStride;
+
+        private ByteBuffer mBuffer;
+    }
+
+    /**
+     * @hide
+     */
+    public static ImagePlane[] initializeImagePlanes(int numPlanes,
+            GraphicBuffer buffer, int fenceFd, int format, long timestamp, int transform,
+            int scalingMode, Rect crop) {
+
+        return nativeCreateImagePlanes(numPlanes, buffer, fenceFd, format, crop.left, crop.top,
+                crop.right, crop.bottom);
+    }
+
+    private synchronized static native ImagePlane[] nativeCreateImagePlanes(int numPlanes,
+            GraphicBuffer buffer, int fenceFd, int format, int cropLeft, int cropTop,
+            int cropRight, int cropBottom);
+
+    /**
+     * @hide
+     */
+    public static void unlockGraphicBuffer(GraphicBuffer buffer) {
+        nativeUnlockGraphicBuffer(buffer);
+    }
+
+    private synchronized static native void nativeUnlockGraphicBuffer(GraphicBuffer buffer);
+
+    /**
+     * We use a class initializer to allow the native code to cache some
+     * field offsets.
+     */
+    private static native void nativeClassInit();
+    static {
+        System.loadLibrary("media_jni");
+        nativeClassInit();
+    }
+}
diff --git a/android/media/ImageUtils.java b/android/media/ImageUtils.java
new file mode 100644
index 0000000..7837d7e
--- /dev/null
+++ b/android/media/ImageUtils.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright 2015 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.graphics.ImageFormat;
+import android.graphics.PixelFormat;
+import android.media.Image.Plane;
+import android.util.Size;
+
+import libcore.io.Memory;
+
+import java.nio.ByteBuffer;
+
+/**
+ * Package private utility class for hosting commonly used Image related methods.
+ */
+class ImageUtils {
+
+    /**
+     * Only a subset of the formats defined in
+     * {@link android.graphics.ImageFormat ImageFormat} and
+     * {@link android.graphics.PixelFormat PixelFormat} are supported by
+     * ImageReader. When reading RGB data from a surface, the formats defined in
+     * {@link android.graphics.PixelFormat PixelFormat} can be used; when
+     * reading YUV, JPEG, HEIC or raw sensor data (for example, from the camera
+     * or video decoder), formats from {@link android.graphics.ImageFormat ImageFormat}
+     * are used.
+     */
+    public static int getNumPlanesForFormat(int format) {
+        switch (format) {
+            case ImageFormat.YV12:
+            case ImageFormat.YUV_420_888:
+            case ImageFormat.NV21:
+            case ImageFormat.YCBCR_P010:
+                return 3;
+            case ImageFormat.NV16:
+                return 2;
+            case PixelFormat.RGB_565:
+            case PixelFormat.RGBA_8888:
+            case PixelFormat.RGBX_8888:
+            case PixelFormat.RGB_888:
+            case ImageFormat.JPEG:
+            case ImageFormat.YUY2:
+            case ImageFormat.Y8:
+            case ImageFormat.Y16:
+            case ImageFormat.RAW_SENSOR:
+            case ImageFormat.RAW_PRIVATE:
+            case ImageFormat.RAW10:
+            case ImageFormat.RAW12:
+            case ImageFormat.DEPTH16:
+            case ImageFormat.DEPTH_POINT_CLOUD:
+            case ImageFormat.RAW_DEPTH:
+            case ImageFormat.RAW_DEPTH10:
+            case ImageFormat.DEPTH_JPEG:
+            case ImageFormat.HEIC:
+                return 1;
+            case ImageFormat.PRIVATE:
+                return 0;
+            default:
+                throw new UnsupportedOperationException(
+                        String.format("Invalid format specified %d", format));
+        }
+    }
+
+    /**
+     * <p>
+     * Copy source image data to destination Image.
+     * </p>
+     * <p>
+     * Only support the copy between two non-{@link ImageFormat#PRIVATE PRIVATE} format
+     * images with same properties (format, size, etc.). The data from the
+     * source image will be copied to the byteBuffers from the destination Image
+     * starting from position zero, and the destination image will be rewound to
+     * zero after copy is done.
+     * </p>
+     *
+     * @param src The source image to be copied from.
+     * @param dst The destination image to be copied to.
+     * @throws IllegalArgumentException If the source and destination images
+     *             have different format, or one of the images is not copyable.
+     */
+    public static void imageCopy(Image src, Image dst) {
+        if (src == null || dst == null) {
+            throw new IllegalArgumentException("Images should be non-null");
+        }
+        if (src.getFormat() != dst.getFormat()) {
+            throw new IllegalArgumentException("Src and dst images should have the same format");
+        }
+        if (src.getFormat() == ImageFormat.PRIVATE ||
+                dst.getFormat() == ImageFormat.PRIVATE) {
+            throw new IllegalArgumentException("PRIVATE format images are not copyable");
+        }
+        if (src.getFormat() == ImageFormat.RAW_PRIVATE) {
+            throw new IllegalArgumentException(
+                    "Copy of RAW_OPAQUE format has not been implemented");
+        }
+        if (src.getFormat() == ImageFormat.RAW_DEPTH) {
+            throw new IllegalArgumentException(
+                    "Copy of RAW_DEPTH format has not been implemented");
+        }
+        if (src.getFormat() == ImageFormat.RAW_DEPTH10) {
+            throw new IllegalArgumentException(
+                    "Copy of RAW_DEPTH10 format has not been implemented");
+        }
+        if (!(dst.getOwner() instanceof ImageWriter)) {
+            throw new IllegalArgumentException("Destination image is not from ImageWriter. Only"
+                    + " the images from ImageWriter are writable");
+        }
+        Size srcSize = new Size(src.getWidth(), src.getHeight());
+        Size dstSize = new Size(dst.getWidth(), dst.getHeight());
+        if (!srcSize.equals(dstSize)) {
+            throw new IllegalArgumentException("source image size " + srcSize + " is different"
+                    + " with " + "destination image size " + dstSize);
+        }
+
+        Plane[] srcPlanes = src.getPlanes();
+        Plane[] dstPlanes = dst.getPlanes();
+        ByteBuffer srcBuffer = null;
+        ByteBuffer dstBuffer = null;
+        for (int i = 0; i < srcPlanes.length; i++) {
+            int srcRowStride = srcPlanes[i].getRowStride();
+            int dstRowStride = dstPlanes[i].getRowStride();
+            srcBuffer = srcPlanes[i].getBuffer();
+            dstBuffer = dstPlanes[i].getBuffer();
+            if (!(srcBuffer.isDirect() && dstBuffer.isDirect())) {
+                throw new IllegalArgumentException("Source and destination ByteBuffers must be"
+                        + " direct byteBuffer!");
+            }
+            if (srcPlanes[i].getPixelStride() != dstPlanes[i].getPixelStride()) {
+                throw new IllegalArgumentException("Source plane image pixel stride " +
+                        srcPlanes[i].getPixelStride() +
+                        " must be same as destination image pixel stride " +
+                        dstPlanes[i].getPixelStride());
+            }
+
+            int srcPos = srcBuffer.position();
+            srcBuffer.rewind();
+            dstBuffer.rewind();
+            if (srcRowStride == dstRowStride) {
+                // Fast path, just copy the content if the byteBuffer all together.
+                dstBuffer.put(srcBuffer);
+            } else {
+                // Source and destination images may have different alignment requirements,
+                // therefore may have different strides. Copy row by row for such case.
+                int srcOffset = srcBuffer.position();
+                int dstOffset = dstBuffer.position();
+                Size effectivePlaneSize = getEffectivePlaneSizeForImage(src, i);
+                int srcByteCount = effectivePlaneSize.getWidth() * srcPlanes[i].getPixelStride();
+                for (int row = 0; row < effectivePlaneSize.getHeight(); row++) {
+                    if (row == effectivePlaneSize.getHeight() - 1) {
+                        // Special case for NV21 backed YUV420_888: need handle the last row
+                        // carefully to avoid memory corruption. Check if we have enough bytes to
+                        // copy.
+                        int remainingBytes = srcBuffer.remaining() - srcOffset;
+                        if (srcByteCount > remainingBytes) {
+                            srcByteCount = remainingBytes;
+                        }
+                    }
+                    directByteBufferCopy(srcBuffer, srcOffset, dstBuffer, dstOffset, srcByteCount);
+                    srcOffset += srcRowStride;
+                    dstOffset += dstRowStride;
+                }
+            }
+
+            srcBuffer.position(srcPos);
+            dstBuffer.rewind();
+        }
+    }
+
+    /**
+     * Return the estimated native allocation size in bytes based on width, height, format,
+     * and number of images.
+     *
+     * <p>This is a very rough estimation and should only be used for native allocation
+     * registration in VM so it can be accounted for during GC.</p>
+     *
+     * @param width The width of the images.
+     * @param height The height of the images.
+     * @param format The format of the images.
+     * @param numImages The number of the images.
+     */
+    public static int getEstimatedNativeAllocBytes(int width, int height, int format,
+            int numImages) {
+        double estimatedBytePerPixel;
+        switch (format) {
+            // 10x compression from RGB_888
+            case ImageFormat.JPEG:
+            case ImageFormat.DEPTH_POINT_CLOUD:
+            case ImageFormat.DEPTH_JPEG:
+            case ImageFormat.HEIC:
+                estimatedBytePerPixel = 0.3;
+                break;
+            case ImageFormat.Y8:
+                estimatedBytePerPixel = 1.0;
+                break;
+            case ImageFormat.RAW10:
+            case ImageFormat.RAW_DEPTH10:
+                estimatedBytePerPixel = 1.25;
+                break;
+            case ImageFormat.YV12:
+            case ImageFormat.YUV_420_888:
+            case ImageFormat.NV21:
+            case ImageFormat.RAW12:
+            case ImageFormat.PRIVATE: // A rough estimate because the real size is unknown.
+                estimatedBytePerPixel = 1.5;
+                break;
+            case ImageFormat.NV16:
+            case PixelFormat.RGB_565:
+            case ImageFormat.YUY2:
+            case ImageFormat.Y16:
+            case ImageFormat.RAW_DEPTH:
+            case ImageFormat.RAW_SENSOR:
+            case ImageFormat.RAW_PRIVATE: // round estimate, real size is unknown
+            case ImageFormat.DEPTH16:
+            case ImageFormat.YCBCR_P010:
+                estimatedBytePerPixel = 2.0;
+                break;
+            case PixelFormat.RGB_888:
+                estimatedBytePerPixel = 3.0;
+                break;
+            case PixelFormat.RGBA_8888:
+            case PixelFormat.RGBX_8888:
+                estimatedBytePerPixel = 4.0;
+                break;
+            default:
+                throw new UnsupportedOperationException(
+                        String.format("Invalid format specified %d", format));
+        }
+
+        return (int)(width * height * estimatedBytePerPixel * numImages);
+    }
+
+    private static Size getEffectivePlaneSizeForImage(Image image, int planeIdx) {
+        switch (image.getFormat()) {
+            case ImageFormat.YCBCR_P010:
+            case ImageFormat.YV12:
+            case ImageFormat.YUV_420_888:
+            case ImageFormat.NV21:
+                if (planeIdx == 0) {
+                    return new Size(image.getWidth(), image.getHeight());
+                } else {
+                    return new Size(image.getWidth() / 2, image.getHeight() / 2);
+                }
+            case ImageFormat.NV16:
+                if (planeIdx == 0) {
+                    return new Size(image.getWidth(), image.getHeight());
+                } else {
+                    return new Size(image.getWidth(), image.getHeight() / 2);
+                }
+            case PixelFormat.RGB_565:
+            case PixelFormat.RGBA_8888:
+            case PixelFormat.RGBX_8888:
+            case PixelFormat.RGB_888:
+            case ImageFormat.JPEG:
+            case ImageFormat.YUY2:
+            case ImageFormat.Y8:
+            case ImageFormat.Y16:
+            case ImageFormat.RAW_SENSOR:
+            case ImageFormat.RAW10:
+            case ImageFormat.RAW12:
+            case ImageFormat.RAW_DEPTH:
+            case ImageFormat.RAW_DEPTH10:
+            case ImageFormat.HEIC:
+                return new Size(image.getWidth(), image.getHeight());
+            case ImageFormat.PRIVATE:
+                return new Size(0, 0);
+            default:
+                throw new UnsupportedOperationException(
+                        String.format("Invalid image format %d", image.getFormat()));
+        }
+    }
+
+    private static void directByteBufferCopy(ByteBuffer srcBuffer, int srcOffset,
+            ByteBuffer dstBuffer, int dstOffset, int srcByteCount) {
+        Memory.memmove(dstBuffer, dstOffset, srcBuffer, srcOffset, srcByteCount);
+    }
+}
diff --git a/android/media/ImageWriter.java b/android/media/ImageWriter.java
new file mode 100644
index 0000000..1b74367
--- /dev/null
+++ b/android/media/ImageWriter.java
@@ -0,0 +1,1001 @@
+/*
+ * Copyright 2015 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.annotation.IntRange;
+import android.annotation.NonNull;
+import android.graphics.GraphicBuffer;
+import android.graphics.ImageFormat;
+import android.graphics.ImageFormat.Format;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.hardware.camera2.params.StreamConfigurationMap;
+import android.hardware.camera2.utils.SurfaceUtils;
+import android.hardware.HardwareBuffer;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Size;
+import android.view.Surface;
+
+import dalvik.system.VMRuntime;
+
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.NioUtils;
+import java.util.List;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * <p>
+ * The ImageWriter class allows an application to produce Image data into a
+ * {@link android.view.Surface}, and have it be consumed by another component
+ * like {@link android.hardware.camera2.CameraDevice CameraDevice}.
+ * </p>
+ * <p>
+ * Several Android API classes can provide input {@link android.view.Surface
+ * Surface} objects for ImageWriter to produce data into, including
+ * {@link MediaCodec MediaCodec} (encoder),
+ * {@link android.hardware.camera2.CameraCaptureSession CameraCaptureSession}
+ * (reprocessing input), {@link ImageReader}, etc.
+ * </p>
+ * <p>
+ * The input Image data is encapsulated in {@link Image} objects. To produce
+ * Image data into a destination {@link android.view.Surface Surface}, the
+ * application can get an input Image via {@link #dequeueInputImage} then write
+ * Image data into it. Multiple such {@link Image} objects can be dequeued at
+ * the same time and queued back in any order, up to the number specified by the
+ * {@code maxImages} constructor parameter.
+ * </p>
+ * <p>
+ * If the application already has an Image from {@link ImageReader}, the
+ * application can directly queue this Image into the ImageWriter (via
+ * {@link #queueInputImage}), potentially with zero buffer copies. This
+ * even works if the image format of the ImageWriter is
+ * {@link ImageFormat#PRIVATE PRIVATE}, and prior to Android P is the only
+ * way to enqueue images into such an ImageWriter. Starting in Android P
+ * private images may also be accessed through their hardware buffers
+ * (when available) through the {@link Image#getHardwareBuffer()} method.
+ * Attempting to access the planes of a private image, will return an
+ * empty array.
+ * </p>
+ * <p>
+ * Once new input Images are queued into an ImageWriter, it's up to the
+ * downstream components (e.g. {@link ImageReader} or
+ * {@link android.hardware.camera2.CameraDevice}) to consume the Images. If the
+ * downstream components cannot consume the Images at least as fast as the
+ * ImageWriter production rate, the {@link #dequeueInputImage} call will
+ * eventually block and the application will have to drop input frames.
+ * </p>
+ * <p>
+ * If the consumer component that provided the input {@link android.view.Surface Surface}
+ * abandons the {@link android.view.Surface Surface}, {@link #queueInputImage queueing}
+ * or {@link #dequeueInputImage dequeueing} an {@link Image} will throw an
+ * {@link IllegalStateException}.
+ * </p>
+ */
+public class ImageWriter implements AutoCloseable {
+    private final Object mListenerLock = new Object();
+    private OnImageReleasedListener mListener;
+    private ListenerHandler mListenerHandler;
+    private long mNativeContext;
+
+    // Field below is used by native code, do not access or modify.
+    private int mWriterFormat;
+
+    private final int mMaxImages;
+    // Keep track of the currently dequeued Image. This need to be thread safe as the images
+    // could be closed by different threads (e.g., application thread and GC thread).
+    private List<Image> mDequeuedImages = new CopyOnWriteArrayList<>();
+    private int mEstimatedNativeAllocBytes;
+
+    /**
+     * <p>
+     * Create a new ImageWriter.
+     * </p>
+     * <p>
+     * The {@code maxImages} parameter determines the maximum number of
+     * {@link Image} objects that can be be dequeued from the
+     * {@code ImageWriter} simultaneously. Requesting more buffers will use up
+     * more memory, so it is important to use only the minimum number necessary.
+     * </p>
+     * <p>
+     * The input Image size and format depend on the Surface that is provided by
+     * the downstream consumer end-point.
+     * </p>
+     *
+     * @param surface The destination Surface this writer produces Image data
+     *            into.
+     * @param maxImages The maximum number of Images the user will want to
+     *            access simultaneously for producing Image data. This should be
+     *            as small as possible to limit memory use. Once maxImages
+     *            Images are dequeued by the user, one of them has to be queued
+     *            back before a new Image can be dequeued for access via
+     *            {@link #dequeueInputImage()}.
+     * @return a new ImageWriter instance.
+     */
+    public static @NonNull ImageWriter newInstance(@NonNull Surface surface,
+            @IntRange(from = 1) int maxImages) {
+        return new ImageWriter(surface, maxImages, ImageFormat.UNKNOWN, -1 /*width*/,
+                -1 /*height*/);
+    }
+
+    /**
+     * <p>
+     * Create a new ImageWriter with given number of max Images, format and producer dimension.
+     * </p>
+     * <p>
+     * The {@code maxImages} parameter determines the maximum number of
+     * {@link Image} objects that can be be dequeued from the
+     * {@code ImageWriter} simultaneously. Requesting more buffers will use up
+     * more memory, so it is important to use only the minimum number necessary.
+     * </p>
+     * <p>
+     * The format specifies the image format of this ImageWriter. The format
+     * from the {@code surface} will be overridden with this format. For example,
+     * if the surface is obtained from a {@link android.graphics.SurfaceTexture}, the default
+     * format may be {@link PixelFormat#RGBA_8888}. If the application creates an ImageWriter
+     * with this surface and {@link ImageFormat#PRIVATE}, this ImageWriter will be able to operate
+     * with {@link ImageFormat#PRIVATE} Images.
+     * </p>
+     * <p>
+     * Note that the consumer end-point may or may not be able to support Images with different
+     * format, for such case, the application should only use this method if the consumer is able
+     * to consume such images.
+     * </p>
+     * <p> The input Image size can also be set by the client. </p>
+     *
+     * @param surface The destination Surface this writer produces Image data
+     *            into.
+     * @param maxImages The maximum number of Images the user will want to
+     *            access simultaneously for producing Image data. This should be
+     *            as small as possible to limit memory use. Once maxImages
+     *            Images are dequeued by the user, one of them has to be queued
+     *            back before a new Image can be dequeued for access via
+     *            {@link #dequeueInputImage()}.
+     * @param format The format of this ImageWriter. It can be any valid format specified by
+     *            {@link ImageFormat} or {@link PixelFormat}.
+     *
+     * @param width Input size width.
+     * @param height Input size height.
+     *
+     * @return a new ImageWriter instance.
+     *
+     * @hide
+     */
+    public static @NonNull ImageWriter newInstance(@NonNull Surface surface,
+            @IntRange(from = 1) int maxImages, @Format int format, int width, int height) {
+        if (!ImageFormat.isPublicFormat(format) && !PixelFormat.isPublicFormat(format)) {
+            throw new IllegalArgumentException("Invalid format is specified: " + format);
+        }
+        return new ImageWriter(surface, maxImages, format, width, height);
+    }
+
+    /**
+     * <p>
+     * Create a new ImageWriter with given number of max Images and format.
+     * </p>
+     * <p>
+     * The {@code maxImages} parameter determines the maximum number of
+     * {@link Image} objects that can be be dequeued from the
+     * {@code ImageWriter} simultaneously. Requesting more buffers will use up
+     * more memory, so it is important to use only the minimum number necessary.
+     * </p>
+     * <p>
+     * The format specifies the image format of this ImageWriter. The format
+     * from the {@code surface} will be overridden with this format. For example,
+     * if the surface is obtained from a {@link android.graphics.SurfaceTexture}, the default
+     * format may be {@link PixelFormat#RGBA_8888}. If the application creates an ImageWriter
+     * with this surface and {@link ImageFormat#PRIVATE}, this ImageWriter will be able to operate
+     * with {@link ImageFormat#PRIVATE} Images.
+     * </p>
+     * <p>
+     * Note that the consumer end-point may or may not be able to support Images with different
+     * format, for such case, the application should only use this method if the consumer is able
+     * to consume such images.
+     * </p>
+     * <p>
+     * The input Image size depends on the Surface that is provided by
+     * the downstream consumer end-point.
+     * </p>
+     *
+     * @param surface The destination Surface this writer produces Image data
+     *            into.
+     * @param maxImages The maximum number of Images the user will want to
+     *            access simultaneously for producing Image data. This should be
+     *            as small as possible to limit memory use. Once maxImages
+     *            Images are dequeued by the user, one of them has to be queued
+     *            back before a new Image can be dequeued for access via
+     *            {@link #dequeueInputImage()}.
+     * @param format The format of this ImageWriter. It can be any valid format specified by
+     *            {@link ImageFormat} or {@link PixelFormat}.
+     *
+     * @return a new ImageWriter instance.
+     */
+    public static @NonNull ImageWriter newInstance(@NonNull Surface surface,
+            @IntRange(from = 1) int maxImages, @Format int format) {
+        if (!ImageFormat.isPublicFormat(format) && !PixelFormat.isPublicFormat(format)) {
+            throw new IllegalArgumentException("Invalid format is specified: " + format);
+        }
+        return new ImageWriter(surface, maxImages, format, -1 /*width*/, -1 /*height*/);
+    }
+
+    /**
+     * @hide
+     */
+    protected ImageWriter(Surface surface, int maxImages, int format, int width, int height) {
+        if (surface == null || maxImages < 1) {
+            throw new IllegalArgumentException("Illegal input argument: surface " + surface
+                    + ", maxImages: " + maxImages);
+        }
+
+        mMaxImages = maxImages;
+
+        // Note that the underlying BufferQueue is working in synchronous mode
+        // to avoid dropping any buffers.
+        mNativeContext = nativeInit(new WeakReference<>(this), surface, maxImages, format, width,
+                height);
+
+        // nativeInit internally overrides UNKNOWN format. So does surface format query after
+        // nativeInit and before getEstimatedNativeAllocBytes().
+        if (format == ImageFormat.UNKNOWN) {
+            format = SurfaceUtils.getSurfaceFormat(surface);
+        }
+        // Several public formats use the same native HAL_PIXEL_FORMAT_BLOB. The native
+        // allocation estimation sequence depends on the public formats values. To avoid
+        // possible errors, convert where necessary.
+        if (format == StreamConfigurationMap.HAL_PIXEL_FORMAT_BLOB) {
+            int surfaceDataspace = SurfaceUtils.getSurfaceDataspace(surface);
+            switch (surfaceDataspace) {
+                case StreamConfigurationMap.HAL_DATASPACE_DEPTH:
+                    format = ImageFormat.DEPTH_POINT_CLOUD;
+                    break;
+                case StreamConfigurationMap.HAL_DATASPACE_DYNAMIC_DEPTH:
+                    format = ImageFormat.DEPTH_JPEG;
+                    break;
+                case StreamConfigurationMap.HAL_DATASPACE_HEIF:
+                    format = ImageFormat.HEIC;
+                    break;
+                default:
+                    format = ImageFormat.JPEG;
+            }
+        }
+        // Estimate the native buffer allocation size and register it so it gets accounted for
+        // during GC. Note that this doesn't include the buffers required by the buffer queue
+        // itself and the buffers requested by the producer.
+        // Only include memory for 1 buffer, since actually accounting for the memory used is
+        // complex, and 1 buffer is enough for the VM to treat the ImageWriter as being of some
+        // size.
+        Size surfSize = SurfaceUtils.getSurfaceSize(surface);
+        mEstimatedNativeAllocBytes =
+                ImageUtils.getEstimatedNativeAllocBytes(surfSize.getWidth(),surfSize.getHeight(),
+                        format, /*buffer count*/ 1);
+        VMRuntime.getRuntime().registerNativeAllocation(mEstimatedNativeAllocBytes);
+    }
+
+    /**
+     * <p>
+     * Maximum number of Images that can be dequeued from the ImageWriter
+     * simultaneously (for example, with {@link #dequeueInputImage()}).
+     * </p>
+     * <p>
+     * An Image is considered dequeued after it's returned by
+     * {@link #dequeueInputImage()} from ImageWriter, and until the Image is
+     * sent back to ImageWriter via {@link #queueInputImage}, or
+     * {@link Image#close()}.
+     * </p>
+     * <p>
+     * Attempting to dequeue more than {@code maxImages} concurrently will
+     * result in the {@link #dequeueInputImage()} function throwing an
+     * {@link IllegalStateException}.
+     * </p>
+     *
+     * @return Maximum number of Images that can be dequeued from this
+     *         ImageWriter.
+     * @see #dequeueInputImage
+     * @see #queueInputImage
+     * @see Image#close
+     */
+    public int getMaxImages() {
+        return mMaxImages;
+    }
+
+    /**
+     * <p>
+     * Dequeue the next available input Image for the application to produce
+     * data into.
+     * </p>
+     * <p>
+     * This method requests a new input Image from ImageWriter. The application
+     * owns this Image after this call. Once the application fills the Image
+     * data, it is expected to return this Image back to ImageWriter for
+     * downstream consumer components (e.g.
+     * {@link android.hardware.camera2.CameraDevice}) to consume. The Image can
+     * be returned to ImageWriter via {@link #queueInputImage} or
+     * {@link Image#close()}.
+     * </p>
+     * <p>
+     * This call will block if all available input images have been queued by
+     * the application and the downstream consumer has not yet consumed any.
+     * When an Image is consumed by the downstream consumer and released, an
+     * {@link OnImageReleasedListener#onImageReleased} callback will be fired,
+     * which indicates that there is one input Image available. For non-
+     * {@link ImageFormat#PRIVATE PRIVATE} formats (
+     * {@link ImageWriter#getFormat()} != {@link ImageFormat#PRIVATE}), it is
+     * recommended to dequeue the next Image only after this callback is fired,
+     * in the steady state.
+     * </p>
+     * <p>
+     * If the format of ImageWriter is {@link ImageFormat#PRIVATE PRIVATE} (
+     * {@link ImageWriter#getFormat()} == {@link ImageFormat#PRIVATE}), the
+     * image buffer is accessible to the application only through the hardware
+     * buffer obtained through {@link Image#getHardwareBuffer()}. (On Android
+     * versions prior to P, dequeueing private buffers will cause an
+     * {@link IllegalStateException} to be thrown). Alternatively,
+     * the application can acquire images from some other component (e.g. an
+     * {@link ImageReader}), and queue them directly to this ImageWriter via the
+     * {@link ImageWriter#queueInputImage queueInputImage()} method.
+     * </p>
+     *
+     * @return The next available input Image from this ImageWriter.
+     * @throws IllegalStateException if {@code maxImages} Images are currently
+     *             dequeued, or the input {@link android.view.Surface Surface}
+     *             has been abandoned by the consumer component that provided
+     *             the {@link android.view.Surface Surface}. Prior to Android
+     *             P, throws if the ImageWriter format is
+     *             {@link ImageFormat#PRIVATE PRIVATE}.
+     * @see #queueInputImage
+     * @see Image#close
+     */
+    public Image dequeueInputImage() {
+        if (mDequeuedImages.size() >= mMaxImages) {
+            throw new IllegalStateException("Already dequeued max number of Images " + mMaxImages);
+        }
+        WriterSurfaceImage newImage = new WriterSurfaceImage(this);
+        nativeDequeueInputImage(mNativeContext, newImage);
+        mDequeuedImages.add(newImage);
+        newImage.mIsImageValid = true;
+        return newImage;
+    }
+
+    /**
+     * <p>
+     * Queue an input {@link Image} back to ImageWriter for the downstream
+     * consumer to access.
+     * </p>
+     * <p>
+     * The input {@link Image} could be from ImageReader (acquired via
+     * {@link ImageReader#acquireNextImage} or
+     * {@link ImageReader#acquireLatestImage}), or from this ImageWriter
+     * (acquired via {@link #dequeueInputImage}). In the former case, the Image
+     * data will be moved to this ImageWriter. Note that the Image properties
+     * (size, format, strides, etc.) must be the same as the properties of the
+     * images dequeued from this ImageWriter. In the latter case, the application has
+     * filled the input image with data. This method then passes the filled
+     * buffer to the downstream consumer. In both cases, it's up to the caller
+     * to ensure that the Image timestamp (in nanoseconds) is correctly set, as
+     * the downstream component may want to use it to indicate the Image data
+     * capture time.
+     * </p>
+     * <p>
+     * After this method is called and the downstream consumer consumes and
+     * releases the Image, an {@link OnImageReleasedListener#onImageReleased}
+     * callback will fire. The application can use this callback to avoid
+     * sending Images faster than the downstream consumer processing rate in
+     * steady state.
+     * </p>
+     * <p>
+     * Passing in an Image from some other component (e.g. an
+     * {@link ImageReader}) requires a free input Image from this ImageWriter as
+     * the destination. In this case, this call will block, as
+     * {@link #dequeueInputImage} does, if there are no free Images available.
+     * To avoid blocking, the application should ensure that there is at least
+     * one free Image available in this ImageWriter before calling this method.
+     * </p>
+     * <p>
+     * After this call, the input Image is no longer valid for further access,
+     * as if the Image is {@link Image#close closed}. Attempting to access the
+     * {@link ByteBuffer ByteBuffers} returned by an earlier
+     * {@link Image.Plane#getBuffer Plane#getBuffer} call will result in an
+     * {@link IllegalStateException}.
+     * </p>
+     *
+     * @param image The Image to be queued back to ImageWriter for future
+     *            consumption.
+     * @throws IllegalStateException if the image was already queued previously,
+     *            or the image was aborted previously, or the input
+     *            {@link android.view.Surface Surface} has been abandoned by the
+     *            consumer component that provided the
+     *            {@link android.view.Surface Surface}.
+     * @see #dequeueInputImage()
+     */
+    public void queueInputImage(Image image) {
+        if (image == null) {
+            throw new IllegalArgumentException("image shouldn't be null");
+        }
+        boolean ownedByMe = isImageOwnedByMe(image);
+        if (ownedByMe && !(((WriterSurfaceImage) image).mIsImageValid)) {
+            throw new IllegalStateException("Image from ImageWriter is invalid");
+        }
+
+        // For images from other components that have non-null owner, need to detach first,
+        // then attach. Images without owners must already be attachable.
+        if (!ownedByMe) {
+            if ((image.getOwner() instanceof ImageReader)) {
+                ImageReader prevOwner = (ImageReader) image.getOwner();
+
+                prevOwner.detachImage(image);
+            } else if (image.getOwner() != null) {
+                throw new IllegalArgumentException("Only images from ImageReader can be queued to"
+                        + " ImageWriter, other image source is not supported yet!");
+            }
+
+            attachAndQueueInputImage(image);
+            // This clears the native reference held by the original owner.
+            // When this Image is detached later by this ImageWriter, the
+            // native memory won't be leaked.
+            image.close();
+            return;
+        }
+
+        Rect crop = image.getCropRect();
+        nativeQueueInputImage(mNativeContext, image, image.getTimestamp(), crop.left, crop.top,
+                crop.right, crop.bottom, image.getTransform(), image.getScalingMode());
+
+        /**
+         * Only remove and cleanup the Images that are owned by this
+         * ImageWriter. Images detached from other owners are only temporarily
+         * owned by this ImageWriter and will be detached immediately after they
+         * are released by downstream consumers, so there is no need to keep
+         * track of them in mDequeuedImages.
+         */
+        if (ownedByMe) {
+            mDequeuedImages.remove(image);
+            // Do not call close here, as close is essentially cancel image.
+            WriterSurfaceImage wi = (WriterSurfaceImage) image;
+            wi.clearSurfacePlanes();
+            wi.mIsImageValid = false;
+        }
+    }
+
+    /**
+     * Get the ImageWriter format.
+     * <p>
+     * This format may be different than the Image format returned by
+     * {@link Image#getFormat()}. However, if the ImageWriter format is
+     * {@link ImageFormat#PRIVATE PRIVATE}, calling {@link #dequeueInputImage()}
+     * will result in an {@link IllegalStateException}.
+     * </p>
+     *
+     * @return The ImageWriter format.
+     */
+    public int getFormat() {
+        return mWriterFormat;
+    }
+
+    /**
+     * ImageWriter callback interface, used to to asynchronously notify the
+     * application of various ImageWriter events.
+     */
+    public interface OnImageReleasedListener {
+        /**
+         * <p>
+         * Callback that is called when an input Image is released back to
+         * ImageWriter after the data consumption.
+         * </p>
+         * <p>
+         * The client can use this callback to be notified that an input Image
+         * has been consumed and released by the downstream consumer. More
+         * specifically, this callback will be fired for below cases:
+         * <li>The application dequeues an input Image via the
+         * {@link ImageWriter#dequeueInputImage dequeueInputImage()} method,
+         * uses it, and then queues it back to this ImageWriter via the
+         * {@link ImageWriter#queueInputImage queueInputImage()} method. After
+         * the downstream consumer uses and releases this image to this
+         * ImageWriter, this callback will be fired. This image will be
+         * available to be dequeued after this callback.</li>
+         * <li>The application obtains an Image from some other component (e.g.
+         * an {@link ImageReader}), uses it, and then queues it to this
+         * ImageWriter via {@link ImageWriter#queueInputImage queueInputImage()}.
+         * After the downstream consumer uses and releases this image to this
+         * ImageWriter, this callback will be fired.</li>
+         * </p>
+         *
+         * @param writer the ImageWriter the callback is associated with.
+         * @see ImageWriter
+         * @see Image
+         */
+        void onImageReleased(ImageWriter writer);
+    }
+
+    /**
+     * Register a listener to be invoked when an input Image is returned to the
+     * ImageWriter.
+     *
+     * @param listener The listener that will be run.
+     * @param handler The handler on which the listener should be invoked, or
+     *            null if the listener should be invoked on the calling thread's
+     *            looper.
+     * @throws IllegalArgumentException If no handler specified and the calling
+     *             thread has no looper.
+     */
+    public void setOnImageReleasedListener(OnImageReleasedListener listener, Handler handler) {
+        synchronized (mListenerLock) {
+            if (listener != null) {
+                Looper looper = handler != null ? handler.getLooper() : Looper.myLooper();
+                if (looper == null) {
+                    throw new IllegalArgumentException(
+                            "handler is null but the current thread is not a looper");
+                }
+                if (mListenerHandler == null || mListenerHandler.getLooper() != looper) {
+                    mListenerHandler = new ListenerHandler(looper);
+                }
+                mListener = listener;
+            } else {
+                mListener = null;
+                mListenerHandler = null;
+            }
+        }
+    }
+
+    /**
+     * Free up all the resources associated with this ImageWriter.
+     * <p>
+     * After calling this method, this ImageWriter cannot be used. Calling any
+     * methods on this ImageWriter and Images previously provided by
+     * {@link #dequeueInputImage()} will result in an
+     * {@link IllegalStateException}, and attempting to write into
+     * {@link ByteBuffer ByteBuffers} returned by an earlier
+     * {@link Image.Plane#getBuffer Plane#getBuffer} call will have undefined
+     * behavior.
+     * </p>
+     */
+    @Override
+    public void close() {
+        setOnImageReleasedListener(null, null);
+        for (Image image : mDequeuedImages) {
+            image.close();
+        }
+        mDequeuedImages.clear();
+        nativeClose(mNativeContext);
+        mNativeContext = 0;
+
+        if (mEstimatedNativeAllocBytes > 0) {
+            VMRuntime.getRuntime().registerNativeFree(mEstimatedNativeAllocBytes);
+            mEstimatedNativeAllocBytes = 0;
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * <p>
+     * Attach and queue input Image to this ImageWriter.
+     * </p>
+     * <p>
+     * When the format of an Image is {@link ImageFormat#PRIVATE PRIVATE}, or
+     * the source Image is so large that copying its data is too expensive, this
+     * method can be used to migrate the source Image into ImageWriter without a
+     * data copy, and then queue it to this ImageWriter. The source Image must
+     * be detached from its previous owner already, or this call will throw an
+     * {@link IllegalStateException}.
+     * </p>
+     * <p>
+     * After this call, the ImageWriter takes ownership of this Image. This
+     * ownership will automatically be removed from this writer after the
+     * consumer releases this Image, that is, after
+     * {@link OnImageReleasedListener#onImageReleased}. The caller is responsible for
+     * closing this Image through {@link Image#close()} to free up the resources
+     * held by this Image.
+     * </p>
+     *
+     * @param image The source Image to be attached and queued into this
+     *            ImageWriter for downstream consumer to use.
+     * @throws IllegalStateException if the Image is not detached from its
+     *             previous owner, or the Image is already attached to this
+     *             ImageWriter, or the source Image is invalid.
+     */
+    private void attachAndQueueInputImage(Image image) {
+        if (image == null) {
+            throw new IllegalArgumentException("image shouldn't be null");
+        }
+        if (isImageOwnedByMe(image)) {
+            throw new IllegalArgumentException(
+                    "Can not attach an image that is owned ImageWriter already");
+        }
+        /**
+         * Throw ISE if the image is not attachable, which means that it is
+         * either owned by other entity now, or completely non-attachable (some
+         * stand-alone images are not backed by native gralloc buffer, thus not
+         * attachable).
+         */
+        if (!image.isAttachable()) {
+            throw new IllegalStateException("Image was not detached from last owner, or image "
+                    + " is not detachable");
+        }
+
+        // TODO: what if attach failed, throw RTE or detach a slot then attach?
+        // need do some cleanup to make sure no orphaned
+        // buffer caused leak.
+        Rect crop = image.getCropRect();
+        if (image.getNativeContext() != 0) {
+            nativeAttachAndQueueImage(mNativeContext, image.getNativeContext(), image.getFormat(),
+                    image.getTimestamp(), crop.left, crop.top, crop.right, crop.bottom,
+                    image.getTransform(), image.getScalingMode());
+        } else {
+            GraphicBuffer gb = GraphicBuffer.createFromHardwareBuffer(image.getHardwareBuffer());
+            nativeAttachAndQueueGraphicBuffer(mNativeContext, gb, image.getFormat(),
+                    image.getTimestamp(), crop.left, crop.top, crop.right, crop.bottom,
+                    image.getTransform(), image.getScalingMode());
+            gb.destroy();
+            image.close();
+        }
+    }
+
+    /**
+     * This custom handler runs asynchronously so callbacks don't get queued
+     * behind UI messages.
+     */
+    private final class ListenerHandler extends Handler {
+        public ListenerHandler(Looper looper) {
+            super(looper, null, true /* async */);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            OnImageReleasedListener listener;
+            synchronized (mListenerLock) {
+                listener = mListener;
+            }
+            if (listener != null) {
+                listener.onImageReleased(ImageWriter.this);
+            }
+        }
+    }
+
+    /**
+     * Called from Native code when an Event happens. This may be called from an
+     * arbitrary Binder thread, so access to the ImageWriter must be
+     * synchronized appropriately.
+     */
+    private static void postEventFromNative(Object selfRef) {
+        @SuppressWarnings("unchecked")
+        WeakReference<ImageWriter> weakSelf = (WeakReference<ImageWriter>) selfRef;
+        final ImageWriter iw = weakSelf.get();
+        if (iw == null) {
+            return;
+        }
+
+        final Handler handler;
+        synchronized (iw.mListenerLock) {
+            handler = iw.mListenerHandler;
+        }
+        if (handler != null) {
+            handler.sendEmptyMessage(0);
+        }
+    }
+
+    /**
+     * <p>
+     * Abort the Images that were dequeued from this ImageWriter, and return
+     * them to this writer for reuse.
+     * </p>
+     * <p>
+     * This method is used for the cases where the application dequeued the
+     * Image, may have filled the data, but does not want the downstream
+     * component to consume it. The Image will be returned to this ImageWriter
+     * for reuse after this call, and the ImageWriter will immediately have an
+     * Image available to be dequeued. This aborted Image will be invisible to
+     * the downstream consumer, as if nothing happened.
+     * </p>
+     *
+     * @param image The Image to be aborted.
+     * @see #dequeueInputImage()
+     * @see Image#close()
+     */
+    private void abortImage(Image image) {
+        if (image == null) {
+            throw new IllegalArgumentException("image shouldn't be null");
+        }
+
+        if (!mDequeuedImages.contains(image)) {
+            throw new IllegalStateException("It is illegal to abort some image that is not"
+                    + " dequeued yet");
+        }
+
+        WriterSurfaceImage wi = (WriterSurfaceImage) image;
+        if (!wi.mIsImageValid) {
+            return;
+        }
+
+        /**
+         * We only need abort Images that are owned and dequeued by ImageWriter.
+         * For attached Images, no need to abort, as there are only two cases:
+         * attached + queued successfully, and attach failed. Neither of the
+         * cases need abort.
+         */
+        cancelImage(mNativeContext, image);
+        mDequeuedImages.remove(image);
+        wi.clearSurfacePlanes();
+        wi.mIsImageValid = false;
+    }
+
+    private boolean isImageOwnedByMe(Image image) {
+        if (!(image instanceof WriterSurfaceImage)) {
+            return false;
+        }
+        WriterSurfaceImage wi = (WriterSurfaceImage) image;
+        if (wi.getOwner() != this) {
+            return false;
+        }
+
+        return true;
+    }
+
+    private static class WriterSurfaceImage extends android.media.Image {
+        private ImageWriter mOwner;
+        // This field is used by native code, do not access or modify.
+        private long mNativeBuffer;
+        private int mNativeFenceFd = -1;
+        private SurfacePlane[] mPlanes;
+        private int mHeight = -1;
+        private int mWidth = -1;
+        private int mFormat = -1;
+        // When this default timestamp is used, timestamp for the input Image
+        // will be generated automatically when queueInputBuffer is called.
+        private final long DEFAULT_TIMESTAMP = Long.MIN_VALUE;
+        private long mTimestamp = DEFAULT_TIMESTAMP;
+
+        private int mTransform = 0; //Default no transform
+        private int mScalingMode = 0; //Default frozen scaling mode
+
+        public WriterSurfaceImage(ImageWriter writer) {
+            mOwner = writer;
+        }
+
+        @Override
+        public int getFormat() {
+            throwISEIfImageIsInvalid();
+
+            if (mFormat == -1) {
+                mFormat = nativeGetFormat();
+            }
+            return mFormat;
+        }
+
+        @Override
+        public int getWidth() {
+            throwISEIfImageIsInvalid();
+
+            if (mWidth == -1) {
+                mWidth = nativeGetWidth();
+            }
+
+            return mWidth;
+        }
+
+        @Override
+        public int getHeight() {
+            throwISEIfImageIsInvalid();
+
+            if (mHeight == -1) {
+                mHeight = nativeGetHeight();
+            }
+
+            return mHeight;
+        }
+
+        @Override
+        public int getTransform() {
+            throwISEIfImageIsInvalid();
+
+            return mTransform;
+        }
+
+        @Override
+        public int getScalingMode() {
+            throwISEIfImageIsInvalid();
+
+            return mScalingMode;
+        }
+
+        @Override
+        public long getTimestamp() {
+            throwISEIfImageIsInvalid();
+
+            return mTimestamp;
+        }
+
+        @Override
+        public void setTimestamp(long timestamp) {
+            throwISEIfImageIsInvalid();
+
+            mTimestamp = timestamp;
+        }
+
+        @Override
+        public HardwareBuffer getHardwareBuffer() {
+            throwISEIfImageIsInvalid();
+
+            return nativeGetHardwareBuffer();
+        }
+
+        @Override
+        public Plane[] getPlanes() {
+            throwISEIfImageIsInvalid();
+
+            if (mPlanes == null) {
+                int numPlanes = ImageUtils.getNumPlanesForFormat(getFormat());
+                mPlanes = nativeCreatePlanes(numPlanes, getOwner().getFormat());
+            }
+
+            return mPlanes.clone();
+        }
+
+        @Override
+        public boolean isAttachable() {
+            throwISEIfImageIsInvalid();
+            // Don't allow Image to be detached from ImageWriter for now, as no
+            // detach API is exposed.
+            return false;
+        }
+
+        @Override
+        ImageWriter getOwner() {
+            throwISEIfImageIsInvalid();
+
+            return mOwner;
+        }
+
+        @Override
+        long getNativeContext() {
+            throwISEIfImageIsInvalid();
+
+            return mNativeBuffer;
+        }
+
+        @Override
+        public void close() {
+            if (mIsImageValid) {
+                getOwner().abortImage(this);
+            }
+        }
+
+        @Override
+        protected final void finalize() throws Throwable {
+            try {
+                close();
+            } finally {
+                super.finalize();
+            }
+        }
+
+        private void clearSurfacePlanes() {
+            if (mIsImageValid && mPlanes != null) {
+                for (int i = 0; i < mPlanes.length; i++) {
+                    if (mPlanes[i] != null) {
+                        mPlanes[i].clearBuffer();
+                        mPlanes[i] = null;
+                    }
+                }
+            }
+        }
+
+        private class SurfacePlane extends android.media.Image.Plane {
+            private ByteBuffer mBuffer;
+            final private int mPixelStride;
+            final private int mRowStride;
+
+            // SurfacePlane instance is created by native code when SurfaceImage#getPlanes() is
+            // called
+            private SurfacePlane(int rowStride, int pixelStride, ByteBuffer buffer) {
+                mRowStride = rowStride;
+                mPixelStride = pixelStride;
+                mBuffer = buffer;
+                /**
+                 * Set the byteBuffer order according to host endianness (native
+                 * order), otherwise, the byteBuffer order defaults to
+                 * ByteOrder.BIG_ENDIAN.
+                 */
+                mBuffer.order(ByteOrder.nativeOrder());
+            }
+
+            @Override
+            public int getRowStride() {
+                throwISEIfImageIsInvalid();
+                return mRowStride;
+            }
+
+            @Override
+            public int getPixelStride() {
+                throwISEIfImageIsInvalid();
+                return mPixelStride;
+            }
+
+            @Override
+            public ByteBuffer getBuffer() {
+                throwISEIfImageIsInvalid();
+                return mBuffer;
+            }
+
+            private void clearBuffer() {
+                // Need null check first, as the getBuffer() may not be called
+                // before an Image is closed.
+                if (mBuffer == null) {
+                    return;
+                }
+
+                if (mBuffer.isDirect()) {
+                    NioUtils.freeDirectBuffer(mBuffer);
+                }
+                mBuffer = null;
+            }
+
+        }
+
+        // Create the SurfacePlane object and fill the information
+        private synchronized native SurfacePlane[] nativeCreatePlanes(int numPlanes, int writerFmt);
+
+        private synchronized native int nativeGetWidth();
+
+        private synchronized native int nativeGetHeight();
+
+        private synchronized native int nativeGetFormat();
+
+        private synchronized native HardwareBuffer nativeGetHardwareBuffer();
+    }
+
+    // Native implemented ImageWriter methods.
+    private synchronized native long nativeInit(Object weakSelf, Surface surface, int maxImgs,
+            int format, int width, int height);
+
+    private synchronized native void nativeClose(long nativeCtx);
+
+    private synchronized native void nativeDequeueInputImage(long nativeCtx, Image wi);
+
+    private synchronized native void nativeQueueInputImage(long nativeCtx, Image image,
+            long timestampNs, int left, int top, int right, int bottom, int transform,
+            int scalingMode);
+
+    private synchronized native int nativeAttachAndQueueImage(long nativeCtx,
+            long imageNativeBuffer, int imageFormat, long timestampNs, int left,
+            int top, int right, int bottom, int transform, int scalingMode);
+    private synchronized native int nativeAttachAndQueueGraphicBuffer(long nativeCtx,
+            GraphicBuffer graphicBuffer, int imageFormat, long timestampNs, int left,
+            int top, int right, int bottom, int transform, int scalingMode);
+
+    private synchronized native void cancelImage(long nativeCtx, Image image);
+
+    /**
+     * We use a class initializer to allow the native code to cache some field
+     * offsets.
+     */
+    private static native void nativeClassInit();
+
+    static {
+        System.loadLibrary("media_jni");
+        nativeClassInit();
+    }
+}
diff --git a/android/media/JetPlayer.java b/android/media/JetPlayer.java
new file mode 100644
index 0000000..875c6f5
--- /dev/null
+++ b/android/media/JetPlayer.java
@@ -0,0 +1,596 @@
+/*
+ * Copyright (C) 2008 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.compat.annotation.UnsupportedAppUsage;
+import android.content.res.AssetFileDescriptor;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.AndroidRuntimeException;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.lang.ref.WeakReference;
+
+/**
+ * JetPlayer provides access to JET content playback and control.
+ * 
+ * <p>Please refer to the JET Creator User Manual for a presentation of the JET interactive
+ * music concept and how to use the JetCreator tool to create content to be player by JetPlayer.
+ * 
+ * <p>Use of the JetPlayer class is based around the playback of a number of JET segments
+ * sequentially added to a playback FIFO queue. The rendering of the MIDI content stored in each
+ * segment can be dynamically affected by two mechanisms:
+ * <ul>
+ * <li>tracks in a segment can be muted or unmuted at any moment, individually or through
+ *    a mask (to change the mute state of multiple tracks at once)</li>
+ * <li>parts of tracks in a segment can be played at predefined points in the segment, in order
+ *    to maintain synchronization with the other tracks in the segment. This is achieved through
+ *    the notion of "clips", which can be triggered at any time, but that will play only at the
+ *    right time, as authored in the corresponding JET file.</li>
+ * </ul>
+ * As a result of the rendering and playback of the JET segments, the user of the JetPlayer instance
+ * can receive notifications from the JET engine relative to:
+ * <ul>
+ * <li>the playback state,</li>
+ * <li>the number of segments left to play in the queue,</li>
+ * <li>application controller events (CC80-83) to mark points in the MIDI segments.</li>
+ * </ul>
+ * Use {@link #getJetPlayer()} to construct a JetPlayer instance. JetPlayer is a singleton class.
+ * </p>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about how to use JetPlayer, read the
+ * <a href="{@docRoot}guide/topics/media/jetplayer.html">JetPlayer</a> developer guide.</p></div>
+ */
+public class JetPlayer
+{    
+    //--------------------------------------------
+    // Constants
+    //------------------------
+    /**
+     * The maximum number of simultaneous tracks. Use {@link #getMaxTracks()} to
+     * access this value.
+     */
+    private static int MAXTRACKS = 32;
+        
+    // to keep in sync with the JetPlayer class constants
+    // defined in frameworks/base/include/media/JetPlayer.h
+    private static final int JET_EVENT                   = 1;
+    private static final int JET_USERID_UPDATE           = 2;
+    private static final int JET_NUMQUEUEDSEGMENT_UPDATE = 3;
+    private static final int JET_PAUSE_UPDATE            = 4;
+    
+    // to keep in sync with external/sonivox/arm-wt-22k/lib_src/jet_data.h
+    // Encoding of event information on 32 bits
+    private static final int JET_EVENT_VAL_MASK    = 0x0000007f; // mask for value
+    private static final int JET_EVENT_CTRL_MASK   = 0x00003f80; // mask for controller
+    private static final int JET_EVENT_CHAN_MASK   = 0x0003c000; // mask for channel
+    private static final int JET_EVENT_TRACK_MASK  = 0x00fc0000; // mask for track number
+    private static final int JET_EVENT_SEG_MASK    = 0xff000000; // mask for segment ID
+    private static final int JET_EVENT_CTRL_SHIFT  = 7;  // shift to get controller number to bit 0
+    private static final int JET_EVENT_CHAN_SHIFT  = 14; // shift to get MIDI channel to bit 0
+    private static final int JET_EVENT_TRACK_SHIFT = 18; // shift to get track ID to bit 0
+    private static final int JET_EVENT_SEG_SHIFT   = 24; // shift to get segment ID to bit 0
+    
+    // to keep in sync with values used in external/sonivox/arm-wt-22k/Android.mk
+    // Jet rendering audio parameters
+    private static final int JET_OUTPUT_RATE = 22050; // _SAMPLE_RATE_22050 in Android.mk
+    private static final int JET_OUTPUT_CHANNEL_CONFIG =
+            AudioFormat.CHANNEL_OUT_STEREO; // NUM_OUTPUT_CHANNELS=2 in Android.mk
+
+    
+    //--------------------------------------------
+    // Member variables
+    //------------------------
+    /**
+     * Handler for jet events and status updates coming from the native code
+     */
+    private NativeEventHandler mEventHandler = null;
+    
+    /**
+     * Looper associated with the thread that creates the AudioTrack instance
+     */
+    private Looper mInitializationLooper = null;
+    
+    /**
+     * Lock to protect the event listener updates against event notifications
+     */
+    private final Object mEventListenerLock = new Object();
+    
+    private OnJetEventListener mJetEventListener = null;
+    
+    private static JetPlayer singletonRef;
+    
+    static {
+        System.loadLibrary("media_jni");
+    }
+    
+    //--------------------------------
+    // Used exclusively by native code
+    //--------------------
+    /** 
+     * Accessed by native methods: provides access to C++ JetPlayer object 
+     */
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private long mNativePlayerInJavaObj;
+
+    
+    //--------------------------------------------
+    // Constructor, finalize
+    //------------------------
+    /**
+     * Factory method for the JetPlayer class.
+     * @return the singleton JetPlayer instance
+     */
+    public static JetPlayer getJetPlayer() {
+        if (singletonRef == null) {
+            singletonRef = new JetPlayer();
+        }
+        return singletonRef;
+    }
+    
+    /**
+     * Cloning a JetPlayer instance is not supported. Calling clone() will generate an exception.
+     */
+    public Object clone() throws CloneNotSupportedException {
+        // JetPlayer is a singleton class,
+        // so you can't clone a JetPlayer instance
+        throw new CloneNotSupportedException();    
+    }
+    
+
+    private JetPlayer() {
+
+        // remember which looper is associated with the JetPlayer instanciation
+        if ((mInitializationLooper = Looper.myLooper()) == null) {
+            mInitializationLooper = Looper.getMainLooper();
+        }
+        
+        int buffSizeInBytes = AudioTrack.getMinBufferSize(JET_OUTPUT_RATE,
+                JET_OUTPUT_CHANNEL_CONFIG, AudioFormat.ENCODING_PCM_16BIT);
+        
+        if ((buffSizeInBytes != AudioTrack.ERROR) 
+                && (buffSizeInBytes != AudioTrack.ERROR_BAD_VALUE)) {
+                            
+            native_setup(new WeakReference<JetPlayer>(this),
+                    JetPlayer.getMaxTracks(),
+                    // bytes to frame conversion:
+                    // 1200 == minimum buffer size in frames on generation 1 hardware
+                    Math.max(1200, buffSizeInBytes /
+                            (AudioFormat.getBytesPerSample(AudioFormat.ENCODING_PCM_16BIT) *
+                            2 /*channels*/)));
+        }
+    }
+    
+    
+    protected void finalize() { 
+        native_finalize(); 
+    }
+    
+    
+    /**
+     * Stops the current JET playback, and releases all associated native resources.
+     * The object can no longer be used and the reference should be set to null
+     * after a call to release().
+     */
+    public void release() {
+        native_release();
+        singletonRef = null;
+    }
+    
+    
+    //--------------------------------------------
+    // Getters
+    //------------------------
+    /**
+     * Returns the maximum number of simultaneous MIDI tracks supported by JetPlayer
+     */
+    public static int getMaxTracks() {
+        return JetPlayer.MAXTRACKS;
+    }
+    
+    
+    //--------------------------------------------
+    // Jet functionality
+    //------------------------
+    /**
+     * Loads a .jet file from a given path.
+     * @param path the path to the .jet file, for instance "/sdcard/mygame/music.jet".
+     * @return true if loading the .jet file was successful, false if loading failed.
+     */
+    public boolean loadJetFile(String path) {
+        return native_loadJetFromFile(path);
+    }
+    
+    
+    /**
+     * Loads a .jet file from an asset file descriptor.
+     * @param afd the asset file descriptor.
+     * @return true if loading the .jet file was successful, false if loading failed.
+     */
+    public boolean loadJetFile(AssetFileDescriptor afd) {
+        long len = afd.getLength();
+        if (len < 0) {
+            throw new AndroidRuntimeException("no length for fd");
+        }
+        return native_loadJetFromFileD(
+                afd.getFileDescriptor(), afd.getStartOffset(), len);
+    }
+    
+    /**
+     * Closes the resource containing the JET content.
+     * @return true if successfully closed, false otherwise.
+     */
+    public boolean closeJetFile() {
+        return native_closeJetFile();
+    }
+    
+    
+    /**
+     * Starts playing the JET segment queue.
+     * @return true if rendering and playback is successfully started, false otherwise.
+     */
+    public boolean play() {
+        return native_playJet();
+    }
+    
+    
+    /**
+     * Pauses the playback of the JET segment queue.
+     * @return true if rendering and playback is successfully paused, false otherwise.
+     */
+    public boolean pause() {
+        return native_pauseJet();
+    }
+    
+    
+    /**
+     * Queues the specified segment in the JET queue.
+     * @param segmentNum the identifier of the segment.
+     * @param libNum the index of the sound bank associated with the segment. Use -1 to indicate
+     *    that no sound bank (DLS file) is associated with this segment, in which case JET will use
+     *    the General MIDI library.
+     * @param repeatCount the number of times the segment will be repeated. 0 means the segment will
+     *    only play once. -1 means the segment will repeat indefinitely.
+     * @param transpose the amount of pitch transposition. Set to 0 for normal playback. 
+     *    Range is -12 to +12.
+     * @param muteFlags a bitmask to specify which MIDI tracks will be muted during playback. Bit 0
+     *    affects track 0, bit 1 affects track 1 etc.
+     * @param userID a value specified by the application that uniquely identifies the segment. 
+     *    this value is received in the
+     *    {@link OnJetEventListener#onJetUserIdUpdate(JetPlayer, int, int)} event listener method.
+     *    Normally, the application will keep a byte value that is incremented each time a new
+     *    segment is queued up. This can be used to look up any special characteristics of that
+     *    track including trigger clips and mute flags.
+     * @return true if the segment was successfully queued, false if the queue is full or if the
+     *    parameters are invalid.
+     */
+    public boolean queueJetSegment(int segmentNum, int libNum, int repeatCount,
+        int transpose, int muteFlags, byte userID) {
+        return native_queueJetSegment(segmentNum, libNum, repeatCount, 
+                transpose, muteFlags, userID);
+    }
+    
+    
+    /**
+     * Queues the specified segment in the JET queue.
+     * @param segmentNum the identifier of the segment.
+     * @param libNum the index of the soundbank associated with the segment. Use -1 to indicate that
+     *    no sound bank (DLS file) is associated with this segment, in which case JET will use
+     *    the General MIDI library.
+     * @param repeatCount the number of times the segment will be repeated. 0 means the segment will
+     *    only play once. -1 means the segment will repeat indefinitely.
+     * @param transpose the amount of pitch transposition. Set to 0 for normal playback. 
+     *    Range is -12 to +12.
+     * @param muteArray an array of booleans to specify which MIDI tracks will be muted during
+     *    playback. The value at index 0 affects track 0, value at index 1 affects track 1 etc. 
+     *    The length of the array must be {@link #getMaxTracks()} for the call to succeed.
+     * @param userID a value specified by the application that uniquely identifies the segment. 
+     *    this value is received in the
+     *    {@link OnJetEventListener#onJetUserIdUpdate(JetPlayer, int, int)} event listener method.
+     *    Normally, the application will keep a byte value that is incremented each time a new
+     *    segment is queued up. This can be used to look up any special characteristics of that
+     *    track including trigger clips and mute flags.
+     * @return true if the segment was successfully queued, false if the queue is full or if the
+     *    parameters are invalid.
+     */
+    public boolean queueJetSegmentMuteArray(int segmentNum, int libNum, int repeatCount,
+            int transpose, boolean[] muteArray, byte userID) {
+        if (muteArray.length != JetPlayer.getMaxTracks()) {
+            return false;
+        }
+        return native_queueJetSegmentMuteArray(segmentNum, libNum, repeatCount,
+                transpose, muteArray, userID);
+    }
+    
+    
+    /**
+     * Modifies the mute flags.
+     * @param muteFlags a bitmask to specify which MIDI tracks are muted. Bit 0 affects track 0,
+     *    bit 1 affects track 1 etc.
+     * @param sync if false, the new mute flags will be applied as soon as possible by the JET
+     *    render and playback engine. If true, the mute flags will be updated at the start of the
+     *    next segment. If the segment is repeated, the flags will take effect the next time 
+     *    segment is repeated.
+     * @return true if the mute flags were successfully updated, false otherwise.
+     */
+    public boolean setMuteFlags(int muteFlags, boolean sync) {
+        return native_setMuteFlags(muteFlags, sync);
+    }
+    
+    
+    /**
+     * Modifies the mute flags for the current active segment.
+     * @param muteArray an array of booleans to specify which MIDI tracks are muted. The value at
+     *    index 0 affects track 0, value at index 1 affects track 1 etc. 
+     *    The length of the array must be {@link #getMaxTracks()} for the call to succeed.
+     * @param sync if false, the new mute flags will be applied as soon as possible by the JET
+     *    render and playback engine. If true, the mute flags will be updated at the start of the
+     *    next segment. If the segment is repeated, the flags will take effect the next time 
+     *    segment is repeated.
+     * @return true if the mute flags were successfully updated, false otherwise.
+     */
+    public boolean setMuteArray(boolean[] muteArray, boolean sync) {
+        if(muteArray.length != JetPlayer.getMaxTracks())
+            return false;
+        return native_setMuteArray(muteArray, sync);
+    }
+    
+    
+    /**
+     * Mutes or unmutes a single track.
+     * @param trackId the index of the track to mute.
+     * @param muteFlag set to true to mute, false to unmute.
+     * @param sync if false, the new mute flags will be applied as soon as possible by the JET
+     *    render and playback engine. If true, the mute flag will be updated at the start of the
+     *    next segment. If the segment is repeated, the flag will take effect the next time 
+     *    segment is repeated.
+     * @return true if the mute flag was successfully updated, false otherwise.
+     */
+    public boolean setMuteFlag(int trackId, boolean muteFlag, boolean sync) {
+        return native_setMuteFlag(trackId, muteFlag, sync);
+    }
+    
+    
+    /**
+     * Schedules the playback of a clip.
+     * This will automatically update the mute flags in sync with the JET Clip Marker (controller 
+     * 103). The parameter clipID must be in the range of 0-63. After the call to triggerClip, when
+     * JET next encounters a controller event 103 with bits 0-5 of the value equal to clipID and 
+     * bit 6 set to 1, it will automatically unmute the track containing the controller event.
+     * When JET encounters the complementary controller event 103 with bits 0-5 of the value equal
+     * to clipID and bit 6 set to 0, it will mute the track again.
+     * @param clipId the identifier of the clip to trigger.
+     * @return true if the clip was successfully triggered, false otherwise.
+     */
+    public boolean triggerClip(int clipId) {
+        return native_triggerClip(clipId);
+    }
+    
+    
+    /**
+     * Empties the segment queue, and clears all clips that are scheduled for playback.
+     * @return true if the queue was successfully cleared, false otherwise.
+     */
+    public boolean clearQueue() {
+        return native_clearQueue();
+    }
+    
+     
+    //---------------------------------------------------------
+    // Internal class to handle events posted from native code
+    //------------------------
+    private class NativeEventHandler extends Handler
+    {
+        private JetPlayer mJet;
+
+        public NativeEventHandler(JetPlayer jet, Looper looper) {
+            super(looper);
+            mJet = jet;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            OnJetEventListener listener = null;
+            synchronized (mEventListenerLock) {
+                listener = mJet.mJetEventListener;
+            }
+            switch(msg.what) {
+            case JET_EVENT:
+                if (listener != null) {
+                    // call the appropriate listener after decoding the event parameters
+                    // encoded in msg.arg1
+                    mJetEventListener.onJetEvent(
+                            mJet,
+                            (short)((msg.arg1 & JET_EVENT_SEG_MASK)   >> JET_EVENT_SEG_SHIFT),
+                            (byte) ((msg.arg1 & JET_EVENT_TRACK_MASK) >> JET_EVENT_TRACK_SHIFT),
+                            // JETCreator channel numbers start at 1, but the index starts at 0
+                            // in the .jet files
+                            (byte)(((msg.arg1 & JET_EVENT_CHAN_MASK)  >> JET_EVENT_CHAN_SHIFT) + 1),
+                            (byte) ((msg.arg1 & JET_EVENT_CTRL_MASK)  >> JET_EVENT_CTRL_SHIFT),
+                            (byte)  (msg.arg1 & JET_EVENT_VAL_MASK) );
+                }
+                return;
+            case JET_USERID_UPDATE:
+                if (listener != null) {
+                    listener.onJetUserIdUpdate(mJet, msg.arg1, msg.arg2);
+                }
+                return;
+            case JET_NUMQUEUEDSEGMENT_UPDATE:
+                if (listener != null) {
+                    listener.onJetNumQueuedSegmentUpdate(mJet, msg.arg1);
+                }
+                return;
+            case JET_PAUSE_UPDATE:
+                if (listener != null)
+                    listener.onJetPauseUpdate(mJet, msg.arg1);
+                return;
+
+            default:
+                loge("Unknown message type " + msg.what);
+                return;
+            }
+        }
+    }
+    
+    
+    //--------------------------------------------
+    // Jet event listener
+    //------------------------
+    /**
+     * Sets the listener JetPlayer notifies when a JET event is generated by the rendering and
+     * playback engine.
+     * Notifications will be received in the same thread as the one in which the JetPlayer
+     * instance was created.
+     * @param listener
+     */
+    public void setEventListener(OnJetEventListener listener) {
+        setEventListener(listener, null);
+    }
+    
+    /**
+     * Sets the listener JetPlayer notifies when a JET event is generated by the rendering and
+     * playback engine.
+     * Use this method to receive JET events in the Handler associated with another
+     * thread than the one in which you created the JetPlayer instance.
+     * @param listener
+     * @param handler the Handler that will receive the event notification messages.
+     */
+    public void setEventListener(OnJetEventListener listener, Handler handler) {
+        synchronized(mEventListenerLock) {
+            
+            mJetEventListener = listener;
+            
+            if (listener != null) {
+                if (handler != null) {
+                    mEventHandler = new NativeEventHandler(this, handler.getLooper());
+                } else {
+                    // no given handler, use the looper the AudioTrack was created in
+                    mEventHandler = new NativeEventHandler(this, mInitializationLooper);
+                }
+            } else {
+                mEventHandler = null;
+            }
+            
+        }
+    }
+    
+    
+    /**
+     * Handles the notification when the JET engine generates an event.
+     */
+    public interface OnJetEventListener {
+        /**
+         * Callback for when the JET engine generates a new event.
+         * 
+         * @param player the JET player the event is coming from
+         * @param segment 8 bit unsigned value
+         * @param track 6 bit unsigned value
+         * @param channel 4 bit unsigned value
+         * @param controller 7 bit unsigned value
+         * @param value 7 bit unsigned value
+         */
+        void onJetEvent(JetPlayer player,
+                short segment, byte track, byte channel, byte controller, byte value);
+        /**
+         * Callback for when JET's currently playing segment's userID is updated.
+         * 
+         * @param player the JET player the status update is coming from
+         * @param userId the ID of the currently playing segment
+         * @param repeatCount the repetition count for the segment (0 means it plays once)
+         */
+        void onJetUserIdUpdate(JetPlayer player, int userId, int repeatCount);
+        
+        /**
+         * Callback for when JET's number of queued segments is updated.
+         * 
+         * @param player the JET player the status update is coming from
+         * @param nbSegments the number of segments in the JET queue
+         */
+        void onJetNumQueuedSegmentUpdate(JetPlayer player, int nbSegments);
+        
+        /**
+         * Callback for when JET pause state is updated.
+         * 
+         * @param player the JET player the status update is coming from
+         * @param paused indicates whether JET is paused (1) or not (0)
+         */
+        void onJetPauseUpdate(JetPlayer player, int paused);
+    }
+    
+    
+    //--------------------------------------------
+    // Native methods
+    //------------------------
+    private native final boolean native_setup(Object Jet_this,
+                int maxTracks, int trackBufferSize);
+    private native final void    native_finalize();
+    private native final void    native_release();
+    private native final boolean native_loadJetFromFile(String pathToJetFile);
+    private native final boolean native_loadJetFromFileD(FileDescriptor fd, long offset, long len);
+    private native final boolean native_closeJetFile();
+    private native final boolean native_playJet();
+    private native final boolean native_pauseJet();
+    private native final boolean native_queueJetSegment(int segmentNum, int libNum,
+            int repeatCount, int transpose, int muteFlags, byte userID);
+    private native final boolean native_queueJetSegmentMuteArray(int segmentNum, int libNum, 
+            int repeatCount, int transpose, boolean[] muteArray, byte userID);
+    private native final boolean native_setMuteFlags(int muteFlags, boolean sync);
+    private native final boolean native_setMuteArray(boolean[]muteArray, boolean sync);
+    private native final boolean native_setMuteFlag(int trackId, boolean muteFlag, boolean sync);
+    private native final boolean native_triggerClip(int clipId);
+    private native final boolean native_clearQueue();
+    
+    //---------------------------------------------------------
+    // Called exclusively by native code
+    //--------------------
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static void postEventFromNative(Object jetplayer_ref,
+            int what, int arg1, int arg2) {
+        //logd("Event posted from the native side: event="+ what + " args="+ arg1+" "+arg2);
+        JetPlayer jet = (JetPlayer)((WeakReference)jetplayer_ref).get();
+
+        if ((jet != null) && (jet.mEventHandler != null)) {
+            Message m = 
+                jet.mEventHandler.obtainMessage(what, arg1, arg2, null);
+            jet.mEventHandler.sendMessage(m);
+        }
+        
+    }
+    
+ 
+    //---------------------------------------------------------
+    // Utils
+    //--------------------
+    private final static String TAG = "JetPlayer-J";
+    
+    private static void logd(String msg) {
+        Log.d(TAG, "[ android.media.JetPlayer ] " + msg);
+    }
+    
+    private static void loge(String msg) {
+        Log.e(TAG, "[ android.media.JetPlayer ] " + msg);
+    }
+ 
+}
diff --git a/android/media/MediaActionSound.java b/android/media/MediaActionSound.java
new file mode 100644
index 0000000..dcd4dce
--- /dev/null
+++ b/android/media/MediaActionSound.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright (C) 2012 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.AudioManager;
+import android.media.SoundPool;
+import android.util.Log;
+
+/**
+ * <p>A class for producing sounds that match those produced by various actions
+ * taken by the media and camera APIs.  </p>
+ *
+ * <p>This class is recommended for use with the {@link android.hardware.camera2} API, since the
+ * camera2 API does not play any sounds on its own for any capture or video recording actions.</p>
+ *
+ * <p>With the older {@link android.hardware.Camera} API, use this class to play an appropriate
+ * camera operation sound when implementing a custom still or video recording mechanism (through the
+ * Camera preview callbacks with
+ * {@link android.hardware.Camera#setPreviewCallback Camera.setPreviewCallback}, or through GPU
+ * processing with {@link android.hardware.Camera#setPreviewTexture Camera.setPreviewTexture}, for
+ * example), or when implementing some other camera-like function in your application.</p>
+ *
+ * <p>There is no need to play sounds when using
+ * {@link android.hardware.Camera#takePicture Camera.takePicture} or
+ * {@link android.media.MediaRecorder} for still images or video, respectively,
+ * as the Android framework will play the appropriate sounds when needed for
+ * these calls.</p>
+ *
+ */
+public class MediaActionSound {
+    private static final int NUM_MEDIA_SOUND_STREAMS = 1;
+
+    private SoundPool mSoundPool;
+    private SoundState[] mSounds;
+
+    private static final String[] SOUND_DIRS = {
+        "/product/media/audio/ui/",
+        "/system/media/audio/ui/",
+    };
+
+    private static final String[] SOUND_FILES = {
+        "camera_click.ogg",
+        "camera_focus.ogg",
+        "VideoRecord.ogg",
+        "VideoStop.ogg"
+    };
+
+    private static final String TAG = "MediaActionSound";
+    /**
+     * The sound used by
+     * {@link android.hardware.Camera#takePicture Camera.takePicture} to
+     * indicate still image capture.
+     * @see #play
+     */
+    public static final int SHUTTER_CLICK         = 0;
+
+    /**
+     * A sound to indicate that focusing has completed. Because deciding
+     * when this occurs is application-dependent, this sound is not used by
+     * any methods in the media or camera APIs.
+     * @see #play
+     */
+    public static final int FOCUS_COMPLETE        = 1;
+
+    /**
+     * The sound used by
+     * {@link android.media.MediaRecorder#start MediaRecorder.start()} to
+     * indicate the start of video recording.
+     * @see #play
+     */
+    public static final int START_VIDEO_RECORDING = 2;
+
+    /**
+     * The sound used by
+     * {@link android.media.MediaRecorder#stop MediaRecorder.stop()} to
+     * indicate the end of video recording.
+     * @see #play
+     */
+    public static final int STOP_VIDEO_RECORDING  = 3;
+
+    /**
+     * States for SoundState.
+     * STATE_NOT_LOADED             : sample not loaded
+     * STATE_LOADING                : sample being loaded: waiting for load completion callback
+     * STATE_LOADING_PLAY_REQUESTED : sample being loaded and playback request received
+     * STATE_LOADED                 : sample loaded, ready for playback
+     */
+    private static final int STATE_NOT_LOADED             = 0;
+    private static final int STATE_LOADING                = 1;
+    private static final int STATE_LOADING_PLAY_REQUESTED = 2;
+    private static final int STATE_LOADED                 = 3;
+
+    private class SoundState {
+        public final int name;
+        public int id;
+        public int state;
+
+        public SoundState(int name) {
+            this.name = name;
+            id = 0; // 0 is an invalid sample ID.
+            state = STATE_NOT_LOADED;
+        }
+    }
+    /**
+     * Construct a new MediaActionSound instance. Only a single instance is
+     * needed for playing any platform media action sound; you do not need a
+     * separate instance for each sound type.
+     */
+    public MediaActionSound() {
+        mSoundPool = new SoundPool.Builder()
+                .setMaxStreams(NUM_MEDIA_SOUND_STREAMS)
+                .setAudioAttributes(new AudioAttributes.Builder()
+                    .setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
+                    .setFlags(AudioAttributes.FLAG_AUDIBILITY_ENFORCED)
+                    .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+                    .build())
+                .build();
+        mSoundPool.setOnLoadCompleteListener(mLoadCompleteListener);
+        mSounds = new SoundState[SOUND_FILES.length];
+        for (int i = 0; i < mSounds.length; i++) {
+            mSounds[i] = new SoundState(i);
+        }
+    }
+
+    private int loadSound(SoundState sound) {
+        final String soundFileName = SOUND_FILES[sound.name];
+        for (String soundDir : SOUND_DIRS) {
+            int id = mSoundPool.load(soundDir + soundFileName, 1);
+            if (id > 0) {
+                sound.state = STATE_LOADING;
+                sound.id = id;
+                return id;
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Preload a predefined platform sound to minimize latency when the sound is
+     * played later by {@link #play}.
+     * @param soundName The type of sound to preload, selected from
+     *         SHUTTER_CLICK, FOCUS_COMPLETE, START_VIDEO_RECORDING, or
+     *         STOP_VIDEO_RECORDING.
+     * @see #play
+     * @see #SHUTTER_CLICK
+     * @see #FOCUS_COMPLETE
+     * @see #START_VIDEO_RECORDING
+     * @see #STOP_VIDEO_RECORDING
+     */
+    public void load(int soundName) {
+        if (soundName < 0 || soundName >= SOUND_FILES.length) {
+            throw new RuntimeException("Unknown sound requested: " + soundName);
+        }
+        SoundState sound = mSounds[soundName];
+        synchronized (sound) {
+            switch (sound.state) {
+            case STATE_NOT_LOADED:
+                if (loadSound(sound) <= 0) {
+                    Log.e(TAG, "load() error loading sound: " + soundName);
+                }
+                break;
+            default:
+                Log.e(TAG, "load() called in wrong state: " + sound + " for sound: "+ soundName);
+                break;
+            }
+        }
+    }
+
+    /**
+     * <p>Play one of the predefined platform sounds for media actions.</p>
+     *
+     * <p>Use this method to play a platform-specific sound for various media
+     * actions. The sound playback is done asynchronously, with the same
+     * behavior and content as the sounds played by
+     * {@link android.hardware.Camera#takePicture Camera.takePicture},
+     * {@link android.media.MediaRecorder#start MediaRecorder.start}, and
+     * {@link android.media.MediaRecorder#stop MediaRecorder.stop}.</p>
+     *
+     * <p>With the {@link android.hardware.camera2 camera2} API, this method can be used to play
+     * standard camera operation sounds with the appropriate system behavior for such sounds.</p>
+
+     * <p>With the older {@link android.hardware.Camera} API, using this method makes it easy to
+     * match the default device sounds when recording or capturing data through the preview
+     * callbacks, or when implementing custom camera-like features in your application.</p>
+     *
+     * <p>If the sound has not been loaded by {@link #load} before calling play,
+     * play will load the sound at the cost of some additional latency before
+     * sound playback begins. </p>
+     *
+     * @param soundName The type of sound to play, selected from
+     *         SHUTTER_CLICK, FOCUS_COMPLETE, START_VIDEO_RECORDING, or
+     *         STOP_VIDEO_RECORDING.
+     * @see android.hardware.Camera#takePicture
+     * @see android.media.MediaRecorder
+     * @see #SHUTTER_CLICK
+     * @see #FOCUS_COMPLETE
+     * @see #START_VIDEO_RECORDING
+     * @see #STOP_VIDEO_RECORDING
+     */
+    public void play(int soundName) {
+        if (soundName < 0 || soundName >= SOUND_FILES.length) {
+            throw new RuntimeException("Unknown sound requested: " + soundName);
+        }
+        SoundState sound = mSounds[soundName];
+        synchronized (sound) {
+            switch (sound.state) {
+            case STATE_NOT_LOADED:
+                loadSound(sound);
+                if (loadSound(sound) <= 0) {
+                    Log.e(TAG, "play() error loading sound: " + soundName);
+                    break;
+                }
+                // FALL THROUGH
+
+            case STATE_LOADING:
+                sound.state = STATE_LOADING_PLAY_REQUESTED;
+                break;
+            case STATE_LOADED:
+                mSoundPool.play(sound.id, 1.0f, 1.0f, 0, 0, 1.0f);
+                break;
+            default:
+                Log.e(TAG, "play() called in wrong state: " + sound.state + " for sound: "+ soundName);
+                break;
+            }
+        }
+    }
+
+    private SoundPool.OnLoadCompleteListener mLoadCompleteListener =
+            new SoundPool.OnLoadCompleteListener() {
+        public void onLoadComplete(SoundPool soundPool,
+                int sampleId, int status) {
+            for (SoundState sound : mSounds) {
+                if (sound.id != sampleId) {
+                    continue;
+                }
+                int playSoundId = 0;
+                synchronized (sound) {
+                    if (status != 0) {
+                        sound.state = STATE_NOT_LOADED;
+                        sound.id = 0;
+                        Log.e(TAG, "OnLoadCompleteListener() error: " + status +
+                                " loading sound: "+ sound.name);
+                        return;
+                    }
+                    switch (sound.state) {
+                    case STATE_LOADING:
+                        sound.state = STATE_LOADED;
+                        break;
+                    case STATE_LOADING_PLAY_REQUESTED:
+                        playSoundId = sound.id;
+                        sound.state = STATE_LOADED;
+                        break;
+                    default:
+                        Log.e(TAG, "OnLoadCompleteListener() called in wrong state: "
+                                + sound.state + " for sound: "+ sound.name);
+                        break;
+                    }
+                }
+                if (playSoundId != 0) {
+                    soundPool.play(playSoundId, 1.0f, 1.0f, 0, 0, 1.0f);
+                }
+                break;
+            }
+        }
+    };
+
+    /**
+     * Free up all audio resources used by this MediaActionSound instance. Do
+     * not call any other methods on a MediaActionSound instance after calling
+     * release().
+     */
+    public void release() {
+        if (mSoundPool != null) {
+            for (SoundState sound : mSounds) {
+                synchronized (sound) {
+                    sound.state = STATE_NOT_LOADED;
+                    sound.id = 0;
+                }
+            }
+            mSoundPool.release();
+            mSoundPool = null;
+        }
+    }
+}
diff --git a/android/media/MediaCas.java b/android/media/MediaCas.java
new file mode 100644
index 0000000..582a28e
--- /dev/null
+++ b/android/media/MediaCas.java
@@ -0,0 +1,1183 @@
+/*
+ * Copyright (C) 2017 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+import android.content.Context;
+import android.hardware.cas.V1_0.HidlCasPluginDescriptor;
+import android.hardware.cas.V1_0.ICas;
+import android.hardware.cas.V1_0.IMediaCasService;
+import android.hardware.cas.V1_2.ICasListener;
+import android.hardware.cas.V1_2.Status;
+import android.media.MediaCasException.*;
+import android.media.tv.TvInputService.PriorityHintUseCaseType;
+import android.media.tv.tunerresourcemanager.CasSessionRequest;
+import android.media.tv.tunerresourcemanager.ResourceClientProfile;
+import android.media.tv.tunerresourcemanager.TunerResourceManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IHwBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.Singleton;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * MediaCas can be used to obtain keys for descrambling protected media streams, in
+ * conjunction with {@link android.media.MediaDescrambler}. The MediaCas APIs are
+ * designed to support conditional access such as those in the ISO/IEC13818-1.
+ * The CA system is identified by a 16-bit integer CA_system_id. The scrambling
+ * algorithms are usually proprietary and implemented by vendor-specific CA plugins
+ * installed on the device.
+ * <p>
+ * The app is responsible for constructing a MediaCas object for the CA system it
+ * intends to use. The app can query if a certain CA system is supported using static
+ * method {@link #isSystemIdSupported}. It can also obtain the entire list of supported
+ * CA systems using static method {@link #enumeratePlugins}.
+ * <p>
+ * Once the MediaCas object is constructed, the app should properly provision it by
+ * using method {@link #provision} and/or {@link #processEmm}. The EMMs (Entitlement
+ * management messages) can be distributed out-of-band, or in-band with the stream.
+ * <p>
+ * To descramble elementary streams, the app first calls {@link #openSession} to
+ * generate a {@link Session} object that will uniquely identify a session. A session
+ * provides a context for subsequent key updates and descrambling activities. The ECMs
+ * (Entitlement control messages) are sent to the session via method
+ * {@link Session#processEcm}.
+ * <p>
+ * The app next constructs a MediaDescrambler object, and initializes it with the
+ * session using {@link MediaDescrambler#setMediaCasSession}. This ties the
+ * descrambler to the session, and the descrambler can then be used to descramble
+ * content secured with the session's key, either during extraction, or during decoding
+ * with {@link android.media.MediaCodec}.
+ * <p>
+ * If the app handles sample extraction using its own extractor, it can use
+ * MediaDescrambler to descramble samples into clear buffers (if the session's license
+ * doesn't require secure decoders), or descramble a small amount of data to retrieve
+ * information necessary for the downstream pipeline to process the sample (if the
+ * session's license requires secure decoders).
+ * <p>
+ * If the session requires a secure decoder, a MediaDescrambler needs to be provided to
+ * MediaCodec to descramble samples queued by {@link MediaCodec#queueSecureInputBuffer}
+ * into protected buffers. The app should use {@link MediaCodec#configure(MediaFormat,
+ * android.view.Surface, int, MediaDescrambler)} instead of the normal {@link
+ * MediaCodec#configure(MediaFormat, android.view.Surface, MediaCrypto, int)} method
+ * to configure MediaCodec.
+ * <p>
+ * <h3>Using Android's MediaExtractor</h3>
+ * <p>
+ * If the app uses {@link MediaExtractor}, it can delegate the CAS session
+ * management to MediaExtractor by calling {@link MediaExtractor#setMediaCas}.
+ * MediaExtractor will take over and call {@link #openSession}, {@link #processEmm}
+ * and/or {@link Session#processEcm}, etc.. if necessary.
+ * <p>
+ * When using {@link MediaExtractor}, the app would still need a MediaDescrambler
+ * to use with {@link MediaCodec} if the licensing requires a secure decoder. The
+ * session associated with the descrambler of a track can be retrieved by calling
+ * {@link MediaExtractor#getCasInfo}, and used to initialize a MediaDescrambler
+ * object for MediaCodec.
+ * <p>
+ * <h3>Listeners</h3>
+ * <p>The app may register a listener to receive events from the CA system using
+ * method {@link #setEventListener}. The exact format of the event is scheme-specific
+ * and is not specified by this API.
+ */
+public final class MediaCas implements AutoCloseable {
+    private static final String TAG = "MediaCas";
+    private ICas mICas;
+    private android.hardware.cas.V1_1.ICas mICasV11;
+    private android.hardware.cas.V1_2.ICas mICasV12;
+    private EventListener mListener;
+    private HandlerThread mHandlerThread;
+    private EventHandler mEventHandler;
+    private @PriorityHintUseCaseType int mPriorityHint;
+    private String mTvInputServiceSessionId;
+    private int mClientId;
+    private int mCasSystemId;
+    private int mUserId;
+    private TunerResourceManager mTunerResourceManager = null;
+    private final Map<Session, Integer> mSessionMap = new HashMap<>();
+
+    /**
+     * Scrambling modes used to open cas sessions.
+     *
+     * @hide
+     */
+    @IntDef(prefix = "SCRAMBLING_MODE_",
+            value = {SCRAMBLING_MODE_RESERVED, SCRAMBLING_MODE_DVB_CSA1, SCRAMBLING_MODE_DVB_CSA2,
+            SCRAMBLING_MODE_DVB_CSA3_STANDARD,
+            SCRAMBLING_MODE_DVB_CSA3_MINIMAL, SCRAMBLING_MODE_DVB_CSA3_ENHANCE,
+            SCRAMBLING_MODE_DVB_CISSA_V1, SCRAMBLING_MODE_DVB_IDSA,
+            SCRAMBLING_MODE_MULTI2, SCRAMBLING_MODE_AES128, SCRAMBLING_MODE_AES_ECB,
+            SCRAMBLING_MODE_AES_SCTE52, SCRAMBLING_MODE_TDES_ECB, SCRAMBLING_MODE_TDES_SCTE52})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScramblingMode {}
+
+    /**
+     * DVB (Digital Video Broadcasting) reserved mode.
+     */
+    public static final int SCRAMBLING_MODE_RESERVED =
+            android.hardware.cas.V1_2.ScramblingMode.RESERVED;
+    /**
+     * DVB (Digital Video Broadcasting) Common Scrambling Algorithm (CSA) 1.
+     */
+    public static final int SCRAMBLING_MODE_DVB_CSA1 =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_CSA1;
+    /**
+     * DVB CSA 2.
+     */
+    public static final int SCRAMBLING_MODE_DVB_CSA2 =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_CSA2;
+    /**
+     * DVB CSA 3 in standard mode.
+     */
+    public static final int SCRAMBLING_MODE_DVB_CSA3_STANDARD =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_STANDARD;
+    /**
+     * DVB CSA 3 in minimally enhanced mode.
+     */
+    public static final int SCRAMBLING_MODE_DVB_CSA3_MINIMAL =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_MINIMAL;
+    /**
+     * DVB CSA 3 in fully enhanced mode.
+     */
+    public static final int SCRAMBLING_MODE_DVB_CSA3_ENHANCE =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_CSA3_ENHANCE;
+    /**
+     * DVB Common IPTV Software-oriented Scrambling Algorithm (CISSA) Version 1.
+     */
+    public static final int SCRAMBLING_MODE_DVB_CISSA_V1 =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_CISSA_V1;
+    /**
+     * ATIS-0800006 IIF Default Scrambling Algorithm (IDSA).
+     */
+    public static final int SCRAMBLING_MODE_DVB_IDSA =
+            android.hardware.cas.V1_2.ScramblingMode.DVB_IDSA;
+    /**
+     * A symmetric key algorithm.
+     */
+    public static final int SCRAMBLING_MODE_MULTI2 =
+            android.hardware.cas.V1_2.ScramblingMode.MULTI2;
+    /**
+     * Advanced Encryption System (AES) 128-bit Encryption mode.
+     */
+    public static final int SCRAMBLING_MODE_AES128 =
+            android.hardware.cas.V1_2.ScramblingMode.AES128;
+    /**
+     * Advanced Encryption System (AES) Electronic Code Book (ECB) mode.
+     */
+    public static final int SCRAMBLING_MODE_AES_ECB =
+            android.hardware.cas.V1_2.ScramblingMode.AES_ECB;
+    /**
+     * Advanced Encryption System (AES) Society of Cable Telecommunications Engineers (SCTE) 52
+     * mode.
+     */
+    public static final int SCRAMBLING_MODE_AES_SCTE52 =
+            android.hardware.cas.V1_2.ScramblingMode.AES_SCTE52;
+    /**
+     * Triple Data Encryption Algorithm (TDES) Electronic Code Book (ECB) mode.
+     */
+    public static final int SCRAMBLING_MODE_TDES_ECB =
+            android.hardware.cas.V1_2.ScramblingMode.TDES_ECB;
+    /**
+     * Triple Data Encryption Algorithm (TDES) Society of Cable Telecommunications Engineers (SCTE)
+     * 52 mode.
+     */
+    public static final int SCRAMBLING_MODE_TDES_SCTE52 =
+            android.hardware.cas.V1_2.ScramblingMode.TDES_SCTE52;
+
+    /**
+     * Usages used to open cas sessions.
+     *
+     * @hide
+     */
+    @IntDef(prefix = "SESSION_USAGE_",
+            value = {SESSION_USAGE_LIVE, SESSION_USAGE_PLAYBACK, SESSION_USAGE_RECORD,
+            SESSION_USAGE_TIMESHIFT})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SessionUsage {}
+    /**
+     * Cas session is used to descramble live streams.
+     */
+    public static final int SESSION_USAGE_LIVE = android.hardware.cas.V1_2.SessionIntent.LIVE;
+    /**
+     * Cas session is used to descramble recoreded streams.
+     */
+    public static final int SESSION_USAGE_PLAYBACK =
+            android.hardware.cas.V1_2.SessionIntent.PLAYBACK;
+    /**
+     * Cas session is used to descramble live streams and encrypt local recorded content
+     */
+    public static final int SESSION_USAGE_RECORD = android.hardware.cas.V1_2.SessionIntent.RECORD;
+    /**
+     * Cas session is used to descramble live streams , encrypt local recorded content and playback
+     * local encrypted content.
+     */
+    public static final int SESSION_USAGE_TIMESHIFT =
+            android.hardware.cas.V1_2.SessionIntent.TIMESHIFT;
+
+    /**
+     * Plugin status events sent from cas system.
+     *
+     * @hide
+     */
+    @IntDef(prefix = "PLUGIN_STATUS_",
+            value = {PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED, PLUGIN_STATUS_SESSION_NUMBER_CHANGED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PluginStatus {}
+
+    /**
+     * The event to indicate that the status of CAS system is changed by the removal or insertion of
+     * physical CAS modules.
+     */
+    public static final int PLUGIN_STATUS_PHYSICAL_MODULE_CHANGED =
+            android.hardware.cas.V1_2.StatusEvent.PLUGIN_PHYSICAL_MODULE_CHANGED;
+    /**
+     * The event to indicate that the number of CAS system's session is changed.
+     */
+    public static final int PLUGIN_STATUS_SESSION_NUMBER_CHANGED =
+            android.hardware.cas.V1_2.StatusEvent.PLUGIN_SESSION_NUMBER_CHANGED;
+
+    private static final Singleton<IMediaCasService> sService = new Singleton<IMediaCasService>() {
+        @Override
+        protected IMediaCasService create() {
+            try {
+                Log.d(TAG, "Trying to get cas@1.2 service");
+                android.hardware.cas.V1_2.IMediaCasService serviceV12 =
+                        android.hardware.cas.V1_2.IMediaCasService.getService(true /*wait*/);
+                if (serviceV12 != null) {
+                    return serviceV12;
+                }
+            } catch (Exception eV1_2) {
+                Log.d(TAG, "Failed to get cas@1.2 service");
+            }
+
+            try {
+                    Log.d(TAG, "Trying to get cas@1.1 service");
+                    android.hardware.cas.V1_1.IMediaCasService serviceV11 =
+                            android.hardware.cas.V1_1.IMediaCasService.getService(true /*wait*/);
+                    if (serviceV11 != null) {
+                        return serviceV11;
+                    }
+            } catch (Exception eV1_1) {
+                Log.d(TAG, "Failed to get cas@1.1 service");
+            }
+
+            try {
+                Log.d(TAG, "Trying to get cas@1.0 service");
+                return IMediaCasService.getService(true /*wait*/);
+            } catch (Exception eV1_0) {
+                Log.d(TAG, "Failed to get cas@1.0 service");
+            }
+
+            return null;
+        }
+    };
+
+    static IMediaCasService getService() {
+        return sService.get();
+    }
+
+    private void validateInternalStates() {
+        if (mICas == null) {
+            throw new IllegalStateException();
+        }
+    }
+
+    private void cleanupAndRethrowIllegalState() {
+        mICas = null;
+        mICasV11 = null;
+        mICasV12 = null;
+        throw new IllegalStateException();
+    }
+
+    private class EventHandler extends Handler {
+
+        private static final int MSG_CAS_EVENT = 0;
+        private static final int MSG_CAS_SESSION_EVENT = 1;
+        private static final int MSG_CAS_STATUS_EVENT = 2;
+        private static final int MSG_CAS_RESOURCE_LOST = 3;
+        private static final String SESSION_KEY = "sessionId";
+        private static final String DATA_KEY = "data";
+
+        public EventHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.what == MSG_CAS_EVENT) {
+                mListener.onEvent(MediaCas.this, msg.arg1, msg.arg2,
+                        toBytes((ArrayList<Byte>) msg.obj));
+            } else if (msg.what == MSG_CAS_SESSION_EVENT) {
+                Bundle bundle = msg.getData();
+                ArrayList<Byte> sessionId = toByteArray(bundle.getByteArray(SESSION_KEY));
+                mListener.onSessionEvent(MediaCas.this,
+                        createFromSessionId(sessionId), msg.arg1, msg.arg2,
+                        bundle.getByteArray(DATA_KEY));
+            } else if (msg.what == MSG_CAS_STATUS_EVENT) {
+                if ((msg.arg1 == PLUGIN_STATUS_SESSION_NUMBER_CHANGED)
+                        && (mTunerResourceManager != null)) {
+                    mTunerResourceManager.updateCasInfo(mCasSystemId, msg.arg2);
+                }
+                mListener.onPluginStatusUpdate(MediaCas.this, msg.arg1, msg.arg2);
+            } else if (msg.what == MSG_CAS_RESOURCE_LOST) {
+                mListener.onResourceLost(MediaCas.this);
+            }
+        }
+    }
+
+    private final ICasListener.Stub mBinder = new ICasListener.Stub() {
+        @Override
+        public void onEvent(int event, int arg, @Nullable ArrayList<Byte> data)
+                throws RemoteException {
+            if (mEventHandler != null) {
+                mEventHandler.sendMessage(mEventHandler.obtainMessage(
+                    EventHandler.MSG_CAS_EVENT, event, arg, data));
+            }
+        }
+        @Override
+        public void onSessionEvent(@NonNull ArrayList<Byte> sessionId,
+                int event, int arg, @Nullable ArrayList<Byte> data)
+                throws RemoteException {
+            if (mEventHandler != null) {
+                Message msg = mEventHandler.obtainMessage();
+                msg.what = EventHandler.MSG_CAS_SESSION_EVENT;
+                msg.arg1 = event;
+                msg.arg2 = arg;
+                Bundle bundle = new Bundle();
+                bundle.putByteArray(EventHandler.SESSION_KEY, toBytes(sessionId));
+                bundle.putByteArray(EventHandler.DATA_KEY, toBytes(data));
+                msg.setData(bundle);
+                mEventHandler.sendMessage(msg);
+            }
+        }
+        @Override
+        public void onStatusUpdate(byte status, int arg)
+                throws RemoteException {
+            if (mEventHandler != null) {
+                mEventHandler.sendMessage(mEventHandler.obtainMessage(
+                    EventHandler.MSG_CAS_STATUS_EVENT, status, arg));
+            }
+        }
+    };
+
+    private final TunerResourceManager.ResourcesReclaimListener mResourceListener =
+            new TunerResourceManager.ResourcesReclaimListener() {
+            @Override
+            public void onReclaimResources() {
+                synchronized (mSessionMap) {
+                    List<Session> sessionList = new ArrayList<>(mSessionMap.keySet());
+                    for (Session casSession: sessionList) {
+                        casSession.close();
+                    }
+                }
+                mEventHandler.sendMessage(mEventHandler.obtainMessage(
+                        EventHandler.MSG_CAS_RESOURCE_LOST));
+            }
+        };
+
+    /**
+     * Describe a CAS plugin with its CA_system_ID and string name.
+     *
+     * Returned as results of {@link #enumeratePlugins}.
+     *
+     */
+    public static class PluginDescriptor {
+        private final int mCASystemId;
+        private final String mName;
+
+        private PluginDescriptor() {
+            mCASystemId = 0xffff;
+            mName = null;
+        }
+
+        PluginDescriptor(@NonNull HidlCasPluginDescriptor descriptor) {
+            mCASystemId = descriptor.caSystemId;
+            mName = descriptor.name;
+        }
+
+        public int getSystemId() {
+            return mCASystemId;
+        }
+
+        @NonNull
+        public String getName() {
+            return mName;
+        }
+
+        @Override
+        public String toString() {
+            return "PluginDescriptor {" + mCASystemId + ", " + mName + "}";
+        }
+    }
+
+    private ArrayList<Byte> toByteArray(@NonNull byte[] data, int offset, int length) {
+        ArrayList<Byte> byteArray = new ArrayList<Byte>(length);
+        for (int i = 0; i < length; i++) {
+            byteArray.add(Byte.valueOf(data[offset + i]));
+        }
+        return byteArray;
+    }
+
+    private ArrayList<Byte> toByteArray(@Nullable byte[] data) {
+        if (data == null) {
+            return new ArrayList<Byte>();
+        }
+        return toByteArray(data, 0, data.length);
+    }
+
+    private byte[] toBytes(@NonNull ArrayList<Byte> byteArray) {
+        byte[] data = null;
+        if (byteArray != null) {
+            data = new byte[byteArray.size()];
+            for (int i = 0; i < data.length; i++) {
+                data[i] = byteArray.get(i);
+            }
+        }
+        return data;
+    }
+    /**
+     * Class for an open session with the CA system.
+     */
+    public final class Session implements AutoCloseable {
+        final ArrayList<Byte> mSessionId;
+        boolean mIsClosed = false;
+
+        Session(@NonNull ArrayList<Byte> sessionId) {
+            mSessionId = new ArrayList<Byte>(sessionId);
+        }
+
+        private void validateSessionInternalStates() {
+            if (mICas == null) {
+                throw new IllegalStateException();
+            }
+            if (mIsClosed) {
+                MediaCasStateException.throwExceptionIfNeeded(Status.ERROR_CAS_SESSION_NOT_OPENED);
+            }
+        }
+
+        /**
+         * Query if an object equal current Session object.
+         *
+         * @param obj an object to compare to current Session object.
+         *
+         * @return Whether input object equal current Session object.
+         */
+        public boolean equals(Object obj) {
+            if (obj instanceof Session) {
+                return mSessionId.equals(((Session) obj).mSessionId);
+            }
+            return false;
+        }
+
+        /**
+         * Set the private data for a session.
+         *
+         * @param data byte array of the private data.
+         *
+         * @throws IllegalStateException if the MediaCas instance is not valid.
+         * @throws MediaCasException for CAS-specific errors.
+         * @throws MediaCasStateException for CAS-specific state exceptions.
+         */
+        public void setPrivateData(@NonNull byte[] data)
+                throws MediaCasException {
+            validateSessionInternalStates();
+
+            try {
+                MediaCasException.throwExceptionIfNeeded(
+                        mICas.setSessionPrivateData(mSessionId, toByteArray(data, 0, data.length)));
+            } catch (RemoteException e) {
+                cleanupAndRethrowIllegalState();
+            }
+        }
+
+
+        /**
+         * Send a received ECM packet to the specified session of the CA system.
+         *
+         * @param data byte array of the ECM data.
+         * @param offset position within data where the ECM data begins.
+         * @param length length of the data (starting from offset).
+         *
+         * @throws IllegalStateException if the MediaCas instance is not valid.
+         * @throws MediaCasException for CAS-specific errors.
+         * @throws MediaCasStateException for CAS-specific state exceptions.
+         */
+        public void processEcm(@NonNull byte[] data, int offset, int length)
+                throws MediaCasException {
+            validateSessionInternalStates();
+
+            try {
+                MediaCasException.throwExceptionIfNeeded(
+                        mICas.processEcm(mSessionId, toByteArray(data, offset, length)));
+            } catch (RemoteException e) {
+                cleanupAndRethrowIllegalState();
+            }
+        }
+
+        /**
+         * Send a received ECM packet to the specified session of the CA system.
+         * This is similar to {@link Session#processEcm(byte[], int, int)}
+         * except that the entire byte array is sent.
+         *
+         * @param data byte array of the ECM data.
+         *
+         * @throws IllegalStateException if the MediaCas instance is not valid.
+         * @throws MediaCasException for CAS-specific errors.
+         * @throws MediaCasStateException for CAS-specific state exceptions.
+         */
+        public void processEcm(@NonNull byte[] data) throws MediaCasException {
+            processEcm(data, 0, data.length);
+        }
+
+        /**
+         * Send a session event to a CA system. The format of the event is
+         * scheme-specific and is opaque to the framework.
+         *
+         * @param event an integer denoting a scheme-specific event to be sent.
+         * @param arg a scheme-specific integer argument for the event.
+         * @param data a byte array containing scheme-specific data for the event.
+         *
+         * @throws IllegalStateException if the MediaCas instance is not valid.
+         * @throws MediaCasException for CAS-specific errors.
+         * @throws MediaCasStateException for CAS-specific state exceptions.
+         */
+        public void sendSessionEvent(int event, int arg, @Nullable byte[] data)
+                throws MediaCasException {
+            validateSessionInternalStates();
+
+            if (mICasV11 == null) {
+                Log.d(TAG, "Send Session Event isn't supported by cas@1.0 interface");
+                throw new UnsupportedCasException("Send Session Event is not supported");
+            }
+
+            try {
+                MediaCasException.throwExceptionIfNeeded(
+                        mICasV11.sendSessionEvent(mSessionId, event, arg, toByteArray(data)));
+            } catch (RemoteException e) {
+                cleanupAndRethrowIllegalState();
+            }
+        }
+
+        /**
+         * Get Session Id.
+         *
+         * @return session Id of the session.
+         *
+         * @throws IllegalStateException if the MediaCas instance is not valid.
+         */
+        @NonNull
+        public byte[] getSessionId() {
+            validateSessionInternalStates();
+            return toBytes(mSessionId);
+        }
+
+        /**
+         * Close the session.
+         *
+         * @throws IllegalStateException if the MediaCas instance is not valid.
+         * @throws MediaCasStateException for CAS-specific state exceptions.
+         */
+        @Override
+        public void close() {
+            validateSessionInternalStates();
+            try {
+                MediaCasStateException.throwExceptionIfNeeded(
+                        mICas.closeSession(mSessionId));
+                mIsClosed = true;
+                removeSessionFromResourceMap(this);
+            } catch (RemoteException e) {
+                cleanupAndRethrowIllegalState();
+            }
+        }
+    }
+
+    Session createFromSessionId(@NonNull ArrayList<Byte> sessionId) {
+        if (sessionId == null || sessionId.size() == 0) {
+            return null;
+        }
+        return new Session(sessionId);
+    }
+
+    /**
+     * Query if a certain CA system is supported on this device.
+     *
+     * @param CA_system_id the id of the CA system.
+     *
+     * @return Whether the specified CA system is supported on this device.
+     */
+    public static boolean isSystemIdSupported(int CA_system_id) {
+        IMediaCasService service = getService();
+
+        if (service != null) {
+            try {
+                return service.isSystemIdSupported(CA_system_id);
+            } catch (RemoteException e) {
+            }
+        }
+        return false;
+    }
+
+    /**
+     * List all available CA plugins on the device.
+     *
+     * @return an array of descriptors for the available CA plugins.
+     */
+    public static PluginDescriptor[] enumeratePlugins() {
+        IMediaCasService service = getService();
+
+        if (service != null) {
+            try {
+                ArrayList<HidlCasPluginDescriptor> descriptors =
+                        service.enumeratePlugins();
+                if (descriptors.size() == 0) {
+                    return null;
+                }
+                PluginDescriptor[] results = new PluginDescriptor[descriptors.size()];
+                for (int i = 0; i < results.length; i++) {
+                    results[i] = new PluginDescriptor(descriptors.get(i));
+                }
+                return results;
+            } catch (RemoteException e) {
+            }
+        }
+        return null;
+    }
+
+    private void createPlugin(int casSystemId) throws UnsupportedCasException {
+        try {
+            mCasSystemId = casSystemId;
+            mUserId = Process.myUid();
+            IMediaCasService service = getService();
+            android.hardware.cas.V1_2.IMediaCasService serviceV12 =
+                    android.hardware.cas.V1_2.IMediaCasService.castFrom(service);
+            if (serviceV12 == null) {
+                android.hardware.cas.V1_1.IMediaCasService serviceV11 =
+                    android.hardware.cas.V1_1.IMediaCasService.castFrom(service);
+                if (serviceV11 == null) {
+                    Log.d(TAG, "Used cas@1_0 interface to create plugin");
+                    mICas = service.createPlugin(casSystemId, mBinder);
+                } else {
+                    Log.d(TAG, "Used cas@1.1 interface to create plugin");
+                    mICas = mICasV11 = serviceV11.createPluginExt(casSystemId, mBinder);
+                }
+            } else {
+                Log.d(TAG, "Used cas@1.2 interface to create plugin");
+                mICas = mICasV11 = mICasV12 =
+                    android.hardware.cas.V1_2.ICas
+                        .castFrom(serviceV12.createPluginExt(casSystemId, mBinder));
+            }
+        } catch(Exception e) {
+            Log.e(TAG, "Failed to create plugin: " + e);
+            mICas = null;
+        } finally {
+            if (mICas == null) {
+                throw new UnsupportedCasException(
+                    "Unsupported casSystemId " + casSystemId);
+            }
+        }
+    }
+
+    private void registerClient(@NonNull Context context,
+            @Nullable String tvInputServiceSessionId,  @PriorityHintUseCaseType int priorityHint)  {
+
+        mTunerResourceManager = (TunerResourceManager)
+            context.getSystemService(Context.TV_TUNER_RESOURCE_MGR_SERVICE);
+        if (mTunerResourceManager != null) {
+            int[] clientId = new int[1];
+            ResourceClientProfile profile = new ResourceClientProfile();
+            profile.tvInputSessionId = tvInputServiceSessionId;
+            profile.useCase = priorityHint;
+            mTunerResourceManager.registerClientProfile(
+                    profile, context.getMainExecutor(), mResourceListener, clientId);
+            mClientId = clientId[0];
+        }
+    }
+    /**
+     * Instantiate a CA system of the specified system id.
+     *
+     * @param casSystemId The system id of the CA system.
+     *
+     * @throws UnsupportedCasException if the device does not support the
+     * specified CA system.
+     */
+    public MediaCas(int casSystemId) throws UnsupportedCasException {
+        createPlugin(casSystemId);
+    }
+
+    /**
+     * Instantiate a CA system of the specified system id.
+     *
+     * @param context the context of the caller.
+     * @param casSystemId The system id of the CA system.
+     * @param tvInputServiceSessionId The Id of the session opened in TV Input Service (TIS)
+     *        {@link android.media.tv.TvInputService#onCreateSession(String, String)}
+     * @param priorityHint priority hint from the use case type for new created CAS system.
+     *
+     * @throws UnsupportedCasException if the device does not support the
+     * specified CA system.
+     */
+    public MediaCas(@NonNull Context context, int casSystemId,
+            @Nullable String tvInputServiceSessionId,
+            @PriorityHintUseCaseType int priorityHint) throws UnsupportedCasException {
+        Objects.requireNonNull(context, "context must not be null");
+        createPlugin(casSystemId);
+        registerClient(context, tvInputServiceSessionId, priorityHint);
+    }
+    /**
+     * Instantiate a CA system of the specified system id with EvenListener.
+     *
+     * @param context the context of the caller.
+     * @param casSystemId The system id of the CA system.
+     * @param tvInputServiceSessionId The Id of the session opened in TV Input Service (TIS)
+     *        {@link android.media.tv.TvInputService#onCreateSession(String, String)}
+     * @param priorityHint priority hint from the use case type for new created CAS system.
+     * @param listener the event listener to be set.
+     * @param handler the handler whose looper the event listener will be called on.
+     * If handler is null, we'll try to use current thread's looper, or the main
+     * looper. If neither are available, an internal thread will be created instead.
+     *
+     * @throws UnsupportedCasException if the device does not support the
+     * specified CA system.
+     */
+    public MediaCas(@NonNull Context context, int casSystemId,
+            @Nullable String tvInputServiceSessionId,
+            @PriorityHintUseCaseType int priorityHint,
+            @Nullable Handler handler, @Nullable EventListener listener)
+            throws UnsupportedCasException {
+        Objects.requireNonNull(context, "context must not be null");
+        setEventListener(listener, handler);
+        createPlugin(casSystemId);
+        registerClient(context, tvInputServiceSessionId, priorityHint);
+    }
+
+    IHwBinder getBinder() {
+        validateInternalStates();
+
+        return mICas.asBinder();
+    }
+
+    /**
+     * An interface registered by the caller to {@link #setEventListener}
+     * to receives scheme-specific notifications from a MediaCas instance.
+     */
+    public interface EventListener {
+
+        /**
+         * Notify the listener of a scheme-specific event from the CA system.
+         *
+         * @param mediaCas the MediaCas object to receive this event.
+         * @param event an integer whose meaning is scheme-specific.
+         * @param arg an integer whose meaning is scheme-specific.
+         * @param data a byte array of data whose format and meaning are
+         * scheme-specific.
+         */
+        void onEvent(@NonNull MediaCas mediaCas, int event, int arg, @Nullable byte[] data);
+
+        /**
+         * Notify the listener of a scheme-specific session event from CA system.
+         *
+         * @param mediaCas the MediaCas object to receive this event.
+         * @param session session object which the event is for.
+         * @param event an integer whose meaning is scheme-specific.
+         * @param arg an integer whose meaning is scheme-specific.
+         * @param data a byte array of data whose format and meaning are
+         * scheme-specific.
+         */
+        default void onSessionEvent(@NonNull MediaCas mediaCas, @NonNull Session session,
+                int event, int arg, @Nullable byte[] data) {
+            Log.d(TAG, "Received MediaCas Session event");
+        }
+
+        /**
+         * Notify the listener that the cas plugin status is updated.
+         *
+         * @param mediaCas the MediaCas object to receive this event.
+         * @param status the plugin status which is updated.
+         * @param arg an integer whose meaning is specific to the status to be updated.
+         */
+        default void onPluginStatusUpdate(@NonNull MediaCas mediaCas, @PluginStatus int status,
+                int arg) {
+            Log.d(TAG, "Received MediaCas Plugin Status event");
+        }
+
+        /**
+         * Notify the listener that the session resources was lost.
+         *
+         * @param mediaCas the MediaCas object to receive this event.
+         */
+        default void onResourceLost(@NonNull MediaCas mediaCas) {
+            Log.d(TAG, "Received MediaCas Resource Reclaim event");
+        }
+    }
+
+    /**
+     * Set an event listener to receive notifications from the MediaCas instance.
+     *
+     * @param listener the event listener to be set.
+     * @param handler the handler whose looper the event listener will be called on.
+     * If handler is null, we'll try to use current thread's looper, or the main
+     * looper. If neither are available, an internal thread will be created instead.
+     */
+    public void setEventListener(
+            @Nullable EventListener listener, @Nullable Handler handler) {
+        mListener = listener;
+
+        if (mListener == null) {
+            mEventHandler = null;
+            return;
+        }
+
+        Looper looper = (handler != null) ? handler.getLooper() : null;
+        if (looper == null
+                && (looper = Looper.myLooper()) == null
+                && (looper = Looper.getMainLooper()) == null) {
+            if (mHandlerThread == null || !mHandlerThread.isAlive()) {
+                mHandlerThread = new HandlerThread("MediaCasEventThread",
+                        Process.THREAD_PRIORITY_FOREGROUND);
+                mHandlerThread.start();
+            }
+            looper = mHandlerThread.getLooper();
+        }
+        mEventHandler = new EventHandler(looper);
+    }
+
+    /**
+     * Send the private data for the CA system.
+     *
+     * @param data byte array of the private data.
+     *
+     * @throws IllegalStateException if the MediaCas instance is not valid.
+     * @throws MediaCasException for CAS-specific errors.
+     * @throws MediaCasStateException for CAS-specific state exceptions.
+     */
+    public void setPrivateData(@NonNull byte[] data) throws MediaCasException {
+        validateInternalStates();
+
+        try {
+            MediaCasException.throwExceptionIfNeeded(
+                    mICas.setPrivateData(toByteArray(data, 0, data.length)));
+        } catch (RemoteException e) {
+            cleanupAndRethrowIllegalState();
+        }
+    }
+
+    private class OpenSessionCallback implements android.hardware.cas.V1_1.ICas.openSessionCallback{
+        public Session mSession;
+        public int mStatus;
+        @Override
+        public void onValues(int status, ArrayList<Byte> sessionId) {
+            mStatus = status;
+            mSession = createFromSessionId(sessionId);
+        }
+    }
+
+    private class OpenSession_1_2_Callback implements
+            android.hardware.cas.V1_2.ICas.openSession_1_2Callback {
+
+        public Session mSession;
+        public int mStatus;
+
+        @Override
+        public void onValues(int status, ArrayList<Byte> sessionId) {
+            mStatus = status;
+            mSession = createFromSessionId(sessionId);
+        }
+    }
+
+    private int getSessionResourceHandle() throws MediaCasException {
+        validateInternalStates();
+
+        int[] sessionResourceHandle = new int[1];
+        sessionResourceHandle[0] = -1;
+        if (mTunerResourceManager != null) {
+            CasSessionRequest casSessionRequest = new CasSessionRequest();
+            casSessionRequest.clientId = mClientId;
+            casSessionRequest.casSystemId = mCasSystemId;
+            if (!mTunerResourceManager
+                    .requestCasSession(casSessionRequest, sessionResourceHandle)) {
+                throw new MediaCasException.InsufficientResourceException(
+                    "insufficient resource to Open Session");
+            }
+        }
+        return sessionResourceHandle[0];
+    }
+
+    private void addSessionToResourceMap(Session session, int sessionResourceHandle) {
+
+        if (sessionResourceHandle != TunerResourceManager.INVALID_RESOURCE_HANDLE) {
+            synchronized (mSessionMap) {
+                mSessionMap.put(session, sessionResourceHandle);
+            }
+        }
+    }
+
+    private void removeSessionFromResourceMap(Session session) {
+
+        synchronized (mSessionMap) {
+            if (mSessionMap.get(session) != null) {
+                mTunerResourceManager.releaseCasSession(mSessionMap.get(session), mClientId);
+                mSessionMap.remove(session);
+            }
+        }
+    }
+
+    /**
+     * Open a session to descramble one or more streams scrambled by the
+     * conditional access system.
+     *
+     * <p>Tuner resource manager (TRM) uses the client priority value to decide whether it is able
+     * to get cas session resource if cas session resources is limited. If the client can't get the
+     * resource, this call returns {@link MediaCasException.InsufficientResourceException }.
+     *
+     * @return session the newly opened session.
+     *
+     * @throws IllegalStateException if the MediaCas instance is not valid.
+     * @throws MediaCasException for CAS-specific errors.
+     * @throws MediaCasStateException for CAS-specific state exceptions.
+     */
+    public Session openSession() throws MediaCasException {
+        int sessionResourceHandle = getSessionResourceHandle();
+
+        try {
+            OpenSessionCallback cb = new OpenSessionCallback();
+            mICas.openSession(cb);
+            MediaCasException.throwExceptionIfNeeded(cb.mStatus);
+            addSessionToResourceMap(cb.mSession, sessionResourceHandle);
+            Log.d(TAG, "Write Stats Log for succeed to Open Session.");
+            FrameworkStatsLog
+                    .write(FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS, mUserId, mCasSystemId,
+                        FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS__STATE__SUCCEEDED);
+            return cb.mSession;
+        } catch (RemoteException e) {
+            cleanupAndRethrowIllegalState();
+        }
+        Log.d(TAG, "Write Stats Log for fail to Open Session.");
+        FrameworkStatsLog
+                .write(FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS, mUserId, mCasSystemId,
+                    FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS__STATE__FAILED);
+        return null;
+    }
+
+    /**
+     * Open a session with usage and scrambling information, so that descrambler can be configured
+     * to descramble one or more streams scrambled by the conditional access system.
+     *
+     * <p>Tuner resource manager (TRM) uses the client priority value to decide whether it is able
+     * to get cas session resource if cas session resources is limited. If the client can't get the
+     * resource, this call returns {@link MediaCasException.InsufficientResourceException}.
+     *
+     * @param sessionUsage used for the created session.
+     * @param scramblingMode used for the created session.
+     *
+     * @return session the newly opened session.
+     *
+     * @throws IllegalStateException if the MediaCas instance is not valid.
+     * @throws MediaCasException for CAS-specific errors.
+     * @throws MediaCasStateException for CAS-specific state exceptions.
+     */
+    @Nullable
+    public Session openSession(@SessionUsage int sessionUsage, @ScramblingMode int scramblingMode)
+            throws MediaCasException {
+        int sessionResourceHandle = getSessionResourceHandle();
+
+        if (mICasV12 == null) {
+            Log.d(TAG, "Open Session with scrambling mode is only supported by cas@1.2+ interface");
+            throw new UnsupportedCasException("Open Session with scrambling mode is not supported");
+        }
+
+        try {
+            OpenSession_1_2_Callback cb = new OpenSession_1_2_Callback();
+            mICasV12.openSession_1_2(sessionUsage, scramblingMode, cb);
+            MediaCasException.throwExceptionIfNeeded(cb.mStatus);
+            addSessionToResourceMap(cb.mSession, sessionResourceHandle);
+            Log.d(TAG, "Write Stats Log for succeed to Open Session.");
+            FrameworkStatsLog
+                    .write(FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS, mUserId, mCasSystemId,
+                        FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS__STATE__SUCCEEDED);
+            return cb.mSession;
+        } catch (RemoteException e) {
+            cleanupAndRethrowIllegalState();
+        }
+        Log.d(TAG, "Write Stats Log for fail to Open Session.");
+        FrameworkStatsLog
+                .write(FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS, mUserId, mCasSystemId,
+                    FrameworkStatsLog.TV_CAS_SESSION_OPEN_STATUS__STATE__FAILED);
+        return null;
+    }
+
+    /**
+     * Send a received EMM packet to the CA system.
+     *
+     * @param data byte array of the EMM data.
+     * @param offset position within data where the EMM data begins.
+     * @param length length of the data (starting from offset).
+     *
+     * @throws IllegalStateException if the MediaCas instance is not valid.
+     * @throws MediaCasException for CAS-specific errors.
+     * @throws MediaCasStateException for CAS-specific state exceptions.
+     */
+    public void processEmm(@NonNull byte[] data, int offset, int length)
+            throws MediaCasException {
+        validateInternalStates();
+
+        try {
+            MediaCasException.throwExceptionIfNeeded(
+                    mICas.processEmm(toByteArray(data, offset, length)));
+        } catch (RemoteException e) {
+            cleanupAndRethrowIllegalState();
+        }
+    }
+
+    /**
+     * Send a received EMM packet to the CA system. This is similar to
+     * {@link #processEmm(byte[], int, int)} except that the entire byte
+     * array is sent.
+     *
+     * @param data byte array of the EMM data.
+     *
+     * @throws IllegalStateException if the MediaCas instance is not valid.
+     * @throws MediaCasException for CAS-specific errors.
+     * @throws MediaCasStateException for CAS-specific state exceptions.
+     */
+    public void processEmm(@NonNull byte[] data) throws MediaCasException {
+        processEmm(data, 0, data.length);
+    }
+
+    /**
+     * Send an event to a CA system. The format of the event is scheme-specific
+     * and is opaque to the framework.
+     *
+     * @param event an integer denoting a scheme-specific event to be sent.
+     * @param arg a scheme-specific integer argument for the event.
+     * @param data a byte array containing scheme-specific data for the event.
+     *
+     * @throws IllegalStateException if the MediaCas instance is not valid.
+     * @throws MediaCasException for CAS-specific errors.
+     * @throws MediaCasStateException for CAS-specific state exceptions.
+     */
+    public void sendEvent(int event, int arg, @Nullable byte[] data)
+            throws MediaCasException {
+        validateInternalStates();
+
+        try {
+            MediaCasException.throwExceptionIfNeeded(
+                    mICas.sendEvent(event, arg, toByteArray(data)));
+        } catch (RemoteException e) {
+            cleanupAndRethrowIllegalState();
+        }
+    }
+
+   /**
+     * Initiate a provisioning operation for a CA system.
+     *
+     * @param provisionString string containing information needed for the
+     * provisioning operation, the format of which is scheme and implementation
+     * specific.
+     *
+     * @throws IllegalStateException if the MediaCas instance is not valid.
+     * @throws MediaCasException for CAS-specific errors.
+     * @throws MediaCasStateException for CAS-specific state exceptions.
+     */
+    public void provision(@NonNull String provisionString) throws MediaCasException {
+        validateInternalStates();
+
+        try {
+            MediaCasException.throwExceptionIfNeeded(
+                    mICas.provision(provisionString));
+        } catch (RemoteException e) {
+            cleanupAndRethrowIllegalState();
+        }
+    }
+
+    /**
+     * Notify the CA system to refresh entitlement keys.
+     *
+     * @param refreshType the type of the refreshment.
+     * @param refreshData private data associated with the refreshment.
+     *
+     * @throws IllegalStateException if the MediaCas instance is not valid.
+     * @throws MediaCasException for CAS-specific errors.
+     * @throws MediaCasStateException for CAS-specific state exceptions.
+     */
+    public void refreshEntitlements(int refreshType, @Nullable byte[] refreshData)
+            throws MediaCasException {
+        validateInternalStates();
+
+        try {
+            MediaCasException.throwExceptionIfNeeded(
+                    mICas.refreshEntitlements(refreshType, toByteArray(refreshData)));
+        } catch (RemoteException e) {
+            cleanupAndRethrowIllegalState();
+        }
+    }
+
+    /**
+     * Release Cas session. This is primarily used as a test API for CTS.
+     * @hide
+     */
+    @TestApi
+    public void forceResourceLost() {
+        if (mResourceListener != null) {
+            mResourceListener.onReclaimResources();
+        }
+    }
+
+    @Override
+    public void close() {
+        if (mICas != null) {
+            try {
+                mICas.release();
+            } catch (RemoteException e) {
+            } finally {
+                mICas = null;
+            }
+        }
+
+        if (mTunerResourceManager != null) {
+            mTunerResourceManager.unregisterClientProfile(mClientId);
+            mTunerResourceManager = null;
+        }
+
+        if (mHandlerThread != null) {
+            mHandlerThread.quit();
+            mHandlerThread = null;
+        }
+    }
+
+    @Override
+    protected void finalize() {
+        close();
+    }
+}
diff --git a/android/media/MediaCasException.java b/android/media/MediaCasException.java
new file mode 100644
index 0000000..349e9b3
--- /dev/null
+++ b/android/media/MediaCasException.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2017 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.hardware.cas.V1_2.Status;
+
+/**
+ * Base class for MediaCas exceptions
+ */
+public class MediaCasException extends Exception {
+    private MediaCasException(String detailMessage) {
+        super(detailMessage);
+    }
+
+    static void throwExceptionIfNeeded(int error) throws MediaCasException {
+        if (error == Status.OK) {
+            return;
+        }
+
+        if (error == Status.ERROR_CAS_NOT_PROVISIONED) {
+            throw new NotProvisionedException(null);
+        } else if (error == Status.ERROR_CAS_RESOURCE_BUSY) {
+            throw new ResourceBusyException(null);
+        } else if (error == Status.ERROR_CAS_DEVICE_REVOKED) {
+            throw new DeniedByServerException(null);
+        } else {
+            MediaCasStateException.throwExceptionIfNeeded(error);
+        }
+    }
+
+    /**
+     * Exception thrown when an attempt is made to construct a MediaCas object
+     * using a CA_system_id that is not supported by the device
+     */
+    public static final class UnsupportedCasException extends MediaCasException {
+        /** @hide */
+        public UnsupportedCasException(String detailMessage) {
+            super(detailMessage);
+        }
+    }
+
+    /**
+     * Exception thrown when an operation on a MediaCas object is attempted
+     * before it's provisioned successfully.
+     */
+    public static final class NotProvisionedException extends MediaCasException {
+        /** @hide */
+        public NotProvisionedException(String detailMessage) {
+            super(detailMessage);
+        }
+    }
+
+    /**
+     * Exception thrown when the provisioning server or key server denies a
+     * license for a device.
+     */
+    public static final class DeniedByServerException extends MediaCasException {
+        /** @hide */
+        public DeniedByServerException(String detailMessage) {
+            super(detailMessage);
+        }
+    }
+
+    /**
+     * Exception thrown when an operation on a MediaCas object is attempted
+     * and hardware resources are not available, due to being in use.
+     */
+    public static final class ResourceBusyException extends MediaCasException {
+        /** @hide */
+        public ResourceBusyException(String detailMessage) {
+            super(detailMessage);
+        }
+    }
+
+    /**
+     * Exception thrown when an operation on a MediaCas object is attempted
+     * and hardware resources are not sufficient to allocate, due to client's lower priority.
+     */
+    public static final class InsufficientResourceException extends MediaCasException {
+        /** @hide */
+        public InsufficientResourceException(String detailMessage) {
+            super(detailMessage);
+        }
+    }
+}
diff --git a/android/media/MediaCasStateException.java b/android/media/MediaCasStateException.java
new file mode 100644
index 0000000..8dbc9f4
--- /dev/null
+++ b/android/media/MediaCasStateException.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2017 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.hardware.cas.V1_2.Status;
+
+/**
+ * Base class for MediaCas runtime exceptions
+ */
+public class MediaCasStateException extends IllegalStateException {
+    private final int mErrorCode;
+    private final String mDiagnosticInfo;
+
+    private MediaCasStateException(int err, @Nullable String msg, @Nullable String diagnosticInfo) {
+        super(msg);
+        mErrorCode = err;
+        mDiagnosticInfo = diagnosticInfo;
+    }
+
+    static void throwExceptionIfNeeded(int err) {
+        throwExceptionIfNeeded(err, null /* msg */);
+    }
+
+    static void throwExceptionIfNeeded(int err, @Nullable String msg) {
+        if (err == Status.OK) {
+            return;
+        }
+        if (err == Status.BAD_VALUE) {
+            throw new IllegalArgumentException();
+        }
+
+        String diagnosticInfo = "";
+        switch (err) {
+            case Status.ERROR_CAS_UNKNOWN:
+                diagnosticInfo = "General CAS error";
+                break;
+            case Status.ERROR_CAS_NO_LICENSE:
+                diagnosticInfo = "No license";
+                break;
+            case Status.ERROR_CAS_LICENSE_EXPIRED:
+                diagnosticInfo = "License expired";
+                break;
+            case Status.ERROR_CAS_SESSION_NOT_OPENED:
+                diagnosticInfo = "Session not opened";
+                break;
+            case Status.ERROR_CAS_CANNOT_HANDLE:
+                diagnosticInfo = "Unsupported scheme or data format";
+                break;
+            case Status.ERROR_CAS_INVALID_STATE:
+                diagnosticInfo = "Invalid CAS state";
+                break;
+            case Status.ERROR_CAS_INSUFFICIENT_OUTPUT_PROTECTION:
+                diagnosticInfo = "Insufficient output protection";
+                break;
+            case Status.ERROR_CAS_TAMPER_DETECTED:
+                diagnosticInfo = "Tamper detected";
+                break;
+            case Status.ERROR_CAS_DECRYPT_UNIT_NOT_INITIALIZED:
+                diagnosticInfo = "Not initialized";
+                break;
+            case Status.ERROR_CAS_DECRYPT:
+                diagnosticInfo = "Decrypt error";
+                break;
+            case Status.ERROR_CAS_NEED_ACTIVATION:
+                diagnosticInfo = "Need Activation";
+                break;
+            case Status.ERROR_CAS_NEED_PAIRING:
+                diagnosticInfo = "Need Pairing";
+                break;
+            case Status.ERROR_CAS_NO_CARD:
+                diagnosticInfo = "No Card";
+                break;
+            case Status.ERROR_CAS_CARD_MUTE:
+                diagnosticInfo = "Card Muted";
+                break;
+            case Status.ERROR_CAS_CARD_INVALID:
+                diagnosticInfo = "Card Invalid";
+                break;
+            case Status.ERROR_CAS_BLACKOUT:
+                diagnosticInfo = "Blackout";
+                break;
+            case Status.ERROR_CAS_REBOOTING:
+                diagnosticInfo = "Rebooting";
+                break;
+            default:
+                diagnosticInfo = "Unknown CAS state exception";
+                break;
+        }
+        throw new MediaCasStateException(err, msg,
+                String.format("%s (err=%d)", diagnosticInfo, err));
+    }
+
+    /**
+     * Retrieve the associated error code
+     *
+     * @hide
+     */
+    public int getErrorCode() {
+        return mErrorCode;
+    }
+
+    /**
+     * Retrieve a developer-readable diagnostic information string
+     * associated with the exception. Do not show this to end-users,
+     * since this string will not be localized or generally comprehensible
+     * to end-users.
+     */
+    @NonNull
+    public String getDiagnosticInfo() {
+        return mDiagnosticInfo;
+    }
+}
diff --git a/android/media/MediaCodec.java b/android/media/MediaCodec.java
new file mode 100644
index 0000000..8b91536
--- /dev/null
+++ b/android/media/MediaCodec.java
@@ -0,0 +1,5323 @@
+/*
+ * Copyright (C) 2012 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.graphics.ImageFormat;
+import android.graphics.Rect;
+import android.graphics.SurfaceTexture;
+import android.hardware.HardwareBuffer;
+import android.media.MediaCodecInfo.CodecCapabilities;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IHwBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.PersistableBundle;
+import android.view.Surface;
+
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.ReadOnlyBufferException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+/**
+ MediaCodec class can be used to access low-level media codecs, i.e. encoder/decoder components.
+ It is part of the Android low-level multimedia support infrastructure (normally used together
+ with {@link MediaExtractor}, {@link MediaSync}, {@link MediaMuxer}, {@link MediaCrypto},
+ {@link MediaDrm}, {@link Image}, {@link Surface}, and {@link AudioTrack}.)
+ <p>
+ <center><object style="width: 540px; height: 205px;" type="image/svg+xml"
+   data="../../../images/media/mediacodec_buffers.svg"><img
+   src="../../../images/media/mediacodec_buffers.png" style="width: 540px; height: 205px"
+   alt="MediaCodec buffer flow diagram"></object></center>
+ <p>
+ In broad terms, a codec processes input data to generate output data. It processes data
+ asynchronously and uses a set of input and output buffers. At a simplistic level, you request
+ (or receive) an empty input buffer, fill it up with data and send it to the codec for
+ processing. The codec uses up the data and transforms it into one of its empty output buffers.
+ Finally, you request (or receive) a filled output buffer, consume its contents and release it
+ back to the codec.
+
+ <h3 id=qualityFloor><a name="qualityFloor">Minimum Quality Floor for Video Encoding</h3>
+ <p>
+ Beginning with {@link android.os.Build.VERSION_CODES#S}, Android's Video MediaCodecs enforce a
+ minimum quality floor. The intent is to eliminate poor quality video encodings. This quality
+ floor is applied when the codec is in Variable Bitrate (VBR) mode; it is not applied when
+ the codec is in Constant Bitrate (CBR) mode. The quality floor enforcement is also restricted
+ to a particular size range; this size range is currently for video resolutions
+ larger than 320x240 up through 1920x1080.
+
+ <p>
+ When this quality floor is in effect, the codec and supporting framework code will work to
+ ensure that the generated video is of at least a "fair" or "good" quality. The metric
+ used to choose these targets is the VMAF (Video Multi-method Assessment Function) with a
+ target score of 70 for selected test sequences.
+
+ <p>
+ The typical effect is that
+ some videos will generate a higher bitrate than originally configured. This will be most
+ notable for videos which were configured with very low bitrates; the codec will use a bitrate
+ that is determined to be more likely to generate an "fair" or "good" quality video. Another
+ situation is where a video includes very complicated content (lots of motion and detail);
+ in such configurations, the codec will use extra bitrate as needed to avoid losing all of
+ the content's finer detail.
+
+ <p>
+ This quality floor will not impact content captured at high bitrates (a high bitrate should
+ already provide the codec with sufficient capacity to encode all of the detail).
+ The quality floor does not operate on CBR encodings.
+ The quality floor currently does not operate on resolutions of 320x240 or lower, nor on
+ videos with resolution above 1920x1080.
+
+ <h3>Data Types</h3>
+ <p>
+ Codecs operate on three kinds of data: compressed data, raw audio data and raw video data.
+ All three kinds of data can be processed using {@link ByteBuffer ByteBuffers}, but you should use
+ a {@link Surface} for raw video data to improve codec performance. Surface uses native video
+ buffers without mapping or copying them to ByteBuffers; thus, it is much more efficient.
+ You normally cannot access the raw video data when using a Surface, but you can use the
+ {@link ImageReader} class to access unsecured decoded (raw) video frames. This may still be more
+ efficient than using ByteBuffers, as some native buffers may be mapped into {@linkplain
+ ByteBuffer#isDirect direct} ByteBuffers. When using ByteBuffer mode, you can access raw video
+ frames using the {@link Image} class and {@link #getInputImage getInput}/{@link #getOutputImage
+ OutputImage(int)}.
+
+ <h4>Compressed Buffers</h4>
+ <p>
+ Input buffers (for decoders) and output buffers (for encoders) contain compressed data according
+ to the {@linkplain MediaFormat#KEY_MIME format's type}. For video types this is normally a single
+ compressed video frame. For audio data this is normally a single access unit (an encoded audio
+ segment typically containing a few milliseconds of audio as dictated by the format type), but
+ this requirement is slightly relaxed in that a buffer may contain multiple encoded access units
+ of audio. In either case, buffers do not start or end on arbitrary byte boundaries, but rather on
+ frame/access unit boundaries unless they are flagged with {@link #BUFFER_FLAG_PARTIAL_FRAME}.
+
+ <h4>Raw Audio Buffers</h4>
+ <p>
+ Raw audio buffers contain entire frames of PCM audio data, which is one sample for each channel
+ in channel order. Each PCM audio sample is either a 16 bit signed integer or a float,
+ in native byte order.
+ Raw audio buffers in the float PCM encoding are only possible
+ if the MediaFormat's {@linkplain MediaFormat#KEY_PCM_ENCODING}
+ is set to {@linkplain AudioFormat#ENCODING_PCM_FLOAT} during MediaCodec
+ {@link #configure configure(&hellip;)}
+ and confirmed by {@link #getOutputFormat} for decoders
+ or {@link #getInputFormat} for encoders.
+ A sample method to check for float PCM in the MediaFormat is as follows:
+
+ <pre class=prettyprint>
+ static boolean isPcmFloat(MediaFormat format) {
+   return format.getInteger(MediaFormat.KEY_PCM_ENCODING, AudioFormat.ENCODING_PCM_16BIT)
+       == AudioFormat.ENCODING_PCM_FLOAT;
+ }</pre>
+
+ In order to extract, in a short array,
+ one channel of a buffer containing 16 bit signed integer audio data,
+ the following code may be used:
+
+ <pre class=prettyprint>
+ // Assumes the buffer PCM encoding is 16 bit.
+ short[] getSamplesForChannel(MediaCodec codec, int bufferId, int channelIx) {
+   ByteBuffer outputBuffer = codec.getOutputBuffer(bufferId);
+   MediaFormat format = codec.getOutputFormat(bufferId);
+   ShortBuffer samples = outputBuffer.order(ByteOrder.nativeOrder()).asShortBuffer();
+   int numChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
+   if (channelIx &lt; 0 || channelIx &gt;= numChannels) {
+     return null;
+   }
+   short[] res = new short[samples.remaining() / numChannels];
+   for (int i = 0; i &lt; res.length; ++i) {
+     res[i] = samples.get(i * numChannels + channelIx);
+   }
+   return res;
+ }</pre>
+
+ <h4>Raw Video Buffers</h4>
+ <p>
+ In ByteBuffer mode video buffers are laid out according to their {@linkplain
+ MediaFormat#KEY_COLOR_FORMAT color format}. You can get the supported color formats as an array
+ from {@link #getCodecInfo}{@code .}{@link MediaCodecInfo#getCapabilitiesForType
+ getCapabilitiesForType(&hellip;)}{@code .}{@link CodecCapabilities#colorFormats colorFormats}.
+ Video codecs may support three kinds of color formats:
+ <ul>
+ <li><strong>native raw video format:</strong> This is marked by {@link
+ CodecCapabilities#COLOR_FormatSurface} and it can be used with an input or output Surface.</li>
+ <li><strong>flexible YUV buffers</strong> (such as {@link
+ CodecCapabilities#COLOR_FormatYUV420Flexible}): These can be used with an input/output Surface,
+ as well as in ByteBuffer mode, by using {@link #getInputImage getInput}/{@link #getOutputImage
+ OutputImage(int)}.</li>
+ <li><strong>other, specific formats:</strong> These are normally only supported in ByteBuffer
+ mode. Some color formats are vendor specific. Others are defined in {@link CodecCapabilities}.
+ For color formats that are equivalent to a flexible format, you can still use {@link
+ #getInputImage getInput}/{@link #getOutputImage OutputImage(int)}.</li>
+ </ul>
+ <p>
+ All video codecs support flexible YUV 4:2:0 buffers since {@link
+ android.os.Build.VERSION_CODES#LOLLIPOP_MR1}.
+
+ <h4>Accessing Raw Video ByteBuffers on Older Devices</h4>
+ <p>
+ Prior to {@link android.os.Build.VERSION_CODES#LOLLIPOP} and {@link Image} support, you need to
+ use the {@link MediaFormat#KEY_STRIDE} and {@link MediaFormat#KEY_SLICE_HEIGHT} output format
+ values to understand the layout of the raw output buffers.
+ <p class=note>
+ Note that on some devices the slice-height is advertised as 0. This could mean either that the
+ slice-height is the same as the frame height, or that the slice-height is the frame height
+ aligned to some value (usually a power of 2). Unfortunately, there is no standard and simple way
+ to tell the actual slice height in this case. Furthermore, the vertical stride of the {@code U}
+ plane in planar formats is also not specified or defined, though usually it is half of the slice
+ height.
+ <p>
+ The {@link MediaFormat#KEY_WIDTH} and {@link MediaFormat#KEY_HEIGHT} keys specify the size of the
+ video frames; however, for most encondings the video (picture) only occupies a portion of the
+ video frame. This is represented by the 'crop rectangle'.
+ <p>
+ You need to use the following keys to get the crop rectangle of raw output images from the
+ {@linkplain #getOutputFormat output format}. If these keys are not present, the video occupies the
+ entire video frame.The crop rectangle is understood in the context of the output frame
+ <em>before</em> applying any {@linkplain MediaFormat#KEY_ROTATION rotation}.
+ <table style="width: 0%">
+  <thead>
+   <tr>
+    <th>Format Key</th>
+    <th>Type</th>
+    <th>Description</th>
+   </tr>
+  </thead>
+  <tbody>
+   <tr>
+    <td>{@code "crop-left"}</td>
+    <td>Integer</td>
+    <td>The left-coordinate (x) of the crop rectangle</td>
+   </tr><tr>
+    <td>{@code "crop-top"}</td>
+    <td>Integer</td>
+    <td>The top-coordinate (y) of the crop rectangle</td>
+   </tr><tr>
+    <td>{@code "crop-right"}</td>
+    <td>Integer</td>
+    <td>The right-coordinate (x) <strong>MINUS 1</strong> of the crop rectangle</td>
+   </tr><tr>
+    <td>{@code "crop-bottom"}</td>
+    <td>Integer</td>
+    <td>The bottom-coordinate (y) <strong>MINUS 1</strong> of the crop rectangle</td>
+   </tr><tr>
+    <td colspan=3>
+     The right and bottom coordinates can be understood as the coordinates of the right-most
+     valid column/bottom-most valid row of the cropped output image.
+    </td>
+   </tr>
+  </tbody>
+ </table>
+ <p>
+ The size of the video frame (before rotation) can be calculated as such:
+ <pre class=prettyprint>
+ MediaFormat format = decoder.getOutputFormat(&hellip;);
+ int width = format.getInteger(MediaFormat.KEY_WIDTH);
+ if (format.containsKey("crop-left") && format.containsKey("crop-right")) {
+     width = format.getInteger("crop-right") + 1 - format.getInteger("crop-left");
+ }
+ int height = format.getInteger(MediaFormat.KEY_HEIGHT);
+ if (format.containsKey("crop-top") && format.containsKey("crop-bottom")) {
+     height = format.getInteger("crop-bottom") + 1 - format.getInteger("crop-top");
+ }
+ </pre>
+ <p class=note>
+ Also note that the meaning of {@link BufferInfo#offset BufferInfo.offset} was not consistent across
+ devices. On some devices the offset pointed to the top-left pixel of the crop rectangle, while on
+ most devices it pointed to the top-left pixel of the entire frame.
+
+ <h3>States</h3>
+ <p>
+ During its life a codec conceptually exists in one of three states: Stopped, Executing or
+ Released. The Stopped collective state is actually the conglomeration of three states:
+ Uninitialized, Configured and Error, whereas the Executing state conceptually progresses through
+ three sub-states: Flushed, Running and End-of-Stream.
+ <p>
+ <center><object style="width: 516px; height: 353px;" type="image/svg+xml"
+   data="../../../images/media/mediacodec_states.svg"><img
+   src="../../../images/media/mediacodec_states.png" style="width: 519px; height: 356px"
+   alt="MediaCodec state diagram"></object></center>
+ <p>
+ When you create a codec using one of the factory methods, the codec is in the Uninitialized
+ state. First, you need to configure it via {@link #configure configure(&hellip;)}, which brings
+ it to the Configured state, then call {@link #start} to move it to the Executing state. In this
+ state you can process data through the buffer queue manipulation described above.
+ <p>
+ The Executing state has three sub-states: Flushed, Running and End-of-Stream. Immediately after
+ {@link #start} the codec is in the Flushed sub-state, where it holds all the buffers. As soon
+ as the first input buffer is dequeued, the codec moves to the Running sub-state, where it spends
+ most of its life. When you queue an input buffer with the {@linkplain #BUFFER_FLAG_END_OF_STREAM
+ end-of-stream marker}, the codec transitions to the End-of-Stream sub-state. In this state the
+ codec no longer accepts further input buffers, but still generates output buffers until the
+ end-of-stream is reached on the output. You can move back to the Flushed sub-state at any time
+ while in the Executing state using {@link #flush}.
+ <p>
+ Call {@link #stop} to return the codec to the Uninitialized state, whereupon it may be configured
+ again. When you are done using a codec, you must release it by calling {@link #release}.
+ <p>
+ On rare occasions the codec may encounter an error and move to the Error state. This is
+ communicated using an invalid return value from a queuing operation, or sometimes via an
+ exception. Call {@link #reset} to make the codec usable again. You can call it from any state to
+ move the codec back to the Uninitialized state. Otherwise, call {@link #release} to move to the
+ terminal Released state.
+
+ <h3>Creation</h3>
+ <p>
+ Use {@link MediaCodecList} to create a MediaCodec for a specific {@link MediaFormat}. When
+ decoding a file or a stream, you can get the desired format from {@link
+ MediaExtractor#getTrackFormat MediaExtractor.getTrackFormat}. Inject any specific features that
+ you want to add using {@link MediaFormat#setFeatureEnabled MediaFormat.setFeatureEnabled}, then
+ call {@link MediaCodecList#findDecoderForFormat MediaCodecList.findDecoderForFormat} to get the
+ name of a codec that can handle that specific media format. Finally, create the codec using
+ {@link #createByCodecName}.
+ <p class=note>
+ <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP}, the format to
+ {@code MediaCodecList.findDecoder}/{@code EncoderForFormat} must not contain a {@linkplain
+ MediaFormat#KEY_FRAME_RATE frame rate}. Use
+ <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
+ to clear any existing frame rate setting in the format.
+ <p>
+ You can also create the preferred codec for a specific MIME type using {@link
+ #createDecoderByType createDecoder}/{@link #createEncoderByType EncoderByType(String)}.
+ This, however, cannot be used to inject features, and may create a codec that cannot handle the
+ specific desired media format.
+
+ <h4>Creating secure decoders</h4>
+ <p>
+ On versions {@link android.os.Build.VERSION_CODES#KITKAT_WATCH} and earlier, secure codecs might
+ not be listed in {@link MediaCodecList}, but may still be available on the system. Secure codecs
+ that exist can be instantiated by name only, by appending {@code ".secure"} to the name of a
+ regular codec (the name of all secure codecs must end in {@code ".secure"}.) {@link
+ #createByCodecName} will throw an {@code IOException} if the codec is not present on the system.
+ <p>
+ From {@link android.os.Build.VERSION_CODES#LOLLIPOP} onwards, you should use the {@link
+ CodecCapabilities#FEATURE_SecurePlayback} feature in the media format to create a secure decoder.
+
+ <h3>Initialization</h3>
+ <p>
+ After creating the codec, you can set a callback using {@link #setCallback setCallback} if you
+ want to process data asynchronously. Then, {@linkplain #configure configure} the codec using the
+ specific media format. This is when you can specify the output {@link Surface} for video
+ producers &ndash; codecs that generate raw video data (e.g. video decoders). This is also when
+ you can set the decryption parameters for secure codecs (see {@link MediaCrypto}). Finally, since
+ some codecs can operate in multiple modes, you must specify whether you want it to work as a
+ decoder or an encoder.
+ <p>
+ Since {@link android.os.Build.VERSION_CODES#LOLLIPOP}, you can query the resulting input and
+ output format in the Configured state. You can use this to verify the resulting configuration,
+ e.g. color formats, before starting the codec.
+ <p>
+ If you want to process raw input video buffers natively with a video consumer &ndash; a codec
+ that processes raw video input, such as a video encoder &ndash; create a destination Surface for
+ your input data using {@link #createInputSurface} after configuration. Alternately, set up the
+ codec to use a previously created {@linkplain #createPersistentInputSurface persistent input
+ surface} by calling {@link #setInputSurface}.
+
+ <h4 id=CSD><a name="CSD"></a>Codec-specific Data</h4>
+ <p>
+ Some formats, notably AAC audio and MPEG4, H.264 and H.265 video formats require the actual data
+ to be prefixed by a number of buffers containing setup data, or codec specific data. When
+ processing such compressed formats, this data must be submitted to the codec after {@link
+ #start} and before any frame data. Such data must be marked using the flag {@link
+ #BUFFER_FLAG_CODEC_CONFIG} in a call to {@link #queueInputBuffer queueInputBuffer}.
+ <p>
+ Codec-specific data can also be included in the format passed to {@link #configure configure} in
+ ByteBuffer entries with keys "csd-0", "csd-1", etc. These keys are always included in the track
+ {@link MediaFormat} obtained from the {@link MediaExtractor#getTrackFormat MediaExtractor}.
+ Codec-specific data in the format is automatically submitted to the codec upon {@link #start};
+ you <strong>MUST NOT</strong> submit this data explicitly. If the format did not contain codec
+ specific data, you can choose to submit it using the specified number of buffers in the correct
+ order, according to the format requirements. In case of H.264 AVC, you can also concatenate all
+ codec-specific data and submit it as a single codec-config buffer.
+ <p>
+ Android uses the following codec-specific data buffers. These are also required to be set in
+ the track format for proper {@link MediaMuxer} track configuration. Each parameter set and the
+ codec-specific-data sections marked with (<sup>*</sup>) must start with a start code of
+ {@code "\x00\x00\x00\x01"}.
+ <p>
+ <style>td.NA { background: #ccc; } .mid > tr > td { vertical-align: middle; }</style>
+ <table>
+  <thead>
+   <th>Format</th>
+   <th>CSD buffer #0</th>
+   <th>CSD buffer #1</th>
+   <th>CSD buffer #2</th>
+  </thead>
+  <tbody class=mid>
+   <tr>
+    <td>AAC</td>
+    <td>Decoder-specific information from ESDS<sup>*</sup></td>
+    <td class=NA>Not Used</td>
+    <td class=NA>Not Used</td>
+   </tr>
+   <tr>
+    <td>VORBIS</td>
+    <td>Identification header</td>
+    <td>Setup header</td>
+    <td class=NA>Not Used</td>
+   </tr>
+   <tr>
+    <td>OPUS</td>
+    <td>Identification header</td>
+    <td>Pre-skip in nanosecs<br>
+        (unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)<br>
+        This overrides the pre-skip value in the identification header.</td>
+    <td>Seek Pre-roll in nanosecs<br>
+        (unsigned 64-bit {@linkplain ByteOrder#nativeOrder native-order} integer.)</td>
+   </tr>
+   <tr>
+    <td>FLAC</td>
+    <td>"fLaC", the FLAC stream marker in ASCII,<br>
+        followed by the STREAMINFO block (the mandatory metadata block),<br>
+        optionally followed by any number of other metadata blocks</td>
+    <td class=NA>Not Used</td>
+    <td class=NA>Not Used</td>
+   </tr>
+   <tr>
+    <td>MPEG-4</td>
+    <td>Decoder-specific information from ESDS<sup>*</sup></td>
+    <td class=NA>Not Used</td>
+    <td class=NA>Not Used</td>
+   </tr>
+   <tr>
+    <td>H.264 AVC</td>
+    <td>SPS (Sequence Parameter Sets<sup>*</sup>)</td>
+    <td>PPS (Picture Parameter Sets<sup>*</sup>)</td>
+    <td class=NA>Not Used</td>
+   </tr>
+   <tr>
+    <td>H.265 HEVC</td>
+    <td>VPS (Video Parameter Sets<sup>*</sup>) +<br>
+     SPS (Sequence Parameter Sets<sup>*</sup>) +<br>
+     PPS (Picture Parameter Sets<sup>*</sup>)</td>
+    <td class=NA>Not Used</td>
+    <td class=NA>Not Used</td>
+   </tr>
+   <tr>
+    <td>VP9</td>
+    <td>VP9 <a href="http://wiki.webmproject.org/vp9-codecprivate">CodecPrivate</a> Data
+        (optional)</td>
+    <td class=NA>Not Used</td>
+    <td class=NA>Not Used</td>
+   </tr>
+  </tbody>
+ </table>
+
+ <p class=note>
+ <strong>Note:</strong> care must be taken if the codec is flushed immediately or shortly
+ after start, before any output buffer or output format change has been returned, as the codec
+ specific data may be lost during the flush. You must resubmit the data using buffers marked with
+ {@link #BUFFER_FLAG_CODEC_CONFIG} after such flush to ensure proper codec operation.
+ <p>
+ Encoders (or codecs that generate compressed data) will create and return the codec specific data
+ before any valid output buffer in output buffers marked with the {@linkplain
+ #BUFFER_FLAG_CODEC_CONFIG codec-config flag}. Buffers containing codec-specific-data have no
+ meaningful timestamps.
+
+ <h3>Data Processing</h3>
+ <p>
+ Each codec maintains a set of input and output buffers that are referred to by a buffer-ID in
+ API calls. After a successful call to {@link #start} the client "owns" neither input nor output
+ buffers. In synchronous mode, call {@link #dequeueInputBuffer dequeueInput}/{@link
+ #dequeueOutputBuffer OutputBuffer(&hellip;)} to obtain (get ownership of) an input or output
+ buffer from the codec. In asynchronous mode, you will automatically receive available buffers via
+ the {@link Callback#onInputBufferAvailable MediaCodec.Callback.onInput}/{@link
+ Callback#onOutputBufferAvailable OutputBufferAvailable(&hellip;)} callbacks.
+ <p>
+ Upon obtaining an input buffer, fill it with data and submit it to the codec using {@link
+ #queueInputBuffer queueInputBuffer} &ndash; or {@link #queueSecureInputBuffer
+ queueSecureInputBuffer} if using decryption. Do not submit multiple input buffers with the same
+ timestamp (unless it is <a href="#CSD">codec-specific data</a> marked as such).
+ <p>
+ The codec in turn will return a read-only output buffer via the {@link
+ Callback#onOutputBufferAvailable onOutputBufferAvailable} callback in asynchronous mode, or in
+ response to a {@link #dequeueOutputBuffer dequeueOutputBuffer} call in synchronous mode. After the
+ output buffer has been processed, call one of the {@link #releaseOutputBuffer
+ releaseOutputBuffer} methods to return the buffer to the codec.
+ <p>
+ While you are not required to resubmit/release buffers immediately to the codec, holding onto
+ input and/or output buffers may stall the codec, and this behavior is device dependent.
+ <strong>Specifically, it is possible that a codec may hold off on generating output buffers until
+ <em>all</em> outstanding buffers have been released/resubmitted.</strong> Therefore, try to
+ hold onto to available buffers as little as possible.
+ <p>
+ Depending on the API version, you can process data in three ways:
+ <table>
+  <thead>
+   <tr>
+    <th>Processing Mode</th>
+    <th>API version <= 20<br>Jelly Bean/KitKat</th>
+    <th>API version >= 21<br>Lollipop and later</th>
+   </tr>
+  </thead>
+  <tbody>
+   <tr>
+    <td>Synchronous API using buffer arrays</td>
+    <td>Supported</td>
+    <td>Deprecated</td>
+   </tr>
+   <tr>
+    <td>Synchronous API using buffers</td>
+    <td class=NA>Not Available</td>
+    <td>Supported</td>
+   </tr>
+   <tr>
+    <td>Asynchronous API using buffers</td>
+    <td class=NA>Not Available</td>
+    <td>Supported</td>
+   </tr>
+  </tbody>
+ </table>
+
+ <h4>Asynchronous Processing using Buffers</h4>
+ <p>
+ Since {@link android.os.Build.VERSION_CODES#LOLLIPOP}, the preferred method is to process data
+ asynchronously by setting a callback before calling {@link #configure configure}. Asynchronous
+ mode changes the state transitions slightly, because you must call {@link #start} after {@link
+ #flush} to transition the codec to the Running sub-state and start receiving input buffers.
+ Similarly, upon an initial call to {@code start} the codec will move directly to the Running
+ sub-state and start passing available input buffers via the callback.
+ <p>
+ <center><object style="width: 516px; height: 353px;" type="image/svg+xml"
+   data="../../../images/media/mediacodec_async_states.svg"><img
+   src="../../../images/media/mediacodec_async_states.png" style="width: 516px; height: 353px"
+   alt="MediaCodec state diagram for asynchronous operation"></object></center>
+ <p>
+ MediaCodec is typically used like this in asynchronous mode:
+ <pre class=prettyprint>
+ MediaCodec codec = MediaCodec.createByCodecName(name);
+ MediaFormat mOutputFormat; // member variable
+ codec.setCallback(new MediaCodec.Callback() {
+   {@literal @Override}
+   void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
+     ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
+     // fill inputBuffer with valid data
+     &hellip;
+     codec.queueInputBuffer(inputBufferId, &hellip;);
+   }
+
+   {@literal @Override}
+   void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, &hellip;) {
+     ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
+     MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
+     // bufferFormat is equivalent to mOutputFormat
+     // outputBuffer is ready to be processed or rendered.
+     &hellip;
+     codec.releaseOutputBuffer(outputBufferId, &hellip;);
+   }
+
+   {@literal @Override}
+   void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {
+     // Subsequent data will conform to new format.
+     // Can ignore if using getOutputFormat(outputBufferId)
+     mOutputFormat = format; // option B
+   }
+
+   {@literal @Override}
+   void onError(&hellip;) {
+     &hellip;
+   }
+ });
+ codec.configure(format, &hellip;);
+ mOutputFormat = codec.getOutputFormat(); // option B
+ codec.start();
+ // wait for processing to complete
+ codec.stop();
+ codec.release();</pre>
+
+ <h4>Synchronous Processing using Buffers</h4>
+ <p>
+ Since {@link android.os.Build.VERSION_CODES#LOLLIPOP}, you should retrieve input and output
+ buffers using {@link #getInputBuffer getInput}/{@link #getOutputBuffer OutputBuffer(int)} and/or
+ {@link #getInputImage getInput}/{@link #getOutputImage OutputImage(int)} even when using the
+ codec in synchronous mode. This allows certain optimizations by the framework, e.g. when
+ processing dynamic content. This optimization is disabled if you call {@link #getInputBuffers
+ getInput}/{@link #getOutputBuffers OutputBuffers()}.
+
+ <p class=note>
+ <strong>Note:</strong> do not mix the methods of using buffers and buffer arrays at the same
+ time. Specifically, only call {@code getInput}/{@code OutputBuffers} directly after {@link
+ #start} or after having dequeued an output buffer ID with the value of {@link
+ #INFO_OUTPUT_FORMAT_CHANGED}.
+ <p>
+ MediaCodec is typically used like this in synchronous mode:
+ <pre>
+ MediaCodec codec = MediaCodec.createByCodecName(name);
+ codec.configure(format, &hellip;);
+ MediaFormat outputFormat = codec.getOutputFormat(); // option B
+ codec.start();
+ for (;;) {
+   int inputBufferId = codec.dequeueInputBuffer(timeoutUs);
+   if (inputBufferId &gt;= 0) {
+     ByteBuffer inputBuffer = codec.getInputBuffer(&hellip;);
+     // fill inputBuffer with valid data
+     &hellip;
+     codec.queueInputBuffer(inputBufferId, &hellip;);
+   }
+   int outputBufferId = codec.dequeueOutputBuffer(&hellip;);
+   if (outputBufferId &gt;= 0) {
+     ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
+     MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
+     // bufferFormat is identical to outputFormat
+     // outputBuffer is ready to be processed or rendered.
+     &hellip;
+     codec.releaseOutputBuffer(outputBufferId, &hellip;);
+   } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+     // Subsequent data will conform to new format.
+     // Can ignore if using getOutputFormat(outputBufferId)
+     outputFormat = codec.getOutputFormat(); // option B
+   }
+ }
+ codec.stop();
+ codec.release();</pre>
+
+ <h4>Synchronous Processing using Buffer Arrays (deprecated)</h4>
+ <p>
+ In versions {@link android.os.Build.VERSION_CODES#KITKAT_WATCH} and before, the set of input and
+ output buffers are represented by the {@code ByteBuffer[]} arrays. After a successful call to
+ {@link #start}, retrieve the buffer arrays using {@link #getInputBuffers getInput}/{@link
+ #getOutputBuffers OutputBuffers()}. Use the buffer ID-s as indices into these arrays (when
+ non-negative), as demonstrated in the sample below. Note that there is no inherent correlation
+ between the size of the arrays and the number of input and output buffers used by the system,
+ although the array size provides an upper bound.
+ <pre>
+ MediaCodec codec = MediaCodec.createByCodecName(name);
+ codec.configure(format, &hellip;);
+ codec.start();
+ ByteBuffer[] inputBuffers = codec.getInputBuffers();
+ ByteBuffer[] outputBuffers = codec.getOutputBuffers();
+ for (;;) {
+   int inputBufferId = codec.dequeueInputBuffer(&hellip;);
+   if (inputBufferId &gt;= 0) {
+     // fill inputBuffers[inputBufferId] with valid data
+     &hellip;
+     codec.queueInputBuffer(inputBufferId, &hellip;);
+   }
+   int outputBufferId = codec.dequeueOutputBuffer(&hellip;);
+   if (outputBufferId &gt;= 0) {
+     // outputBuffers[outputBufferId] is ready to be processed or rendered.
+     &hellip;
+     codec.releaseOutputBuffer(outputBufferId, &hellip;);
+   } else if (outputBufferId == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
+     outputBuffers = codec.getOutputBuffers();
+   } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
+     // Subsequent data will conform to new format.
+     MediaFormat format = codec.getOutputFormat();
+   }
+ }
+ codec.stop();
+ codec.release();</pre>
+
+ <h4>End-of-stream Handling</h4>
+ <p>
+ When you reach the end of the input data, you must signal it to the codec by specifying the
+ {@link #BUFFER_FLAG_END_OF_STREAM} flag in the call to {@link #queueInputBuffer
+ queueInputBuffer}. You can do this on the last valid input buffer, or by submitting an additional
+ empty input buffer with the end-of-stream flag set. If using an empty buffer, the timestamp will
+ be ignored.
+ <p>
+ The codec will continue to return output buffers until it eventually signals the end of the
+ output stream by specifying the same end-of-stream flag in the {@link BufferInfo} set in {@link
+ #dequeueOutputBuffer dequeueOutputBuffer} or returned via {@link Callback#onOutputBufferAvailable
+ onOutputBufferAvailable}. This can be set on the last valid output buffer, or on an empty buffer
+ after the last valid output buffer. The timestamp of such empty buffer should be ignored.
+ <p>
+ Do not submit additional input buffers after signaling the end of the input stream, unless the
+ codec has been flushed, or stopped and restarted.
+
+ <h4>Using an Output Surface</h4>
+ <p>
+ The data processing is nearly identical to the ByteBuffer mode when using an output {@link
+ Surface}; however, the output buffers will not be accessible, and are represented as {@code null}
+ values. E.g. {@link #getOutputBuffer getOutputBuffer}/{@link #getOutputImage Image(int)} will
+ return {@code null} and {@link #getOutputBuffers} will return an array containing only {@code
+ null}-s.
+ <p>
+ When using an output Surface, you can select whether or not to render each output buffer on the
+ surface. You have three choices:
+ <ul>
+ <li><strong>Do not render the buffer:</strong> Call {@link #releaseOutputBuffer(int, boolean)
+ releaseOutputBuffer(bufferId, false)}.</li>
+ <li><strong>Render the buffer with the default timestamp:</strong> Call {@link
+ #releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, true)}.</li>
+ <li><strong>Render the buffer with a specific timestamp:</strong> Call {@link
+ #releaseOutputBuffer(int, long) releaseOutputBuffer(bufferId, timestamp)}.</li>
+ </ul>
+ <p>
+ Since {@link android.os.Build.VERSION_CODES#M}, the default timestamp is the {@linkplain
+ BufferInfo#presentationTimeUs presentation timestamp} of the buffer (converted to nanoseconds).
+ It was not defined prior to that.
+ <p>
+ Also since {@link android.os.Build.VERSION_CODES#M}, you can change the output Surface
+ dynamically using {@link #setOutputSurface setOutputSurface}.
+ <p>
+ When rendering output to a Surface, the Surface may be configured to drop excessive frames (that
+ are not consumed by the Surface in a timely manner). Or it may be configured to not drop excessive
+ frames. In the latter mode if the Surface is not consuming output frames fast enough, it will
+ eventually block the decoder. Prior to {@link android.os.Build.VERSION_CODES#Q} the exact behavior
+ was undefined, with the exception that View surfaces (SurfaceView or TextureView) always dropped
+ excessive frames. Since {@link android.os.Build.VERSION_CODES#Q} the default behavior is to drop
+ excessive frames. Applications can opt out of this behavior for non-View surfaces (such as
+ ImageReader or SurfaceTexture) by targeting SDK {@link android.os.Build.VERSION_CODES#Q} and
+ setting the key {@link MediaFormat#KEY_ALLOW_FRAME_DROP} to {@code 0}
+ in their configure format.
+
+ <h4>Transformations When Rendering onto Surface</h4>
+
+ If the codec is configured into Surface mode, any crop rectangle, {@linkplain
+ MediaFormat#KEY_ROTATION rotation} and {@linkplain #setVideoScalingMode video scaling
+ mode} will be automatically applied with one exception:
+ <p class=note>
+ Prior to the {@link android.os.Build.VERSION_CODES#M} release, software decoders may not
+ have applied the rotation when being rendered onto a Surface. Unfortunately, there is no standard
+ and simple way to identify software decoders, or if they apply the rotation other than by trying
+ it out.
+ <p>
+ There are also some caveats.
+ <p class=note>
+ Note that the pixel aspect ratio is not considered when displaying the output onto the
+ Surface. This means that if you are using {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT} mode, you
+ must position the output Surface so that it has the proper final display aspect ratio. Conversely,
+ you can only use {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING} mode for content with
+ square pixels (pixel aspect ratio or 1:1).
+ <p class=note>
+ Note also that as of {@link android.os.Build.VERSION_CODES#N} release, {@link
+ #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING} mode may not work correctly for videos rotated
+ by 90 or 270 degrees.
+ <p class=note>
+ When setting the video scaling mode, note that it must be reset after each time the output
+ buffers change. Since the {@link #INFO_OUTPUT_BUFFERS_CHANGED} event is deprecated, you can
+ do this after each time the output format changes.
+
+ <h4>Using an Input Surface</h4>
+ <p>
+ When using an input Surface, there are no accessible input buffers, as buffers are automatically
+ passed from the input surface to the codec. Calling {@link #dequeueInputBuffer
+ dequeueInputBuffer} will throw an {@code IllegalStateException}, and {@link #getInputBuffers}
+ returns a bogus {@code ByteBuffer[]} array that <strong>MUST NOT</strong> be written into.
+ <p>
+ Call {@link #signalEndOfInputStream} to signal end-of-stream. The input surface will stop
+ submitting data to the codec immediately after this call.
+ <p>
+
+ <h3>Seeking &amp; Adaptive Playback Support</h3>
+ <p>
+ Video decoders (and in general codecs that consume compressed video data) behave differently
+ regarding seek and format change whether or not they support and are configured for adaptive
+ playback. You can check if a decoder supports {@linkplain
+ CodecCapabilities#FEATURE_AdaptivePlayback adaptive playback} via {@link
+ CodecCapabilities#isFeatureSupported CodecCapabilities.isFeatureSupported(String)}. Adaptive
+ playback support for video decoders is only activated if you configure the codec to decode onto a
+ {@link Surface}.
+
+ <h4 id=KeyFrames><a name="KeyFrames"></a>Stream Boundary and Key Frames</h4>
+ <p>
+ It is important that the input data after {@link #start} or {@link #flush} starts at a suitable
+ stream boundary: the first frame must a key frame. A <em>key frame</em> can be decoded
+ completely on its own (for most codecs this means an I-frame), and no frames that are to be
+ displayed after a key frame refer to frames before the key frame.
+ <p>
+ The following table summarizes suitable key frames for various video formats.
+ <table>
+  <thead>
+   <tr>
+    <th>Format</th>
+    <th>Suitable key frame</th>
+   </tr>
+  </thead>
+  <tbody class=mid>
+   <tr>
+    <td>VP9/VP8</td>
+    <td>a suitable intraframe where no subsequent frames refer to frames prior to this frame.<br>
+      <i>(There is no specific name for such key frame.)</i></td>
+   </tr>
+   <tr>
+    <td>H.265 HEVC</td>
+    <td>IDR or CRA</td>
+   </tr>
+   <tr>
+    <td>H.264 AVC</td>
+    <td>IDR</td>
+   </tr>
+   <tr>
+    <td>MPEG-4<br>H.263<br>MPEG-2</td>
+    <td>a suitable I-frame where no subsequent frames refer to frames prior to this frame.<br>
+      <i>(There is no specific name for such key frame.)</td>
+   </tr>
+  </tbody>
+ </table>
+
+ <h4>For decoders that do not support adaptive playback (including when not decoding onto a
+ Surface)</h4>
+ <p>
+ In order to start decoding data that is not adjacent to previously submitted data (i.e. after a
+ seek) you <strong>MUST</strong> flush the decoder. Since all output buffers are immediately
+ revoked at the point of the flush, you may want to first signal then wait for the end-of-stream
+ before you call {@code flush}. It is important that the input data after a flush starts at a
+ suitable stream boundary/key frame.
+ <p class=note>
+ <strong>Note:</strong> the format of the data submitted after a flush must not change; {@link
+ #flush} does not support format discontinuities; for that, a full {@link #stop} - {@link
+ #configure configure(&hellip;)} - {@link #start} cycle is necessary.
+
+ <p class=note>
+ <strong>Also note:</strong> if you flush the codec too soon after {@link #start} &ndash;
+ generally, before the first output buffer or output format change is received &ndash; you
+ will need to resubmit the codec-specific-data to the codec. See the <a
+ href="#CSD">codec-specific-data section</a> for more info.
+
+ <h4>For decoders that support and are configured for adaptive playback</h4>
+ <p>
+ In order to start decoding data that is not adjacent to previously submitted data (i.e. after a
+ seek) it is <em>not necessary</em> to flush the decoder; however, input data after the
+ discontinuity must start at a suitable stream boundary/key frame.
+ <p>
+ For some video formats - namely H.264, H.265, VP8 and VP9 - it is also possible to change the
+ picture size or configuration mid-stream. To do this you must package the entire new
+ codec-specific configuration data together with the key frame into a single buffer (including
+ any start codes), and submit it as a <strong>regular</strong> input buffer.
+ <p>
+ You will receive an {@link #INFO_OUTPUT_FORMAT_CHANGED} return value from {@link
+ #dequeueOutputBuffer dequeueOutputBuffer} or a {@link Callback#onOutputBufferAvailable
+ onOutputFormatChanged} callback just after the picture-size change takes place and before any
+ frames with the new size have been returned.
+ <p class=note>
+ <strong>Note:</strong> just as the case for codec-specific data, be careful when calling
+ {@link #flush} shortly after you have changed the picture size. If you have not received
+ confirmation of the picture size change, you will need to repeat the request for the new picture
+ size.
+
+ <h3>Error handling</h3>
+ <p>
+ The factory methods {@link #createByCodecName createByCodecName} and {@link #createDecoderByType
+ createDecoder}/{@link #createEncoderByType EncoderByType} throw {@code IOException} on failure
+ which you must catch or declare to pass up. MediaCodec methods throw {@code
+ IllegalStateException} when the method is called from a codec state that does not allow it; this
+ is typically due to incorrect application API usage. Methods involving secure buffers may throw
+ {@link CryptoException}, which has further error information obtainable from {@link
+ CryptoException#getErrorCode}.
+ <p>
+ Internal codec errors result in a {@link CodecException}, which may be due to media content
+ corruption, hardware failure, resource exhaustion, and so forth, even when the application is
+ correctly using the API. The recommended action when receiving a {@code CodecException}
+ can be determined by calling {@link CodecException#isRecoverable} and {@link
+ CodecException#isTransient}:
+ <ul>
+ <li><strong>recoverable errors:</strong> If {@code isRecoverable()} returns true, then call
+ {@link #stop}, {@link #configure configure(&hellip;)}, and {@link #start} to recover.</li>
+ <li><strong>transient errors:</strong> If {@code isTransient()} returns true, then resources are
+ temporarily unavailable and the method may be retried at a later time.</li>
+ <li><strong>fatal errors:</strong> If both {@code isRecoverable()} and {@code isTransient()}
+ return false, then the {@code CodecException} is fatal and the codec must be {@linkplain #reset
+ reset} or {@linkplain #release released}.</li>
+ </ul>
+ <p>
+ Both {@code isRecoverable()} and {@code isTransient()} do not return true at the same time.
+
+ <h2 id=History><a name="History"></a>Valid API Calls and API History</h2>
+ <p>
+ This sections summarizes the valid API calls in each state and the API history of the MediaCodec
+ class. For API version numbers, see {@link android.os.Build.VERSION_CODES}.
+
+ <style>
+ .api > tr > th, .api > tr > td { text-align: center; padding: 4px 4px; }
+ .api > tr > th     { vertical-align: bottom; }
+ .api > tr > td     { vertical-align: middle; }
+ .sml > tr > th, .sml > tr > td { text-align: center; padding: 2px 4px; }
+ .fn { text-align: left; }
+ .fn > code > a { font: 14px/19px Roboto Condensed, sans-serif; }
+ .deg45 {
+   white-space: nowrap; background: none; border: none; vertical-align: bottom;
+   width: 30px; height: 83px;
+ }
+ .deg45 > div {
+   transform: skew(-45deg, 0deg) translate(1px, -67px);
+   transform-origin: bottom left 0;
+   width: 30px; height: 20px;
+ }
+ .deg45 > div > div { border: 1px solid #ddd; background: #999; height: 90px; width: 42px; }
+ .deg45 > div > div > div { transform: skew(45deg, 0deg) translate(-55px, 55px) rotate(-45deg); }
+ </style>
+
+ <table align="right" style="width: 0%">
+  <thead>
+   <tr><th>Symbol</th><th>Meaning</th></tr>
+  </thead>
+  <tbody class=sml>
+   <tr><td>&#9679;</td><td>Supported</td></tr>
+   <tr><td>&#8277;</td><td>Semantics changed</td></tr>
+   <tr><td>&#9675;</td><td>Experimental support</td></tr>
+   <tr><td>[ ]</td><td>Deprecated</td></tr>
+   <tr><td>&#9099;</td><td>Restricted to surface input mode</td></tr>
+   <tr><td>&#9094;</td><td>Restricted to surface output mode</td></tr>
+   <tr><td>&#9639;</td><td>Restricted to ByteBuffer input mode</td></tr>
+   <tr><td>&#8617;</td><td>Restricted to synchronous mode</td></tr>
+   <tr><td>&#8644;</td><td>Restricted to asynchronous mode</td></tr>
+   <tr><td>( )</td><td>Can be called, but shouldn't</td></tr>
+  </tbody>
+ </table>
+
+ <table style="width: 100%;">
+  <thead class=api>
+   <tr>
+    <th class=deg45><div><div style="background:#4285f4"><div>Uninitialized</div></div></div></th>
+    <th class=deg45><div><div style="background:#f4b400"><div>Configured</div></div></div></th>
+    <th class=deg45><div><div style="background:#e67c73"><div>Flushed</div></div></div></th>
+    <th class=deg45><div><div style="background:#0f9d58"><div>Running</div></div></div></th>
+    <th class=deg45><div><div style="background:#f7cb4d"><div>End of Stream</div></div></div></th>
+    <th class=deg45><div><div style="background:#db4437"><div>Error</div></div></div></th>
+    <th class=deg45><div><div style="background:#666"><div>Released</div></div></div></th>
+    <th></th>
+    <th colspan="8">SDK Version</th>
+   </tr>
+   <tr>
+    <th colspan="7">State</th>
+    <th>Method</th>
+    <th>16</th>
+    <th>17</th>
+    <th>18</th>
+    <th>19</th>
+    <th>20</th>
+    <th>21</th>
+    <th>22</th>
+    <th>23</th>
+   </tr>
+  </thead>
+  <tbody class=api>
+   <tr>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td class=fn>{@link #createByCodecName createByCodecName}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td class=fn>{@link #createDecoderByType createDecoderByType}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td class=fn>{@link #createEncoderByType createEncoderByType}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td class=fn>{@link #createPersistentInputSurface createPersistentInputSurface}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>16+</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #configure configure}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#8277;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>18+</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #createInputSurface createInputSurface}</td>
+    <td></td>
+    <td></td>
+    <td>&#9099;</td>
+    <td>&#9099;</td>
+    <td>&#9099;</td>
+    <td>&#9099;</td>
+    <td>&#9099;</td>
+    <td>&#9099;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>(16+)</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #dequeueInputBuffer dequeueInputBuffer}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9639;</td>
+    <td>&#9639;</td>
+    <td>&#9639;</td>
+    <td>&#8277;&#9639;&#8617;</td>
+    <td>&#9639;&#8617;</td>
+    <td>&#9639;&#8617;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #dequeueOutputBuffer dequeueOutputBuffer}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#8277;&#8617;</td>
+    <td>&#8617;</td>
+    <td>&#8617;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #flush flush}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>18+</td>
+    <td>18+</td>
+    <td>18+</td>
+    <td>18+</td>
+    <td>18+</td>
+    <td>18+</td>
+    <td>-</td>
+    <td class=fn>{@link #getCodecInfo getCodecInfo}</td>
+    <td></td>
+    <td></td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>(21+)</td>
+    <td>21+</td>
+    <td>(21+)</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #getInputBuffer getInputBuffer}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>16+</td>
+    <td>(16+)</td>
+    <td>(16+)</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #getInputBuffers getInputBuffers}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>[&#8277;&#8617;]</td>
+    <td>[&#8617;]</td>
+    <td>[&#8617;]</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>21+</td>
+    <td>(21+)</td>
+    <td>(21+)</td>
+    <td>(21+)</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #getInputFormat getInputFormat}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>(21+)</td>
+    <td>21+</td>
+    <td>(21+)</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #getInputImage getInputImage}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9675;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>18+</td>
+    <td>18+</td>
+    <td>18+</td>
+    <td>18+</td>
+    <td>18+</td>
+    <td>18+</td>
+    <td>-</td>
+    <td class=fn>{@link #getName getName}</td>
+    <td></td>
+    <td></td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>(21+)</td>
+    <td>21+</td>
+    <td>21+</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #getOutputBuffer getOutputBuffer}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #getOutputBuffers getOutputBuffers}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>[&#8277;&#8617;]</td>
+    <td>[&#8617;]</td>
+    <td>[&#8617;]</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>21+</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #getOutputFormat()}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>(21+)</td>
+    <td>21+</td>
+    <td>21+</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #getOutputFormat(int)}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>(21+)</td>
+    <td>21+</td>
+    <td>21+</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #getOutputImage getOutputImage}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9675;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>16+</td>
+    <td>(16+)</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #queueInputBuffer queueInputBuffer}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#8277;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>16+</td>
+    <td>(16+)</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #queueSecureInputBuffer queueSecureInputBuffer}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#8277;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>16+</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td class=fn>{@link #release release}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #releaseOutputBuffer(int, boolean)}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#8277;</td>
+    <td>&#9679;</td>
+    <td>&#8277;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>21+</td>
+    <td>21+</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #releaseOutputBuffer(int, long)}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9094;</td>
+    <td>&#9094;</td>
+    <td>&#9094;</td>
+   </tr>
+   <tr>
+    <td>21+</td>
+    <td>21+</td>
+    <td>21+</td>
+    <td>21+</td>
+    <td>21+</td>
+    <td>21+</td>
+    <td>-</td>
+    <td class=fn>{@link #reset reset}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>21+</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #setCallback(Callback) setCallback}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>{@link #setCallback(Callback, Handler) &#8277;}</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>23+</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #setInputSurface setInputSurface}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9099;</td>
+   </tr>
+   <tr>
+    <td>23+</td>
+    <td>23+</td>
+    <td>23+</td>
+    <td>23+</td>
+    <td>23+</td>
+    <td>(23+)</td>
+    <td>(23+)</td>
+    <td class=fn>{@link #setOnFrameRenderedListener setOnFrameRenderedListener}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9675; &#9094;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>23+</td>
+    <td>23+</td>
+    <td>23+</td>
+    <td>23+</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #setOutputSurface setOutputSurface}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9094;</td>
+   </tr>
+   <tr>
+    <td>19+</td>
+    <td>19+</td>
+    <td>19+</td>
+    <td>19+</td>
+    <td>19+</td>
+    <td>(19+)</td>
+    <td>-</td>
+    <td class=fn>{@link #setParameters setParameters}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>(16+)</td>
+    <td>(16+)</td>
+    <td>16+</td>
+    <td>(16+)</td>
+    <td>(16+)</td>
+    <td>-</td>
+    <td class=fn>{@link #setVideoScalingMode setVideoScalingMode}</td>
+    <td>&#9094;</td>
+    <td>&#9094;</td>
+    <td>&#9094;</td>
+    <td>&#9094;</td>
+    <td>&#9094;</td>
+    <td>&#9094;</td>
+    <td>&#9094;</td>
+    <td>&#9094;</td>
+   </tr>
+   <tr>
+    <td>(29+)</td>
+    <td>29+</td>
+    <td>29+</td>
+    <td>29+</td>
+    <td>(29+)</td>
+    <td>(29+)</td>
+    <td>-</td>
+    <td class=fn>{@link #setAudioPresentation setAudioPresentation}</td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+    <td></td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>18+</td>
+    <td>18+</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #signalEndOfInputStream signalEndOfInputStream}</td>
+    <td></td>
+    <td></td>
+    <td>&#9099;</td>
+    <td>&#9099;</td>
+    <td>&#9099;</td>
+    <td>&#9099;</td>
+    <td>&#9099;</td>
+    <td>&#9099;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>16+</td>
+    <td>21+(&#8644;)</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #start start}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#8277;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+   <tr>
+    <td>-</td>
+    <td>-</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>16+</td>
+    <td>-</td>
+    <td>-</td>
+    <td class=fn>{@link #stop stop}</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+  </tbody>
+ </table>
+ */
+final public class MediaCodec {
+
+    /**
+     * Per buffer metadata includes an offset and size specifying
+     * the range of valid data in the associated codec (output) buffer.
+     */
+    public final static class BufferInfo {
+        /**
+         * Update the buffer metadata information.
+         *
+         * @param newOffset the start-offset of the data in the buffer.
+         * @param newSize   the amount of data (in bytes) in the buffer.
+         * @param newTimeUs the presentation timestamp in microseconds.
+         * @param newFlags  buffer flags associated with the buffer.  This
+         * should be a combination of  {@link #BUFFER_FLAG_KEY_FRAME} and
+         * {@link #BUFFER_FLAG_END_OF_STREAM}.
+         */
+        public void set(
+                int newOffset, int newSize, long newTimeUs, @BufferFlag int newFlags) {
+            offset = newOffset;
+            size = newSize;
+            presentationTimeUs = newTimeUs;
+            flags = newFlags;
+        }
+
+        /**
+         * The start-offset of the data in the buffer.
+         */
+        public int offset;
+
+        /**
+         * The amount of data (in bytes) in the buffer.  If this is {@code 0},
+         * the buffer has no data in it and can be discarded.  The only
+         * use of a 0-size buffer is to carry the end-of-stream marker.
+         */
+        public int size;
+
+        /**
+         * The presentation timestamp in microseconds for the buffer.
+         * This is derived from the presentation timestamp passed in
+         * with the corresponding input buffer.  This should be ignored for
+         * a 0-sized buffer.
+         */
+        public long presentationTimeUs;
+
+        /**
+         * Buffer flags associated with the buffer.  A combination of
+         * {@link #BUFFER_FLAG_KEY_FRAME} and {@link #BUFFER_FLAG_END_OF_STREAM}.
+         *
+         * <p>Encoded buffers that are key frames are marked with
+         * {@link #BUFFER_FLAG_KEY_FRAME}.
+         *
+         * <p>The last output buffer corresponding to the input buffer
+         * marked with {@link #BUFFER_FLAG_END_OF_STREAM} will also be marked
+         * with {@link #BUFFER_FLAG_END_OF_STREAM}. In some cases this could
+         * be an empty buffer, whose sole purpose is to carry the end-of-stream
+         * marker.
+         */
+        @BufferFlag
+        public int flags;
+
+        /** @hide */
+        @NonNull
+        public BufferInfo dup() {
+            BufferInfo copy = new BufferInfo();
+            copy.set(offset, size, presentationTimeUs, flags);
+            return copy;
+        }
+    };
+
+    // The follow flag constants MUST stay in sync with their equivalents
+    // in MediaCodec.h !
+
+    /**
+     * This indicates that the (encoded) buffer marked as such contains
+     * the data for a key frame.
+     *
+     * @deprecated Use {@link #BUFFER_FLAG_KEY_FRAME} instead.
+     */
+    public static final int BUFFER_FLAG_SYNC_FRAME = 1;
+
+    /**
+     * This indicates that the (encoded) buffer marked as such contains
+     * the data for a key frame.
+     */
+    public static final int BUFFER_FLAG_KEY_FRAME = 1;
+
+    /**
+     * This indicated that the buffer marked as such contains codec
+     * initialization / codec specific data instead of media data.
+     */
+    public static final int BUFFER_FLAG_CODEC_CONFIG = 2;
+
+    /**
+     * This signals the end of stream, i.e. no buffers will be available
+     * after this, unless of course, {@link #flush} follows.
+     */
+    public static final int BUFFER_FLAG_END_OF_STREAM = 4;
+
+    /**
+     * This indicates that the buffer only contains part of a frame,
+     * and the decoder should batch the data until a buffer without
+     * this flag appears before decoding the frame.
+     */
+    public static final int BUFFER_FLAG_PARTIAL_FRAME = 8;
+
+    /**
+     * This indicates that the buffer contains non-media data for the
+     * muxer to process.
+     *
+     * All muxer data should start with a FOURCC header that determines the type of data.
+     *
+     * For example, when it contains Exif data sent to a MediaMuxer track of
+     * {@link MediaFormat#MIMETYPE_IMAGE_ANDROID_HEIC} type, the data must start with
+     * Exif header ("Exif\0\0"), followed by the TIFF header (See JEITA CP-3451C Section 4.5.2.)
+     *
+     * @hide
+     */
+    public static final int BUFFER_FLAG_MUXER_DATA = 16;
+
+    /** @hide */
+    @IntDef(
+        flag = true,
+        value = {
+            BUFFER_FLAG_SYNC_FRAME,
+            BUFFER_FLAG_KEY_FRAME,
+            BUFFER_FLAG_CODEC_CONFIG,
+            BUFFER_FLAG_END_OF_STREAM,
+            BUFFER_FLAG_PARTIAL_FRAME,
+            BUFFER_FLAG_MUXER_DATA,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface BufferFlag {}
+
+    private EventHandler mEventHandler;
+    private EventHandler mOnFirstTunnelFrameReadyHandler;
+    private EventHandler mOnFrameRenderedHandler;
+    private EventHandler mCallbackHandler;
+    private Callback mCallback;
+    private OnFirstTunnelFrameReadyListener mOnFirstTunnelFrameReadyListener;
+    private OnFrameRenderedListener mOnFrameRenderedListener;
+    private final Object mListenerLock = new Object();
+    private MediaCodecInfo mCodecInfo;
+    private final Object mCodecInfoLock = new Object();
+    private MediaCrypto mCrypto;
+
+    private static final int EVENT_CALLBACK = 1;
+    private static final int EVENT_SET_CALLBACK = 2;
+    private static final int EVENT_FRAME_RENDERED = 3;
+    private static final int EVENT_FIRST_TUNNEL_FRAME_READY = 4;
+
+    private static final int CB_INPUT_AVAILABLE = 1;
+    private static final int CB_OUTPUT_AVAILABLE = 2;
+    private static final int CB_ERROR = 3;
+    private static final int CB_OUTPUT_FORMAT_CHANGE = 4;
+
+
+    private class EventHandler extends Handler {
+        private MediaCodec mCodec;
+
+        public EventHandler(@NonNull MediaCodec codec, @NonNull Looper looper) {
+            super(looper);
+            mCodec = codec;
+        }
+
+        @Override
+        public void handleMessage(@NonNull Message msg) {
+            switch (msg.what) {
+                case EVENT_CALLBACK:
+                {
+                    handleCallback(msg);
+                    break;
+                }
+                case EVENT_SET_CALLBACK:
+                {
+                    mCallback = (MediaCodec.Callback) msg.obj;
+                    break;
+                }
+                case EVENT_FRAME_RENDERED:
+                    Map<String, Object> map = (Map<String, Object>)msg.obj;
+                    for (int i = 0; ; ++i) {
+                        Object mediaTimeUs = map.get(i + "-media-time-us");
+                        Object systemNano = map.get(i + "-system-nano");
+                        OnFrameRenderedListener onFrameRenderedListener;
+                        synchronized (mListenerLock) {
+                            onFrameRenderedListener = mOnFrameRenderedListener;
+                        }
+                        if (mediaTimeUs == null || systemNano == null
+                                || onFrameRenderedListener == null) {
+                            break;
+                        }
+                        onFrameRenderedListener.onFrameRendered(
+                                mCodec, (long)mediaTimeUs, (long)systemNano);
+                    }
+                    break;
+                case EVENT_FIRST_TUNNEL_FRAME_READY:
+                    OnFirstTunnelFrameReadyListener onFirstTunnelFrameReadyListener;
+                    synchronized (mListenerLock) {
+                        onFirstTunnelFrameReadyListener = mOnFirstTunnelFrameReadyListener;
+                    }
+                    if (onFirstTunnelFrameReadyListener == null) {
+                        break;
+                    }
+                    onFirstTunnelFrameReadyListener.onFirstTunnelFrameReady(mCodec);
+                    break;
+                default:
+                {
+                    break;
+                }
+            }
+        }
+
+        private void handleCallback(@NonNull Message msg) {
+            if (mCallback == null) {
+                return;
+            }
+
+            switch (msg.arg1) {
+                case CB_INPUT_AVAILABLE:
+                {
+                    int index = msg.arg2;
+                    synchronized(mBufferLock) {
+                        switch (mBufferMode) {
+                            case BUFFER_MODE_LEGACY:
+                                validateInputByteBuffer(mCachedInputBuffers, index);
+                                break;
+                            case BUFFER_MODE_BLOCK:
+                                while (mQueueRequests.size() <= index) {
+                                    mQueueRequests.add(null);
+                                }
+                                QueueRequest request = mQueueRequests.get(index);
+                                if (request == null) {
+                                    request = new QueueRequest(mCodec, index);
+                                    mQueueRequests.set(index, request);
+                                }
+                                request.setAccessible(true);
+                                break;
+                            default:
+                                throw new IllegalStateException(
+                                        "Unrecognized buffer mode: " + mBufferMode);
+                        }
+                    }
+                    mCallback.onInputBufferAvailable(mCodec, index);
+                    break;
+                }
+
+                case CB_OUTPUT_AVAILABLE:
+                {
+                    int index = msg.arg2;
+                    BufferInfo info = (MediaCodec.BufferInfo) msg.obj;
+                    synchronized(mBufferLock) {
+                        switch (mBufferMode) {
+                            case BUFFER_MODE_LEGACY:
+                                validateOutputByteBuffer(mCachedOutputBuffers, index, info);
+                                break;
+                            case BUFFER_MODE_BLOCK:
+                                while (mOutputFrames.size() <= index) {
+                                    mOutputFrames.add(null);
+                                }
+                                OutputFrame frame = mOutputFrames.get(index);
+                                if (frame == null) {
+                                    frame = new OutputFrame(index);
+                                    mOutputFrames.set(index, frame);
+                                }
+                                frame.setBufferInfo(info);
+                                frame.setAccessible(true);
+                                break;
+                            default:
+                                throw new IllegalStateException(
+                                        "Unrecognized buffer mode: " + mBufferMode);
+                        }
+                    }
+                    mCallback.onOutputBufferAvailable(
+                            mCodec, index, info);
+                    break;
+                }
+
+                case CB_ERROR:
+                {
+                    mCallback.onError(mCodec, (MediaCodec.CodecException) msg.obj);
+                    break;
+                }
+
+                case CB_OUTPUT_FORMAT_CHANGE:
+                {
+                    mCallback.onOutputFormatChanged(mCodec,
+                            new MediaFormat((Map<String, Object>) msg.obj));
+                    break;
+                }
+
+                default:
+                {
+                    break;
+                }
+            }
+        }
+    }
+
+    private boolean mHasSurface = false;
+
+    /**
+     * Instantiate the preferred decoder supporting input data of the given mime type.
+     *
+     * The following is a partial list of defined mime types and their semantics:
+     * <ul>
+     * <li>"video/x-vnd.on2.vp8" - VP8 video (i.e. video in .webm)
+     * <li>"video/x-vnd.on2.vp9" - VP9 video (i.e. video in .webm)
+     * <li>"video/avc" - H.264/AVC video
+     * <li>"video/hevc" - H.265/HEVC video
+     * <li>"video/mp4v-es" - MPEG4 video
+     * <li>"video/3gpp" - H.263 video
+     * <li>"audio/3gpp" - AMR narrowband audio
+     * <li>"audio/amr-wb" - AMR wideband audio
+     * <li>"audio/mpeg" - MPEG1/2 audio layer III
+     * <li>"audio/mp4a-latm" - AAC audio (note, this is raw AAC packets, not packaged in LATM!)
+     * <li>"audio/vorbis" - vorbis audio
+     * <li>"audio/g711-alaw" - G.711 alaw audio
+     * <li>"audio/g711-mlaw" - G.711 ulaw audio
+     * </ul>
+     *
+     * <strong>Note:</strong> It is preferred to use {@link MediaCodecList#findDecoderForFormat}
+     * and {@link #createByCodecName} to ensure that the resulting codec can handle a
+     * given format.
+     *
+     * @param type The mime type of the input data.
+     * @throws IOException if the codec cannot be created.
+     * @throws IllegalArgumentException if type is not a valid mime type.
+     * @throws NullPointerException if type is null.
+     */
+    @NonNull
+    public static MediaCodec createDecoderByType(@NonNull String type)
+            throws IOException {
+        return new MediaCodec(type, true /* nameIsType */, false /* encoder */);
+    }
+
+    /**
+     * Instantiate the preferred encoder supporting output data of the given mime type.
+     *
+     * <strong>Note:</strong> It is preferred to use {@link MediaCodecList#findEncoderForFormat}
+     * and {@link #createByCodecName} to ensure that the resulting codec can handle a
+     * given format.
+     *
+     * @param type The desired mime type of the output data.
+     * @throws IOException if the codec cannot be created.
+     * @throws IllegalArgumentException if type is not a valid mime type.
+     * @throws NullPointerException if type is null.
+     */
+    @NonNull
+    public static MediaCodec createEncoderByType(@NonNull String type)
+            throws IOException {
+        return new MediaCodec(type, true /* nameIsType */, true /* encoder */);
+    }
+
+    /**
+     * If you know the exact name of the component you want to instantiate
+     * use this method to instantiate it. Use with caution.
+     * Likely to be used with information obtained from {@link android.media.MediaCodecList}
+     * @param name The name of the codec to be instantiated.
+     * @throws IOException if the codec cannot be created.
+     * @throws IllegalArgumentException if name is not valid.
+     * @throws NullPointerException if name is null.
+     */
+    @NonNull
+    public static MediaCodec createByCodecName(@NonNull String name)
+            throws IOException {
+        return new MediaCodec(
+                name, false /* nameIsType */, false /* unused */);
+    }
+
+    private MediaCodec(
+            @NonNull String name, boolean nameIsType, boolean encoder) {
+        Looper looper;
+        if ((looper = Looper.myLooper()) != null) {
+            mEventHandler = new EventHandler(this, looper);
+        } else if ((looper = Looper.getMainLooper()) != null) {
+            mEventHandler = new EventHandler(this, looper);
+        } else {
+            mEventHandler = null;
+        }
+        mCallbackHandler = mEventHandler;
+        mOnFirstTunnelFrameReadyHandler = mEventHandler;
+        mOnFrameRenderedHandler = mEventHandler;
+
+        mBufferLock = new Object();
+
+        // save name used at creation
+        mNameAtCreation = nameIsType ? null : name;
+
+        native_setup(name, nameIsType, encoder);
+    }
+
+    private String mNameAtCreation;
+
+    @Override
+    protected void finalize() {
+        native_finalize();
+        mCrypto = null;
+    }
+
+    /**
+     * Returns the codec to its initial (Uninitialized) state.
+     *
+     * Call this if an {@link MediaCodec.CodecException#isRecoverable unrecoverable}
+     * error has occured to reset the codec to its initial state after creation.
+     *
+     * @throws CodecException if an unrecoverable error has occured and the codec
+     * could not be reset.
+     * @throws IllegalStateException if in the Released state.
+     */
+    public final void reset() {
+        freeAllTrackedBuffers(); // free buffers first
+        native_reset();
+        mCrypto = null;
+    }
+
+    private native final void native_reset();
+
+    /**
+     * Free up resources used by the codec instance.
+     *
+     * Make sure you call this when you're done to free up any opened
+     * component instance instead of relying on the garbage collector
+     * to do this for you at some point in the future.
+     */
+    public final void release() {
+        freeAllTrackedBuffers(); // free buffers first
+        native_release();
+        mCrypto = null;
+    }
+
+    private native final void native_release();
+
+    /**
+     * If this codec is to be used as an encoder, pass this flag.
+     */
+    public static final int CONFIGURE_FLAG_ENCODE = 1;
+
+    /**
+     * If this codec is to be used with {@link LinearBlock} and/or {@link
+     * HardwareBuffer}, pass this flag.
+     * <p>
+     * When this flag is set, the following APIs throw {@link IncompatibleWithBlockModelException}.
+     * <ul>
+     * <li>{@link #getInputBuffer}
+     * <li>{@link #getInputImage}
+     * <li>{@link #getInputBuffers}
+     * <li>{@link #getOutputBuffer}
+     * <li>{@link #getOutputImage}
+     * <li>{@link #getOutputBuffers}
+     * <li>{@link #queueInputBuffer}
+     * <li>{@link #queueSecureInputBuffer}
+     * <li>{@link #dequeueInputBuffer}
+     * <li>{@link #dequeueOutputBuffer}
+     * </ul>
+     */
+    public static final int CONFIGURE_FLAG_USE_BLOCK_MODEL = 2;
+
+    /** @hide */
+    @IntDef(
+        flag = true,
+        value = {
+            CONFIGURE_FLAG_ENCODE,
+            CONFIGURE_FLAG_USE_BLOCK_MODEL,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ConfigureFlag {}
+
+    /**
+     * Thrown when the codec is configured for block model and an incompatible API is called.
+     */
+    public class IncompatibleWithBlockModelException extends RuntimeException {
+        IncompatibleWithBlockModelException() { }
+
+        IncompatibleWithBlockModelException(String message) {
+            super(message);
+        }
+
+        IncompatibleWithBlockModelException(String message, Throwable cause) {
+            super(message, cause);
+        }
+
+        IncompatibleWithBlockModelException(Throwable cause) {
+            super(cause);
+        }
+    }
+
+    /**
+     * Configures a component.
+     *
+     * @param format The format of the input data (decoder) or the desired
+     *               format of the output data (encoder). Passing {@code null}
+     *               as {@code format} is equivalent to passing an
+     *               {@link MediaFormat#MediaFormat an empty mediaformat}.
+     * @param surface Specify a surface on which to render the output of this
+     *                decoder. Pass {@code null} as {@code surface} if the
+     *                codec does not generate raw video output (e.g. not a video
+     *                decoder) and/or if you want to configure the codec for
+     *                {@link ByteBuffer} output.
+     * @param crypto  Specify a crypto object to facilitate secure decryption
+     *                of the media data. Pass {@code null} as {@code crypto} for
+     *                non-secure codecs.
+     *                Please note that {@link MediaCodec} does NOT take ownership
+     *                of the {@link MediaCrypto} object; it is the application's
+     *                responsibility to properly cleanup the {@link MediaCrypto} object
+     *                when not in use.
+     * @param flags   Specify {@link #CONFIGURE_FLAG_ENCODE} to configure the
+     *                component as an encoder.
+     * @throws IllegalArgumentException if the surface has been released (or is invalid),
+     * or the format is unacceptable (e.g. missing a mandatory key),
+     * or the flags are not set properly
+     * (e.g. missing {@link #CONFIGURE_FLAG_ENCODE} for an encoder).
+     * @throws IllegalStateException if not in the Uninitialized state.
+     * @throws CryptoException upon DRM error.
+     * @throws CodecException upon codec error.
+     */
+    public void configure(
+            @Nullable MediaFormat format,
+            @Nullable Surface surface, @Nullable MediaCrypto crypto,
+            @ConfigureFlag int flags) {
+        configure(format, surface, crypto, null, flags);
+    }
+
+    /**
+     * Configure a component to be used with a descrambler.
+     * @param format The format of the input data (decoder) or the desired
+     *               format of the output data (encoder). Passing {@code null}
+     *               as {@code format} is equivalent to passing an
+     *               {@link MediaFormat#MediaFormat an empty mediaformat}.
+     * @param surface Specify a surface on which to render the output of this
+     *                decoder. Pass {@code null} as {@code surface} if the
+     *                codec does not generate raw video output (e.g. not a video
+     *                decoder) and/or if you want to configure the codec for
+     *                {@link ByteBuffer} output.
+     * @param flags   Specify {@link #CONFIGURE_FLAG_ENCODE} to configure the
+     *                component as an encoder.
+     * @param descrambler Specify a descrambler object to facilitate secure
+     *                descrambling of the media data, or null for non-secure codecs.
+     * @throws IllegalArgumentException if the surface has been released (or is invalid),
+     * or the format is unacceptable (e.g. missing a mandatory key),
+     * or the flags are not set properly
+     * (e.g. missing {@link #CONFIGURE_FLAG_ENCODE} for an encoder).
+     * @throws IllegalStateException if not in the Uninitialized state.
+     * @throws CryptoException upon DRM error.
+     * @throws CodecException upon codec error.
+     */
+    public void configure(
+            @Nullable MediaFormat format, @Nullable Surface surface,
+            @ConfigureFlag int flags, @Nullable MediaDescrambler descrambler) {
+        configure(format, surface, null,
+                descrambler != null ? descrambler.getBinder() : null, flags);
+    }
+
+    private static final int BUFFER_MODE_INVALID = -1;
+    private static final int BUFFER_MODE_LEGACY = 0;
+    private static final int BUFFER_MODE_BLOCK = 1;
+    private int mBufferMode = BUFFER_MODE_INVALID;
+
+    private void configure(
+            @Nullable MediaFormat format, @Nullable Surface surface,
+            @Nullable MediaCrypto crypto, @Nullable IHwBinder descramblerBinder,
+            @ConfigureFlag int flags) {
+        if (crypto != null && descramblerBinder != null) {
+            throw new IllegalArgumentException("Can't use crypto and descrambler together!");
+        }
+
+        String[] keys = null;
+        Object[] values = null;
+
+        if (format != null) {
+            Map<String, Object> formatMap = format.getMap();
+            keys = new String[formatMap.size()];
+            values = new Object[formatMap.size()];
+
+            int i = 0;
+            for (Map.Entry<String, Object> entry: formatMap.entrySet()) {
+                if (entry.getKey().equals(MediaFormat.KEY_AUDIO_SESSION_ID)) {
+                    int sessionId = 0;
+                    try {
+                        sessionId = (Integer)entry.getValue();
+                    }
+                    catch (Exception e) {
+                        throw new IllegalArgumentException("Wrong Session ID Parameter!");
+                    }
+                    keys[i] = "audio-hw-sync";
+                    values[i] = AudioSystem.getAudioHwSyncForSession(sessionId);
+                } else {
+                    keys[i] = entry.getKey();
+                    values[i] = entry.getValue();
+                }
+                ++i;
+            }
+        }
+
+        mHasSurface = surface != null;
+        mCrypto = crypto;
+        synchronized (mBufferLock) {
+            if ((flags & CONFIGURE_FLAG_USE_BLOCK_MODEL) != 0) {
+                mBufferMode = BUFFER_MODE_BLOCK;
+            } else {
+                mBufferMode = BUFFER_MODE_LEGACY;
+            }
+        }
+
+        native_configure(keys, values, surface, crypto, descramblerBinder, flags);
+    }
+
+    /**
+     *  Dynamically sets the output surface of a codec.
+     *  <p>
+     *  This can only be used if the codec was configured with an output surface.  The
+     *  new output surface should have a compatible usage type to the original output surface.
+     *  E.g. codecs may not support switching from a SurfaceTexture (GPU readable) output
+     *  to ImageReader (software readable) output.
+     *  @param surface the output surface to use. It must not be {@code null}.
+     *  @throws IllegalStateException if the codec does not support setting the output
+     *            surface in the current state.
+     *  @throws IllegalArgumentException if the new surface is not of a suitable type for the codec.
+     */
+    public void setOutputSurface(@NonNull Surface surface) {
+        if (!mHasSurface) {
+            throw new IllegalStateException("codec was not configured for an output surface");
+        }
+        native_setSurface(surface);
+    }
+
+    private native void native_setSurface(@NonNull Surface surface);
+
+    /**
+     * Create a persistent input surface that can be used with codecs that normally have an input
+     * surface, such as video encoders. A persistent input can be reused by subsequent
+     * {@link MediaCodec} or {@link MediaRecorder} instances, but can only be used by at
+     * most one codec or recorder instance concurrently.
+     * <p>
+     * The application is responsible for calling release() on the Surface when done.
+     *
+     * @return an input surface that can be used with {@link #setInputSurface}.
+     */
+    @NonNull
+    public static Surface createPersistentInputSurface() {
+        return native_createPersistentInputSurface();
+    }
+
+    static class PersistentSurface extends Surface {
+        @SuppressWarnings("unused")
+        PersistentSurface() {} // used by native
+
+        @Override
+        public void release() {
+            native_releasePersistentInputSurface(this);
+            super.release();
+        }
+
+        private long mPersistentObject;
+    };
+
+    /**
+     * Configures the codec (e.g. encoder) to use a persistent input surface in place of input
+     * buffers.  This may only be called after {@link #configure} and before {@link #start}, in
+     * lieu of {@link #createInputSurface}.
+     * @param surface a persistent input surface created by {@link #createPersistentInputSurface}
+     * @throws IllegalStateException if not in the Configured state or does not require an input
+     *           surface.
+     * @throws IllegalArgumentException if the surface was not created by
+     *           {@link #createPersistentInputSurface}.
+     */
+    public void setInputSurface(@NonNull Surface surface) {
+        if (!(surface instanceof PersistentSurface)) {
+            throw new IllegalArgumentException("not a PersistentSurface");
+        }
+        native_setInputSurface(surface);
+    }
+
+    @NonNull
+    private static native final PersistentSurface native_createPersistentInputSurface();
+    private static native final void native_releasePersistentInputSurface(@NonNull Surface surface);
+    private native final void native_setInputSurface(@NonNull Surface surface);
+
+    private native final void native_setCallback(@Nullable Callback cb);
+
+    private native final void native_configure(
+            @Nullable String[] keys, @Nullable Object[] values,
+            @Nullable Surface surface, @Nullable MediaCrypto crypto,
+            @Nullable IHwBinder descramblerBinder, @ConfigureFlag int flags);
+
+    /**
+     * Requests a Surface to use as the input to an encoder, in place of input buffers.  This
+     * may only be called after {@link #configure} and before {@link #start}.
+     * <p>
+     * The application is responsible for calling release() on the Surface when
+     * done.
+     * <p>
+     * The Surface must be rendered with a hardware-accelerated API, such as OpenGL ES.
+     * {@link android.view.Surface#lockCanvas(android.graphics.Rect)} may fail or produce
+     * unexpected results.
+     * @throws IllegalStateException if not in the Configured state.
+     */
+    @NonNull
+    public native final Surface createInputSurface();
+
+    /**
+     * After successfully configuring the component, call {@code start}.
+     * <p>
+     * Call {@code start} also if the codec is configured in asynchronous mode,
+     * and it has just been flushed, to resume requesting input buffers.
+     * @throws IllegalStateException if not in the Configured state
+     *         or just after {@link #flush} for a codec that is configured
+     *         in asynchronous mode.
+     * @throws MediaCodec.CodecException upon codec error. Note that some codec errors
+     * for start may be attributed to future method calls.
+     */
+    public final void start() {
+        native_start();
+        synchronized(mBufferLock) {
+            cacheBuffers(true /* input */);
+            cacheBuffers(false /* input */);
+        }
+    }
+    private native final void native_start();
+
+    /**
+     * Finish the decode/encode session, note that the codec instance
+     * remains active and ready to be {@link #start}ed again.
+     * To ensure that it is available to other client call {@link #release}
+     * and don't just rely on garbage collection to eventually do this for you.
+     * @throws IllegalStateException if in the Released state.
+     */
+    public final void stop() {
+        native_stop();
+        freeAllTrackedBuffers();
+
+        synchronized (mListenerLock) {
+            if (mCallbackHandler != null) {
+                mCallbackHandler.removeMessages(EVENT_SET_CALLBACK);
+                mCallbackHandler.removeMessages(EVENT_CALLBACK);
+            }
+            if (mOnFirstTunnelFrameReadyHandler != null) {
+                mOnFirstTunnelFrameReadyHandler.removeMessages(EVENT_FIRST_TUNNEL_FRAME_READY);
+            }
+            if (mOnFrameRenderedHandler != null) {
+                mOnFrameRenderedHandler.removeMessages(EVENT_FRAME_RENDERED);
+            }
+        }
+    }
+
+    private native final void native_stop();
+
+    /**
+     * Flush both input and output ports of the component.
+     * <p>
+     * Upon return, all indices previously returned in calls to {@link #dequeueInputBuffer
+     * dequeueInputBuffer} and {@link #dequeueOutputBuffer dequeueOutputBuffer} &mdash; or obtained
+     * via {@link Callback#onInputBufferAvailable onInputBufferAvailable} or
+     * {@link Callback#onOutputBufferAvailable onOutputBufferAvailable} callbacks &mdash; become
+     * invalid, and all buffers are owned by the codec.
+     * <p>
+     * If the codec is configured in asynchronous mode, call {@link #start}
+     * after {@code flush} has returned to resume codec operations. The codec
+     * will not request input buffers until this has happened.
+     * <strong>Note, however, that there may still be outstanding {@code onOutputBufferAvailable}
+     * callbacks that were not handled prior to calling {@code flush}.
+     * The indices returned via these callbacks also become invalid upon calling {@code flush} and
+     * should be discarded.</strong>
+     * <p>
+     * If the codec is configured in synchronous mode, codec will resume
+     * automatically if it is configured with an input surface.  Otherwise, it
+     * will resume when {@link #dequeueInputBuffer dequeueInputBuffer} is called.
+     *
+     * @throws IllegalStateException if not in the Executing state.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    public final void flush() {
+        synchronized(mBufferLock) {
+            invalidateByteBuffers(mCachedInputBuffers);
+            invalidateByteBuffers(mCachedOutputBuffers);
+            mDequeuedInputBuffers.clear();
+            mDequeuedOutputBuffers.clear();
+        }
+        native_flush();
+    }
+
+    private native final void native_flush();
+
+    /**
+     * Thrown when an internal codec error occurs.
+     */
+    public final static class CodecException extends IllegalStateException {
+        @UnsupportedAppUsage
+        CodecException(int errorCode, int actionCode, @Nullable String detailMessage) {
+            super(detailMessage);
+            mErrorCode = errorCode;
+            mActionCode = actionCode;
+
+            // TODO get this from codec
+            final String sign = errorCode < 0 ? "neg_" : "";
+            mDiagnosticInfo =
+                "android.media.MediaCodec.error_" + sign + Math.abs(errorCode);
+        }
+
+        /**
+         * Returns true if the codec exception is a transient issue,
+         * perhaps due to resource constraints, and that the method
+         * (or encoding/decoding) may be retried at a later time.
+         */
+        public boolean isTransient() {
+            return mActionCode == ACTION_TRANSIENT;
+        }
+
+        /**
+         * Returns true if the codec cannot proceed further,
+         * but can be recovered by stopping, configuring,
+         * and starting again.
+         */
+        public boolean isRecoverable() {
+            return mActionCode == ACTION_RECOVERABLE;
+        }
+
+        /**
+         * Retrieve the error code associated with a CodecException
+         */
+        public int getErrorCode() {
+            return mErrorCode;
+        }
+
+        /**
+         * Retrieve a developer-readable diagnostic information string
+         * associated with the exception. Do not show this to end-users,
+         * since this string will not be localized or generally
+         * comprehensible to end-users.
+         */
+        public @NonNull String getDiagnosticInfo() {
+            return mDiagnosticInfo;
+        }
+
+        /**
+         * This indicates required resource was not able to be allocated.
+         */
+        public static final int ERROR_INSUFFICIENT_RESOURCE = 1100;
+
+        /**
+         * This indicates the resource manager reclaimed the media resource used by the codec.
+         * <p>
+         * With this exception, the codec must be released, as it has moved to terminal state.
+         */
+        public static final int ERROR_RECLAIMED = 1101;
+
+        /** @hide */
+        @IntDef({
+            ERROR_INSUFFICIENT_RESOURCE,
+            ERROR_RECLAIMED,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface ReasonCode {}
+
+        /* Must be in sync with android_media_MediaCodec.cpp */
+        private final static int ACTION_TRANSIENT = 1;
+        private final static int ACTION_RECOVERABLE = 2;
+
+        private final String mDiagnosticInfo;
+        private final int mErrorCode;
+        private final int mActionCode;
+    }
+
+    /**
+     * Thrown when a crypto error occurs while queueing a secure input buffer.
+     */
+    public final static class CryptoException extends RuntimeException {
+        public CryptoException(int errorCode, @Nullable String detailMessage) {
+            super(detailMessage);
+            mErrorCode = errorCode;
+        }
+
+        /**
+         * This indicates that the requested key was not found when trying to
+         * perform a decrypt operation.  The operation can be retried after adding
+         * the correct decryption key.
+         * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_NO_KEY}.
+         */
+        public static final int ERROR_NO_KEY = MediaDrm.ErrorCodes.ERROR_NO_KEY;
+
+        /**
+         * This indicates that the key used for decryption is no longer
+         * valid due to license term expiration.  The operation can be retried
+         * after updating the expired keys.
+         * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_KEY_EXPIRED}.
+         */
+        public static final int ERROR_KEY_EXPIRED = MediaDrm.ErrorCodes.ERROR_KEY_EXPIRED;
+
+        /**
+         * This indicates that a required crypto resource was not able to be
+         * allocated while attempting the requested operation.  The operation
+         * can be retried if the app is able to release resources.
+         * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_RESOURCE_BUSY}
+         */
+        public static final int ERROR_RESOURCE_BUSY = MediaDrm.ErrorCodes.ERROR_RESOURCE_BUSY;
+
+        /**
+         * This indicates that the output protection levels supported by the
+         * device are not sufficient to meet the requirements set by the
+         * content owner in the license policy.
+         * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_INSUFFICIENT_OUTPUT_PROTECTION}
+         */
+        public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION =
+                MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_OUTPUT_PROTECTION;
+
+        /**
+         * This indicates that decryption was attempted on a session that is
+         * not opened, which could be due to a failure to open the session,
+         * closing the session prematurely, or the session being reclaimed
+         * by the resource manager.
+         * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_SESSION_NOT_OPENED}
+         */
+        public static final int ERROR_SESSION_NOT_OPENED =
+                MediaDrm.ErrorCodes.ERROR_SESSION_NOT_OPENED;
+
+        /**
+         * This indicates that an operation was attempted that could not be
+         * supported by the crypto system of the device in its current
+         * configuration.  It may occur when the license policy requires
+         * device security features that aren't supported by the device,
+         * or due to an internal error in the crypto system that prevents
+         * the specified security policy from being met.
+         * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_UNSUPPORTED_OPERATION}
+         */
+        public static final int ERROR_UNSUPPORTED_OPERATION =
+                MediaDrm.ErrorCodes.ERROR_UNSUPPORTED_OPERATION;
+
+        /**
+         * This indicates that the security level of the device is not
+         * sufficient to meet the requirements set by the content owner
+         * in the license policy.
+         * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_INSUFFICIENT_SECURITY}
+         */
+        public static final int ERROR_INSUFFICIENT_SECURITY =
+                MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_SECURITY;
+
+        /**
+         * This indicates that the video frame being decrypted exceeds
+         * the size of the device's protected output buffers. When
+         * encountering this error the app should try playing content
+         * of a lower resolution.
+         * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_FRAME_TOO_LARGE}
+         */
+        public static final int ERROR_FRAME_TOO_LARGE = MediaDrm.ErrorCodes.ERROR_FRAME_TOO_LARGE;
+
+        /**
+         * This error indicates that session state has been
+         * invalidated. It can occur on devices that are not capable
+         * of retaining crypto session state across device
+         * suspend/resume. The session must be closed and a new
+         * session opened to resume operation.
+         * @deprecated Please use {@link MediaDrm.ErrorCodes#ERROR_LOST_STATE}
+         */
+        public static final int ERROR_LOST_STATE = MediaDrm.ErrorCodes.ERROR_LOST_STATE;
+
+        /** @hide */
+        @IntDef({
+            MediaDrm.ErrorCodes.ERROR_NO_KEY,
+            MediaDrm.ErrorCodes.ERROR_KEY_EXPIRED,
+            MediaDrm.ErrorCodes.ERROR_RESOURCE_BUSY,
+            MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_OUTPUT_PROTECTION,
+            MediaDrm.ErrorCodes.ERROR_SESSION_NOT_OPENED,
+            MediaDrm.ErrorCodes.ERROR_UNSUPPORTED_OPERATION,
+            MediaDrm.ErrorCodes.ERROR_INSUFFICIENT_SECURITY,
+            MediaDrm.ErrorCodes.ERROR_FRAME_TOO_LARGE,
+            MediaDrm.ErrorCodes.ERROR_LOST_STATE,
+            MediaDrm.ErrorCodes.ERROR_GENERIC_OEM,
+            MediaDrm.ErrorCodes.ERROR_GENERIC_PLUGIN,
+            MediaDrm.ErrorCodes.ERROR_LICENSE_PARSE,
+            MediaDrm.ErrorCodes.ERROR_MEDIA_FRAMEWORK,
+            MediaDrm.ErrorCodes.ERROR_ZERO_SUBSAMPLES
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface CryptoErrorCode {}
+
+        /**
+         * Returns error code associated with this {@link CryptoException}.
+         * <p>
+         * Please refer to {@link MediaDrm.ErrorCodes} for the general error
+         * handling strategy and details about each possible return value.
+         *
+         * @return an error code defined in {@link MediaDrm.ErrorCodes}.
+         */
+        @CryptoErrorCode
+        public int getErrorCode() {
+            return mErrorCode;
+        }
+
+        private int mErrorCode;
+    }
+
+    /**
+     * After filling a range of the input buffer at the specified index
+     * submit it to the component. Once an input buffer is queued to
+     * the codec, it MUST NOT be used until it is later retrieved by
+     * {@link #getInputBuffer} in response to a {@link #dequeueInputBuffer}
+     * return value or a {@link Callback#onInputBufferAvailable}
+     * callback.
+     * <p>
+     * Many decoders require the actual compressed data stream to be
+     * preceded by "codec specific data", i.e. setup data used to initialize
+     * the codec such as PPS/SPS in the case of AVC video or code tables
+     * in the case of vorbis audio.
+     * The class {@link android.media.MediaExtractor} provides codec
+     * specific data as part of
+     * the returned track format in entries named "csd-0", "csd-1" ...
+     * <p>
+     * These buffers can be submitted directly after {@link #start} or
+     * {@link #flush} by specifying the flag {@link
+     * #BUFFER_FLAG_CODEC_CONFIG}.  However, if you configure the
+     * codec with a {@link MediaFormat} containing these keys, they
+     * will be automatically submitted by MediaCodec directly after
+     * start.  Therefore, the use of {@link
+     * #BUFFER_FLAG_CODEC_CONFIG} flag is discouraged and is
+     * recommended only for advanced users.
+     * <p>
+     * To indicate that this is the final piece of input data (or rather that
+     * no more input data follows unless the decoder is subsequently flushed)
+     * specify the flag {@link #BUFFER_FLAG_END_OF_STREAM}.
+     * <p class=note>
+     * <strong>Note:</strong> Prior to {@link android.os.Build.VERSION_CODES#M},
+     * {@code presentationTimeUs} was not propagated to the frame timestamp of (rendered)
+     * Surface output buffers, and the resulting frame timestamp was undefined.
+     * Use {@link #releaseOutputBuffer(int, long)} to ensure a specific frame timestamp is set.
+     * Similarly, since frame timestamps can be used by the destination surface for rendering
+     * synchronization, <strong>care must be taken to normalize presentationTimeUs so as to not be
+     * mistaken for a system time. (See {@linkplain #releaseOutputBuffer(int, long)
+     * SurfaceView specifics}).</strong>
+     *
+     * @param index The index of a client-owned input buffer previously returned
+     *              in a call to {@link #dequeueInputBuffer}.
+     * @param offset The byte offset into the input buffer at which the data starts.
+     * @param size The number of bytes of valid input data.
+     * @param presentationTimeUs The presentation timestamp in microseconds for this
+     *                           buffer. This is normally the media time at which this
+     *                           buffer should be presented (rendered). When using an output
+     *                           surface, this will be propagated as the {@link
+     *                           SurfaceTexture#getTimestamp timestamp} for the frame (after
+     *                           conversion to nanoseconds).
+     * @param flags A bitmask of flags
+     *              {@link #BUFFER_FLAG_CODEC_CONFIG} and {@link #BUFFER_FLAG_END_OF_STREAM}.
+     *              While not prohibited, most codecs do not use the
+     *              {@link #BUFFER_FLAG_KEY_FRAME} flag for input buffers.
+     * @throws IllegalStateException if not in the Executing state.
+     * @throws MediaCodec.CodecException upon codec error.
+     * @throws CryptoException if a crypto object has been specified in
+     *         {@link #configure}
+     */
+    public final void queueInputBuffer(
+            int index,
+            int offset, int size, long presentationTimeUs, int flags)
+        throws CryptoException {
+        synchronized(mBufferLock) {
+            if (mBufferMode == BUFFER_MODE_BLOCK) {
+                throw new IncompatibleWithBlockModelException("queueInputBuffer() "
+                        + "is not compatible with CONFIGURE_FLAG_USE_BLOCK_MODEL. "
+                        + "Please use getQueueRequest() to queue buffers");
+            }
+            invalidateByteBuffer(mCachedInputBuffers, index);
+            mDequeuedInputBuffers.remove(index);
+        }
+        try {
+            native_queueInputBuffer(
+                    index, offset, size, presentationTimeUs, flags);
+        } catch (CryptoException | IllegalStateException e) {
+            revalidateByteBuffer(mCachedInputBuffers, index);
+            throw e;
+        }
+    }
+
+    private native final void native_queueInputBuffer(
+            int index,
+            int offset, int size, long presentationTimeUs, int flags)
+        throws CryptoException;
+
+    public static final int CRYPTO_MODE_UNENCRYPTED = 0;
+    public static final int CRYPTO_MODE_AES_CTR     = 1;
+    public static final int CRYPTO_MODE_AES_CBC     = 2;
+
+    /**
+     * Metadata describing the structure of an encrypted input sample.
+     * <p>
+     * A buffer's data is considered to be partitioned into "subSamples". Each subSample starts with
+     * a run of plain, unencrypted bytes followed by a run of encrypted bytes. Either of these runs
+     * may be empty. If pattern encryption applies, each of the encrypted runs is encrypted only
+     * partly, according to a repeating pattern of "encrypt" and "skip" blocks.
+     * {@link #numBytesOfClearData} can be null to indicate that all data is encrypted, and
+     * {@link #numBytesOfEncryptedData} can be null to indicate that all data is clear. At least one
+     * of {@link #numBytesOfClearData} and {@link #numBytesOfEncryptedData} must be non-null.
+     * <p>
+     * This information encapsulates per-sample metadata as outlined in ISO/IEC FDIS 23001-7:2016
+     * "Common encryption in ISO base media file format files".
+     * <p>
+     * <h3>ISO-CENC Schemes</h3>
+     * ISO/IEC FDIS 23001-7:2016 defines four possible schemes by which media may be encrypted,
+     * corresponding to each possible combination of an AES mode with the presence or absence of
+     * patterned encryption.
+     *
+     * <table style="width: 0%">
+     *   <thead>
+     *     <tr>
+     *       <th>&nbsp;</th>
+     *       <th>AES-CTR</th>
+     *       <th>AES-CBC</th>
+     *     </tr>
+     *   </thead>
+     *   <tbody>
+     *     <tr>
+     *       <th>Without Patterns</th>
+     *       <td>cenc</td>
+     *       <td>cbc1</td>
+     *     </tr><tr>
+     *       <th>With Patterns</th>
+     *       <td>cens</td>
+     *       <td>cbcs</td>
+     *     </tr>
+     *   </tbody>
+     * </table>
+     *
+     * For {@code CryptoInfo}, the scheme is selected implicitly by the combination of the
+     * {@link #mode} field and the value set with {@link #setPattern}. For the pattern, setting the
+     * pattern to all zeroes (that is, both {@code blocksToEncrypt} and {@code blocksToSkip} are
+     * zero) is interpreted as turning patterns off completely. A scheme that does not use patterns
+     * will be selected, either cenc or cbc1. Setting the pattern to any nonzero value will choose
+     * one of the pattern-supporting schemes, cens or cbcs. The default pattern if
+     * {@link #setPattern} is never called is all zeroes.
+     * <p>
+     * <h4>HLS SAMPLE-AES Audio</h4>
+     * HLS SAMPLE-AES audio is encrypted in a manner compatible with the cbcs scheme, except that it
+     * does not use patterned encryption. However, if {@link #setPattern} is used to set the pattern
+     * to all zeroes, this will be interpreted as selecting the cbc1 scheme. The cbc1 scheme cannot
+     * successfully decrypt HLS SAMPLE-AES audio because of differences in how the IVs are handled.
+     * For this reason, it is recommended that a pattern of {@code 1} encrypted block and {@code 0}
+     * skip blocks be used with HLS SAMPLE-AES audio. This will trigger decryption to use cbcs mode
+     * while still decrypting every block.
+     */
+    public final static class CryptoInfo {
+        /**
+         * The number of subSamples that make up the buffer's contents.
+         */
+        public int numSubSamples;
+        /**
+         * The number of leading unencrypted bytes in each subSample. If null, all bytes are treated
+         * as encrypted and {@link #numBytesOfEncryptedData} must be specified.
+         */
+        public int[] numBytesOfClearData;
+        /**
+         * The number of trailing encrypted bytes in each subSample. If null, all bytes are treated
+         * as clear and {@link #numBytesOfClearData} must be specified.
+         */
+        public int[] numBytesOfEncryptedData;
+        /**
+         * A 16-byte key id
+         */
+        public byte[] key;
+        /**
+         * A 16-byte initialization vector
+         */
+        public byte[] iv;
+        /**
+         * The type of encryption that has been applied,
+         * see {@link #CRYPTO_MODE_UNENCRYPTED}, {@link #CRYPTO_MODE_AES_CTR}
+         * and {@link #CRYPTO_MODE_AES_CBC}
+         */
+        public int mode;
+
+        /**
+         * Metadata describing an encryption pattern for the protected bytes in a subsample.  An
+         * encryption pattern consists of a repeating sequence of crypto blocks comprised of a
+         * number of encrypted blocks followed by a number of unencrypted, or skipped, blocks.
+         */
+        public final static class Pattern {
+            /**
+             * Number of blocks to be encrypted in the pattern. If both this and
+             * {@link #mSkipBlocks} are zero, pattern encryption is inoperative.
+             */
+            private int mEncryptBlocks;
+
+            /**
+             * Number of blocks to be skipped (left clear) in the pattern. If both this and
+             * {@link #mEncryptBlocks} are zero, pattern encryption is inoperative.
+             */
+            private int mSkipBlocks;
+
+            /**
+             * Construct a sample encryption pattern given the number of blocks to encrypt and skip
+             * in the pattern. If both parameters are zero, pattern encryption is inoperative.
+             */
+            public Pattern(int blocksToEncrypt, int blocksToSkip) {
+                set(blocksToEncrypt, blocksToSkip);
+            }
+
+            /**
+             * Set the number of blocks to encrypt and skip in a sample encryption pattern. If both
+             * parameters are zero, pattern encryption is inoperative.
+             */
+            public void set(int blocksToEncrypt, int blocksToSkip) {
+                mEncryptBlocks = blocksToEncrypt;
+                mSkipBlocks = blocksToSkip;
+            }
+
+            /**
+             * Return the number of blocks to skip in a sample encryption pattern.
+             */
+            public int getSkipBlocks() {
+                return mSkipBlocks;
+            }
+
+            /**
+             * Return the number of blocks to encrypt in a sample encryption pattern.
+             */
+            public int getEncryptBlocks() {
+                return mEncryptBlocks;
+            }
+        };
+
+        private static final Pattern ZERO_PATTERN = new Pattern(0, 0);
+
+        /**
+         * The pattern applicable to the protected data in each subsample.
+         */
+        private Pattern mPattern = ZERO_PATTERN;
+
+        /**
+         * Set the subsample count, clear/encrypted sizes, key, IV and mode fields of
+         * a {@link MediaCodec.CryptoInfo} instance.
+         */
+        public void set(
+                int newNumSubSamples,
+                @NonNull int[] newNumBytesOfClearData,
+                @NonNull int[] newNumBytesOfEncryptedData,
+                @NonNull byte[] newKey,
+                @NonNull byte[] newIV,
+                int newMode) {
+            numSubSamples = newNumSubSamples;
+            numBytesOfClearData = newNumBytesOfClearData;
+            numBytesOfEncryptedData = newNumBytesOfEncryptedData;
+            key = newKey;
+            iv = newIV;
+            mode = newMode;
+            mPattern = ZERO_PATTERN;
+        }
+
+        /**
+         * Returns the {@link Pattern encryption pattern}.
+         */
+        public @NonNull Pattern getPattern() {
+            return new Pattern(mPattern.getEncryptBlocks(), mPattern.getSkipBlocks());
+        }
+
+        /**
+         * Set the encryption pattern on a {@link MediaCodec.CryptoInfo} instance.
+         * See {@link Pattern}.
+         */
+        public void setPattern(Pattern newPattern) {
+            if (newPattern == null) {
+                newPattern = ZERO_PATTERN;
+            }
+            setPattern(newPattern.getEncryptBlocks(), newPattern.getSkipBlocks());
+        }
+
+        // Accessed from android_media_MediaExtractor.cpp.
+        private void setPattern(int blocksToEncrypt, int blocksToSkip) {
+            mPattern = new Pattern(blocksToEncrypt, blocksToSkip);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder builder = new StringBuilder();
+            builder.append(numSubSamples + " subsamples, key [");
+            String hexdigits = "0123456789abcdef";
+            for (int i = 0; i < key.length; i++) {
+                builder.append(hexdigits.charAt((key[i] & 0xf0) >> 4));
+                builder.append(hexdigits.charAt(key[i] & 0x0f));
+            }
+            builder.append("], iv [");
+            for (int i = 0; i < iv.length; i++) {
+                builder.append(hexdigits.charAt((iv[i] & 0xf0) >> 4));
+                builder.append(hexdigits.charAt(iv[i] & 0x0f));
+            }
+            builder.append("], clear ");
+            builder.append(Arrays.toString(numBytesOfClearData));
+            builder.append(", encrypted ");
+            builder.append(Arrays.toString(numBytesOfEncryptedData));
+            builder.append(", pattern (encrypt: ");
+            builder.append(mPattern.mEncryptBlocks);
+            builder.append(", skip: ");
+            builder.append(mPattern.mSkipBlocks);
+            builder.append(")");
+            return builder.toString();
+        }
+    };
+
+    /**
+     * Similar to {@link #queueInputBuffer queueInputBuffer} but submits a buffer that is
+     * potentially encrypted.
+     * <strong>Check out further notes at {@link #queueInputBuffer queueInputBuffer}.</strong>
+     *
+     * @param index The index of a client-owned input buffer previously returned
+     *              in a call to {@link #dequeueInputBuffer}.
+     * @param offset The byte offset into the input buffer at which the data starts.
+     * @param info Metadata required to facilitate decryption, the object can be
+     *             reused immediately after this call returns.
+     * @param presentationTimeUs The presentation timestamp in microseconds for this
+     *                           buffer. This is normally the media time at which this
+     *                           buffer should be presented (rendered).
+     * @param flags A bitmask of flags
+     *              {@link #BUFFER_FLAG_CODEC_CONFIG} and {@link #BUFFER_FLAG_END_OF_STREAM}.
+     *              While not prohibited, most codecs do not use the
+     *              {@link #BUFFER_FLAG_KEY_FRAME} flag for input buffers.
+     * @throws IllegalStateException if not in the Executing state.
+     * @throws MediaCodec.CodecException upon codec error.
+     * @throws CryptoException if an error occurs while attempting to decrypt the buffer.
+     *              An error code associated with the exception helps identify the
+     *              reason for the failure.
+     */
+    public final void queueSecureInputBuffer(
+            int index,
+            int offset,
+            @NonNull CryptoInfo info,
+            long presentationTimeUs,
+            int flags) throws CryptoException {
+        synchronized(mBufferLock) {
+            if (mBufferMode == BUFFER_MODE_BLOCK) {
+                throw new IncompatibleWithBlockModelException("queueSecureInputBuffer() "
+                        + "is not compatible with CONFIGURE_FLAG_USE_BLOCK_MODEL. "
+                        + "Please use getQueueRequest() to queue buffers");
+            }
+            invalidateByteBuffer(mCachedInputBuffers, index);
+            mDequeuedInputBuffers.remove(index);
+        }
+        try {
+            native_queueSecureInputBuffer(
+                    index, offset, info, presentationTimeUs, flags);
+        } catch (CryptoException | IllegalStateException e) {
+            revalidateByteBuffer(mCachedInputBuffers, index);
+            throw e;
+        }
+    }
+
+    private native final void native_queueSecureInputBuffer(
+            int index,
+            int offset,
+            @NonNull CryptoInfo info,
+            long presentationTimeUs,
+            int flags) throws CryptoException;
+
+    /**
+     * Returns the index of an input buffer to be filled with valid data
+     * or -1 if no such buffer is currently available.
+     * This method will return immediately if timeoutUs == 0, wait indefinitely
+     * for the availability of an input buffer if timeoutUs &lt; 0 or wait up
+     * to "timeoutUs" microseconds if timeoutUs &gt; 0.
+     * @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
+     * @throws IllegalStateException if not in the Executing state,
+     *         or codec is configured in asynchronous mode.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    public final int dequeueInputBuffer(long timeoutUs) {
+        synchronized (mBufferLock) {
+            if (mBufferMode == BUFFER_MODE_BLOCK) {
+                throw new IncompatibleWithBlockModelException("dequeueInputBuffer() "
+                        + "is not compatible with CONFIGURE_FLAG_USE_BLOCK_MODEL. "
+                        + "Please use MediaCodec.Callback objectes to get input buffer slots.");
+            }
+        }
+        int res = native_dequeueInputBuffer(timeoutUs);
+        if (res >= 0) {
+            synchronized(mBufferLock) {
+                validateInputByteBuffer(mCachedInputBuffers, res);
+            }
+        }
+        return res;
+    }
+
+    private native final int native_dequeueInputBuffer(long timeoutUs);
+
+    /**
+     * Section of memory that represents a linear block. Applications may
+     * acquire a block via {@link LinearBlock#obtain} and queue all or part
+     * of the block as an input buffer to a codec, or get a block allocated by
+     * codec as an output buffer from {@link OutputFrame}.
+     *
+     * {@see QueueRequest#setLinearBlock}
+     * {@see QueueRequest#setEncryptedLinearBlock}
+     * {@see OutputFrame#getLinearBlock}
+     */
+    public static final class LinearBlock {
+        // No public constructors.
+        private LinearBlock() {}
+
+        /**
+         * Returns true if the buffer is mappable.
+         * @throws IllegalStateException if invalid
+         */
+        public boolean isMappable() {
+            synchronized (mLock) {
+                if (!mValid) {
+                    throw new IllegalStateException("The linear block is invalid");
+                }
+                return mMappable;
+            }
+        }
+
+        /**
+         * Map the memory and return the mapped region.
+         * <p>
+         * The returned memory region becomes inaccessible after
+         * {@link #recycle}, or the buffer is queued to the codecs and not
+         * returned to the client yet.
+         *
+         * @return mapped memory region as {@link ByteBuffer} object
+         * @throws IllegalStateException if not mappable or invalid
+         */
+        public @NonNull ByteBuffer map() {
+            synchronized (mLock) {
+                if (!mValid) {
+                    throw new IllegalStateException("The linear block is invalid");
+                }
+                if (!mMappable) {
+                    throw new IllegalStateException("The linear block is not mappable");
+                }
+                if (mMapped == null) {
+                    mMapped = native_map();
+                }
+                return mMapped;
+            }
+        }
+
+        private native ByteBuffer native_map();
+
+        /**
+         * Mark this block as ready to be recycled by the framework once it is
+         * no longer in use. All operations to this object after
+         * this call will cause exceptions, as well as attempt to access the
+         * previously mapped memory region. Caller should clear all references
+         * to this object after this call.
+         * <p>
+         * To avoid excessive memory consumption, it is recommended that callers
+         * recycle buffers as soon as they no longer need the buffers
+         *
+         * @throws IllegalStateException if invalid
+         */
+        public void recycle() {
+            synchronized (mLock) {
+                if (!mValid) {
+                    throw new IllegalStateException("The linear block is invalid");
+                }
+                if (mMapped != null) {
+                    mMapped.setAccessible(false);
+                    mMapped = null;
+                }
+                native_recycle();
+                mValid = false;
+                mNativeContext = 0;
+            }
+            sPool.offer(this);
+        }
+
+        private native void native_recycle();
+
+        private native void native_obtain(int capacity, String[] codecNames);
+
+        @Override
+        protected void finalize() {
+            native_recycle();
+        }
+
+        /**
+         * Returns true if it is possible to allocate a linear block that can be
+         * passed to all listed codecs as input buffers without copying the
+         * content.
+         * <p>
+         * Note that even if this function returns true, {@link #obtain} may
+         * still throw due to invalid arguments or allocation failure.
+         *
+         * @param codecNames  list of codecs that the client wants to use a
+         *                    linear block without copying. Null entries are
+         *                    ignored.
+         */
+        public static boolean isCodecCopyFreeCompatible(@NonNull String[] codecNames) {
+            return native_checkCompatible(codecNames);
+        }
+
+        private static native boolean native_checkCompatible(@NonNull String[] codecNames);
+
+        /**
+         * Obtain a linear block object no smaller than {@code capacity}.
+         * If {@link #isCodecCopyFreeCompatible} with the same
+         * {@code codecNames} returned true, the returned
+         * {@link LinearBlock} object can be queued to the listed codecs without
+         * copying. The returned {@link LinearBlock} object is always
+         * read/write mappable.
+         *
+         * @param capacity requested capacity of the linear block in bytes
+         * @param codecNames  list of codecs that the client wants to use this
+         *                    linear block without copying. Null entries are
+         *                    ignored.
+         * @return  a linear block object.
+         * @throws IllegalArgumentException if the capacity is invalid or
+         *                                  codecNames contains invalid name
+         * @throws IOException if an error occurred while allocating a buffer
+         */
+        public static @Nullable LinearBlock obtain(
+                int capacity, @NonNull String[] codecNames) {
+            LinearBlock buffer = sPool.poll();
+            if (buffer == null) {
+                buffer = new LinearBlock();
+            }
+            synchronized (buffer.mLock) {
+                buffer.native_obtain(capacity, codecNames);
+            }
+            return buffer;
+        }
+
+        // Called from native
+        private void setInternalStateLocked(long context, boolean isMappable) {
+            mNativeContext = context;
+            mMappable = isMappable;
+            mValid = (context != 0);
+        }
+
+        private static final BlockingQueue<LinearBlock> sPool =
+                new LinkedBlockingQueue<>();
+
+        private final Object mLock = new Object();
+        private boolean mValid = false;
+        private boolean mMappable = false;
+        private ByteBuffer mMapped = null;
+        private long mNativeContext = 0;
+    }
+
+    /**
+     * Map a {@link HardwareBuffer} object into {@link Image}, so that the content of the buffer is
+     * accessible. Depending on the usage and pixel format of the hardware buffer, it may not be
+     * mappable; this method returns null in that case.
+     *
+     * @param hardwareBuffer {@link HardwareBuffer} to map.
+     * @return Mapped {@link Image} object, or null if the buffer is not mappable.
+     */
+    public static @Nullable Image mapHardwareBuffer(@NonNull HardwareBuffer hardwareBuffer) {
+        return native_mapHardwareBuffer(hardwareBuffer);
+    }
+
+    private static native @Nullable Image native_mapHardwareBuffer(
+            @NonNull HardwareBuffer hardwareBuffer);
+
+    private static native void native_closeMediaImage(long context);
+
+    /**
+     * Builder-like class for queue requests. Use this class to prepare a
+     * queue request and send it.
+     */
+    public final class QueueRequest {
+        // No public constructor
+        private QueueRequest(@NonNull MediaCodec codec, int index) {
+            mCodec = codec;
+            mIndex = index;
+        }
+
+        /**
+         * Set a linear block to this queue request. Exactly one buffer must be
+         * set for a queue request before calling {@link #queue}. It is possible
+         * to use the same {@link LinearBlock} object for multiple queue
+         * requests. The behavior is undefined if the range of the buffer
+         * overlaps for multiple requests, or the application writes into the
+         * region being processed by the codec.
+         *
+         * @param block The linear block object
+         * @param offset The byte offset into the input buffer at which the data starts.
+         * @param size The number of bytes of valid input data.
+         * @return this object
+         * @throws IllegalStateException if a buffer is already set
+         */
+        public @NonNull QueueRequest setLinearBlock(
+                @NonNull LinearBlock block,
+                int offset,
+                int size) {
+            if (!isAccessible()) {
+                throw new IllegalStateException("The request is stale");
+            }
+            if (mLinearBlock != null || mHardwareBuffer != null) {
+                throw new IllegalStateException("Cannot set block twice");
+            }
+            mLinearBlock = block;
+            mOffset = offset;
+            mSize = size;
+            mCryptoInfo = null;
+            return this;
+        }
+
+        /**
+         * Set an encrypted linear block to this queue request. Exactly one buffer must be
+         * set for a queue request before calling {@link #queue}. It is possible
+         * to use the same {@link LinearBlock} object for multiple queue
+         * requests. The behavior is undefined if the range of the buffer
+         * overlaps for multiple requests, or the application writes into the
+         * region being processed by the codec.
+         *
+         * @param block The linear block object
+         * @param offset The byte offset into the input buffer at which the data starts.
+         * @param size The number of bytes of valid input data.
+         * @param cryptoInfo Metadata describing the structure of the encrypted input sample.
+         * @return this object
+         * @throws IllegalStateException if a buffer is already set
+         */
+        public @NonNull QueueRequest setEncryptedLinearBlock(
+                @NonNull LinearBlock block,
+                int offset,
+                int size,
+                @NonNull MediaCodec.CryptoInfo cryptoInfo) {
+            Objects.requireNonNull(cryptoInfo);
+            if (!isAccessible()) {
+                throw new IllegalStateException("The request is stale");
+            }
+            if (mLinearBlock != null || mHardwareBuffer != null) {
+                throw new IllegalStateException("Cannot set block twice");
+            }
+            mLinearBlock = block;
+            mOffset = offset;
+            mSize = size;
+            mCryptoInfo = cryptoInfo;
+            return this;
+        }
+
+        /**
+         * Set a harware graphic buffer to this queue request. Exactly one buffer must
+         * be set for a queue request before calling {@link #queue}.
+         * <p>
+         * Note: buffers should have format {@link HardwareBuffer#YCBCR_420_888},
+         * a single layer, and an appropriate usage ({@link HardwareBuffer#USAGE_CPU_READ_OFTEN}
+         * for software codecs and {@link HardwareBuffer#USAGE_VIDEO_ENCODE} for hardware)
+         * for codecs to recognize.  Codecs may throw exception if the buffer is not recognizable.
+         *
+         * @param buffer The hardware graphic buffer object
+         * @return this object
+         * @throws IllegalStateException if a buffer is already set
+         */
+        public @NonNull QueueRequest setHardwareBuffer(
+                @NonNull HardwareBuffer buffer) {
+            if (!isAccessible()) {
+                throw new IllegalStateException("The request is stale");
+            }
+            if (mLinearBlock != null || mHardwareBuffer != null) {
+                throw new IllegalStateException("Cannot set block twice");
+            }
+            mHardwareBuffer = buffer;
+            return this;
+        }
+
+        /**
+         * Set timestamp to this queue request.
+         *
+         * @param presentationTimeUs The presentation timestamp in microseconds for this
+         *                           buffer. This is normally the media time at which this
+         *                           buffer should be presented (rendered). When using an output
+         *                           surface, this will be propagated as the {@link
+         *                           SurfaceTexture#getTimestamp timestamp} for the frame (after
+         *                           conversion to nanoseconds).
+         * @return this object
+         */
+        public @NonNull QueueRequest setPresentationTimeUs(long presentationTimeUs) {
+            if (!isAccessible()) {
+                throw new IllegalStateException("The request is stale");
+            }
+            mPresentationTimeUs = presentationTimeUs;
+            return this;
+        }
+
+        /**
+         * Set flags to this queue request.
+         *
+         * @param flags A bitmask of flags
+         *              {@link #BUFFER_FLAG_CODEC_CONFIG} and {@link #BUFFER_FLAG_END_OF_STREAM}.
+         *              While not prohibited, most codecs do not use the
+         *              {@link #BUFFER_FLAG_KEY_FRAME} flag for input buffers.
+         * @return this object
+         */
+        public @NonNull QueueRequest setFlags(@BufferFlag int flags) {
+            if (!isAccessible()) {
+                throw new IllegalStateException("The request is stale");
+            }
+            mFlags = flags;
+            return this;
+        }
+
+        /**
+         * Add an integer parameter.
+         * See {@link MediaFormat} for an exhaustive list of supported keys with
+         * values of type int, that can also be set with {@link MediaFormat#setInteger}.
+         *
+         * If there was {@link MediaCodec#setParameters}
+         * call with the same key which is not processed by the codec yet, the
+         * value set from this method will override the unprocessed value.
+         *
+         * @return this object
+         */
+        public @NonNull QueueRequest setIntegerParameter(
+                @NonNull String key, int value) {
+            if (!isAccessible()) {
+                throw new IllegalStateException("The request is stale");
+            }
+            mTuningKeys.add(key);
+            mTuningValues.add(Integer.valueOf(value));
+            return this;
+        }
+
+        /**
+         * Add a long parameter.
+         * See {@link MediaFormat} for an exhaustive list of supported keys with
+         * values of type long, that can also be set with {@link MediaFormat#setLong}.
+         *
+         * If there was {@link MediaCodec#setParameters}
+         * call with the same key which is not processed by the codec yet, the
+         * value set from this method will override the unprocessed value.
+         *
+         * @return this object
+         */
+        public @NonNull QueueRequest setLongParameter(
+                @NonNull String key, long value) {
+            if (!isAccessible()) {
+                throw new IllegalStateException("The request is stale");
+            }
+            mTuningKeys.add(key);
+            mTuningValues.add(Long.valueOf(value));
+            return this;
+        }
+
+        /**
+         * Add a float parameter.
+         * See {@link MediaFormat} for an exhaustive list of supported keys with
+         * values of type float, that can also be set with {@link MediaFormat#setFloat}.
+         *
+         * If there was {@link MediaCodec#setParameters}
+         * call with the same key which is not processed by the codec yet, the
+         * value set from this method will override the unprocessed value.
+         *
+         * @return this object
+         */
+        public @NonNull QueueRequest setFloatParameter(
+                @NonNull String key, float value) {
+            if (!isAccessible()) {
+                throw new IllegalStateException("The request is stale");
+            }
+            mTuningKeys.add(key);
+            mTuningValues.add(Float.valueOf(value));
+            return this;
+        }
+
+        /**
+         * Add a {@link ByteBuffer} parameter.
+         * See {@link MediaFormat} for an exhaustive list of supported keys with
+         * values of byte buffer, that can also be set with {@link MediaFormat#setByteBuffer}.
+         *
+         * If there was {@link MediaCodec#setParameters}
+         * call with the same key which is not processed by the codec yet, the
+         * value set from this method will override the unprocessed value.
+         *
+         * @return this object
+         */
+        public @NonNull QueueRequest setByteBufferParameter(
+                @NonNull String key, @NonNull ByteBuffer value) {
+            if (!isAccessible()) {
+                throw new IllegalStateException("The request is stale");
+            }
+            mTuningKeys.add(key);
+            mTuningValues.add(value);
+            return this;
+        }
+
+        /**
+         * Add a string parameter.
+         * See {@link MediaFormat} for an exhaustive list of supported keys with
+         * values of type string, that can also be set with {@link MediaFormat#setString}.
+         *
+         * If there was {@link MediaCodec#setParameters}
+         * call with the same key which is not processed by the codec yet, the
+         * value set from this method will override the unprocessed value.
+         *
+         * @return this object
+         */
+        public @NonNull QueueRequest setStringParameter(
+                @NonNull String key, @NonNull String value) {
+            if (!isAccessible()) {
+                throw new IllegalStateException("The request is stale");
+            }
+            mTuningKeys.add(key);
+            mTuningValues.add(value);
+            return this;
+        }
+
+        /**
+         * Finish building a queue request and queue the buffers with tunings.
+         */
+        public void queue() {
+            if (!isAccessible()) {
+                throw new IllegalStateException("The request is stale");
+            }
+            if (mLinearBlock == null && mHardwareBuffer == null) {
+                throw new IllegalStateException("No block is set");
+            }
+            setAccessible(false);
+            if (mLinearBlock != null) {
+                mCodec.native_queueLinearBlock(
+                        mIndex, mLinearBlock, mOffset, mSize, mCryptoInfo,
+                        mPresentationTimeUs, mFlags,
+                        mTuningKeys, mTuningValues);
+            } else if (mHardwareBuffer != null) {
+                mCodec.native_queueHardwareBuffer(
+                        mIndex, mHardwareBuffer, mPresentationTimeUs, mFlags,
+                        mTuningKeys, mTuningValues);
+            }
+            clear();
+        }
+
+        @NonNull QueueRequest clear() {
+            mLinearBlock = null;
+            mOffset = 0;
+            mSize = 0;
+            mCryptoInfo = null;
+            mHardwareBuffer = null;
+            mPresentationTimeUs = 0;
+            mFlags = 0;
+            mTuningKeys.clear();
+            mTuningValues.clear();
+            return this;
+        }
+
+        boolean isAccessible() {
+            return mAccessible;
+        }
+
+        @NonNull QueueRequest setAccessible(boolean accessible) {
+            mAccessible = accessible;
+            return this;
+        }
+
+        private final MediaCodec mCodec;
+        private final int mIndex;
+        private LinearBlock mLinearBlock = null;
+        private int mOffset = 0;
+        private int mSize = 0;
+        private MediaCodec.CryptoInfo mCryptoInfo = null;
+        private HardwareBuffer mHardwareBuffer = null;
+        private long mPresentationTimeUs = 0;
+        private @BufferFlag int mFlags = 0;
+        private final ArrayList<String> mTuningKeys = new ArrayList<>();
+        private final ArrayList<Object> mTuningValues = new ArrayList<>();
+
+        private boolean mAccessible = false;
+    }
+
+    private native void native_queueLinearBlock(
+            int index,
+            @NonNull LinearBlock block,
+            int offset,
+            int size,
+            @Nullable CryptoInfo cryptoInfo,
+            long presentationTimeUs,
+            int flags,
+            @NonNull ArrayList<String> keys,
+            @NonNull ArrayList<Object> values);
+
+    private native void native_queueHardwareBuffer(
+            int index,
+            @NonNull HardwareBuffer buffer,
+            long presentationTimeUs,
+            int flags,
+            @NonNull ArrayList<String> keys,
+            @NonNull ArrayList<Object> values);
+
+    private final ArrayList<QueueRequest> mQueueRequests = new ArrayList<>();
+
+    /**
+     * Return a {@link QueueRequest} object for an input slot index.
+     *
+     * @param index input slot index from
+     *              {@link Callback#onInputBufferAvailable}
+     * @return queue request object
+     * @throws IllegalStateException if not using block model
+     * @throws IllegalArgumentException if the input slot is not available or
+     *                                  the index is out of range
+     */
+    public @NonNull QueueRequest getQueueRequest(int index) {
+        synchronized (mBufferLock) {
+            if (mBufferMode != BUFFER_MODE_BLOCK) {
+                throw new IllegalStateException("The codec is not configured for block model");
+            }
+            if (index < 0 || index >= mQueueRequests.size()) {
+                throw new IndexOutOfBoundsException("Expected range of index: [0,"
+                        + (mQueueRequests.size() - 1) + "]; actual: " + index);
+            }
+            QueueRequest request = mQueueRequests.get(index);
+            if (request == null) {
+                throw new IllegalArgumentException("Unavailable index: " + index);
+            }
+            if (!request.isAccessible()) {
+                throw new IllegalArgumentException(
+                        "The request is stale at index " + index);
+            }
+            return request.clear();
+        }
+    }
+
+    /**
+     * If a non-negative timeout had been specified in the call
+     * to {@link #dequeueOutputBuffer}, indicates that the call timed out.
+     */
+    public static final int INFO_TRY_AGAIN_LATER        = -1;
+
+    /**
+     * The output format has changed, subsequent data will follow the new
+     * format. {@link #getOutputFormat()} returns the new format.  Note, that
+     * you can also use the new {@link #getOutputFormat(int)} method to
+     * get the format for a specific output buffer.  This frees you from
+     * having to track output format changes.
+     */
+    public static final int INFO_OUTPUT_FORMAT_CHANGED  = -2;
+
+    /**
+     * The output buffers have changed, the client must refer to the new
+     * set of output buffers returned by {@link #getOutputBuffers} from
+     * this point on.
+     *
+     * <p>Additionally, this event signals that the video scaling mode
+     * may have been reset to the default.</p>
+     *
+     * @deprecated This return value can be ignored as {@link
+     * #getOutputBuffers} has been deprecated.  Client should
+     * request a current buffer using on of the get-buffer or
+     * get-image methods each time one has been dequeued.
+     */
+    public static final int INFO_OUTPUT_BUFFERS_CHANGED = -3;
+
+    /** @hide */
+    @IntDef({
+        INFO_TRY_AGAIN_LATER,
+        INFO_OUTPUT_FORMAT_CHANGED,
+        INFO_OUTPUT_BUFFERS_CHANGED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface OutputBufferInfo {}
+
+    /**
+     * Dequeue an output buffer, block at most "timeoutUs" microseconds.
+     * Returns the index of an output buffer that has been successfully
+     * decoded or one of the INFO_* constants.
+     * @param info Will be filled with buffer meta data.
+     * @param timeoutUs The timeout in microseconds, a negative timeout indicates "infinite".
+     * @throws IllegalStateException if not in the Executing state,
+     *         or codec is configured in asynchronous mode.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    @OutputBufferInfo
+    public final int dequeueOutputBuffer(
+            @NonNull BufferInfo info, long timeoutUs) {
+        synchronized (mBufferLock) {
+            if (mBufferMode == BUFFER_MODE_BLOCK) {
+                throw new IncompatibleWithBlockModelException("dequeueOutputBuffer() "
+                        + "is not compatible with CONFIGURE_FLAG_USE_BLOCK_MODEL. "
+                        + "Please use MediaCodec.Callback objects to get output buffer slots.");
+            }
+        }
+        int res = native_dequeueOutputBuffer(info, timeoutUs);
+        synchronized (mBufferLock) {
+            if (res == INFO_OUTPUT_BUFFERS_CHANGED) {
+                cacheBuffers(false /* input */);
+            } else if (res >= 0) {
+                validateOutputByteBuffer(mCachedOutputBuffers, res, info);
+                if (mHasSurface) {
+                    mDequeuedOutputInfos.put(res, info.dup());
+                }
+            }
+        }
+        return res;
+    }
+
+    private native final int native_dequeueOutputBuffer(
+            @NonNull BufferInfo info, long timeoutUs);
+
+    /**
+     * If you are done with a buffer, use this call to return the buffer to the codec
+     * or to render it on the output surface. If you configured the codec with an
+     * output surface, setting {@code render} to {@code true} will first send the buffer
+     * to that output surface. The surface will release the buffer back to the codec once
+     * it is no longer used/displayed.
+     *
+     * Once an output buffer is released to the codec, it MUST NOT
+     * be used until it is later retrieved by {@link #getOutputBuffer} in response
+     * to a {@link #dequeueOutputBuffer} return value or a
+     * {@link Callback#onOutputBufferAvailable} callback.
+     *
+     * @param index The index of a client-owned output buffer previously returned
+     *              from a call to {@link #dequeueOutputBuffer}.
+     * @param render If a valid surface was specified when configuring the codec,
+     *               passing true renders this output buffer to the surface.
+     * @throws IllegalStateException if not in the Executing state.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    public final void releaseOutputBuffer(int index, boolean render) {
+        releaseOutputBufferInternal(index, render, false /* updatePTS */, 0 /* dummy */);
+    }
+
+    /**
+     * If you are done with a buffer, use this call to update its surface timestamp
+     * and return it to the codec to render it on the output surface. If you
+     * have not specified an output surface when configuring this video codec,
+     * this call will simply return the buffer to the codec.<p>
+     *
+     * The timestamp may have special meaning depending on the destination surface.
+     *
+     * <table>
+     * <tr><th>SurfaceView specifics</th></tr>
+     * <tr><td>
+     * If you render your buffer on a {@link android.view.SurfaceView},
+     * you can use the timestamp to render the buffer at a specific time (at the
+     * VSYNC at or after the buffer timestamp).  For this to work, the timestamp
+     * needs to be <i>reasonably close</i> to the current {@link System#nanoTime}.
+     * Currently, this is set as within one (1) second. A few notes:
+     *
+     * <ul>
+     * <li>the buffer will not be returned to the codec until the timestamp
+     * has passed and the buffer is no longer used by the {@link android.view.Surface}.
+     * <li>buffers are processed sequentially, so you may block subsequent buffers to
+     * be displayed on the {@link android.view.Surface}.  This is important if you
+     * want to react to user action, e.g. stop the video or seek.
+     * <li>if multiple buffers are sent to the {@link android.view.Surface} to be
+     * rendered at the same VSYNC, the last one will be shown, and the other ones
+     * will be dropped.
+     * <li>if the timestamp is <em>not</em> "reasonably close" to the current system
+     * time, the {@link android.view.Surface} will ignore the timestamp, and
+     * display the buffer at the earliest feasible time.  In this mode it will not
+     * drop frames.
+     * <li>for best performance and quality, call this method when you are about
+     * two VSYNCs' time before the desired render time.  For 60Hz displays, this is
+     * about 33 msec.
+     * </ul>
+     * </td></tr>
+     * </table>
+     *
+     * Once an output buffer is released to the codec, it MUST NOT
+     * be used until it is later retrieved by {@link #getOutputBuffer} in response
+     * to a {@link #dequeueOutputBuffer} return value or a
+     * {@link Callback#onOutputBufferAvailable} callback.
+     *
+     * @param index The index of a client-owned output buffer previously returned
+     *              from a call to {@link #dequeueOutputBuffer}.
+     * @param renderTimestampNs The timestamp to associate with this buffer when
+     *              it is sent to the Surface.
+     * @throws IllegalStateException if not in the Executing state.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    public final void releaseOutputBuffer(int index, long renderTimestampNs) {
+        releaseOutputBufferInternal(
+                index, true /* render */, true /* updatePTS */, renderTimestampNs);
+    }
+
+    private void releaseOutputBufferInternal(
+            int index, boolean render, boolean updatePts, long renderTimestampNs) {
+        BufferInfo info = null;
+        synchronized(mBufferLock) {
+            switch (mBufferMode) {
+                case BUFFER_MODE_LEGACY:
+                    invalidateByteBuffer(mCachedOutputBuffers, index);
+                    mDequeuedOutputBuffers.remove(index);
+                    if (mHasSurface) {
+                        info = mDequeuedOutputInfos.remove(index);
+                    }
+                    break;
+                case BUFFER_MODE_BLOCK:
+                    OutputFrame frame = mOutputFrames.get(index);
+                    frame.setAccessible(false);
+                    frame.clear();
+                    break;
+                default:
+                    throw new IllegalStateException(
+                            "Unrecognized buffer mode: " + mBufferMode);
+            }
+        }
+        releaseOutputBuffer(
+                index, render, updatePts, renderTimestampNs);
+    }
+
+    @UnsupportedAppUsage
+    private native final void releaseOutputBuffer(
+            int index, boolean render, boolean updatePTS, long timeNs);
+
+    /**
+     * Signals end-of-stream on input.  Equivalent to submitting an empty buffer with
+     * {@link #BUFFER_FLAG_END_OF_STREAM} set.  This may only be used with
+     * encoders receiving input from a Surface created by {@link #createInputSurface}.
+     * @throws IllegalStateException if not in the Executing state.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    public native final void signalEndOfInputStream();
+
+    /**
+     * Call this after dequeueOutputBuffer signals a format change by returning
+     * {@link #INFO_OUTPUT_FORMAT_CHANGED}.
+     * You can also call this after {@link #configure} returns
+     * successfully to get the output format initially configured
+     * for the codec.  Do this to determine what optional
+     * configuration parameters were supported by the codec.
+     *
+     * @throws IllegalStateException if not in the Executing or
+     *                               Configured state.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    @NonNull
+    public final MediaFormat getOutputFormat() {
+        return new MediaFormat(getFormatNative(false /* input */));
+    }
+
+    /**
+     * Call this after {@link #configure} returns successfully to
+     * get the input format accepted by the codec. Do this to
+     * determine what optional configuration parameters were
+     * supported by the codec.
+     *
+     * @throws IllegalStateException if not in the Executing or
+     *                               Configured state.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    @NonNull
+    public final MediaFormat getInputFormat() {
+        return new MediaFormat(getFormatNative(true /* input */));
+    }
+
+    /**
+     * Returns the output format for a specific output buffer.
+     *
+     * @param index The index of a client-owned input buffer previously
+     *              returned from a call to {@link #dequeueInputBuffer}.
+     *
+     * @return the format for the output buffer, or null if the index
+     * is not a dequeued output buffer.
+     */
+    @NonNull
+    public final MediaFormat getOutputFormat(int index) {
+        return new MediaFormat(getOutputFormatNative(index));
+    }
+
+    @NonNull
+    private native final Map<String, Object> getFormatNative(boolean input);
+
+    @NonNull
+    private native final Map<String, Object> getOutputFormatNative(int index);
+
+    // used to track dequeued buffers
+    private static class BufferMap {
+        // various returned representations of the codec buffer
+        private static class CodecBuffer {
+            private Image mImage;
+            private ByteBuffer mByteBuffer;
+
+            public void free() {
+                if (mByteBuffer != null) {
+                    // all of our ByteBuffers are direct
+                    java.nio.NioUtils.freeDirectBuffer(mByteBuffer);
+                    mByteBuffer = null;
+                }
+                if (mImage != null) {
+                    mImage.close();
+                    mImage = null;
+                }
+            }
+
+            public void setImage(@Nullable Image image) {
+                free();
+                mImage = image;
+            }
+
+            public void setByteBuffer(@Nullable ByteBuffer buffer) {
+                free();
+                mByteBuffer = buffer;
+            }
+        }
+
+        private final Map<Integer, CodecBuffer> mMap =
+            new HashMap<Integer, CodecBuffer>();
+
+        public void remove(int index) {
+            CodecBuffer buffer = mMap.get(index);
+            if (buffer != null) {
+                buffer.free();
+                mMap.remove(index);
+            }
+        }
+
+        public void put(int index, @Nullable ByteBuffer newBuffer) {
+            CodecBuffer buffer = mMap.get(index);
+            if (buffer == null) { // likely
+                buffer = new CodecBuffer();
+                mMap.put(index, buffer);
+            }
+            buffer.setByteBuffer(newBuffer);
+        }
+
+        public void put(int index, @Nullable Image newImage) {
+            CodecBuffer buffer = mMap.get(index);
+            if (buffer == null) { // likely
+                buffer = new CodecBuffer();
+                mMap.put(index, buffer);
+            }
+            buffer.setImage(newImage);
+        }
+
+        public void clear() {
+            for (CodecBuffer buffer: mMap.values()) {
+                buffer.free();
+            }
+            mMap.clear();
+        }
+    }
+
+    private ByteBuffer[] mCachedInputBuffers;
+    private ByteBuffer[] mCachedOutputBuffers;
+    private final BufferMap mDequeuedInputBuffers = new BufferMap();
+    private final BufferMap mDequeuedOutputBuffers = new BufferMap();
+    private final Map<Integer, BufferInfo> mDequeuedOutputInfos =
+        new HashMap<Integer, BufferInfo>();
+    final private Object mBufferLock;
+
+    private final void invalidateByteBuffer(
+            @Nullable ByteBuffer[] buffers, int index) {
+        if (buffers != null && index >= 0 && index < buffers.length) {
+            ByteBuffer buffer = buffers[index];
+            if (buffer != null) {
+                buffer.setAccessible(false);
+            }
+        }
+    }
+
+    private final void validateInputByteBuffer(
+            @Nullable ByteBuffer[] buffers, int index) {
+        if (buffers != null && index >= 0 && index < buffers.length) {
+            ByteBuffer buffer = buffers[index];
+            if (buffer != null) {
+                buffer.setAccessible(true);
+                buffer.clear();
+            }
+        }
+    }
+
+    private final void revalidateByteBuffer(
+            @Nullable ByteBuffer[] buffers, int index) {
+        synchronized(mBufferLock) {
+            if (buffers != null && index >= 0 && index < buffers.length) {
+                ByteBuffer buffer = buffers[index];
+                if (buffer != null) {
+                    buffer.setAccessible(true);
+                }
+            }
+        }
+    }
+
+    private final void validateOutputByteBuffer(
+            @Nullable ByteBuffer[] buffers, int index, @NonNull BufferInfo info) {
+        if (buffers != null && index >= 0 && index < buffers.length) {
+            ByteBuffer buffer = buffers[index];
+            if (buffer != null) {
+                buffer.setAccessible(true);
+                buffer.limit(info.offset + info.size).position(info.offset);
+            }
+        }
+    }
+
+    private final void invalidateByteBuffers(@Nullable ByteBuffer[] buffers) {
+        if (buffers != null) {
+            for (ByteBuffer buffer: buffers) {
+                if (buffer != null) {
+                    buffer.setAccessible(false);
+                }
+            }
+        }
+    }
+
+    private final void freeByteBuffer(@Nullable ByteBuffer buffer) {
+        if (buffer != null /* && buffer.isDirect() */) {
+            // all of our ByteBuffers are direct
+            java.nio.NioUtils.freeDirectBuffer(buffer);
+        }
+    }
+
+    private final void freeByteBuffers(@Nullable ByteBuffer[] buffers) {
+        if (buffers != null) {
+            for (ByteBuffer buffer: buffers) {
+                freeByteBuffer(buffer);
+            }
+        }
+    }
+
+    private final void freeAllTrackedBuffers() {
+        synchronized(mBufferLock) {
+            freeByteBuffers(mCachedInputBuffers);
+            freeByteBuffers(mCachedOutputBuffers);
+            mCachedInputBuffers = null;
+            mCachedOutputBuffers = null;
+            mDequeuedInputBuffers.clear();
+            mDequeuedOutputBuffers.clear();
+            mQueueRequests.clear();
+            mOutputFrames.clear();
+        }
+    }
+
+    private final void cacheBuffers(boolean input) {
+        ByteBuffer[] buffers = null;
+        try {
+            buffers = getBuffers(input);
+            invalidateByteBuffers(buffers);
+        } catch (IllegalStateException e) {
+            // we don't get buffers in async mode
+        }
+        if (input) {
+            mCachedInputBuffers = buffers;
+        } else {
+            mCachedOutputBuffers = buffers;
+        }
+    }
+
+    /**
+     * Retrieve the set of input buffers.  Call this after start()
+     * returns. After calling this method, any ByteBuffers
+     * previously returned by an earlier call to this method MUST no
+     * longer be used.
+     *
+     * @deprecated Use the new {@link #getInputBuffer} method instead
+     * each time an input buffer is dequeued.
+     *
+     * <b>Note:</b> As of API 21, dequeued input buffers are
+     * automatically {@link java.nio.Buffer#clear cleared}.
+     *
+     * <em>Do not use this method if using an input surface.</em>
+     *
+     * @throws IllegalStateException if not in the Executing state,
+     *         or codec is configured in asynchronous mode.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    @NonNull
+    public ByteBuffer[] getInputBuffers() {
+        synchronized (mBufferLock) {
+            if (mBufferMode == BUFFER_MODE_BLOCK) {
+                throw new IncompatibleWithBlockModelException("getInputBuffers() "
+                        + "is not compatible with CONFIGURE_FLAG_USE_BLOCK_MODEL. "
+                        + "Please obtain MediaCodec.LinearBlock or HardwareBuffer "
+                        + "objects and attach to QueueRequest objects.");
+            }
+            if (mCachedInputBuffers == null) {
+                throw new IllegalStateException();
+            }
+            // FIXME: check codec status
+            return mCachedInputBuffers;
+        }
+    }
+
+    /**
+     * Retrieve the set of output buffers.  Call this after start()
+     * returns and whenever dequeueOutputBuffer signals an output
+     * buffer change by returning {@link
+     * #INFO_OUTPUT_BUFFERS_CHANGED}. After calling this method, any
+     * ByteBuffers previously returned by an earlier call to this
+     * method MUST no longer be used.
+     *
+     * @deprecated Use the new {@link #getOutputBuffer} method instead
+     * each time an output buffer is dequeued.  This method is not
+     * supported if codec is configured in asynchronous mode.
+     *
+     * <b>Note:</b> As of API 21, the position and limit of output
+     * buffers that are dequeued will be set to the valid data
+     * range.
+     *
+     * <em>Do not use this method if using an output surface.</em>
+     *
+     * @throws IllegalStateException if not in the Executing state,
+     *         or codec is configured in asynchronous mode.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    @NonNull
+    public ByteBuffer[] getOutputBuffers() {
+        synchronized (mBufferLock) {
+            if (mBufferMode == BUFFER_MODE_BLOCK) {
+                throw new IncompatibleWithBlockModelException("getOutputBuffers() "
+                        + "is not compatible with CONFIGURE_FLAG_USE_BLOCK_MODEL. "
+                        + "Please use getOutputFrame to get output frames.");
+            }
+            if (mCachedOutputBuffers == null) {
+                throw new IllegalStateException();
+            }
+            // FIXME: check codec status
+            return mCachedOutputBuffers;
+        }
+    }
+
+    /**
+     * Returns a {@link java.nio.Buffer#clear cleared}, writable ByteBuffer
+     * object for a dequeued input buffer index to contain the input data.
+     *
+     * After calling this method any ByteBuffer or Image object
+     * previously returned for the same input index MUST no longer
+     * be used.
+     *
+     * @param index The index of a client-owned input buffer previously
+     *              returned from a call to {@link #dequeueInputBuffer},
+     *              or received via an onInputBufferAvailable callback.
+     *
+     * @return the input buffer, or null if the index is not a dequeued
+     * input buffer, or if the codec is configured for surface input.
+     *
+     * @throws IllegalStateException if not in the Executing state.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    @Nullable
+    public ByteBuffer getInputBuffer(int index) {
+        synchronized (mBufferLock) {
+            if (mBufferMode == BUFFER_MODE_BLOCK) {
+                throw new IncompatibleWithBlockModelException("getInputBuffer() "
+                        + "is not compatible with CONFIGURE_FLAG_USE_BLOCK_MODEL. "
+                        + "Please obtain MediaCodec.LinearBlock or HardwareBuffer "
+                        + "objects and attach to QueueRequest objects.");
+            }
+        }
+        ByteBuffer newBuffer = getBuffer(true /* input */, index);
+        synchronized (mBufferLock) {
+            invalidateByteBuffer(mCachedInputBuffers, index);
+            mDequeuedInputBuffers.put(index, newBuffer);
+        }
+        return newBuffer;
+    }
+
+    /**
+     * Returns a writable Image object for a dequeued input buffer
+     * index to contain the raw input video frame.
+     *
+     * After calling this method any ByteBuffer or Image object
+     * previously returned for the same input index MUST no longer
+     * be used.
+     *
+     * @param index The index of a client-owned input buffer previously
+     *              returned from a call to {@link #dequeueInputBuffer},
+     *              or received via an onInputBufferAvailable callback.
+     *
+     * @return the input image, or null if the index is not a
+     * dequeued input buffer, or not a ByteBuffer that contains a
+     * raw image.
+     *
+     * @throws IllegalStateException if not in the Executing state.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    @Nullable
+    public Image getInputImage(int index) {
+        synchronized (mBufferLock) {
+            if (mBufferMode == BUFFER_MODE_BLOCK) {
+                throw new IncompatibleWithBlockModelException("getInputImage() "
+                        + "is not compatible with CONFIGURE_FLAG_USE_BLOCK_MODEL. "
+                        + "Please obtain MediaCodec.LinearBlock or HardwareBuffer "
+                        + "objects and attach to QueueRequest objects.");
+            }
+        }
+        Image newImage = getImage(true /* input */, index);
+        synchronized (mBufferLock) {
+            invalidateByteBuffer(mCachedInputBuffers, index);
+            mDequeuedInputBuffers.put(index, newImage);
+        }
+        return newImage;
+    }
+
+    /**
+     * Returns a read-only ByteBuffer for a dequeued output buffer
+     * index. The position and limit of the returned buffer are set
+     * to the valid output data.
+     *
+     * After calling this method, any ByteBuffer or Image object
+     * previously returned for the same output index MUST no longer
+     * be used.
+     *
+     * @param index The index of a client-owned output buffer previously
+     *              returned from a call to {@link #dequeueOutputBuffer},
+     *              or received via an onOutputBufferAvailable callback.
+     *
+     * @return the output buffer, or null if the index is not a dequeued
+     * output buffer, or the codec is configured with an output surface.
+     *
+     * @throws IllegalStateException if not in the Executing state.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    @Nullable
+    public ByteBuffer getOutputBuffer(int index) {
+        synchronized (mBufferLock) {
+            if (mBufferMode == BUFFER_MODE_BLOCK) {
+                throw new IncompatibleWithBlockModelException("getOutputBuffer() "
+                        + "is not compatible with CONFIGURE_FLAG_USE_BLOCK_MODEL. "
+                        + "Please use getOutputFrame() to get output frames.");
+            }
+        }
+        ByteBuffer newBuffer = getBuffer(false /* input */, index);
+        synchronized (mBufferLock) {
+            invalidateByteBuffer(mCachedOutputBuffers, index);
+            mDequeuedOutputBuffers.put(index, newBuffer);
+        }
+        return newBuffer;
+    }
+
+    /**
+     * Returns a read-only Image object for a dequeued output buffer
+     * index that contains the raw video frame.
+     *
+     * After calling this method, any ByteBuffer or Image object previously
+     * returned for the same output index MUST no longer be used.
+     *
+     * @param index The index of a client-owned output buffer previously
+     *              returned from a call to {@link #dequeueOutputBuffer},
+     *              or received via an onOutputBufferAvailable callback.
+     *
+     * @return the output image, or null if the index is not a
+     * dequeued output buffer, not a raw video frame, or if the codec
+     * was configured with an output surface.
+     *
+     * @throws IllegalStateException if not in the Executing state.
+     * @throws MediaCodec.CodecException upon codec error.
+     */
+    @Nullable
+    public Image getOutputImage(int index) {
+        synchronized (mBufferLock) {
+            if (mBufferMode == BUFFER_MODE_BLOCK) {
+                throw new IncompatibleWithBlockModelException("getOutputImage() "
+                        + "is not compatible with CONFIGURE_FLAG_USE_BLOCK_MODEL. "
+                        + "Please use getOutputFrame() to get output frames.");
+            }
+        }
+        Image newImage = getImage(false /* input */, index);
+        synchronized (mBufferLock) {
+            invalidateByteBuffer(mCachedOutputBuffers, index);
+            mDequeuedOutputBuffers.put(index, newImage);
+        }
+        return newImage;
+    }
+
+    /**
+     * A single output frame and its associated metadata.
+     */
+    public static final class OutputFrame {
+        // No public constructor
+        OutputFrame(int index) {
+            mIndex = index;
+        }
+
+        /**
+         * Returns the output linear block, or null if this frame is empty.
+         *
+         * @throws IllegalStateException if this output frame is not linear.
+         */
+        public @Nullable LinearBlock getLinearBlock() {
+            if (mHardwareBuffer != null) {
+                throw new IllegalStateException("This output frame is not linear");
+            }
+            return mLinearBlock;
+        }
+
+        /**
+         * Returns the output hardware graphic buffer, or null if this frame is empty.
+         *
+         * @throws IllegalStateException if this output frame is not graphic.
+         */
+        public @Nullable HardwareBuffer getHardwareBuffer() {
+            if (mLinearBlock != null) {
+                throw new IllegalStateException("This output frame is not graphic");
+            }
+            return mHardwareBuffer;
+        }
+
+        /**
+         * Returns the presentation timestamp in microseconds.
+         */
+        public long getPresentationTimeUs() {
+            return mPresentationTimeUs;
+        }
+
+        /**
+         * Returns the buffer flags.
+         */
+        public @BufferFlag int getFlags() {
+            return mFlags;
+        }
+
+        /**
+         * Returns a read-only {@link MediaFormat} for this frame. The returned
+         * object is valid only until the client calls {@link MediaCodec#releaseOutputBuffer}.
+         */
+        public @NonNull MediaFormat getFormat() {
+            return mFormat;
+        }
+
+        /**
+         * Returns an unmodifiable set of the names of entries that has changed from
+         * the previous frame. The entries may have been removed/changed/added.
+         * Client can find out what the change is by querying {@link MediaFormat}
+         * object returned from {@link #getFormat}.
+         */
+        public @NonNull Set<String> getChangedKeys() {
+            if (mKeySet.isEmpty() && !mChangedKeys.isEmpty()) {
+                mKeySet.addAll(mChangedKeys);
+            }
+            return Collections.unmodifiableSet(mKeySet);
+        }
+
+        void clear() {
+            mLinearBlock = null;
+            mHardwareBuffer = null;
+            mFormat = null;
+            mChangedKeys.clear();
+            mKeySet.clear();
+            mLoaded = false;
+        }
+
+        boolean isAccessible() {
+            return mAccessible;
+        }
+
+        void setAccessible(boolean accessible) {
+            mAccessible = accessible;
+        }
+
+        void setBufferInfo(MediaCodec.BufferInfo info) {
+            mPresentationTimeUs = info.presentationTimeUs;
+            mFlags = info.flags;
+        }
+
+        boolean isLoaded() {
+            return mLoaded;
+        }
+
+        void setLoaded(boolean loaded) {
+            mLoaded = loaded;
+        }
+
+        private final int mIndex;
+        private LinearBlock mLinearBlock = null;
+        private HardwareBuffer mHardwareBuffer = null;
+        private long mPresentationTimeUs = 0;
+        private @BufferFlag int mFlags = 0;
+        private MediaFormat mFormat = null;
+        private final ArrayList<String> mChangedKeys = new ArrayList<>();
+        private final Set<String> mKeySet = new HashSet<>();
+        private boolean mAccessible = false;
+        private boolean mLoaded = false;
+    }
+
+    private final ArrayList<OutputFrame> mOutputFrames = new ArrayList<>();
+
+    /**
+     * Returns an {@link OutputFrame} object.
+     *
+     * @param index output buffer index from
+     *              {@link Callback#onOutputBufferAvailable}
+     * @return {@link OutputFrame} object describing the output buffer
+     * @throws IllegalStateException if not using block model
+     * @throws IllegalArgumentException if the output buffer is not available or
+     *                                  the index is out of range
+     */
+    public @NonNull OutputFrame getOutputFrame(int index) {
+        synchronized (mBufferLock) {
+            if (mBufferMode != BUFFER_MODE_BLOCK) {
+                throw new IllegalStateException("The codec is not configured for block model");
+            }
+            if (index < 0 || index >= mOutputFrames.size()) {
+                throw new IndexOutOfBoundsException("Expected range of index: [0,"
+                        + (mQueueRequests.size() - 1) + "]; actual: " + index);
+            }
+            OutputFrame frame = mOutputFrames.get(index);
+            if (frame == null) {
+                throw new IllegalArgumentException("Unavailable index: " + index);
+            }
+            if (!frame.isAccessible()) {
+                throw new IllegalArgumentException(
+                        "The output frame is stale at index " + index);
+            }
+            if (!frame.isLoaded()) {
+                native_getOutputFrame(frame, index);
+                frame.setLoaded(true);
+            }
+            return frame;
+        }
+    }
+
+    private native void native_getOutputFrame(OutputFrame frame, int index);
+
+    /**
+     * The content is scaled to the surface dimensions
+     */
+    public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT               = 1;
+
+    /**
+     * The content is scaled, maintaining its aspect ratio, the whole
+     * surface area is used, content may be cropped.
+     * <p class=note>
+     * This mode is only suitable for content with 1:1 pixel aspect ratio as you cannot
+     * configure the pixel aspect ratio for a {@link Surface}.
+     * <p class=note>
+     * As of {@link android.os.Build.VERSION_CODES#N} release, this mode may not work if
+     * the video is {@linkplain MediaFormat#KEY_ROTATION rotated} by 90 or 270 degrees.
+     */
+    public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2;
+
+    /** @hide */
+    @IntDef({
+        VIDEO_SCALING_MODE_SCALE_TO_FIT,
+        VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface VideoScalingMode {}
+
+    /**
+     * If a surface has been specified in a previous call to {@link #configure}
+     * specifies the scaling mode to use. The default is "scale to fit".
+     * <p class=note>
+     * The scaling mode may be reset to the <strong>default</strong> each time an
+     * {@link #INFO_OUTPUT_BUFFERS_CHANGED} event is received from the codec; therefore, the client
+     * must call this method after every buffer change event (and before the first output buffer is
+     * released for rendering) to ensure consistent scaling mode.
+     * <p class=note>
+     * Since the {@link #INFO_OUTPUT_BUFFERS_CHANGED} event is deprecated, this can also be done
+     * after each {@link #INFO_OUTPUT_FORMAT_CHANGED} event.
+     *
+     * @throws IllegalArgumentException if mode is not recognized.
+     * @throws IllegalStateException if in the Released state.
+     */
+    public native final void setVideoScalingMode(@VideoScalingMode int mode);
+
+    /**
+     * Sets the audio presentation.
+     * @param presentation see {@link AudioPresentation}. In particular, id should be set.
+     */
+    public void setAudioPresentation(@NonNull AudioPresentation presentation) {
+        if (presentation == null) {
+            throw new NullPointerException("audio presentation is null");
+        }
+        native_setAudioPresentation(presentation.getPresentationId(), presentation.getProgramId());
+    }
+
+    private native void native_setAudioPresentation(int presentationId, int programId);
+
+    /**
+     * Retrieve the codec name.
+     *
+     * If the codec was created by createDecoderByType or createEncoderByType, what component is
+     * chosen is not known beforehand. This method returns the name of the codec that was
+     * selected by the platform.
+     *
+     * <strong>Note:</strong> Implementations may provide multiple aliases (codec
+     * names) for the same underlying codec, any of which can be used to instantiate the same
+     * underlying codec in {@link MediaCodec#createByCodecName}. This method returns the
+     * name used to create the codec in this case.
+     *
+     * @throws IllegalStateException if in the Released state.
+     */
+    @NonNull
+    public final String getName() {
+        // get canonical name to handle exception
+        String canonicalName = getCanonicalName();
+        return mNameAtCreation != null ? mNameAtCreation : canonicalName;
+    }
+
+    /**
+     * Retrieve the underlying codec name.
+     *
+     * This method is similar to {@link #getName}, except that it returns the underlying component
+     * name even if an alias was used to create this MediaCodec object by name,
+     *
+     * @throws IllegalStateException if in the Released state.
+     */
+    @NonNull
+    public native final String getCanonicalName();
+
+    /**
+     *  Return Metrics data about the current codec instance.
+     *
+     * @return a {@link PersistableBundle} containing the set of attributes and values
+     * available for the media being handled by this instance of MediaCodec
+     * The attributes are descibed in {@link MetricsConstants}.
+     *
+     * Additional vendor-specific fields may also be present in
+     * the return value.
+     */
+    public PersistableBundle getMetrics() {
+        PersistableBundle bundle = native_getMetrics();
+        return bundle;
+    }
+
+    private native PersistableBundle native_getMetrics();
+
+    /**
+     * Change a video encoder's target bitrate on the fly. The value is an
+     * Integer object containing the new bitrate in bps.
+     *
+     * @see #setParameters(Bundle)
+     */
+    public static final String PARAMETER_KEY_VIDEO_BITRATE = "video-bitrate";
+
+    /**
+     * Temporarily suspend/resume encoding of input data. While suspended
+     * input data is effectively discarded instead of being fed into the
+     * encoder. This parameter really only makes sense to use with an encoder
+     * in "surface-input" mode, as the client code has no control over the
+     * input-side of the encoder in that case.
+     * The value is an Integer object containing the value 1 to suspend
+     * or the value 0 to resume.
+     *
+     * @see #setParameters(Bundle)
+     */
+    public static final String PARAMETER_KEY_SUSPEND = "drop-input-frames";
+
+    /**
+     * When {@link #PARAMETER_KEY_SUSPEND} is present, the client can also
+     * optionally use this key to specify the timestamp (in micro-second)
+     * at which the suspend/resume operation takes effect.
+     *
+     * Note that the specified timestamp must be greater than or equal to the
+     * timestamp of any previously queued suspend/resume operations.
+     *
+     * The value is a long int, indicating the timestamp to suspend/resume.
+     *
+     * @see #setParameters(Bundle)
+     */
+    public static final String PARAMETER_KEY_SUSPEND_TIME = "drop-start-time-us";
+
+    /**
+     * Specify an offset (in micro-second) to be added on top of the timestamps
+     * onward. A typical use case is to apply an adjust to the timestamps after
+     * a period of pause by the user.
+     *
+     * This parameter can only be used on an encoder in "surface-input" mode.
+     *
+     * The value is a long int, indicating the timestamp offset to be applied.
+     *
+     * @see #setParameters(Bundle)
+     */
+    public static final String PARAMETER_KEY_OFFSET_TIME = "time-offset-us";
+
+    /**
+     * Request that the encoder produce a sync frame "soon".
+     * Provide an Integer with the value 0.
+     *
+     * @see #setParameters(Bundle)
+     */
+    public static final String PARAMETER_KEY_REQUEST_SYNC_FRAME = "request-sync";
+
+    /**
+     * Set the HDR10+ metadata on the next queued input frame.
+     *
+     * Provide a byte array of data that's conforming to the
+     * user_data_registered_itu_t_t35() syntax of SEI message for ST 2094-40.
+     *<p>
+     * For decoders:
+     *<p>
+     * When a decoder is configured for one of the HDR10+ profiles that uses
+     * out-of-band metadata (such as {@link
+     * MediaCodecInfo.CodecProfileLevel#VP9Profile2HDR10Plus} or {@link
+     * MediaCodecInfo.CodecProfileLevel#VP9Profile3HDR10Plus}), this
+     * parameter sets the HDR10+ metadata on the next input buffer queued
+     * to the decoder. A decoder supporting these profiles must propagate
+     * the metadata to the format of the output buffer corresponding to this
+     * particular input buffer (under key {@link MediaFormat#KEY_HDR10_PLUS_INFO}).
+     * The metadata should be applied to that output buffer and the buffers
+     * following it (in display order), until the next output buffer (in
+     * display order) upon which an HDR10+ metadata is set.
+     *<p>
+     * This parameter shouldn't be set if the decoder is not configured for
+     * an HDR10+ profile that uses out-of-band metadata. In particular,
+     * it shouldn't be set for HDR10+ profiles that uses in-band metadata
+     * where the metadata is embedded in the input buffers, for example
+     * {@link MediaCodecInfo.CodecProfileLevel#HEVCProfileMain10HDR10Plus}.
+     *<p>
+     * For encoders:
+     *<p>
+     * When an encoder is configured for one of the HDR10+ profiles and the
+     * operates in byte buffer input mode (instead of surface input mode),
+     * this parameter sets the HDR10+ metadata on the next input buffer queued
+     * to the encoder. For the HDR10+ profiles that uses out-of-band metadata
+     * (such as {@link MediaCodecInfo.CodecProfileLevel#VP9Profile2HDR10Plus},
+     * or {@link MediaCodecInfo.CodecProfileLevel#VP9Profile3HDR10Plus}),
+     * the metadata must be propagated to the format of the output buffer
+     * corresponding to this particular input buffer (under key {@link
+     * MediaFormat#KEY_HDR10_PLUS_INFO}). For the HDR10+ profiles that uses
+     * in-band metadata (such as {@link
+     * MediaCodecInfo.CodecProfileLevel#HEVCProfileMain10HDR10Plus}), the
+     * metadata info must be embedded in the corresponding output buffer itself.
+     *<p>
+     * This parameter shouldn't be set if the encoder is not configured for
+     * an HDR10+ profile, or if it's operating in surface input mode.
+     *<p>
+     *
+     * @see MediaFormat#KEY_HDR10_PLUS_INFO
+     */
+    public static final String PARAMETER_KEY_HDR10_PLUS_INFO = MediaFormat.KEY_HDR10_PLUS_INFO;
+
+    /**
+     * Enable/disable low latency decoding mode.
+     * When enabled, the decoder doesn't hold input and output data more than
+     * required by the codec standards.
+     * The value is an Integer object containing the value 1 to enable
+     * or the value 0 to disable.
+     *
+     * @see #setParameters(Bundle)
+     * @see MediaFormat#KEY_LOW_LATENCY
+     */
+    public static final String PARAMETER_KEY_LOW_LATENCY =
+            MediaFormat.KEY_LOW_LATENCY;
+
+    /**
+     * Control video peek of the first frame when a codec is configured for tunnel mode with
+     * {@link MediaFormat#KEY_AUDIO_SESSION_ID} while the {@link AudioTrack} is paused.
+     *<p>
+     * When disabled (1) after a {@link #flush} or {@link #start}, (2) while the corresponding
+     * {@link AudioTrack} is paused and (3) before any buffers are queued, the first frame is not to
+     * be rendered until either this parameter is enabled or the corresponding {@link AudioTrack}
+     * has begun playback. Once the frame is decoded and ready to be rendered,
+     * {@link OnFirstTunnelFrameReadyListener#onFirstTunnelFrameReady} is called but the frame is
+     * not rendered. The surface continues to show the previously-rendered content, or black if the
+     * surface is new. A subsequent call to {@link AudioTrack#play} renders this frame and triggers
+     * a callback to {@link OnFrameRenderedListener#onFrameRendered}, and video playback begins.
+     *<p>
+     * <b>Note</b>: To clear any previously rendered content and show black, configure the
+     * MediaCodec with {@code KEY_PUSH_BLANK_BUFFERS_ON_STOP(1)}, and call {@link #stop} before
+     * pushing new video frames to the codec.
+     *<p>
+     * When enabled (1) after a {@link #flush} or {@link #start} and (2) while the corresponding
+     * {@link AudioTrack} is paused, the first frame is rendered as soon as it is decoded, or
+     * immediately, if it has already been decoded. If not already decoded, when the frame is
+     * decoded and ready to be rendered,
+     * {@link OnFirstTunnelFrameReadyListener#onFirstTunnelFrameReady} is called. The frame is then
+     * immediately rendered and {@link OnFrameRenderedListener#onFrameRendered} is subsequently
+     * called.
+     *<p>
+     * The value is an Integer object containing the value 1 to enable or the value 0 to disable.
+     *<p>
+     * The default for this parameter is <b>enabled</b>. Once a frame has been rendered, changing
+     * this parameter has no effect until a subsequent {@link #flush} or
+     * {@link #stop}/{@link #start}.
+     *
+     * @see #setParameters(Bundle)
+     */
+    public static final String PARAMETER_KEY_TUNNEL_PEEK = "tunnel-peek";
+
+    /**
+     * Communicate additional parameter changes to the component instance.
+     * <b>Note:</b> Some of these parameter changes may silently fail to apply.
+     *
+     * @param params The bundle of parameters to set.
+     * @throws IllegalStateException if in the Released state.
+     */
+    public final void setParameters(@Nullable Bundle params) {
+        if (params == null) {
+            return;
+        }
+
+        String[] keys = new String[params.size()];
+        Object[] values = new Object[params.size()];
+
+        int i = 0;
+        for (final String key: params.keySet()) {
+            if (key.equals(MediaFormat.KEY_AUDIO_SESSION_ID)) {
+                int sessionId = 0;
+                try {
+                    sessionId = (Integer)params.get(key);
+                } catch (Exception e) {
+                    throw new IllegalArgumentException("Wrong Session ID Parameter!");
+                }
+                keys[i] = "audio-hw-sync";
+                values[i] = AudioSystem.getAudioHwSyncForSession(sessionId);
+            } else {
+                keys[i] = key;
+                Object value = params.get(key);
+
+                // Bundle's byte array is a byte[], JNI layer only takes ByteBuffer
+                if (value instanceof byte[]) {
+                    values[i] = ByteBuffer.wrap((byte[])value);
+                } else {
+                    values[i] = value;
+                }
+            }
+            ++i;
+        }
+
+        setParameters(keys, values);
+    }
+
+    /**
+     * Sets an asynchronous callback for actionable MediaCodec events.
+     *
+     * If the client intends to use the component in asynchronous mode,
+     * a valid callback should be provided before {@link #configure} is called.
+     *
+     * When asynchronous callback is enabled, the client should not call
+     * {@link #getInputBuffers}, {@link #getOutputBuffers},
+     * {@link #dequeueInputBuffer(long)} or {@link #dequeueOutputBuffer(BufferInfo, long)}.
+     * <p>
+     * Also, {@link #flush} behaves differently in asynchronous mode.  After calling
+     * {@code flush}, you must call {@link #start} to "resume" receiving input buffers,
+     * even if an input surface was created.
+     *
+     * @param cb The callback that will run.  Use {@code null} to clear a previously
+     *           set callback (before {@link #configure configure} is called and run
+     *           in synchronous mode).
+     * @param handler Callbacks will happen on the handler's thread. If {@code null},
+     *           callbacks are done on the default thread (the caller's thread or the
+     *           main thread.)
+     */
+    public void setCallback(@Nullable /* MediaCodec. */ Callback cb, @Nullable Handler handler) {
+        if (cb != null) {
+            synchronized (mListenerLock) {
+                EventHandler newHandler = getEventHandlerOn(handler, mCallbackHandler);
+                // NOTE: there are no callbacks on the handler at this time, but check anyways
+                // even if we were to extend this to be callable dynamically, it must
+                // be called when codec is flushed, so no messages are pending.
+                if (newHandler != mCallbackHandler) {
+                    mCallbackHandler.removeMessages(EVENT_SET_CALLBACK);
+                    mCallbackHandler.removeMessages(EVENT_CALLBACK);
+                    mCallbackHandler = newHandler;
+                }
+            }
+        } else if (mCallbackHandler != null) {
+            mCallbackHandler.removeMessages(EVENT_SET_CALLBACK);
+            mCallbackHandler.removeMessages(EVENT_CALLBACK);
+        }
+
+        if (mCallbackHandler != null) {
+            // set java callback on main handler
+            Message msg = mCallbackHandler.obtainMessage(EVENT_SET_CALLBACK, 0, 0, cb);
+            mCallbackHandler.sendMessage(msg);
+
+            // set native handler here, don't post to handler because
+            // it may cause the callback to be delayed and set in a wrong state.
+            // Note that native codec may start sending events to the callback
+            // handler after this returns.
+            native_setCallback(cb);
+        }
+    }
+
+    /**
+     * Sets an asynchronous callback for actionable MediaCodec events on the default
+     * looper.
+     * <p>
+     * Same as {@link #setCallback(Callback, Handler)} with handler set to null.
+     * @param cb The callback that will run.  Use {@code null} to clear a previously
+     *           set callback (before {@link #configure configure} is called and run
+     *           in synchronous mode).
+     * @see #setCallback(Callback, Handler)
+     */
+    public void setCallback(@Nullable /* MediaCodec. */ Callback cb) {
+        setCallback(cb, null /* handler */);
+    }
+
+    /**
+     * Listener to be called when the first output frame has been decoded
+     * and is ready to be rendered for a codec configured for tunnel mode with
+     * {@code KEY_AUDIO_SESSION_ID}.
+     *
+     * @see MediaCodec#setOnFirstTunnelFrameReadyListener
+     */
+    public interface OnFirstTunnelFrameReadyListener {
+
+        /**
+         * Called when the first output frame has been decoded and is ready to be
+         * rendered.
+         */
+        void onFirstTunnelFrameReady(@NonNull MediaCodec codec);
+    }
+
+    /**
+     * Registers a callback to be invoked when the first output frame has been decoded
+     * and is ready to be rendered on a codec configured for tunnel mode with {@code
+     * KEY_AUDIO_SESSION_ID}.
+     *
+     * @param handler the callback will be run on the handler's thread. If {@code
+     * null}, the callback will be run on the default thread, which is the looper from
+     * which the codec was created, or a new thread if there was none.
+     *
+     * @param listener the callback that will be run. If {@code null}, clears any registered
+     * listener.
+     */
+    public void setOnFirstTunnelFrameReadyListener(
+            @Nullable Handler handler, @Nullable OnFirstTunnelFrameReadyListener listener) {
+        synchronized (mListenerLock) {
+            mOnFirstTunnelFrameReadyListener = listener;
+            if (listener != null) {
+                EventHandler newHandler = getEventHandlerOn(
+                        handler,
+                        mOnFirstTunnelFrameReadyHandler);
+                if (newHandler != mOnFirstTunnelFrameReadyHandler) {
+                    mOnFirstTunnelFrameReadyHandler.removeMessages(EVENT_FIRST_TUNNEL_FRAME_READY);
+                }
+                mOnFirstTunnelFrameReadyHandler = newHandler;
+            } else if (mOnFirstTunnelFrameReadyHandler != null) {
+                mOnFirstTunnelFrameReadyHandler.removeMessages(EVENT_FIRST_TUNNEL_FRAME_READY);
+            }
+            native_enableOnFirstTunnelFrameReadyListener(listener != null);
+        }
+    }
+
+    private native void native_enableOnFirstTunnelFrameReadyListener(boolean enable);
+
+    /**
+     * Listener to be called when an output frame has rendered on the output surface
+     *
+     * @see MediaCodec#setOnFrameRenderedListener
+     */
+    public interface OnFrameRenderedListener {
+
+        /**
+         * Called when an output frame has rendered on the output surface.
+         * <p>
+         * <strong>Note:</strong> This callback is for informational purposes only: to get precise
+         * render timing samples, and can be significantly delayed and batched. Some frames may have
+         * been rendered even if there was no callback generated.
+         *
+         * @param codec the MediaCodec instance
+         * @param presentationTimeUs the presentation time (media time) of the frame rendered.
+         *          This is usually the same as specified in {@link #queueInputBuffer}; however,
+         *          some codecs may alter the media time by applying some time-based transformation,
+         *          such as frame rate conversion. In that case, presentation time corresponds
+         *          to the actual output frame rendered.
+         * @param nanoTime The system time when the frame was rendered.
+         *
+         * @see System#nanoTime
+         */
+        public void onFrameRendered(
+                @NonNull MediaCodec codec, long presentationTimeUs, long nanoTime);
+    }
+
+    /**
+     * Registers a callback to be invoked when an output frame is rendered on the output surface.
+     * <p>
+     * This method can be called in any codec state, but will only have an effect in the
+     * Executing state for codecs that render buffers to the output surface.
+     * <p>
+     * <strong>Note:</strong> This callback is for informational purposes only: to get precise
+     * render timing samples, and can be significantly delayed and batched. Some frames may have
+     * been rendered even if there was no callback generated.
+     *
+     * @param listener the callback that will be run
+     * @param handler the callback will be run on the handler's thread. If {@code null},
+     *           the callback will be run on the default thread, which is the looper
+     *           from which the codec was created, or a new thread if there was none.
+     */
+    public void setOnFrameRenderedListener(
+            @Nullable OnFrameRenderedListener listener, @Nullable Handler handler) {
+        synchronized (mListenerLock) {
+            mOnFrameRenderedListener = listener;
+            if (listener != null) {
+                EventHandler newHandler = getEventHandlerOn(handler, mOnFrameRenderedHandler);
+                if (newHandler != mOnFrameRenderedHandler) {
+                    mOnFrameRenderedHandler.removeMessages(EVENT_FRAME_RENDERED);
+                }
+                mOnFrameRenderedHandler = newHandler;
+            } else if (mOnFrameRenderedHandler != null) {
+                mOnFrameRenderedHandler.removeMessages(EVENT_FRAME_RENDERED);
+            }
+            native_enableOnFrameRenderedListener(listener != null);
+        }
+    }
+
+    private native void native_enableOnFrameRenderedListener(boolean enable);
+
+    /**
+     * Returns a list of vendor parameter names.
+     * <p>
+     * This method can be called in any codec state except for released state.
+     *
+     * @return a list containing supported vendor parameters; an empty
+     *         list if no vendor parameters are supported. The order of the
+     *         parameters is arbitrary.
+     * @throws IllegalStateException if in the Released state.
+     */
+    @NonNull
+    public List<String> getSupportedVendorParameters() {
+        return native_getSupportedVendorParameters();
+    }
+
+    @NonNull
+    private native List<String> native_getSupportedVendorParameters();
+
+    /**
+     * Contains description of a parameter.
+     */
+    public static class ParameterDescriptor {
+        private ParameterDescriptor() {}
+
+        /**
+         * Returns the name of the parameter.
+         */
+        @NonNull
+        public String getName() {
+            return mName;
+        }
+
+        /**
+         * Returns the type of the parameter.
+         * {@link MediaFormat#TYPE_NULL} is never returned.
+         */
+        @MediaFormat.Type
+        public int getType() {
+            return mType;
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null) {
+                return false;
+            }
+            if (!(o instanceof ParameterDescriptor)) {
+                return false;
+            }
+            ParameterDescriptor other = (ParameterDescriptor) o;
+            return this.mName.equals(other.mName) && this.mType == other.mType;
+        }
+
+        @Override
+        public int hashCode() {
+            return Arrays.asList(
+                    (Object) mName,
+                    (Object) Integer.valueOf(mType)).hashCode();
+        }
+
+        private String mName;
+        private @MediaFormat.Type int mType;
+    }
+
+    /**
+     * Describe a parameter with the name.
+     * <p>
+     * This method can be called in any codec state except for released state.
+     *
+     * @param name name of the parameter to describe, typically one from
+     *             {@link #getSupportedVendorParameters}.
+     * @return {@link ParameterDescriptor} object that describes the parameter.
+     *         {@code null} if unrecognized / not able to describe.
+     * @throws IllegalStateException if in the Released state.
+     */
+    @Nullable
+    public ParameterDescriptor getParameterDescriptor(@NonNull String name) {
+        return native_getParameterDescriptor(name);
+    }
+
+    @Nullable
+    private native ParameterDescriptor native_getParameterDescriptor(@NonNull String name);
+
+    /**
+     * Subscribe to vendor parameters, so that these parameters will be present in
+     * {@link #getOutputFormat} and changes to these parameters generate
+     * output format change event.
+     * <p>
+     * Unrecognized parameter names or standard (non-vendor) parameter names will be ignored.
+     * {@link #reset} also resets the list of subscribed parameters.
+     * If a parameter in {@code names} is already subscribed, it will remain subscribed.
+     * <p>
+     * This method can be called in any codec state except for released state. When called in
+     * running state with newly subscribed parameters, it takes effect no later than the
+     * processing of the subsequently queued buffer. For the new parameters, the codec will generate
+     * output format change event.
+     * <p>
+     * Note that any vendor parameters set in a {@link #configure} or
+     * {@link #setParameters} call are automatically subscribed.
+     * <p>
+     * See also {@link #INFO_OUTPUT_FORMAT_CHANGED} or {@link Callback#onOutputFormatChanged}
+     * for output format change events.
+     *
+     * @param names names of the vendor parameters to subscribe. This may be an empty list,
+     *              and in that case this method will not change the list of subscribed parameters.
+     * @throws IllegalStateException if in the Released state.
+     */
+    public void subscribeToVendorParameters(@NonNull List<String> names) {
+        native_subscribeToVendorParameters(names);
+    }
+
+    private native void native_subscribeToVendorParameters(@NonNull List<String> names);
+
+    /**
+     * Unsubscribe from vendor parameters, so that these parameters will not be present in
+     * {@link #getOutputFormat} and changes to these parameters no longer generate
+     * output format change event.
+     * <p>
+     * Unrecognized parameter names, standard (non-vendor) parameter names will be ignored.
+     * {@link #reset} also resets the list of subscribed parameters.
+     * If a parameter in {@code names} is already unsubscribed, it will remain unsubscribed.
+     * <p>
+     * This method can be called in any codec state except for released state. When called in
+     * running state with newly unsubscribed parameters, it takes effect no later than the
+     * processing of the subsequently queued buffer. For the removed parameters, the codec will
+     * generate output format change event.
+     * <p>
+     * Note that any vendor parameters set in a {@link #configure} or
+     * {@link #setParameters} call are automatically subscribed, and with this method
+     * they can be unsubscribed.
+     * <p>
+     * See also {@link #INFO_OUTPUT_FORMAT_CHANGED} or {@link Callback#onOutputFormatChanged}
+     * for output format change events.
+     *
+     * @param names names of the vendor parameters to unsubscribe. This may be an empty list,
+     *              and in that case this method will not change the list of subscribed parameters.
+     * @throws IllegalStateException if in the Released state.
+     */
+    public void unsubscribeFromVendorParameters(@NonNull List<String> names) {
+        native_unsubscribeFromVendorParameters(names);
+    }
+
+    private native void native_unsubscribeFromVendorParameters(@NonNull List<String> names);
+
+    private EventHandler getEventHandlerOn(
+            @Nullable Handler handler, @NonNull EventHandler lastHandler) {
+        if (handler == null) {
+            return mEventHandler;
+        } else {
+            Looper looper = handler.getLooper();
+            if (lastHandler.getLooper() == looper) {
+                return lastHandler;
+            } else {
+                return new EventHandler(this, looper);
+            }
+        }
+    }
+
+    /**
+     * MediaCodec callback interface. Used to notify the user asynchronously
+     * of various MediaCodec events.
+     */
+    public static abstract class Callback {
+        /**
+         * Called when an input buffer becomes available.
+         *
+         * @param codec The MediaCodec object.
+         * @param index The index of the available input buffer.
+         */
+        public abstract void onInputBufferAvailable(@NonNull MediaCodec codec, int index);
+
+        /**
+         * Called when an output buffer becomes available.
+         *
+         * @param codec The MediaCodec object.
+         * @param index The index of the available output buffer.
+         * @param info Info regarding the available output buffer {@link MediaCodec.BufferInfo}.
+         */
+        public abstract void onOutputBufferAvailable(
+                @NonNull MediaCodec codec, int index, @NonNull BufferInfo info);
+
+        /**
+         * Called when the MediaCodec encountered an error
+         *
+         * @param codec The MediaCodec object.
+         * @param e The {@link MediaCodec.CodecException} object describing the error.
+         */
+        public abstract void onError(@NonNull MediaCodec codec, @NonNull CodecException e);
+
+        /**
+         * Called when the output format has changed
+         *
+         * @param codec The MediaCodec object.
+         * @param format The new output format.
+         */
+        public abstract void onOutputFormatChanged(
+                @NonNull MediaCodec codec, @NonNull MediaFormat format);
+    }
+
+    private void postEventFromNative(
+            int what, int arg1, int arg2, @Nullable Object obj) {
+        synchronized (mListenerLock) {
+            EventHandler handler = mEventHandler;
+            if (what == EVENT_CALLBACK) {
+                handler = mCallbackHandler;
+            } else if (what == EVENT_FIRST_TUNNEL_FRAME_READY) {
+                handler = mOnFirstTunnelFrameReadyHandler;
+            } else if (what == EVENT_FRAME_RENDERED) {
+                handler = mOnFrameRenderedHandler;
+            }
+            if (handler != null) {
+                Message msg = handler.obtainMessage(what, arg1, arg2, obj);
+                handler.sendMessage(msg);
+            }
+        }
+    }
+
+    @UnsupportedAppUsage
+    private native final void setParameters(@NonNull String[] keys, @NonNull Object[] values);
+
+    /**
+     * Get the codec info. If the codec was created by createDecoderByType
+     * or createEncoderByType, what component is chosen is not known beforehand,
+     * and thus the caller does not have the MediaCodecInfo.
+     * @throws IllegalStateException if in the Released state.
+     */
+    @NonNull
+    public MediaCodecInfo getCodecInfo() {
+        // Get the codec name first. If the codec is already released,
+        // IllegalStateException will be thrown here.
+        String name = getName();
+        synchronized (mCodecInfoLock) {
+            if (mCodecInfo == null) {
+                // Get the codec info for this codec itself first. Only initialize
+                // the full codec list if this somehow fails because it can be slow.
+                mCodecInfo = getOwnCodecInfo();
+                if (mCodecInfo == null) {
+                    mCodecInfo = MediaCodecList.getInfoFor(name);
+                }
+            }
+            return mCodecInfo;
+        }
+    }
+
+    @NonNull
+    private native final MediaCodecInfo getOwnCodecInfo();
+
+    @NonNull
+    @UnsupportedAppUsage
+    private native final ByteBuffer[] getBuffers(boolean input);
+
+    @Nullable
+    private native final ByteBuffer getBuffer(boolean input, int index);
+
+    @Nullable
+    private native final Image getImage(boolean input, int index);
+
+    private static native final void native_init();
+
+    private native final void native_setup(
+            @NonNull String name, boolean nameIsType, boolean encoder);
+
+    private native final void native_finalize();
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private long mNativeContext = 0;
+    private final Lock mNativeContextLock = new ReentrantLock();
+
+    private final long lockAndGetContext() {
+        mNativeContextLock.lock();
+        return mNativeContext;
+    }
+
+    private final void setAndUnlockContext(long context) {
+        mNativeContext = context;
+        mNativeContextLock.unlock();
+    }
+
+    /** @hide */
+    public static class MediaImage extends Image {
+        private final boolean mIsReadOnly;
+        private final int mWidth;
+        private final int mHeight;
+        private final int mFormat;
+        private long mTimestamp;
+        private final Plane[] mPlanes;
+        private final ByteBuffer mBuffer;
+        private final ByteBuffer mInfo;
+        private final int mXOffset;
+        private final int mYOffset;
+        private final long mBufferContext;
+
+        private final static int TYPE_YUV = 1;
+
+        private final int mTransform = 0; //Default no transform
+        private final int mScalingMode = 0; //Default frozen scaling mode
+
+        @Override
+        public int getFormat() {
+            throwISEIfImageIsInvalid();
+            return mFormat;
+        }
+
+        @Override
+        public int getHeight() {
+            throwISEIfImageIsInvalid();
+            return mHeight;
+        }
+
+        @Override
+        public int getWidth() {
+            throwISEIfImageIsInvalid();
+            return mWidth;
+        }
+
+        @Override
+        public int getTransform() {
+            throwISEIfImageIsInvalid();
+            return mTransform;
+        }
+
+        @Override
+        public int getScalingMode() {
+            throwISEIfImageIsInvalid();
+            return mScalingMode;
+        }
+
+        @Override
+        public long getTimestamp() {
+            throwISEIfImageIsInvalid();
+            return mTimestamp;
+        }
+
+        @Override
+        @NonNull
+        public Plane[] getPlanes() {
+            throwISEIfImageIsInvalid();
+            return Arrays.copyOf(mPlanes, mPlanes.length);
+        }
+
+        @Override
+        public void close() {
+            if (mIsImageValid) {
+                if (mBuffer != null) {
+                    java.nio.NioUtils.freeDirectBuffer(mBuffer);
+                }
+                if (mBufferContext != 0) {
+                    native_closeMediaImage(mBufferContext);
+                }
+                mIsImageValid = false;
+            }
+        }
+
+        /**
+         * Set the crop rectangle associated with this frame.
+         * <p>
+         * The crop rectangle specifies the region of valid pixels in the image,
+         * using coordinates in the largest-resolution plane.
+         */
+        @Override
+        public void setCropRect(@Nullable Rect cropRect) {
+            if (mIsReadOnly) {
+                throw new ReadOnlyBufferException();
+            }
+            super.setCropRect(cropRect);
+        }
+
+        public MediaImage(
+                @NonNull ByteBuffer buffer, @NonNull ByteBuffer info, boolean readOnly,
+                long timestamp, int xOffset, int yOffset, @Nullable Rect cropRect) {
+            mFormat = ImageFormat.YUV_420_888;
+            mTimestamp = timestamp;
+            mIsImageValid = true;
+            mIsReadOnly = buffer.isReadOnly();
+            mBuffer = buffer.duplicate();
+
+            // save offsets and info
+            mXOffset = xOffset;
+            mYOffset = yOffset;
+            mInfo = info;
+
+            mBufferContext = 0;
+
+            // read media-info.  See MediaImage2
+            if (info.remaining() == 104) {
+                int type = info.getInt();
+                if (type != TYPE_YUV) {
+                    throw new UnsupportedOperationException("unsupported type: " + type);
+                }
+                int numPlanes = info.getInt();
+                if (numPlanes != 3) {
+                    throw new RuntimeException("unexpected number of planes: " + numPlanes);
+                }
+                mWidth = info.getInt();
+                mHeight = info.getInt();
+                if (mWidth < 1 || mHeight < 1) {
+                    throw new UnsupportedOperationException(
+                            "unsupported size: " + mWidth + "x" + mHeight);
+                }
+                int bitDepth = info.getInt();
+                if (bitDepth != 8) {
+                    throw new UnsupportedOperationException("unsupported bit depth: " + bitDepth);
+                }
+                int bitDepthAllocated = info.getInt();
+                if (bitDepthAllocated != 8) {
+                    throw new UnsupportedOperationException(
+                            "unsupported allocated bit depth: " + bitDepthAllocated);
+                }
+                mPlanes = new MediaPlane[numPlanes];
+                for (int ix = 0; ix < numPlanes; ix++) {
+                    int planeOffset = info.getInt();
+                    int colInc = info.getInt();
+                    int rowInc = info.getInt();
+                    int horiz = info.getInt();
+                    int vert = info.getInt();
+                    if (horiz != vert || horiz != (ix == 0 ? 1 : 2)) {
+                        throw new UnsupportedOperationException("unexpected subsampling: "
+                                + horiz + "x" + vert + " on plane " + ix);
+                    }
+                    if (colInc < 1 || rowInc < 1) {
+                        throw new UnsupportedOperationException("unexpected strides: "
+                                + colInc + " pixel, " + rowInc + " row on plane " + ix);
+                    }
+                    buffer.clear();
+                    buffer.position(mBuffer.position() + planeOffset
+                            + (xOffset / horiz) * colInc + (yOffset / vert) * rowInc);
+                    buffer.limit(buffer.position() + Utils.divUp(bitDepth, 8)
+                            + (mHeight / vert - 1) * rowInc + (mWidth / horiz - 1) * colInc);
+                    mPlanes[ix] = new MediaPlane(buffer.slice(), rowInc, colInc);
+                }
+            } else {
+                throw new UnsupportedOperationException(
+                        "unsupported info length: " + info.remaining());
+            }
+
+            if (cropRect == null) {
+                cropRect = new Rect(0, 0, mWidth, mHeight);
+            }
+            cropRect.offset(-xOffset, -yOffset);
+            super.setCropRect(cropRect);
+        }
+
+        public MediaImage(
+                @NonNull ByteBuffer[] buffers, int[] rowStrides, int[] pixelStrides,
+                int width, int height, int format, boolean readOnly,
+                long timestamp, int xOffset, int yOffset, @Nullable Rect cropRect, long context) {
+            if (buffers.length != rowStrides.length || buffers.length != pixelStrides.length) {
+                throw new IllegalArgumentException(
+                        "buffers, rowStrides and pixelStrides should have the same length");
+            }
+            mWidth = width;
+            mHeight = height;
+            mFormat = format;
+            mTimestamp = timestamp;
+            mIsImageValid = true;
+            mIsReadOnly = readOnly;
+            mBuffer = null;
+            mInfo = null;
+            mPlanes = new MediaPlane[buffers.length];
+            for (int i = 0; i < buffers.length; ++i) {
+                mPlanes[i] = new MediaPlane(buffers[i], rowStrides[i], pixelStrides[i]);
+            }
+
+            // save offsets and info
+            mXOffset = xOffset;
+            mYOffset = yOffset;
+
+            if (cropRect == null) {
+                cropRect = new Rect(0, 0, mWidth, mHeight);
+            }
+            cropRect.offset(-xOffset, -yOffset);
+            super.setCropRect(cropRect);
+
+            mBufferContext = context;
+        }
+
+        private class MediaPlane extends Plane {
+            public MediaPlane(@NonNull ByteBuffer buffer, int rowInc, int colInc) {
+                mData = buffer;
+                mRowInc = rowInc;
+                mColInc = colInc;
+            }
+
+            @Override
+            public int getRowStride() {
+                throwISEIfImageIsInvalid();
+                return mRowInc;
+            }
+
+            @Override
+            public int getPixelStride() {
+                throwISEIfImageIsInvalid();
+                return mColInc;
+            }
+
+            @Override
+            @NonNull
+            public ByteBuffer getBuffer() {
+                throwISEIfImageIsInvalid();
+                return mData;
+            }
+
+            private final int mRowInc;
+            private final int mColInc;
+            private final ByteBuffer mData;
+        }
+    }
+
+    public final static class MetricsConstants
+    {
+        private MetricsConstants() {}
+
+        /**
+         * Key to extract the codec being used
+         * from the {@link MediaCodec#getMetrics} return value.
+         * The value is a String.
+         */
+        public static final String CODEC = "android.media.mediacodec.codec";
+
+        /**
+         * Key to extract the MIME type
+         * from the {@link MediaCodec#getMetrics} return value.
+         * The value is a String.
+         */
+        public static final String MIME_TYPE = "android.media.mediacodec.mime";
+
+        /**
+         * Key to extract what the codec mode
+         * from the {@link MediaCodec#getMetrics} return value.
+         * The value is a String. Values will be one of the constants
+         * {@link #MODE_AUDIO} or {@link #MODE_VIDEO}.
+         */
+        public static final String MODE = "android.media.mediacodec.mode";
+
+        /**
+         * The value returned for the key {@link #MODE} when the
+         * codec is a audio codec.
+         */
+        public static final String MODE_AUDIO = "audio";
+
+        /**
+         * The value returned for the key {@link #MODE} when the
+         * codec is a video codec.
+         */
+        public static final String MODE_VIDEO = "video";
+
+        /**
+         * Key to extract the flag indicating whether the codec is running
+         * as an encoder or decoder from the {@link MediaCodec#getMetrics} return value.
+         * The value is an integer.
+         * A 0 indicates decoder; 1 indicates encoder.
+         */
+        public static final String ENCODER = "android.media.mediacodec.encoder";
+
+        /**
+         * Key to extract the flag indicating whether the codec is running
+         * in secure (DRM) mode from the {@link MediaCodec#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String SECURE = "android.media.mediacodec.secure";
+
+        /**
+         * Key to extract the width (in pixels) of the video track
+         * from the {@link MediaCodec#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String WIDTH = "android.media.mediacodec.width";
+
+        /**
+         * Key to extract the height (in pixels) of the video track
+         * from the {@link MediaCodec#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String HEIGHT = "android.media.mediacodec.height";
+
+        /**
+         * Key to extract the rotation (in degrees) to properly orient the video
+         * from the {@link MediaCodec#getMetrics} return.
+         * The value is a integer.
+         */
+        public static final String ROTATION = "android.media.mediacodec.rotation";
+
+    }
+}
diff --git a/android/media/MediaCodecInfo.java b/android/media/MediaCodecInfo.java
new file mode 100644
index 0000000..c3b1bca
--- /dev/null
+++ b/android/media/MediaCodecInfo.java
@@ -0,0 +1,4049 @@
+/*
+ * Copyright (C) 2012 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.Utils.intersectSortedDistinctRanges;
+import static android.media.Utils.sortDistinctRanges;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.Process;
+import android.os.SystemProperties;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Range;
+import android.util.Rational;
+import android.util.Size;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Vector;
+
+/**
+ * Provides information about a given media codec available on the device. You can
+ * iterate through all codecs available by querying {@link MediaCodecList}. For example,
+ * here's how to find an encoder that supports a given MIME type:
+ * <pre>
+ * private static MediaCodecInfo selectCodec(String mimeType) {
+ *     int numCodecs = MediaCodecList.getCodecCount();
+ *     for (int i = 0; i &lt; numCodecs; i++) {
+ *         MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
+ *
+ *         if (!codecInfo.isEncoder()) {
+ *             continue;
+ *         }
+ *
+ *         String[] types = codecInfo.getSupportedTypes();
+ *         for (int j = 0; j &lt; types.length; j++) {
+ *             if (types[j].equalsIgnoreCase(mimeType)) {
+ *                 return codecInfo;
+ *             }
+ *         }
+ *     }
+ *     return null;
+ * }</pre>
+ *
+ */
+public final class MediaCodecInfo {
+    private static final String TAG = "MediaCodecInfo";
+
+    private static final int FLAG_IS_ENCODER = (1 << 0);
+    private static final int FLAG_IS_VENDOR = (1 << 1);
+    private static final int FLAG_IS_SOFTWARE_ONLY = (1 << 2);
+    private static final int FLAG_IS_HARDWARE_ACCELERATED = (1 << 3);
+
+    private int mFlags;
+    private String mName;
+    private String mCanonicalName;
+    private Map<String, CodecCapabilities> mCaps;
+
+    /* package private */ MediaCodecInfo(
+            String name, String canonicalName, int flags, CodecCapabilities[] caps) {
+        mName = name;
+        mCanonicalName = canonicalName;
+        mFlags = flags;
+        mCaps = new HashMap<String, CodecCapabilities>();
+
+        for (CodecCapabilities c: caps) {
+            mCaps.put(c.getMimeType(), c);
+        }
+    }
+
+    /**
+     * Retrieve the codec name.
+     *
+     * <strong>Note:</strong> Implementations may provide multiple aliases (codec
+     * names) for the same underlying codec, any of which can be used to instantiate the same
+     * underlying codec in {@link MediaCodec#createByCodecName}.
+     *
+     * Applications targeting SDK < {@link android.os.Build.VERSION_CODES#Q}, cannot determine if
+     * the multiple codec names listed in MediaCodecList are in-fact for the same codec.
+     */
+    @NonNull
+    public final String getName() {
+        return mName;
+    }
+
+    /**
+     * Retrieve the underlying codec name.
+     *
+     * Device implementations may provide multiple aliases (codec names) for the same underlying
+     * codec to maintain backward app compatibility. This method returns the name of the underlying
+     * codec name, which must not be another alias. For non-aliases this is always the name of the
+     * codec.
+     */
+    @NonNull
+    public final String getCanonicalName() {
+        return mCanonicalName;
+    }
+
+    /**
+     * Query if the codec is an alias for another underlying codec.
+     */
+    public final boolean isAlias() {
+        return !mName.equals(mCanonicalName);
+    }
+
+    /**
+     * Query if the codec is an encoder.
+     */
+    public final boolean isEncoder() {
+        return (mFlags & FLAG_IS_ENCODER) != 0;
+    }
+
+    /**
+     * Query if the codec is provided by the Android platform (false) or the device manufacturer
+     * (true).
+     */
+    public final boolean isVendor() {
+        return (mFlags & FLAG_IS_VENDOR) != 0;
+    }
+
+    /**
+     * Query if the codec is software only. Software-only codecs are more secure as they run in
+     * a tighter security sandbox. On the other hand, software-only codecs do not provide any
+     * performance guarantees.
+     */
+    public final boolean isSoftwareOnly() {
+        return (mFlags & FLAG_IS_SOFTWARE_ONLY) != 0;
+    }
+
+    /**
+     * Query if the codec is hardware accelerated. This attribute is provided by the device
+     * manufacturer. Note that it cannot be tested for correctness.
+     */
+    public final boolean isHardwareAccelerated() {
+        return (mFlags & FLAG_IS_HARDWARE_ACCELERATED) != 0;
+    }
+
+    /**
+     * Query the media types supported by the codec.
+     */
+    public final String[] getSupportedTypes() {
+        Set<String> typeSet = mCaps.keySet();
+        String[] types = typeSet.toArray(new String[typeSet.size()]);
+        Arrays.sort(types);
+        return types;
+    }
+
+    private static int checkPowerOfTwo(int value, String message) {
+        if ((value & (value - 1)) != 0) {
+            throw new IllegalArgumentException(message);
+        }
+        return value;
+    }
+
+    private static class Feature {
+        public String mName;
+        public int mValue;
+        public boolean mDefault;
+        public Feature(String name, int value, boolean def) {
+            mName = name;
+            mValue = value;
+            mDefault = def;
+        }
+    }
+
+    // COMMON CONSTANTS
+    private static final Range<Integer> POSITIVE_INTEGERS =
+            Range.create(1, Integer.MAX_VALUE);
+    private static final Range<Long> POSITIVE_LONGS =
+            Range.create(1L, Long.MAX_VALUE);
+    private static final Range<Rational> POSITIVE_RATIONALS =
+            Range.create(new Rational(1, Integer.MAX_VALUE),
+                         new Rational(Integer.MAX_VALUE, 1));
+    private static final Range<Integer> SIZE_RANGE =
+            Process.is64Bit() ? Range.create(1, 32768) : Range.create(1, 4096);
+    private static final Range<Integer> FRAME_RATE_RANGE = Range.create(0, 960);
+    private static final Range<Integer> BITRATE_RANGE = Range.create(0, 500000000);
+    private static final int DEFAULT_MAX_SUPPORTED_INSTANCES = 32;
+    private static final int MAX_SUPPORTED_INSTANCES_LIMIT = 256;
+
+    // found stuff that is not supported by framework (=> this should not happen)
+    private static final int ERROR_UNRECOGNIZED   = (1 << 0);
+    // found profile/level for which we don't have capability estimates
+    private static final int ERROR_UNSUPPORTED    = (1 << 1);
+    // have not found any profile/level for which we don't have capability estimate
+    private static final int ERROR_NONE_SUPPORTED = (1 << 2);
+
+
+    /**
+     * Encapsulates the capabilities of a given codec component.
+     * For example, what profile/level combinations it supports and what colorspaces
+     * it is capable of providing the decoded data in, as well as some
+     * codec-type specific capability flags.
+     * <p>You can get an instance for a given {@link MediaCodecInfo} object with
+     * {@link MediaCodecInfo#getCapabilitiesForType getCapabilitiesForType()}, passing a MIME type.
+     */
+    public static final class CodecCapabilities {
+        public CodecCapabilities() {
+        }
+
+        // CLASSIFICATION
+        private String mMime;
+        private int mMaxSupportedInstances;
+
+        // LEGACY FIELDS
+
+        // Enumerates supported profile/level combinations as defined
+        // by the type of encoded data. These combinations impose restrictions
+        // on video resolution, bitrate... and limit the available encoder tools
+        // such as B-frame support, arithmetic coding...
+        public CodecProfileLevel[] profileLevels;  // NOTE this array is modifiable by user
+
+        // from MediaCodecConstants
+        /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */
+        public static final int COLOR_FormatMonochrome              = 1;
+        /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */
+        public static final int COLOR_Format8bitRGB332              = 2;
+        /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */
+        public static final int COLOR_Format12bitRGB444             = 3;
+        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
+        public static final int COLOR_Format16bitARGB4444           = 4;
+        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
+        public static final int COLOR_Format16bitARGB1555           = 5;
+
+        /**
+         * 16 bits per pixel RGB color format, with 5-bit red & blue and 6-bit green component.
+         * <p>
+         * Using 16-bit little-endian representation, colors stored as Red 15:11, Green 10:5, Blue 4:0.
+         * <pre>
+         *            byte                   byte
+         *  <--------- i --------> | <------ i + 1 ------>
+         * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+         * |     BLUE     |      GREEN      |     RED      |
+         * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+         *  0           4  5     7   0     2  3           7
+         * bit
+         * </pre>
+         *
+         * This format corresponds to {@link android.graphics.PixelFormat#RGB_565} and
+         * {@link android.graphics.ImageFormat#RGB_565}.
+         */
+        public static final int COLOR_Format16bitRGB565             = 6;
+        /** @deprecated Use {@link #COLOR_Format16bitRGB565}. */
+        public static final int COLOR_Format16bitBGR565             = 7;
+        /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */
+        public static final int COLOR_Format18bitRGB666             = 8;
+        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
+        public static final int COLOR_Format18bitARGB1665           = 9;
+        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
+        public static final int COLOR_Format19bitARGB1666           = 10;
+
+        /** @deprecated Use {@link #COLOR_Format24bitBGR888} or {@link #COLOR_FormatRGBFlexible}. */
+        public static final int COLOR_Format24bitRGB888             = 11;
+
+        /**
+         * 24 bits per pixel RGB color format, with 8-bit red, green & blue components.
+         * <p>
+         * Using 24-bit little-endian representation, colors stored as Red 7:0, Green 15:8, Blue 23:16.
+         * <pre>
+         *         byte              byte             byte
+         *  <------ i -----> | <---- i+1 ----> | <---- i+2 ----->
+         * +-----------------+-----------------+-----------------+
+         * |       RED       |      GREEN      |       BLUE      |
+         * +-----------------+-----------------+-----------------+
+         * </pre>
+         *
+         * This format corresponds to {@link android.graphics.PixelFormat#RGB_888}, and can also be
+         * represented as a flexible format by {@link #COLOR_FormatRGBFlexible}.
+         */
+        public static final int COLOR_Format24bitBGR888             = 12;
+        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
+        public static final int COLOR_Format24bitARGB1887           = 13;
+        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
+        public static final int COLOR_Format25bitARGB1888           = 14;
+
+        /**
+         * @deprecated Use {@link #COLOR_Format32bitABGR8888} Or {@link #COLOR_FormatRGBAFlexible}.
+         */
+        public static final int COLOR_Format32bitBGRA8888           = 15;
+        /**
+         * @deprecated Use {@link #COLOR_Format32bitABGR8888} Or {@link #COLOR_FormatRGBAFlexible}.
+         */
+        public static final int COLOR_Format32bitARGB8888           = 16;
+        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
+        public static final int COLOR_FormatYUV411Planar            = 17;
+        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
+        public static final int COLOR_FormatYUV411PackedPlanar      = 18;
+        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
+        public static final int COLOR_FormatYUV420Planar            = 19;
+        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
+        public static final int COLOR_FormatYUV420PackedPlanar      = 20;
+        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
+        public static final int COLOR_FormatYUV420SemiPlanar        = 21;
+
+        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
+        public static final int COLOR_FormatYUV422Planar            = 22;
+        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
+        public static final int COLOR_FormatYUV422PackedPlanar      = 23;
+        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
+        public static final int COLOR_FormatYUV422SemiPlanar        = 24;
+
+        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
+        public static final int COLOR_FormatYCbYCr                  = 25;
+        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
+        public static final int COLOR_FormatYCrYCb                  = 26;
+        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
+        public static final int COLOR_FormatCbYCrY                  = 27;
+        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
+        public static final int COLOR_FormatCrYCbY                  = 28;
+
+        /** @deprecated Use {@link #COLOR_FormatYUV444Flexible}. */
+        public static final int COLOR_FormatYUV444Interleaved       = 29;
+
+        /**
+         * SMIA 8-bit Bayer format.
+         * Each byte represents the top 8-bits of a 10-bit signal.
+         */
+        public static final int COLOR_FormatRawBayer8bit            = 30;
+        /**
+         * SMIA 10-bit Bayer format.
+         */
+        public static final int COLOR_FormatRawBayer10bit           = 31;
+
+        /**
+         * SMIA 8-bit compressed Bayer format.
+         * Each byte represents a sample from the 10-bit signal that is compressed into 8-bits
+         * using DPCM/PCM compression, as defined by the SMIA Functional Specification.
+         */
+        public static final int COLOR_FormatRawBayer8bitcompressed  = 32;
+
+        /** @deprecated Use {@link #COLOR_FormatL8}. */
+        public static final int COLOR_FormatL2                      = 33;
+        /** @deprecated Use {@link #COLOR_FormatL8}. */
+        public static final int COLOR_FormatL4                      = 34;
+
+        /**
+         * 8 bits per pixel Y color format.
+         * <p>
+         * Each byte contains a single pixel.
+         * This format corresponds to {@link android.graphics.PixelFormat#L_8}.
+         */
+        public static final int COLOR_FormatL8                      = 35;
+
+        /**
+         * 16 bits per pixel, little-endian Y color format.
+         * <p>
+         * <pre>
+         *            byte                   byte
+         *  <--------- i --------> | <------ i + 1 ------>
+         * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+         * |                       Y                       |
+         * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
+         *  0                    7   0                    7
+         * bit
+         * </pre>
+         */
+        public static final int COLOR_FormatL16                     = 36;
+        /** @deprecated Use {@link #COLOR_FormatL16}. */
+        public static final int COLOR_FormatL24                     = 37;
+
+        /**
+         * 32 bits per pixel, little-endian Y color format.
+         * <p>
+         * <pre>
+         *         byte              byte             byte              byte
+         *  <------ i -----> | <---- i+1 ----> | <---- i+2 ----> | <---- i+3 ----->
+         * +-----------------+-----------------+-----------------+-----------------+
+         * |                                   Y                                   |
+         * +-----------------+-----------------+-----------------+-----------------+
+         *  0               7 0               7 0               7 0               7
+         * bit
+         * </pre>
+         *
+         * @deprecated Use {@link #COLOR_FormatL16}.
+         */
+        public static final int COLOR_FormatL32                     = 38;
+
+        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
+        public static final int COLOR_FormatYUV420PackedSemiPlanar  = 39;
+        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
+        public static final int COLOR_FormatYUV422PackedSemiPlanar  = 40;
+
+        /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */
+        public static final int COLOR_Format18BitBGR666             = 41;
+
+        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
+        public static final int COLOR_Format24BitARGB6666           = 42;
+        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
+        public static final int COLOR_Format24BitABGR6666           = 43;
+
+        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
+        public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100;
+        // COLOR_FormatSurface indicates that the data will be a GraphicBuffer metadata reference.
+        // Note: in OMX this is called OMX_COLOR_FormatAndroidOpaque.
+        public static final int COLOR_FormatSurface                   = 0x7F000789;
+
+        /**
+         * 32 bits per pixel RGBA color format, with 8-bit red, green, blue, and alpha components.
+         * <p>
+         * Using 32-bit little-endian representation, colors stored as Red 7:0, Green 15:8,
+         * Blue 23:16, and Alpha 31:24.
+         * <pre>
+         *         byte              byte             byte              byte
+         *  <------ i -----> | <---- i+1 ----> | <---- i+2 ----> | <---- i+3 ----->
+         * +-----------------+-----------------+-----------------+-----------------+
+         * |       RED       |      GREEN      |       BLUE      |      ALPHA      |
+         * +-----------------+-----------------+-----------------+-----------------+
+         * </pre>
+         *
+         * This corresponds to {@link android.graphics.PixelFormat#RGBA_8888}.
+         */
+        public static final int COLOR_Format32bitABGR8888             = 0x7F00A000;
+
+        /**
+         * Flexible 12 bits per pixel, subsampled YUV color format with 8-bit chroma and luma
+         * components.
+         * <p>
+         * Chroma planes are subsampled by 2 both horizontally and vertically.
+         * Use this format with {@link Image}.
+         * This format corresponds to {@link android.graphics.ImageFormat#YUV_420_888},
+         * and can represent the {@link #COLOR_FormatYUV411Planar},
+         * {@link #COLOR_FormatYUV411PackedPlanar}, {@link #COLOR_FormatYUV420Planar},
+         * {@link #COLOR_FormatYUV420PackedPlanar}, {@link #COLOR_FormatYUV420SemiPlanar}
+         * and {@link #COLOR_FormatYUV420PackedSemiPlanar} formats.
+         *
+         * @see Image#getFormat
+         */
+        public static final int COLOR_FormatYUV420Flexible            = 0x7F420888;
+
+        /**
+         * Flexible 16 bits per pixel, subsampled YUV color format with 8-bit chroma and luma
+         * components.
+         * <p>
+         * Chroma planes are horizontally subsampled by 2. Use this format with {@link Image}.
+         * This format corresponds to {@link android.graphics.ImageFormat#YUV_422_888},
+         * and can represent the {@link #COLOR_FormatYCbYCr}, {@link #COLOR_FormatYCrYCb},
+         * {@link #COLOR_FormatCbYCrY}, {@link #COLOR_FormatCrYCbY},
+         * {@link #COLOR_FormatYUV422Planar}, {@link #COLOR_FormatYUV422PackedPlanar},
+         * {@link #COLOR_FormatYUV422SemiPlanar} and {@link #COLOR_FormatYUV422PackedSemiPlanar}
+         * formats.
+         *
+         * @see Image#getFormat
+         */
+        public static final int COLOR_FormatYUV422Flexible            = 0x7F422888;
+
+        /**
+         * Flexible 24 bits per pixel YUV color format with 8-bit chroma and luma
+         * components.
+         * <p>
+         * Chroma planes are not subsampled. Use this format with {@link Image}.
+         * This format corresponds to {@link android.graphics.ImageFormat#YUV_444_888},
+         * and can represent the {@link #COLOR_FormatYUV444Interleaved} format.
+         * @see Image#getFormat
+         */
+        public static final int COLOR_FormatYUV444Flexible            = 0x7F444888;
+
+        /**
+         * Flexible 24 bits per pixel RGB color format with 8-bit red, green and blue
+         * components.
+         * <p>
+         * Use this format with {@link Image}. This format corresponds to
+         * {@link android.graphics.ImageFormat#FLEX_RGB_888}, and can represent
+         * {@link #COLOR_Format24bitBGR888} and {@link #COLOR_Format24bitRGB888} formats.
+         * @see Image#getFormat()
+         */
+        public static final int COLOR_FormatRGBFlexible               = 0x7F36B888;
+
+        /**
+         * Flexible 32 bits per pixel RGBA color format with 8-bit red, green, blue, and alpha
+         * components.
+         * <p>
+         * Use this format with {@link Image}. This format corresponds to
+         * {@link android.graphics.ImageFormat#FLEX_RGBA_8888}, and can represent
+         * {@link #COLOR_Format32bitBGRA8888}, {@link #COLOR_Format32bitABGR8888} and
+         * {@link #COLOR_Format32bitARGB8888} formats.
+         *
+         * @see Image#getFormat()
+         */
+        public static final int COLOR_FormatRGBAFlexible              = 0x7F36A888;
+
+        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
+        public static final int COLOR_QCOM_FormatYUV420SemiPlanar     = 0x7fa30c00;
+
+        /**
+         * The color format for the media. This is one of the color constants defined in this class.
+         */
+        public int[] colorFormats; // NOTE this array is modifiable by user
+
+        // FEATURES
+
+        private int mFlagsSupported;
+        private int mFlagsRequired;
+        private int mFlagsVerified;
+
+        /**
+         * <b>video decoder only</b>: codec supports seamless resolution changes.
+         */
+        public static final String FEATURE_AdaptivePlayback       = "adaptive-playback";
+
+        /**
+         * <b>video decoder only</b>: codec supports secure decryption.
+         */
+        public static final String FEATURE_SecurePlayback         = "secure-playback";
+
+        /**
+         * <b>video or audio decoder only</b>: codec supports tunneled playback.
+         */
+        public static final String FEATURE_TunneledPlayback       = "tunneled-playback";
+
+        /**
+         * If true, the timestamp of each output buffer is derived from the timestamp of the input
+         * buffer that produced the output. If false, the timestamp of each output buffer is
+         * derived from the timestamp of the first input buffer.
+         */
+        public static final String FEATURE_DynamicTimestamp = "dynamic-timestamp";
+
+        /**
+         * <b>decoder only</b>If true, the codec supports partial (including multiple) access units
+         * per input buffer.
+         */
+        public static final String FEATURE_FrameParsing = "frame-parsing";
+
+        /**
+         * If true, the codec supports multiple access units (for decoding, or to output for
+         * encoders). If false, the codec only supports single access units. Producing multiple
+         * access units for output is an optional feature.
+         */
+        public static final String FEATURE_MultipleFrames = "multiple-frames";
+
+        /**
+         * <b>video decoder only</b>: codec supports queuing partial frames.
+         */
+        public static final String FEATURE_PartialFrame = "partial-frame";
+
+        /**
+         * <b>video encoder only</b>: codec supports intra refresh.
+         */
+        public static final String FEATURE_IntraRefresh = "intra-refresh";
+
+        /**
+         * <b>decoder only</b>: codec supports low latency decoding.
+         * If supported, clients can enable the low latency mode for the decoder.
+         * When the mode is enabled, the decoder doesn't hold input and output data more than
+         * required by the codec standards.
+         */
+        public static final String FEATURE_LowLatency = "low-latency";
+
+        /**
+         * <b>video encoder only</b>: codec supports quantization parameter bounds.
+         * @see MediaFormat#KEY_VIDEO_QP_MAX
+         * @see MediaFormat#KEY_VIDEO_QP_MIN
+         */
+        @SuppressLint("AllUpper")
+        public static final String FEATURE_QpBounds = "qp-bounds";
+
+        /**
+         * Query codec feature capabilities.
+         * <p>
+         * These features are supported to be used by the codec.  These
+         * include optional features that can be turned on, as well as
+         * features that are always on.
+         */
+        public final boolean isFeatureSupported(String name) {
+            return checkFeature(name, mFlagsSupported);
+        }
+
+        /**
+         * Query codec feature requirements.
+         * <p>
+         * These features are required to be used by the codec, and as such,
+         * they are always turned on.
+         */
+        public final boolean isFeatureRequired(String name) {
+            return checkFeature(name, mFlagsRequired);
+        }
+
+        private static final Feature[] decoderFeatures = {
+            new Feature(FEATURE_AdaptivePlayback, (1 << 0), true),
+            new Feature(FEATURE_SecurePlayback,   (1 << 1), false),
+            new Feature(FEATURE_TunneledPlayback, (1 << 2), false),
+            new Feature(FEATURE_PartialFrame,     (1 << 3), false),
+            new Feature(FEATURE_FrameParsing,     (1 << 4), false),
+            new Feature(FEATURE_MultipleFrames,   (1 << 5), false),
+            new Feature(FEATURE_DynamicTimestamp, (1 << 6), false),
+            new Feature(FEATURE_LowLatency,       (1 << 7), true),
+        };
+
+        private static final Feature[] encoderFeatures = {
+            new Feature(FEATURE_IntraRefresh, (1 << 0), false),
+            new Feature(FEATURE_MultipleFrames, (1 << 1), false),
+            new Feature(FEATURE_DynamicTimestamp, (1 << 2), false),
+            new Feature(FEATURE_QpBounds, (1 << 3), false),
+        };
+
+        /** @hide */
+        public String[] validFeatures() {
+            Feature[] features = getValidFeatures();
+            String[] res = new String[features.length];
+            for (int i = 0; i < res.length; i++) {
+                res[i] = features[i].mName;
+            }
+            return res;
+        }
+
+        private Feature[] getValidFeatures() {
+            if (!isEncoder()) {
+                return decoderFeatures;
+            }
+            return encoderFeatures;
+        }
+
+        private boolean checkFeature(String name, int flags) {
+            for (Feature feat: getValidFeatures()) {
+                if (feat.mName.equals(name)) {
+                    return (flags & feat.mValue) != 0;
+                }
+            }
+            return false;
+        }
+
+        /** @hide */
+        public boolean isRegular() {
+            // regular codecs only require default features
+            for (Feature feat: getValidFeatures()) {
+                if (!feat.mDefault && isFeatureRequired(feat.mName)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /**
+         * Query whether codec supports a given {@link MediaFormat}.
+         *
+         * <p class=note>
+         * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP},
+         * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE
+         * frame rate}. Use
+         * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
+         * to clear any existing frame rate setting in the format.
+         * <p>
+         *
+         * The following table summarizes the format keys considered by this method.
+         * This is especially important to consider when targeting a higher SDK version than the
+         * minimum SDK version, as this method will disregard some keys on devices below the target
+         * SDK version.
+         *
+         * <table style="width: 0%">
+         *  <thead>
+         *   <tr>
+         *    <th rowspan=3>OS Version(s)</th>
+         *    <td colspan=3>{@code MediaFormat} keys considered for</th>
+         *   </tr><tr>
+         *    <th>Audio Codecs</th>
+         *    <th>Video Codecs</th>
+         *    <th>Encoders</th>
+         *   </tr>
+         *  </thead>
+         *  <tbody>
+         *   <tr>
+         *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP}</td>
+         *    <td rowspan=3>{@link MediaFormat#KEY_MIME}<sup>*</sup>,<br>
+         *        {@link MediaFormat#KEY_SAMPLE_RATE},<br>
+         *        {@link MediaFormat#KEY_CHANNEL_COUNT},</td>
+         *    <td>{@link MediaFormat#KEY_MIME}<sup>*</sup>,<br>
+         *        {@link CodecCapabilities#FEATURE_AdaptivePlayback}<sup>D</sup>,<br>
+         *        {@link CodecCapabilities#FEATURE_SecurePlayback}<sup>D</sup>,<br>
+         *        {@link CodecCapabilities#FEATURE_TunneledPlayback}<sup>D</sup>,<br>
+         *        {@link MediaFormat#KEY_WIDTH},<br>
+         *        {@link MediaFormat#KEY_HEIGHT},<br>
+         *        <strong>no</strong> {@code KEY_FRAME_RATE}</td>
+         *    <td rowspan=10>as to the left, plus<br>
+         *        {@link MediaFormat#KEY_BITRATE_MODE},<br>
+         *        {@link MediaFormat#KEY_PROFILE}
+         *        (and/or {@link MediaFormat#KEY_AAC_PROFILE}<sup>~</sup>),<br>
+         *        <!-- {link MediaFormat#KEY_QUALITY},<br> -->
+         *        {@link MediaFormat#KEY_COMPLEXITY}
+         *        (and/or {@link MediaFormat#KEY_FLAC_COMPRESSION_LEVEL}<sup>~</sup>)</td>
+         *   </tr><tr>
+         *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}</td>
+         *    <td rowspan=2>as above, plus<br>
+         *        {@link MediaFormat#KEY_FRAME_RATE}</td>
+         *   </tr><tr>
+         *    <td>{@link android.os.Build.VERSION_CODES#M}</td>
+         *   </tr><tr>
+         *    <td>{@link android.os.Build.VERSION_CODES#N}</td>
+         *    <td rowspan=2>as above, plus<br>
+         *        {@link MediaFormat#KEY_PROFILE},<br>
+         *        <!-- {link MediaFormat#KEY_MAX_BIT_RATE},<br> -->
+         *        {@link MediaFormat#KEY_BIT_RATE}</td>
+         *    <td rowspan=2>as above, plus<br>
+         *        {@link MediaFormat#KEY_PROFILE},<br>
+         *        {@link MediaFormat#KEY_LEVEL}<sup>+</sup>,<br>
+         *        <!-- {link MediaFormat#KEY_MAX_BIT_RATE},<br> -->
+         *        {@link MediaFormat#KEY_BIT_RATE},<br>
+         *        {@link CodecCapabilities#FEATURE_IntraRefresh}<sup>E</sup></td>
+         *   </tr><tr>
+         *    <td>{@link android.os.Build.VERSION_CODES#N_MR1}</td>
+         *   </tr><tr>
+         *    <td>{@link android.os.Build.VERSION_CODES#O}</td>
+         *    <td rowspan=3 colspan=2>as above, plus<br>
+         *        {@link CodecCapabilities#FEATURE_PartialFrame}<sup>D</sup></td>
+         *   </tr><tr>
+         *    <td>{@link android.os.Build.VERSION_CODES#O_MR1}</td>
+         *   </tr><tr>
+         *    <td>{@link android.os.Build.VERSION_CODES#P}</td>
+         *   </tr><tr>
+         *    <td>{@link android.os.Build.VERSION_CODES#Q}</td>
+         *    <td colspan=2>as above, plus<br>
+         *        {@link CodecCapabilities#FEATURE_FrameParsing}<sup>D</sup>,<br>
+         *        {@link CodecCapabilities#FEATURE_MultipleFrames},<br>
+         *        {@link CodecCapabilities#FEATURE_DynamicTimestamp}</td>
+         *   </tr><tr>
+         *    <td>{@link android.os.Build.VERSION_CODES#R}</td>
+         *    <td colspan=2>as above, plus<br>
+         *        {@link CodecCapabilities#FEATURE_LowLatency}<sup>D</sup></td>
+         *   </tr>
+         *   <tr>
+         *    <td colspan=4>
+         *     <p class=note><strong>Notes:</strong><br>
+         *      *: must be specified; otherwise, method returns {@code false}.<br>
+         *      +: method does not verify that the format parameters are supported
+         *      by the specified level.<br>
+         *      D: decoders only<br>
+         *      E: encoders only<br>
+         *      ~: if both keys are provided values must match
+         *    </td>
+         *   </tr>
+         *  </tbody>
+         * </table>
+         *
+         * @param format media format with optional feature directives.
+         * @throws IllegalArgumentException if format is not a valid media format.
+         * @return whether the codec capabilities support the given format
+         *         and feature requests.
+         */
+        public final boolean isFormatSupported(MediaFormat format) {
+            final Map<String, Object> map = format.getMap();
+            final String mime = (String)map.get(MediaFormat.KEY_MIME);
+
+            // mime must match if present
+            if (mime != null && !mMime.equalsIgnoreCase(mime)) {
+                return false;
+            }
+
+            // check feature support
+            for (Feature feat: getValidFeatures()) {
+                Integer yesNo = (Integer)map.get(MediaFormat.KEY_FEATURE_ + feat.mName);
+                if (yesNo == null) {
+                    continue;
+                }
+                if ((yesNo == 1 && !isFeatureSupported(feat.mName)) ||
+                        (yesNo == 0 && isFeatureRequired(feat.mName))) {
+                    return false;
+                }
+            }
+
+            Integer profile = (Integer)map.get(MediaFormat.KEY_PROFILE);
+            Integer level = (Integer)map.get(MediaFormat.KEY_LEVEL);
+
+            if (profile != null) {
+                if (!supportsProfileLevel(profile, level)) {
+                    return false;
+                }
+
+                // If we recognize this profile, check that this format is supported by the
+                // highest level supported by the codec for that profile. (Ignore specified
+                // level beyond the above profile/level check as level is only used as a
+                // guidance. E.g. AVC Level 1 CIF format is supported if codec supports level 1.1
+                // even though max size for Level 1 is QCIF. However, MPEG2 Simple Profile
+                // 1080p format is not supported even if codec supports Main Profile Level High,
+                // as Simple Profile does not support 1080p.
+                CodecCapabilities levelCaps = null;
+                int maxLevel = 0;
+                for (CodecProfileLevel pl : profileLevels) {
+                    if (pl.profile == profile && pl.level > maxLevel) {
+                        // H.263 levels are not completely ordered:
+                        // Level45 support only implies Level10 support
+                        if (!mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)
+                                || pl.level != CodecProfileLevel.H263Level45
+                                || maxLevel == CodecProfileLevel.H263Level10) {
+                            maxLevel = pl.level;
+                        }
+                    }
+                }
+                levelCaps = createFromProfileLevel(mMime, profile, maxLevel);
+                // remove profile from this format otherwise levelCaps.isFormatSupported will
+                // get into this same conditon and loop forever.
+                Map<String, Object> mapWithoutProfile = new HashMap<>(map);
+                mapWithoutProfile.remove(MediaFormat.KEY_PROFILE);
+                MediaFormat formatWithoutProfile = new MediaFormat(mapWithoutProfile);
+                if (levelCaps != null && !levelCaps.isFormatSupported(formatWithoutProfile)) {
+                    return false;
+                }
+            }
+            if (mAudioCaps != null && !mAudioCaps.supportsFormat(format)) {
+                return false;
+            }
+            if (mVideoCaps != null && !mVideoCaps.supportsFormat(format)) {
+                return false;
+            }
+            if (mEncoderCaps != null && !mEncoderCaps.supportsFormat(format)) {
+                return false;
+            }
+            return true;
+        }
+
+        private static boolean supportsBitrate(
+                Range<Integer> bitrateRange, MediaFormat format) {
+            Map<String, Object> map = format.getMap();
+
+            // consider max bitrate over average bitrate for support
+            Integer maxBitrate = (Integer)map.get(MediaFormat.KEY_MAX_BIT_RATE);
+            Integer bitrate = (Integer)map.get(MediaFormat.KEY_BIT_RATE);
+            if (bitrate == null) {
+                bitrate = maxBitrate;
+            } else if (maxBitrate != null) {
+                bitrate = Math.max(bitrate, maxBitrate);
+            }
+
+            if (bitrate != null && bitrate > 0) {
+                return bitrateRange.contains(bitrate);
+            }
+
+            return true;
+        }
+
+        private boolean supportsProfileLevel(int profile, Integer level) {
+            for (CodecProfileLevel pl: profileLevels) {
+                if (pl.profile != profile) {
+                    continue;
+                }
+
+                // AAC does not use levels
+                if (level == null || mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AAC)) {
+                    return true;
+                }
+
+                // H.263 levels are not completely ordered:
+                // Level45 support only implies Level10 support
+                if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) {
+                    if (pl.level != level && pl.level == CodecProfileLevel.H263Level45
+                            && level > CodecProfileLevel.H263Level10) {
+                        continue;
+                    }
+                }
+
+                // MPEG4 levels are not completely ordered:
+                // Level1 support only implies Level0 (and not Level0b) support
+                if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG4)) {
+                    if (pl.level != level && pl.level == CodecProfileLevel.MPEG4Level1
+                            && level > CodecProfileLevel.MPEG4Level0) {
+                        continue;
+                    }
+                }
+
+                // HEVC levels incorporate both tiers and levels. Verify tier support.
+                if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
+                    boolean supportsHighTier =
+                        (pl.level & CodecProfileLevel.HEVCHighTierLevels) != 0;
+                    boolean checkingHighTier = (level & CodecProfileLevel.HEVCHighTierLevels) != 0;
+                    // high tier levels are only supported by other high tier levels
+                    if (checkingHighTier && !supportsHighTier) {
+                        continue;
+                    }
+                }
+
+                if (pl.level >= level) {
+                    // if we recognize the listed profile/level, we must also recognize the
+                    // profile/level arguments.
+                    if (createFromProfileLevel(mMime, profile, pl.level) != null) {
+                        return createFromProfileLevel(mMime, profile, level) != null;
+                    }
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        // errors while reading profile levels - accessed from sister capabilities
+        int mError;
+
+        private static final String TAG = "CodecCapabilities";
+
+        // NEW-STYLE CAPABILITIES
+        private AudioCapabilities mAudioCaps;
+        private VideoCapabilities mVideoCaps;
+        private EncoderCapabilities mEncoderCaps;
+        private MediaFormat mDefaultFormat;
+
+        /**
+         * Returns a MediaFormat object with default values for configurations that have
+         * defaults.
+         */
+        public MediaFormat getDefaultFormat() {
+            return mDefaultFormat;
+        }
+
+        /**
+         * Returns the mime type for which this codec-capability object was created.
+         */
+        public String getMimeType() {
+            return mMime;
+        }
+
+        /**
+         * Returns the max number of the supported concurrent codec instances.
+         * <p>
+         * This is a hint for an upper bound. Applications should not expect to successfully
+         * operate more instances than the returned value, but the actual number of
+         * concurrently operable instances may be less as it depends on the available
+         * resources at time of use.
+         */
+        public int getMaxSupportedInstances() {
+            return mMaxSupportedInstances;
+        }
+
+        private boolean isAudio() {
+            return mAudioCaps != null;
+        }
+
+        /**
+         * Returns the audio capabilities or {@code null} if this is not an audio codec.
+         */
+        public AudioCapabilities getAudioCapabilities() {
+            return mAudioCaps;
+        }
+
+        private boolean isEncoder() {
+            return mEncoderCaps != null;
+        }
+
+        /**
+         * Returns the encoding capabilities or {@code null} if this is not an encoder.
+         */
+        public EncoderCapabilities getEncoderCapabilities() {
+            return mEncoderCaps;
+        }
+
+        private boolean isVideo() {
+            return mVideoCaps != null;
+        }
+
+        /**
+         * Returns the video capabilities or {@code null} if this is not a video codec.
+         */
+        public VideoCapabilities getVideoCapabilities() {
+            return mVideoCaps;
+        }
+
+        /** @hide */
+        public CodecCapabilities dup() {
+            CodecCapabilities caps = new CodecCapabilities();
+
+            // profileLevels and colorFormats may be modified by client.
+            caps.profileLevels = Arrays.copyOf(profileLevels, profileLevels.length);
+            caps.colorFormats = Arrays.copyOf(colorFormats, colorFormats.length);
+
+            caps.mMime = mMime;
+            caps.mMaxSupportedInstances = mMaxSupportedInstances;
+            caps.mFlagsRequired = mFlagsRequired;
+            caps.mFlagsSupported = mFlagsSupported;
+            caps.mFlagsVerified = mFlagsVerified;
+            caps.mAudioCaps = mAudioCaps;
+            caps.mVideoCaps = mVideoCaps;
+            caps.mEncoderCaps = mEncoderCaps;
+            caps.mDefaultFormat = mDefaultFormat;
+            caps.mCapabilitiesInfo = mCapabilitiesInfo;
+
+            return caps;
+        }
+
+        /**
+         * Retrieve the codec capabilities for a certain {@code mime type}, {@code
+         * profile} and {@code level}.  If the type, or profile-level combination
+         * is not understood by the framework, it returns null.
+         * <p class=note> In {@link android.os.Build.VERSION_CODES#M}, calling this
+         * method without calling any method of the {@link MediaCodecList} class beforehand
+         * results in a {@link NullPointerException}.</p>
+         */
+        public static CodecCapabilities createFromProfileLevel(
+                String mime, int profile, int level) {
+            CodecProfileLevel pl = new CodecProfileLevel();
+            pl.profile = profile;
+            pl.level = level;
+            MediaFormat defaultFormat = new MediaFormat();
+            defaultFormat.setString(MediaFormat.KEY_MIME, mime);
+
+            CodecCapabilities ret = new CodecCapabilities(
+                new CodecProfileLevel[] { pl }, new int[0], true /* encoder */,
+                defaultFormat, new MediaFormat() /* info */);
+            if (ret.mError != 0) {
+                return null;
+            }
+            return ret;
+        }
+
+        /* package private */ CodecCapabilities(
+                CodecProfileLevel[] profLevs, int[] colFmts,
+                boolean encoder,
+                Map<String, Object>defaultFormatMap,
+                Map<String, Object>capabilitiesMap) {
+            this(profLevs, colFmts, encoder,
+                    new MediaFormat(defaultFormatMap),
+                    new MediaFormat(capabilitiesMap));
+        }
+
+        private MediaFormat mCapabilitiesInfo;
+
+        /* package private */ CodecCapabilities(
+                CodecProfileLevel[] profLevs, int[] colFmts, boolean encoder,
+                MediaFormat defaultFormat, MediaFormat info) {
+            final Map<String, Object> map = info.getMap();
+            colorFormats = colFmts;
+            mFlagsVerified = 0; // TODO: remove as it is unused
+            mDefaultFormat = defaultFormat;
+            mCapabilitiesInfo = info;
+            mMime = mDefaultFormat.getString(MediaFormat.KEY_MIME);
+
+            /* VP9 introduced profiles around 2016, so some VP9 codecs may not advertise any
+               supported profiles. Determine the level for them using the info they provide. */
+            if (profLevs.length == 0 && mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)) {
+                CodecProfileLevel profLev = new CodecProfileLevel();
+                profLev.profile = CodecProfileLevel.VP9Profile0;
+                profLev.level = VideoCapabilities.equivalentVP9Level(info);
+                profLevs = new CodecProfileLevel[] { profLev };
+            }
+            profileLevels = profLevs;
+
+            if (mMime.toLowerCase().startsWith("audio/")) {
+                mAudioCaps = AudioCapabilities.create(info, this);
+                mAudioCaps.getDefaultFormat(mDefaultFormat);
+            } else if (mMime.toLowerCase().startsWith("video/")
+                    || mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC)) {
+                mVideoCaps = VideoCapabilities.create(info, this);
+            }
+            if (encoder) {
+                mEncoderCaps = EncoderCapabilities.create(info, this);
+                mEncoderCaps.getDefaultFormat(mDefaultFormat);
+            }
+
+            final Map<String, Object> global = MediaCodecList.getGlobalSettings();
+            mMaxSupportedInstances = Utils.parseIntSafely(
+                    global.get("max-concurrent-instances"), DEFAULT_MAX_SUPPORTED_INSTANCES);
+
+            int maxInstances = Utils.parseIntSafely(
+                    map.get("max-concurrent-instances"), mMaxSupportedInstances);
+            mMaxSupportedInstances =
+                    Range.create(1, MAX_SUPPORTED_INSTANCES_LIMIT).clamp(maxInstances);
+
+            for (Feature feat: getValidFeatures()) {
+                String key = MediaFormat.KEY_FEATURE_ + feat.mName;
+                Integer yesNo = (Integer)map.get(key);
+                if (yesNo == null) {
+                    continue;
+                }
+                if (yesNo > 0) {
+                    mFlagsRequired |= feat.mValue;
+                }
+                mFlagsSupported |= feat.mValue;
+                mDefaultFormat.setInteger(key, 1);
+                // TODO restrict features by mFlagsVerified once all codecs reliably verify them
+            }
+        }
+    }
+
+    /**
+     * A class that supports querying the audio capabilities of a codec.
+     */
+    public static final class AudioCapabilities {
+        private static final String TAG = "AudioCapabilities";
+        private CodecCapabilities mParent;
+        private Range<Integer> mBitrateRange;
+
+        private int[] mSampleRates;
+        private Range<Integer>[] mSampleRateRanges;
+        private Range<Integer>[] mInputChannelRanges;
+
+        private static final int MAX_INPUT_CHANNEL_COUNT = 30;
+
+        /**
+         * Returns the range of supported bitrates in bits/second.
+         */
+        public Range<Integer> getBitrateRange() {
+            return mBitrateRange;
+        }
+
+        /**
+         * Returns the array of supported sample rates if the codec
+         * supports only discrete values.  Otherwise, it returns
+         * {@code null}.  The array is sorted in ascending order.
+         */
+        public int[] getSupportedSampleRates() {
+            return mSampleRates != null ? Arrays.copyOf(mSampleRates, mSampleRates.length) : null;
+        }
+
+        /**
+         * Returns the array of supported sample rate ranges.  The
+         * array is sorted in ascending order, and the ranges are
+         * distinct.
+         */
+        public Range<Integer>[] getSupportedSampleRateRanges() {
+            return Arrays.copyOf(mSampleRateRanges, mSampleRateRanges.length);
+        }
+
+        /**
+         * Returns the maximum number of input channels supported.
+         *
+         * Through {@link android.os.Build.VERSION_CODES#R}, this method indicated support
+         * for any number of input channels between 1 and this maximum value.
+         *
+         * As of {@link android.os.Build.VERSION_CODES#S},
+         * the implied lower limit of 1 channel is no longer valid.
+         * As of {@link android.os.Build.VERSION_CODES#S}, {@link #getMaxInputChannelCount} is
+         * superseded by {@link #getInputChannelCountRanges},
+         * which returns an array of ranges of channels.
+         * The {@link #getMaxInputChannelCount} method will return the highest value
+         * in the ranges returned by {@link #getInputChannelCountRanges}
+         *
+         */
+        @IntRange(from = 1, to = 255)
+        public int getMaxInputChannelCount() {
+            int overall_max = 0;
+            for (int i = mInputChannelRanges.length - 1; i >= 0; i--) {
+                int lmax = mInputChannelRanges[i].getUpper();
+                if (lmax > overall_max) {
+                    overall_max = lmax;
+                }
+            }
+            return overall_max;
+        }
+
+        /**
+         * Returns the minimum number of input channels supported.
+         * This is often 1, but does vary for certain mime types.
+         *
+         * This returns the lowest channel count in the ranges returned by
+         * {@link #getInputChannelCountRanges}.
+         */
+        @IntRange(from = 1, to = 255)
+        public int getMinInputChannelCount() {
+            int overall_min = MAX_INPUT_CHANNEL_COUNT;
+            for (int i = mInputChannelRanges.length - 1; i >= 0; i--) {
+                int lmin = mInputChannelRanges[i].getLower();
+                if (lmin < overall_min) {
+                    overall_min = lmin;
+                }
+            }
+            return overall_min;
+        }
+
+        /*
+         * Returns an array of ranges representing the number of input channels supported.
+         * The codec supports any number of input channels within this range.
+         *
+         * This supersedes the {@link #getMaxInputChannelCount} method.
+         *
+         * For many codecs, this will be a single range [1..N], for some N.
+         */
+        @SuppressLint("ArrayReturn")
+        @NonNull
+        public Range<Integer>[] getInputChannelCountRanges() {
+            return Arrays.copyOf(mInputChannelRanges, mInputChannelRanges.length);
+        }
+
+        /* no public constructor */
+        private AudioCapabilities() { }
+
+        /** @hide */
+        public static AudioCapabilities create(
+                MediaFormat info, CodecCapabilities parent) {
+            AudioCapabilities caps = new AudioCapabilities();
+            caps.init(info, parent);
+            return caps;
+        }
+
+        private void init(MediaFormat info, CodecCapabilities parent) {
+            mParent = parent;
+            initWithPlatformLimits();
+            applyLevelLimits();
+            parseFromInfo(info);
+        }
+
+        private void initWithPlatformLimits() {
+            mBitrateRange = Range.create(0, Integer.MAX_VALUE);
+            mInputChannelRanges = new Range[] {Range.create(1, MAX_INPUT_CHANNEL_COUNT)};
+            // mBitrateRange = Range.create(1, 320000);
+            final int minSampleRate = SystemProperties.
+                getInt("ro.mediacodec.min_sample_rate", 7350);
+            final int maxSampleRate = SystemProperties.
+                getInt("ro.mediacodec.max_sample_rate", 192000);
+            mSampleRateRanges = new Range[] { Range.create(minSampleRate, maxSampleRate) };
+            mSampleRates = null;
+        }
+
+        private boolean supports(Integer sampleRate, Integer inputChannels) {
+            // channels and sample rates are checked orthogonally
+            if (inputChannels != null) {
+                int ix = Utils.binarySearchDistinctRanges(
+                        mInputChannelRanges, inputChannels);
+                if (ix < 0) {
+                    return false;
+                }
+            }
+            if (sampleRate != null) {
+                int ix = Utils.binarySearchDistinctRanges(
+                        mSampleRateRanges, sampleRate);
+                if (ix < 0) {
+                    return false;
+                }
+            }
+            return true;
+        }
+
+        /**
+         * Query whether the sample rate is supported by the codec.
+         */
+        public boolean isSampleRateSupported(int sampleRate) {
+            return supports(sampleRate, null);
+        }
+
+        /** modifies rates */
+        private void limitSampleRates(int[] rates) {
+            Arrays.sort(rates);
+            ArrayList<Range<Integer>> ranges = new ArrayList<Range<Integer>>();
+            for (int rate: rates) {
+                if (supports(rate, null /* channels */)) {
+                    ranges.add(Range.create(rate, rate));
+                }
+            }
+            mSampleRateRanges = ranges.toArray(new Range[ranges.size()]);
+            createDiscreteSampleRates();
+        }
+
+        private void createDiscreteSampleRates() {
+            mSampleRates = new int[mSampleRateRanges.length];
+            for (int i = 0; i < mSampleRateRanges.length; i++) {
+                mSampleRates[i] = mSampleRateRanges[i].getLower();
+            }
+        }
+
+        /** modifies rateRanges */
+        private void limitSampleRates(Range<Integer>[] rateRanges) {
+            sortDistinctRanges(rateRanges);
+            mSampleRateRanges = intersectSortedDistinctRanges(mSampleRateRanges, rateRanges);
+
+            // check if all values are discrete
+            for (Range<Integer> range: mSampleRateRanges) {
+                if (!range.getLower().equals(range.getUpper())) {
+                    mSampleRates = null;
+                    return;
+                }
+            }
+            createDiscreteSampleRates();
+        }
+
+        private void applyLevelLimits() {
+            int[] sampleRates = null;
+            Range<Integer> sampleRateRange = null, bitRates = null;
+            int maxChannels = MAX_INPUT_CHANNEL_COUNT;
+            String mime = mParent.getMimeType();
+
+            if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MPEG)) {
+                sampleRates = new int[] {
+                        8000, 11025, 12000,
+                        16000, 22050, 24000,
+                        32000, 44100, 48000 };
+                bitRates = Range.create(8000, 320000);
+                maxChannels = 2;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB)) {
+                sampleRates = new int[] { 8000 };
+                bitRates = Range.create(4750, 12200);
+                maxChannels = 1;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB)) {
+                sampleRates = new int[] { 16000 };
+                bitRates = Range.create(6600, 23850);
+                maxChannels = 1;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AAC)) {
+                sampleRates = new int[] {
+                        7350, 8000,
+                        11025, 12000, 16000,
+                        22050, 24000, 32000,
+                        44100, 48000, 64000,
+                        88200, 96000 };
+                bitRates = Range.create(8000, 510000);
+                maxChannels = 48;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_VORBIS)) {
+                bitRates = Range.create(32000, 500000);
+                sampleRateRange = Range.create(8000, 192000);
+                maxChannels = 255;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_OPUS)) {
+                bitRates = Range.create(6000, 510000);
+                sampleRates = new int[] { 8000, 12000, 16000, 24000, 48000 };
+                maxChannels = 255;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_RAW)) {
+                sampleRateRange = Range.create(1, 96000);
+                bitRates = Range.create(1, 10000000);
+                maxChannels = AudioSystem.OUT_CHANNEL_COUNT_MAX;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
+                sampleRateRange = Range.create(1, 655350);
+                // lossless codec, so bitrate is ignored
+                maxChannels = 255;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW)
+                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW)) {
+                sampleRates = new int[] { 8000 };
+                bitRates = Range.create(64000, 64000);
+                // platform allows multiple channels for this format
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM)) {
+                sampleRates = new int[] { 8000 };
+                bitRates = Range.create(13000, 13000);
+                maxChannels = 1;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AC3)) {
+                maxChannels = 6;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_EAC3)) {
+                maxChannels = 16;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_EAC3_JOC)) {
+                sampleRates = new int[] { 48000 };
+                bitRates = Range.create(32000, 6144000);
+                maxChannels = 16;
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AC4)) {
+                sampleRates = new int[] { 44100, 48000, 96000, 192000 };
+                bitRates = Range.create(16000, 2688000);
+                maxChannels = 24;
+            } else {
+                Log.w(TAG, "Unsupported mime " + mime);
+                mParent.mError |= ERROR_UNSUPPORTED;
+            }
+
+            // restrict ranges
+            if (sampleRates != null) {
+                limitSampleRates(sampleRates);
+            } else if (sampleRateRange != null) {
+                limitSampleRates(new Range[] { sampleRateRange });
+            }
+
+            Range<Integer> channelRange = Range.create(1, maxChannels);
+
+            applyLimits(new Range[] { channelRange }, bitRates);
+        }
+
+        private void applyLimits(Range<Integer>[] inputChannels, Range<Integer> bitRates) {
+
+            // clamp & make a local copy
+            Range<Integer>[] myInputChannels = new Range[inputChannels.length];
+            for (int i = 0; i < inputChannels.length; i++) {
+                int lower = inputChannels[i].clamp(1);
+                int upper = inputChannels[i].clamp(MAX_INPUT_CHANNEL_COUNT);
+                myInputChannels[i] = Range.create(lower, upper);
+            }
+
+            // sort, intersect with existing, & save channel list
+            sortDistinctRanges(myInputChannels);
+            Range<Integer>[] joinedChannelList =
+                            intersectSortedDistinctRanges(myInputChannels, mInputChannelRanges);
+            mInputChannelRanges = joinedChannelList;
+
+            if (bitRates != null) {
+                mBitrateRange = mBitrateRange.intersect(bitRates);
+            }
+        }
+
+        private void parseFromInfo(MediaFormat info) {
+            int maxInputChannels = MAX_INPUT_CHANNEL_COUNT;
+            Range<Integer>[] channels = new Range[] { Range.create(1, maxInputChannels)};
+            Range<Integer> bitRates = POSITIVE_INTEGERS;
+
+            if (info.containsKey("sample-rate-ranges")) {
+                String[] rateStrings = info.getString("sample-rate-ranges").split(",");
+                Range<Integer>[] rateRanges = new Range[rateStrings.length];
+                for (int i = 0; i < rateStrings.length; i++) {
+                    rateRanges[i] = Utils.parseIntRange(rateStrings[i], null);
+                }
+                limitSampleRates(rateRanges);
+            }
+
+            // we will prefer channel-ranges over max-channel-count
+            if (info.containsKey("channel-ranges")) {
+                String[] channelStrings = info.getString("channel-ranges").split(",");
+                Range<Integer>[] channelRanges = new Range[channelStrings.length];
+                for (int i = 0; i < channelStrings.length; i++) {
+                    channelRanges[i] = Utils.parseIntRange(channelStrings[i], null);
+                }
+                channels = channelRanges;
+            } else if (info.containsKey("channel-range")) {
+                Range<Integer> oneRange = Utils.parseIntRange(info.getString("channel-range"),
+                                                              null);
+                channels = new Range[] { oneRange };
+            } else if (info.containsKey("max-channel-count")) {
+                maxInputChannels = Utils.parseIntSafely(
+                        info.getString("max-channel-count"), maxInputChannels);
+                if (maxInputChannels == 0) {
+                    channels = new Range[] {Range.create(0, 0)};
+                } else {
+                    channels = new Range[] {Range.create(1, maxInputChannels)};
+                }
+            } else if ((mParent.mError & ERROR_UNSUPPORTED) != 0) {
+                maxInputChannels = 0;
+                channels = new Range[] {Range.create(0, 0)};
+            }
+
+            if (info.containsKey("bitrate-range")) {
+                bitRates = bitRates.intersect(
+                        Utils.parseIntRange(info.getString("bitrate-range"), bitRates));
+            }
+
+            applyLimits(channels, bitRates);
+        }
+
+        /** @hide */
+        public void getDefaultFormat(MediaFormat format) {
+            // report settings that have only a single choice
+            if (mBitrateRange.getLower().equals(mBitrateRange.getUpper())) {
+                format.setInteger(MediaFormat.KEY_BIT_RATE, mBitrateRange.getLower());
+            }
+            if (getMaxInputChannelCount() == 1) {
+                // mono-only format
+                format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
+            }
+            if (mSampleRates != null && mSampleRates.length == 1) {
+                format.setInteger(MediaFormat.KEY_SAMPLE_RATE, mSampleRates[0]);
+            }
+        }
+
+        /** @hide */
+        public boolean supportsFormat(MediaFormat format) {
+            Map<String, Object> map = format.getMap();
+            Integer sampleRate = (Integer)map.get(MediaFormat.KEY_SAMPLE_RATE);
+            Integer channels = (Integer)map.get(MediaFormat.KEY_CHANNEL_COUNT);
+
+            if (!supports(sampleRate, channels)) {
+                return false;
+            }
+
+            if (!CodecCapabilities.supportsBitrate(mBitrateRange, format)) {
+                return false;
+            }
+
+            // nothing to do for:
+            // KEY_CHANNEL_MASK: codecs don't get this
+            // KEY_IS_ADTS:      required feature for all AAC decoders
+            return true;
+        }
+    }
+
+    /**
+     * A class that supports querying the video capabilities of a codec.
+     */
+    public static final class VideoCapabilities {
+        private static final String TAG = "VideoCapabilities";
+        private CodecCapabilities mParent;
+        private Range<Integer> mBitrateRange;
+
+        private Range<Integer> mHeightRange;
+        private Range<Integer> mWidthRange;
+        private Range<Integer> mBlockCountRange;
+        private Range<Integer> mHorizontalBlockRange;
+        private Range<Integer> mVerticalBlockRange;
+        private Range<Rational> mAspectRatioRange;
+        private Range<Rational> mBlockAspectRatioRange;
+        private Range<Long> mBlocksPerSecondRange;
+        private Map<Size, Range<Long>> mMeasuredFrameRates;
+        private List<PerformancePoint> mPerformancePoints;
+        private Range<Integer> mFrameRateRange;
+
+        private int mBlockWidth;
+        private int mBlockHeight;
+        private int mWidthAlignment;
+        private int mHeightAlignment;
+        private int mSmallerDimensionUpperLimit;
+
+        private boolean mAllowMbOverride; // allow XML to override calculated limits
+
+        /**
+         * Returns the range of supported bitrates in bits/second.
+         */
+        public Range<Integer> getBitrateRange() {
+            return mBitrateRange;
+        }
+
+        /**
+         * Returns the range of supported video widths.
+         * <p class=note>
+         * 32-bit processes will not support resolutions larger than 4096x4096 due to
+         * the limited address space.
+         */
+        public Range<Integer> getSupportedWidths() {
+            return mWidthRange;
+        }
+
+        /**
+         * Returns the range of supported video heights.
+         * <p class=note>
+         * 32-bit processes will not support resolutions larger than 4096x4096 due to
+         * the limited address space.
+         */
+        public Range<Integer> getSupportedHeights() {
+            return mHeightRange;
+        }
+
+        /**
+         * Returns the alignment requirement for video width (in pixels).
+         *
+         * This is a power-of-2 value that video width must be a
+         * multiple of.
+         */
+        public int getWidthAlignment() {
+            return mWidthAlignment;
+        }
+
+        /**
+         * Returns the alignment requirement for video height (in pixels).
+         *
+         * This is a power-of-2 value that video height must be a
+         * multiple of.
+         */
+        public int getHeightAlignment() {
+            return mHeightAlignment;
+        }
+
+        /**
+         * Return the upper limit on the smaller dimension of width or height.
+         * <p></p>
+         * Some codecs have a limit on the smaller dimension, whether it be
+         * the width or the height.  E.g. a codec may only be able to handle
+         * up to 1920x1080 both in landscape and portrait mode (1080x1920).
+         * In this case the maximum width and height are both 1920, but the
+         * smaller dimension limit will be 1080. For other codecs, this is
+         * {@code Math.min(getSupportedWidths().getUpper(),
+         * getSupportedHeights().getUpper())}.
+         *
+         * @hide
+         */
+        public int getSmallerDimensionUpperLimit() {
+            return mSmallerDimensionUpperLimit;
+        }
+
+        /**
+         * Returns the range of supported frame rates.
+         * <p>
+         * This is not a performance indicator.  Rather, it expresses the
+         * limits specified in the coding standard, based on the complexities
+         * of encoding material for later playback at a certain frame rate,
+         * or the decoding of such material in non-realtime.
+         */
+        public Range<Integer> getSupportedFrameRates() {
+            return mFrameRateRange;
+        }
+
+        /**
+         * Returns the range of supported video widths for a video height.
+         * @param height the height of the video
+         */
+        public Range<Integer> getSupportedWidthsFor(int height) {
+            try {
+                Range<Integer> range = mWidthRange;
+                if (!mHeightRange.contains(height)
+                        || (height % mHeightAlignment) != 0) {
+                    throw new IllegalArgumentException("unsupported height");
+                }
+                final int heightInBlocks = Utils.divUp(height, mBlockHeight);
+
+                // constrain by block count and by block aspect ratio
+                final int minWidthInBlocks = Math.max(
+                        Utils.divUp(mBlockCountRange.getLower(), heightInBlocks),
+                        (int)Math.ceil(mBlockAspectRatioRange.getLower().doubleValue()
+                                * heightInBlocks));
+                final int maxWidthInBlocks = Math.min(
+                        mBlockCountRange.getUpper() / heightInBlocks,
+                        (int)(mBlockAspectRatioRange.getUpper().doubleValue()
+                                * heightInBlocks));
+                range = range.intersect(
+                        (minWidthInBlocks - 1) * mBlockWidth + mWidthAlignment,
+                        maxWidthInBlocks * mBlockWidth);
+
+                // constrain by smaller dimension limit
+                if (height > mSmallerDimensionUpperLimit) {
+                    range = range.intersect(1, mSmallerDimensionUpperLimit);
+                }
+
+                // constrain by aspect ratio
+                range = range.intersect(
+                        (int)Math.ceil(mAspectRatioRange.getLower().doubleValue()
+                                * height),
+                        (int)(mAspectRatioRange.getUpper().doubleValue() * height));
+                return range;
+            } catch (IllegalArgumentException e) {
+                // height is not supported because there are no suitable widths
+                Log.v(TAG, "could not get supported widths for " + height);
+                throw new IllegalArgumentException("unsupported height");
+            }
+        }
+
+        /**
+         * Returns the range of supported video heights for a video width
+         * @param width the width of the video
+         */
+        public Range<Integer> getSupportedHeightsFor(int width) {
+            try {
+                Range<Integer> range = mHeightRange;
+                if (!mWidthRange.contains(width)
+                        || (width % mWidthAlignment) != 0) {
+                    throw new IllegalArgumentException("unsupported width");
+                }
+                final int widthInBlocks = Utils.divUp(width, mBlockWidth);
+
+                // constrain by block count and by block aspect ratio
+                final int minHeightInBlocks = Math.max(
+                        Utils.divUp(mBlockCountRange.getLower(), widthInBlocks),
+                        (int)Math.ceil(widthInBlocks /
+                                mBlockAspectRatioRange.getUpper().doubleValue()));
+                final int maxHeightInBlocks = Math.min(
+                        mBlockCountRange.getUpper() / widthInBlocks,
+                        (int)(widthInBlocks /
+                                mBlockAspectRatioRange.getLower().doubleValue()));
+                range = range.intersect(
+                        (minHeightInBlocks - 1) * mBlockHeight + mHeightAlignment,
+                        maxHeightInBlocks * mBlockHeight);
+
+                // constrain by smaller dimension limit
+                if (width > mSmallerDimensionUpperLimit) {
+                    range = range.intersect(1, mSmallerDimensionUpperLimit);
+                }
+
+                // constrain by aspect ratio
+                range = range.intersect(
+                        (int)Math.ceil(width /
+                                mAspectRatioRange.getUpper().doubleValue()),
+                        (int)(width / mAspectRatioRange.getLower().doubleValue()));
+                return range;
+            } catch (IllegalArgumentException e) {
+                // width is not supported because there are no suitable heights
+                Log.v(TAG, "could not get supported heights for " + width);
+                throw new IllegalArgumentException("unsupported width");
+            }
+        }
+
+        /**
+         * Returns the range of supported video frame rates for a video size.
+         * <p>
+         * This is not a performance indicator.  Rather, it expresses the limits specified in
+         * the coding standard, based on the complexities of encoding material of a given
+         * size for later playback at a certain frame rate, or the decoding of such material
+         * in non-realtime.
+
+         * @param width the width of the video
+         * @param height the height of the video
+         */
+        public Range<Double> getSupportedFrameRatesFor(int width, int height) {
+            Range<Integer> range = mHeightRange;
+            if (!supports(width, height, null)) {
+                throw new IllegalArgumentException("unsupported size");
+            }
+            final int blockCount =
+                Utils.divUp(width, mBlockWidth) * Utils.divUp(height, mBlockHeight);
+
+            return Range.create(
+                    Math.max(mBlocksPerSecondRange.getLower() / (double) blockCount,
+                            (double) mFrameRateRange.getLower()),
+                    Math.min(mBlocksPerSecondRange.getUpper() / (double) blockCount,
+                            (double) mFrameRateRange.getUpper()));
+        }
+
+        private int getBlockCount(int width, int height) {
+            return Utils.divUp(width, mBlockWidth) * Utils.divUp(height, mBlockHeight);
+        }
+
+        @NonNull
+        private Size findClosestSize(int width, int height) {
+            int targetBlockCount = getBlockCount(width, height);
+            Size closestSize = null;
+            int minDiff = Integer.MAX_VALUE;
+            for (Size size : mMeasuredFrameRates.keySet()) {
+                int diff = Math.abs(targetBlockCount -
+                        getBlockCount(size.getWidth(), size.getHeight()));
+                if (diff < minDiff) {
+                    minDiff = diff;
+                    closestSize = size;
+                }
+            }
+            return closestSize;
+        }
+
+        private Range<Double> estimateFrameRatesFor(int width, int height) {
+            Size size = findClosestSize(width, height);
+            Range<Long> range = mMeasuredFrameRates.get(size);
+            Double ratio = getBlockCount(size.getWidth(), size.getHeight())
+                    / (double)Math.max(getBlockCount(width, height), 1);
+            return Range.create(range.getLower() * ratio, range.getUpper() * ratio);
+        }
+
+        /**
+         * Returns the range of achievable video frame rates for a video size.
+         * May return {@code null}, if the codec did not publish any measurement
+         * data.
+         * <p>
+         * This is a performance estimate provided by the device manufacturer based on statistical
+         * sampling of full-speed decoding and encoding measurements in various configurations
+         * of common video sizes supported by the codec. As such it should only be used to
+         * compare individual codecs on the device. The value is not suitable for comparing
+         * different devices or even different android releases for the same device.
+         * <p>
+         * <em>On {@link android.os.Build.VERSION_CODES#M} release</em> the returned range
+         * corresponds to the fastest frame rates achieved in the tested configurations. As
+         * such, it should not be used to gauge guaranteed or even average codec performance
+         * on the device.
+         * <p>
+         * <em>On {@link android.os.Build.VERSION_CODES#N} release</em> the returned range
+         * corresponds closer to sustained performance <em>in tested configurations</em>.
+         * One can expect to achieve sustained performance higher than the lower limit more than
+         * 50% of the time, and higher than half of the lower limit at least 90% of the time
+         * <em>in tested configurations</em>.
+         * Conversely, one can expect performance lower than twice the upper limit at least
+         * 90% of the time.
+         * <p class=note>
+         * Tested configurations use a single active codec. For use cases where multiple
+         * codecs are active, applications can expect lower and in most cases significantly lower
+         * performance.
+         * <p class=note>
+         * The returned range value is interpolated from the nearest frame size(s) tested.
+         * Codec performance is severely impacted by other activity on the device as well
+         * as environmental factors (such as battery level, temperature or power source), and can
+         * vary significantly even in a steady environment.
+         * <p class=note>
+         * Use this method in cases where only codec performance matters, e.g. to evaluate if
+         * a codec has any chance of meeting a performance target. Codecs are listed
+         * in {@link MediaCodecList} in the preferred order as defined by the device
+         * manufacturer. As such, applications should use the first suitable codec in the
+         * list to achieve the best balance between power use and performance.
+         *
+         * @param width the width of the video
+         * @param height the height of the video
+         *
+         * @throws IllegalArgumentException if the video size is not supported.
+         */
+        @Nullable
+        public Range<Double> getAchievableFrameRatesFor(int width, int height) {
+            if (!supports(width, height, null)) {
+                throw new IllegalArgumentException("unsupported size");
+            }
+
+            if (mMeasuredFrameRates == null || mMeasuredFrameRates.size() <= 0) {
+                Log.w(TAG, "Codec did not publish any measurement data.");
+                return null;
+            }
+
+            return estimateFrameRatesFor(width, height);
+        }
+
+        /**
+         * Video performance points are a set of standard performance points defined by number of
+         * pixels, pixel rate and frame rate. Performance point represents an upper bound. This
+         * means that it covers all performance points with fewer pixels, pixel rate and frame
+         * rate.
+         */
+        public static final class PerformancePoint {
+            private Size mBlockSize; // codec block size in macroblocks
+            private int mWidth; // width in macroblocks
+            private int mHeight; // height in macroblocks
+            private int mMaxFrameRate; // max frames per second
+            private long mMaxMacroBlockRate; // max macro block rate
+
+            /**
+             * Maximum number of macroblocks in the frame.
+             *
+             * Video frames are conceptually divided into 16-by-16 pixel blocks called macroblocks.
+             * Most coding standards operate on these 16-by-16 pixel blocks; thus, codec performance
+             * is characterized using such blocks.
+             *
+             * @hide
+             */
+            @TestApi
+            public int getMaxMacroBlocks() {
+                return saturateLongToInt(mWidth * (long)mHeight);
+            }
+
+            /**
+             * Maximum frame rate in frames per second.
+             *
+             * @hide
+             */
+            @TestApi
+            public int getMaxFrameRate() {
+                return mMaxFrameRate;
+            }
+
+            /**
+             * Maximum number of macroblocks processed per second.
+             *
+             * @hide
+             */
+            @TestApi
+            public long getMaxMacroBlockRate() {
+                return mMaxMacroBlockRate;
+            }
+
+            /** Convert to a debug string */
+            public String toString() {
+                int blockWidth = 16 * mBlockSize.getWidth();
+                int blockHeight = 16 * mBlockSize.getHeight();
+                int origRate = (int)Utils.divUp(mMaxMacroBlockRate, getMaxMacroBlocks());
+                String info = (mWidth * 16) + "x" + (mHeight * 16) + "@" + origRate;
+                if (origRate < mMaxFrameRate) {
+                    info += ", max " + mMaxFrameRate + "fps";
+                }
+                if (blockWidth > 16 || blockHeight > 16) {
+                    info += ", " + blockWidth + "x" + blockHeight + " blocks";
+                }
+                return "PerformancePoint(" + info + ")";
+            }
+
+            @Override
+            public int hashCode() {
+                // only max frame rate must equal between performance points that equal to one
+                // another
+                return mMaxFrameRate;
+            }
+
+            /**
+             * Create a detailed performance point with custom max frame rate and macroblock size.
+             *
+             * @param width  frame width in pixels
+             * @param height frame height in pixels
+             * @param frameRate frames per second for frame width and height
+             * @param maxFrameRate maximum frames per second for any frame size
+             * @param blockSize block size for codec implementation. Must be powers of two in both
+             *        width and height.
+             *
+             * @throws IllegalArgumentException if the blockSize dimensions are not powers of two.
+             *
+             * @hide
+             */
+            @TestApi
+            public PerformancePoint(
+                    int width, int height, int frameRate, int maxFrameRate,
+                    @NonNull Size blockSize) {
+                checkPowerOfTwo(blockSize.getWidth(), "block width");
+                checkPowerOfTwo(blockSize.getHeight(), "block height");
+
+                mBlockSize = new Size(Utils.divUp(blockSize.getWidth(), 16),
+                                      Utils.divUp(blockSize.getHeight(), 16));
+                // these are guaranteed not to overflow as we decimate by 16
+                mWidth = (int)(Utils.divUp(Math.max(1L, width),
+                                           Math.max(blockSize.getWidth(), 16))
+                               * mBlockSize.getWidth());
+                mHeight = (int)(Utils.divUp(Math.max(1L, height),
+                                            Math.max(blockSize.getHeight(), 16))
+                                * mBlockSize.getHeight());
+                mMaxFrameRate = Math.max(1, Math.max(frameRate, maxFrameRate));
+                mMaxMacroBlockRate = Math.max(1, frameRate) * getMaxMacroBlocks();
+            }
+
+            /**
+             * Convert a performance point to a larger blocksize.
+             *
+             * @param pp performance point
+             * @param blockSize block size for codec implementation
+             *
+             * @hide
+             */
+            @TestApi
+            public PerformancePoint(@NonNull PerformancePoint pp, @NonNull Size newBlockSize) {
+                this(
+                        pp.mWidth * 16, pp.mHeight * 16,
+                        // guaranteed not to overflow as these were multiplied at construction
+                        (int)Utils.divUp(pp.mMaxMacroBlockRate, pp.getMaxMacroBlocks()),
+                        pp.mMaxFrameRate,
+                        new Size(Math.max(newBlockSize.getWidth(), pp.mBlockSize.getWidth() * 16),
+                                 Math.max(newBlockSize.getHeight(), pp.mBlockSize.getHeight() * 16))
+                );
+            }
+
+            /**
+             * Create a performance point for a given frame size and frame rate.
+             *
+             * @param width width of the frame in pixels
+             * @param height height of the frame in pixels
+             * @param frameRate frame rate in frames per second
+             */
+            public PerformancePoint(int width, int height, int frameRate) {
+                this(width, height, frameRate, frameRate /* maxFrameRate */, new Size(16, 16));
+            }
+
+            /** Saturates a long value to int */
+            private int saturateLongToInt(long value) {
+                if (value < Integer.MIN_VALUE) {
+                    return Integer.MIN_VALUE;
+                } else if (value > Integer.MAX_VALUE) {
+                    return Integer.MAX_VALUE;
+                } else {
+                    return (int)value;
+                }
+            }
+
+            /* This method may overflow */
+            private int align(int value, int alignment) {
+                return Utils.divUp(value, alignment) * alignment;
+            }
+
+            /** Checks that value is a power of two. */
+            private void checkPowerOfTwo2(int value, @NonNull String description) {
+                if (value == 0 || (value & (value - 1)) != 0) {
+                    throw new IllegalArgumentException(
+                            description + " (" + value + ") must be a power of 2");
+                }
+            }
+
+            /**
+             * Checks whether the performance point covers a media format.
+             *
+             * @param format Stream format considered
+             *
+             * @return {@code true} if the performance point covers the format.
+             */
+            public boolean covers(@NonNull MediaFormat format) {
+                PerformancePoint other = new PerformancePoint(
+                        format.getInteger(MediaFormat.KEY_WIDTH, 0),
+                        format.getInteger(MediaFormat.KEY_HEIGHT, 0),
+                        // safely convert ceil(double) to int through float cast and Math.round
+                        Math.round((float)(
+                                Math.ceil(format.getNumber(MediaFormat.KEY_FRAME_RATE, 0)
+                                        .doubleValue()))));
+                return covers(other);
+            }
+
+            /**
+             * Checks whether the performance point covers another performance point. Use this
+             * method to determine if a performance point advertised by a codec covers the
+             * performance point required. This method can also be used for loose ordering as this
+             * method is transitive.
+             *
+             * @param other other performance point considered
+             *
+             * @return {@code true} if the performance point covers the other.
+             */
+            public boolean covers(@NonNull PerformancePoint other) {
+                // convert performance points to common block size
+                Size commonSize = getCommonBlockSize(other);
+                PerformancePoint aligned = new PerformancePoint(this, commonSize);
+                PerformancePoint otherAligned = new PerformancePoint(other, commonSize);
+
+                return (aligned.getMaxMacroBlocks() >= otherAligned.getMaxMacroBlocks()
+                        && aligned.mMaxFrameRate >= otherAligned.mMaxFrameRate
+                        && aligned.mMaxMacroBlockRate >= otherAligned.mMaxMacroBlockRate);
+            }
+
+            private @NonNull Size getCommonBlockSize(@NonNull PerformancePoint other) {
+                return new Size(
+                        Math.max(mBlockSize.getWidth(), other.mBlockSize.getWidth()) * 16,
+                        Math.max(mBlockSize.getHeight(), other.mBlockSize.getHeight()) * 16);
+            }
+
+            @Override
+            public boolean equals(Object o) {
+                if (o instanceof PerformancePoint) {
+                    // convert performance points to common block size
+                    PerformancePoint other = (PerformancePoint)o;
+                    Size commonSize = getCommonBlockSize(other);
+                    PerformancePoint aligned = new PerformancePoint(this, commonSize);
+                    PerformancePoint otherAligned = new PerformancePoint(other, commonSize);
+
+                    return (aligned.getMaxMacroBlocks() == otherAligned.getMaxMacroBlocks()
+                            && aligned.mMaxFrameRate == otherAligned.mMaxFrameRate
+                            && aligned.mMaxMacroBlockRate == otherAligned.mMaxMacroBlockRate);
+                }
+                return false;
+            }
+
+            /** 480p 24fps */
+            @NonNull
+            public static final PerformancePoint SD_24 = new PerformancePoint(720, 480, 24);
+            /** 576p 25fps */
+            @NonNull
+            public static final PerformancePoint SD_25 = new PerformancePoint(720, 576, 25);
+            /** 480p 30fps */
+            @NonNull
+            public static final PerformancePoint SD_30 = new PerformancePoint(720, 480, 30);
+            /** 480p 48fps */
+            @NonNull
+            public static final PerformancePoint SD_48 = new PerformancePoint(720, 480, 48);
+            /** 576p 50fps */
+            @NonNull
+            public static final PerformancePoint SD_50 = new PerformancePoint(720, 576, 50);
+            /** 480p 60fps */
+            @NonNull
+            public static final PerformancePoint SD_60 = new PerformancePoint(720, 480, 60);
+
+            /** 720p 24fps */
+            @NonNull
+            public static final PerformancePoint HD_24 = new PerformancePoint(1280, 720, 24);
+            /** 720p 25fps */
+            @NonNull
+            public static final PerformancePoint HD_25 = new PerformancePoint(1280, 720, 25);
+            /** 720p 30fps */
+            @NonNull
+            public static final PerformancePoint HD_30 = new PerformancePoint(1280, 720, 30);
+            /** 720p 50fps */
+            @NonNull
+            public static final PerformancePoint HD_50 = new PerformancePoint(1280, 720, 50);
+            /** 720p 60fps */
+            @NonNull
+            public static final PerformancePoint HD_60 = new PerformancePoint(1280, 720, 60);
+            /** 720p 100fps */
+            @NonNull
+            public static final PerformancePoint HD_100 = new PerformancePoint(1280, 720, 100);
+            /** 720p 120fps */
+            @NonNull
+            public static final PerformancePoint HD_120 = new PerformancePoint(1280, 720, 120);
+            /** 720p 200fps */
+            @NonNull
+            public static final PerformancePoint HD_200 = new PerformancePoint(1280, 720, 200);
+            /** 720p 240fps */
+            @NonNull
+            public static final PerformancePoint HD_240 = new PerformancePoint(1280, 720, 240);
+
+            /** 1080p 24fps */
+            @NonNull
+            public static final PerformancePoint FHD_24 = new PerformancePoint(1920, 1080, 24);
+            /** 1080p 25fps */
+            @NonNull
+            public static final PerformancePoint FHD_25 = new PerformancePoint(1920, 1080, 25);
+            /** 1080p 30fps */
+            @NonNull
+            public static final PerformancePoint FHD_30 = new PerformancePoint(1920, 1080, 30);
+            /** 1080p 50fps */
+            @NonNull
+            public static final PerformancePoint FHD_50 = new PerformancePoint(1920, 1080, 50);
+            /** 1080p 60fps */
+            @NonNull
+            public static final PerformancePoint FHD_60 = new PerformancePoint(1920, 1080, 60);
+            /** 1080p 100fps */
+            @NonNull
+            public static final PerformancePoint FHD_100 = new PerformancePoint(1920, 1080, 100);
+            /** 1080p 120fps */
+            @NonNull
+            public static final PerformancePoint FHD_120 = new PerformancePoint(1920, 1080, 120);
+            /** 1080p 200fps */
+            @NonNull
+            public static final PerformancePoint FHD_200 = new PerformancePoint(1920, 1080, 200);
+            /** 1080p 240fps */
+            @NonNull
+            public static final PerformancePoint FHD_240 = new PerformancePoint(1920, 1080, 240);
+
+            /** 2160p 24fps */
+            @NonNull
+            public static final PerformancePoint UHD_24 = new PerformancePoint(3840, 2160, 24);
+            /** 2160p 25fps */
+            @NonNull
+            public static final PerformancePoint UHD_25 = new PerformancePoint(3840, 2160, 25);
+            /** 2160p 30fps */
+            @NonNull
+            public static final PerformancePoint UHD_30 = new PerformancePoint(3840, 2160, 30);
+            /** 2160p 50fps */
+            @NonNull
+            public static final PerformancePoint UHD_50 = new PerformancePoint(3840, 2160, 50);
+            /** 2160p 60fps */
+            @NonNull
+            public static final PerformancePoint UHD_60 = new PerformancePoint(3840, 2160, 60);
+            /** 2160p 100fps */
+            @NonNull
+            public static final PerformancePoint UHD_100 = new PerformancePoint(3840, 2160, 100);
+            /** 2160p 120fps */
+            @NonNull
+            public static final PerformancePoint UHD_120 = new PerformancePoint(3840, 2160, 120);
+            /** 2160p 200fps */
+            @NonNull
+            public static final PerformancePoint UHD_200 = new PerformancePoint(3840, 2160, 200);
+            /** 2160p 240fps */
+            @NonNull
+            public static final PerformancePoint UHD_240 = new PerformancePoint(3840, 2160, 240);
+        }
+
+        /**
+         * Returns the supported performance points. May return {@code null} if the codec did not
+         * publish any performance point information (e.g. the vendor codecs have not been updated
+         * to the latest android release). May return an empty list if the codec published that
+         * if does not guarantee any performance points.
+         * <p>
+         * This is a performance guarantee provided by the device manufacturer for hardware codecs
+         * based on hardware capabilities of the device.
+         * <p>
+         * The returned list is sorted first by decreasing number of pixels, then by decreasing
+         * width, and finally by decreasing frame rate.
+         * Performance points assume a single active codec. For use cases where multiple
+         * codecs are active, should use that highest pixel count, and add the frame rates of
+         * each individual codec.
+         * <p class=note>
+         * 32-bit processes will not support resolutions larger than 4096x4096 due to
+         * the limited address space, but performance points will be presented as is.
+         * In other words, even though a component publishes a performance point for
+         * a resolution higher than 4096x4096, it does not mean that the resolution is supported
+         * for 32-bit processes.
+         */
+        @Nullable
+        public List<PerformancePoint> getSupportedPerformancePoints() {
+            return mPerformancePoints;
+        }
+
+        /**
+         * Returns whether a given video size ({@code width} and
+         * {@code height}) and {@code frameRate} combination is supported.
+         */
+        public boolean areSizeAndRateSupported(
+                int width, int height, double frameRate) {
+            return supports(width, height, frameRate);
+        }
+
+        /**
+         * Returns whether a given video size ({@code width} and
+         * {@code height}) is supported.
+         */
+        public boolean isSizeSupported(int width, int height) {
+            return supports(width, height, null);
+        }
+
+        private boolean supports(Integer width, Integer height, Number rate) {
+            boolean ok = true;
+
+            if (ok && width != null) {
+                ok = mWidthRange.contains(width)
+                        && (width % mWidthAlignment == 0);
+            }
+            if (ok && height != null) {
+                ok = mHeightRange.contains(height)
+                        && (height % mHeightAlignment == 0);
+            }
+            if (ok && rate != null) {
+                ok = mFrameRateRange.contains(Utils.intRangeFor(rate.doubleValue()));
+            }
+            if (ok && height != null && width != null) {
+                ok = Math.min(height, width) <= mSmallerDimensionUpperLimit;
+
+                final int widthInBlocks = Utils.divUp(width, mBlockWidth);
+                final int heightInBlocks = Utils.divUp(height, mBlockHeight);
+                final int blockCount = widthInBlocks * heightInBlocks;
+                ok = ok && mBlockCountRange.contains(blockCount)
+                        && mBlockAspectRatioRange.contains(
+                                new Rational(widthInBlocks, heightInBlocks))
+                        && mAspectRatioRange.contains(new Rational(width, height));
+                if (ok && rate != null) {
+                    double blocksPerSec = blockCount * rate.doubleValue();
+                    ok = mBlocksPerSecondRange.contains(
+                            Utils.longRangeFor(blocksPerSec));
+                }
+            }
+            return ok;
+        }
+
+        /**
+         * @hide
+         * @throws java.lang.ClassCastException */
+        public boolean supportsFormat(MediaFormat format) {
+            final Map<String, Object> map = format.getMap();
+            Integer width = (Integer)map.get(MediaFormat.KEY_WIDTH);
+            Integer height = (Integer)map.get(MediaFormat.KEY_HEIGHT);
+            Number rate = (Number)map.get(MediaFormat.KEY_FRAME_RATE);
+
+            if (!supports(width, height, rate)) {
+                return false;
+            }
+
+            if (!CodecCapabilities.supportsBitrate(mBitrateRange, format)) {
+                return false;
+            }
+
+            // we ignore color-format for now as it is not reliably reported by codec
+            return true;
+        }
+
+        /* no public constructor */
+        private VideoCapabilities() { }
+
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+        public static VideoCapabilities create(
+                MediaFormat info, CodecCapabilities parent) {
+            VideoCapabilities caps = new VideoCapabilities();
+            caps.init(info, parent);
+            return caps;
+        }
+
+        private void init(MediaFormat info, CodecCapabilities parent) {
+            mParent = parent;
+            initWithPlatformLimits();
+            applyLevelLimits();
+            parseFromInfo(info);
+            updateLimits();
+        }
+
+        /** @hide */
+        public Size getBlockSize() {
+            return new Size(mBlockWidth, mBlockHeight);
+        }
+
+        /** @hide */
+        public Range<Integer> getBlockCountRange() {
+            return mBlockCountRange;
+        }
+
+        /** @hide */
+        public Range<Long> getBlocksPerSecondRange() {
+            return mBlocksPerSecondRange;
+        }
+
+        /** @hide */
+        public Range<Rational> getAspectRatioRange(boolean blocks) {
+            return blocks ? mBlockAspectRatioRange : mAspectRatioRange;
+        }
+
+        private void initWithPlatformLimits() {
+            mBitrateRange = BITRATE_RANGE;
+
+            mWidthRange  = SIZE_RANGE;
+            mHeightRange = SIZE_RANGE;
+            mFrameRateRange = FRAME_RATE_RANGE;
+
+            mHorizontalBlockRange = SIZE_RANGE;
+            mVerticalBlockRange   = SIZE_RANGE;
+
+            // full positive ranges are supported as these get calculated
+            mBlockCountRange      = POSITIVE_INTEGERS;
+            mBlocksPerSecondRange = POSITIVE_LONGS;
+
+            mBlockAspectRatioRange = POSITIVE_RATIONALS;
+            mAspectRatioRange      = POSITIVE_RATIONALS;
+
+            // YUV 4:2:0 requires 2:2 alignment
+            mWidthAlignment = 2;
+            mHeightAlignment = 2;
+            mBlockWidth = 2;
+            mBlockHeight = 2;
+            mSmallerDimensionUpperLimit = SIZE_RANGE.getUpper();
+        }
+
+        private @Nullable List<PerformancePoint> getPerformancePoints(Map<String, Object> map) {
+            Vector<PerformancePoint> ret = new Vector<>();
+            final String prefix = "performance-point-";
+            Set<String> keys = map.keySet();
+            for (String key : keys) {
+                // looking for: performance-point-WIDTHxHEIGHT-range
+                if (!key.startsWith(prefix)) {
+                    continue;
+                }
+                String subKey = key.substring(prefix.length());
+                if (subKey.equals("none") && ret.size() == 0) {
+                    // This means that component knowingly did not publish performance points.
+                    // This is different from when the component forgot to publish performance
+                    // points.
+                    return Collections.unmodifiableList(ret);
+                }
+                String[] temp = key.split("-");
+                if (temp.length != 4) {
+                    continue;
+                }
+                String sizeStr = temp[2];
+                Size size = Utils.parseSize(sizeStr, null);
+                if (size == null || size.getWidth() * size.getHeight() <= 0) {
+                    continue;
+                }
+                if (size.getWidth() > SIZE_RANGE.getUpper()
+                        || size.getHeight() > SIZE_RANGE.getUpper()) {
+                    size = new Size(
+                            Math.min(size.getWidth(), SIZE_RANGE.getUpper()),
+                            Math.min(size.getHeight(), SIZE_RANGE.getUpper()));
+                }
+                Range<Long> range = Utils.parseLongRange(map.get(key), null);
+                if (range == null || range.getLower() < 0 || range.getUpper() < 0) {
+                    continue;
+                }
+                PerformancePoint given = new PerformancePoint(
+                        size.getWidth(), size.getHeight(), range.getLower().intValue(),
+                        range.getUpper().intValue(), new Size(mBlockWidth, mBlockHeight));
+                PerformancePoint rotated = new PerformancePoint(
+                        size.getHeight(), size.getWidth(), range.getLower().intValue(),
+                        range.getUpper().intValue(), new Size(mBlockWidth, mBlockHeight));
+                ret.add(given);
+                if (!given.covers(rotated)) {
+                    ret.add(rotated);
+                }
+            }
+
+            // check if the component specified no performance point indication
+            if (ret.size() == 0) {
+                return null;
+            }
+
+            // sort reversed by area first, then by frame rate
+            ret.sort((a, b) ->
+                     -((a.getMaxMacroBlocks() != b.getMaxMacroBlocks()) ?
+                               (a.getMaxMacroBlocks() < b.getMaxMacroBlocks() ? -1 : 1) :
+                       (a.getMaxMacroBlockRate() != b.getMaxMacroBlockRate()) ?
+                               (a.getMaxMacroBlockRate() < b.getMaxMacroBlockRate() ? -1 : 1) :
+                       (a.getMaxFrameRate() != b.getMaxFrameRate()) ?
+                               (a.getMaxFrameRate() < b.getMaxFrameRate() ? -1 : 1) : 0));
+
+            return Collections.unmodifiableList(ret);
+        }
+
+        private Map<Size, Range<Long>> getMeasuredFrameRates(Map<String, Object> map) {
+            Map<Size, Range<Long>> ret = new HashMap<Size, Range<Long>>();
+            final String prefix = "measured-frame-rate-";
+            Set<String> keys = map.keySet();
+            for (String key : keys) {
+                // looking for: measured-frame-rate-WIDTHxHEIGHT-range
+                if (!key.startsWith(prefix)) {
+                    continue;
+                }
+                String subKey = key.substring(prefix.length());
+                String[] temp = key.split("-");
+                if (temp.length != 5) {
+                    continue;
+                }
+                String sizeStr = temp[3];
+                Size size = Utils.parseSize(sizeStr, null);
+                if (size == null || size.getWidth() * size.getHeight() <= 0) {
+                    continue;
+                }
+                Range<Long> range = Utils.parseLongRange(map.get(key), null);
+                if (range == null || range.getLower() < 0 || range.getUpper() < 0) {
+                    continue;
+                }
+                ret.put(size, range);
+            }
+            return ret;
+        }
+
+        private static Pair<Range<Integer>, Range<Integer>> parseWidthHeightRanges(Object o) {
+            Pair<Size, Size> range = Utils.parseSizeRange(o);
+            if (range != null) {
+                try {
+                    return Pair.create(
+                            Range.create(range.first.getWidth(), range.second.getWidth()),
+                            Range.create(range.first.getHeight(), range.second.getHeight()));
+                } catch (IllegalArgumentException e) {
+                    Log.w(TAG, "could not parse size range '" + o + "'");
+                }
+            }
+            return null;
+        }
+
+        /** @hide */
+        public static int equivalentVP9Level(MediaFormat info) {
+            final Map<String, Object> map = info.getMap();
+
+            Size blockSize = Utils.parseSize(map.get("block-size"), new Size(8, 8));
+            int BS = blockSize.getWidth() * blockSize.getHeight();
+
+            Range<Integer> counts = Utils.parseIntRange(map.get("block-count-range"), null);
+            int FS = counts == null ? 0 : BS * counts.getUpper();
+
+            Range<Long> blockRates =
+                Utils.parseLongRange(map.get("blocks-per-second-range"), null);
+            long SR = blockRates == null ? 0 : BS * blockRates.getUpper();
+
+            Pair<Range<Integer>, Range<Integer>> dimensionRanges =
+                parseWidthHeightRanges(map.get("size-range"));
+            int D = dimensionRanges == null ? 0 : Math.max(
+                    dimensionRanges.first.getUpper(), dimensionRanges.second.getUpper());
+
+            Range<Integer> bitRates = Utils.parseIntRange(map.get("bitrate-range"), null);
+            int BR = bitRates == null ? 0 : Utils.divUp(bitRates.getUpper(), 1000);
+
+            if (SR <=      829440 && FS <=    36864 && BR <=    200 && D <=   512)
+                return CodecProfileLevel.VP9Level1;
+            if (SR <=     2764800 && FS <=    73728 && BR <=    800 && D <=   768)
+                return CodecProfileLevel.VP9Level11;
+            if (SR <=     4608000 && FS <=   122880 && BR <=   1800 && D <=   960)
+                return CodecProfileLevel.VP9Level2;
+            if (SR <=     9216000 && FS <=   245760 && BR <=   3600 && D <=  1344)
+                return CodecProfileLevel.VP9Level21;
+            if (SR <=    20736000 && FS <=   552960 && BR <=   7200 && D <=  2048)
+                return CodecProfileLevel.VP9Level3;
+            if (SR <=    36864000 && FS <=   983040 && BR <=  12000 && D <=  2752)
+                return CodecProfileLevel.VP9Level31;
+            if (SR <=    83558400 && FS <=  2228224 && BR <=  18000 && D <=  4160)
+                return CodecProfileLevel.VP9Level4;
+            if (SR <=   160432128 && FS <=  2228224 && BR <=  30000 && D <=  4160)
+                return CodecProfileLevel.VP9Level41;
+            if (SR <=   311951360 && FS <=  8912896 && BR <=  60000 && D <=  8384)
+                return CodecProfileLevel.VP9Level5;
+            if (SR <=   588251136 && FS <=  8912896 && BR <= 120000 && D <=  8384)
+                return CodecProfileLevel.VP9Level51;
+            if (SR <=  1176502272 && FS <=  8912896 && BR <= 180000 && D <=  8384)
+                return CodecProfileLevel.VP9Level52;
+            if (SR <=  1176502272 && FS <= 35651584 && BR <= 180000 && D <= 16832)
+                return CodecProfileLevel.VP9Level6;
+            if (SR <= 2353004544L && FS <= 35651584 && BR <= 240000 && D <= 16832)
+                return CodecProfileLevel.VP9Level61;
+            if (SR <= 4706009088L && FS <= 35651584 && BR <= 480000 && D <= 16832)
+                return CodecProfileLevel.VP9Level62;
+            // returning largest level
+            return CodecProfileLevel.VP9Level62;
+        }
+
+        private void parseFromInfo(MediaFormat info) {
+            final Map<String, Object> map = info.getMap();
+            Size blockSize = new Size(mBlockWidth, mBlockHeight);
+            Size alignment = new Size(mWidthAlignment, mHeightAlignment);
+            Range<Integer> counts = null, widths = null, heights = null;
+            Range<Integer> frameRates = null, bitRates = null;
+            Range<Long> blockRates = null;
+            Range<Rational> ratios = null, blockRatios = null;
+
+            blockSize = Utils.parseSize(map.get("block-size"), blockSize);
+            alignment = Utils.parseSize(map.get("alignment"), alignment);
+            counts = Utils.parseIntRange(map.get("block-count-range"), null);
+            blockRates =
+                Utils.parseLongRange(map.get("blocks-per-second-range"), null);
+            mMeasuredFrameRates = getMeasuredFrameRates(map);
+            mPerformancePoints = getPerformancePoints(map);
+            Pair<Range<Integer>, Range<Integer>> sizeRanges =
+                parseWidthHeightRanges(map.get("size-range"));
+            if (sizeRanges != null) {
+                widths = sizeRanges.first;
+                heights = sizeRanges.second;
+            }
+            // for now this just means using the smaller max size as 2nd
+            // upper limit.
+            // for now we are keeping the profile specific "width/height
+            // in macroblocks" limits.
+            if (map.containsKey("feature-can-swap-width-height")) {
+                if (widths != null) {
+                    mSmallerDimensionUpperLimit =
+                        Math.min(widths.getUpper(), heights.getUpper());
+                    widths = heights = widths.extend(heights);
+                } else {
+                    Log.w(TAG, "feature can-swap-width-height is best used with size-range");
+                    mSmallerDimensionUpperLimit =
+                        Math.min(mWidthRange.getUpper(), mHeightRange.getUpper());
+                    mWidthRange = mHeightRange = mWidthRange.extend(mHeightRange);
+                }
+            }
+
+            ratios = Utils.parseRationalRange(
+                    map.get("block-aspect-ratio-range"), null);
+            blockRatios = Utils.parseRationalRange(
+                    map.get("pixel-aspect-ratio-range"), null);
+            frameRates = Utils.parseIntRange(map.get("frame-rate-range"), null);
+            if (frameRates != null) {
+                try {
+                    frameRates = frameRates.intersect(FRAME_RATE_RANGE);
+                } catch (IllegalArgumentException e) {
+                    Log.w(TAG, "frame rate range (" + frameRates
+                            + ") is out of limits: " + FRAME_RATE_RANGE);
+                    frameRates = null;
+                }
+            }
+            bitRates = Utils.parseIntRange(map.get("bitrate-range"), null);
+            if (bitRates != null) {
+                try {
+                    bitRates = bitRates.intersect(BITRATE_RANGE);
+                } catch (IllegalArgumentException e) {
+                    Log.w(TAG,  "bitrate range (" + bitRates
+                            + ") is out of limits: " + BITRATE_RANGE);
+                    bitRates = null;
+                }
+            }
+
+            checkPowerOfTwo(
+                    blockSize.getWidth(), "block-size width must be power of two");
+            checkPowerOfTwo(
+                    blockSize.getHeight(), "block-size height must be power of two");
+
+            checkPowerOfTwo(
+                    alignment.getWidth(), "alignment width must be power of two");
+            checkPowerOfTwo(
+                    alignment.getHeight(), "alignment height must be power of two");
+
+            // update block-size and alignment
+            applyMacroBlockLimits(
+                    Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE,
+                    Long.MAX_VALUE, blockSize.getWidth(), blockSize.getHeight(),
+                    alignment.getWidth(), alignment.getHeight());
+
+            if ((mParent.mError & ERROR_UNSUPPORTED) != 0 || mAllowMbOverride) {
+                // codec supports profiles that we don't know.
+                // Use supplied values clipped to platform limits
+                if (widths != null) {
+                    mWidthRange = SIZE_RANGE.intersect(widths);
+                }
+                if (heights != null) {
+                    mHeightRange = SIZE_RANGE.intersect(heights);
+                }
+                if (counts != null) {
+                    mBlockCountRange = POSITIVE_INTEGERS.intersect(
+                            Utils.factorRange(counts, mBlockWidth * mBlockHeight
+                                    / blockSize.getWidth() / blockSize.getHeight()));
+                }
+                if (blockRates != null) {
+                    mBlocksPerSecondRange = POSITIVE_LONGS.intersect(
+                            Utils.factorRange(blockRates, mBlockWidth * mBlockHeight
+                                    / blockSize.getWidth() / blockSize.getHeight()));
+                }
+                if (blockRatios != null) {
+                    mBlockAspectRatioRange = POSITIVE_RATIONALS.intersect(
+                            Utils.scaleRange(blockRatios,
+                                    mBlockHeight / blockSize.getHeight(),
+                                    mBlockWidth / blockSize.getWidth()));
+                }
+                if (ratios != null) {
+                    mAspectRatioRange = POSITIVE_RATIONALS.intersect(ratios);
+                }
+                if (frameRates != null) {
+                    mFrameRateRange = FRAME_RATE_RANGE.intersect(frameRates);
+                }
+                if (bitRates != null) {
+                    // only allow bitrate override if unsupported profiles were encountered
+                    if ((mParent.mError & ERROR_UNSUPPORTED) != 0) {
+                        mBitrateRange = BITRATE_RANGE.intersect(bitRates);
+                    } else {
+                        mBitrateRange = mBitrateRange.intersect(bitRates);
+                    }
+                }
+            } else {
+                // no unsupported profile/levels, so restrict values to known limits
+                if (widths != null) {
+                    mWidthRange = mWidthRange.intersect(widths);
+                }
+                if (heights != null) {
+                    mHeightRange = mHeightRange.intersect(heights);
+                }
+                if (counts != null) {
+                    mBlockCountRange = mBlockCountRange.intersect(
+                            Utils.factorRange(counts, mBlockWidth * mBlockHeight
+                                    / blockSize.getWidth() / blockSize.getHeight()));
+                }
+                if (blockRates != null) {
+                    mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(
+                            Utils.factorRange(blockRates, mBlockWidth * mBlockHeight
+                                    / blockSize.getWidth() / blockSize.getHeight()));
+                }
+                if (blockRatios != null) {
+                    mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(
+                            Utils.scaleRange(blockRatios,
+                                    mBlockHeight / blockSize.getHeight(),
+                                    mBlockWidth / blockSize.getWidth()));
+                }
+                if (ratios != null) {
+                    mAspectRatioRange = mAspectRatioRange.intersect(ratios);
+                }
+                if (frameRates != null) {
+                    mFrameRateRange = mFrameRateRange.intersect(frameRates);
+                }
+                if (bitRates != null) {
+                    mBitrateRange = mBitrateRange.intersect(bitRates);
+                }
+            }
+            updateLimits();
+        }
+
+        private void applyBlockLimits(
+                int blockWidth, int blockHeight,
+                Range<Integer> counts, Range<Long> rates, Range<Rational> ratios) {
+            checkPowerOfTwo(blockWidth, "blockWidth must be a power of two");
+            checkPowerOfTwo(blockHeight, "blockHeight must be a power of two");
+
+            final int newBlockWidth = Math.max(blockWidth, mBlockWidth);
+            final int newBlockHeight = Math.max(blockHeight, mBlockHeight);
+
+            // factor will always be a power-of-2
+            int factor =
+                newBlockWidth * newBlockHeight / mBlockWidth / mBlockHeight;
+            if (factor != 1) {
+                mBlockCountRange = Utils.factorRange(mBlockCountRange, factor);
+                mBlocksPerSecondRange = Utils.factorRange(
+                        mBlocksPerSecondRange, factor);
+                mBlockAspectRatioRange = Utils.scaleRange(
+                        mBlockAspectRatioRange,
+                        newBlockHeight / mBlockHeight,
+                        newBlockWidth / mBlockWidth);
+                mHorizontalBlockRange = Utils.factorRange(
+                        mHorizontalBlockRange, newBlockWidth / mBlockWidth);
+                mVerticalBlockRange = Utils.factorRange(
+                        mVerticalBlockRange, newBlockHeight / mBlockHeight);
+            }
+            factor = newBlockWidth * newBlockHeight / blockWidth / blockHeight;
+            if (factor != 1) {
+                counts = Utils.factorRange(counts, factor);
+                rates = Utils.factorRange(rates, factor);
+                ratios = Utils.scaleRange(
+                        ratios, newBlockHeight / blockHeight,
+                        newBlockWidth / blockWidth);
+            }
+            mBlockCountRange = mBlockCountRange.intersect(counts);
+            mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(rates);
+            mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(ratios);
+            mBlockWidth = newBlockWidth;
+            mBlockHeight = newBlockHeight;
+        }
+
+        private void applyAlignment(int widthAlignment, int heightAlignment) {
+            checkPowerOfTwo(widthAlignment, "widthAlignment must be a power of two");
+            checkPowerOfTwo(heightAlignment, "heightAlignment must be a power of two");
+
+            if (widthAlignment > mBlockWidth || heightAlignment > mBlockHeight) {
+                // maintain assumption that 0 < alignment <= block-size
+                applyBlockLimits(
+                        Math.max(widthAlignment, mBlockWidth),
+                        Math.max(heightAlignment, mBlockHeight),
+                        POSITIVE_INTEGERS, POSITIVE_LONGS, POSITIVE_RATIONALS);
+            }
+
+            mWidthAlignment = Math.max(widthAlignment, mWidthAlignment);
+            mHeightAlignment = Math.max(heightAlignment, mHeightAlignment);
+
+            mWidthRange = Utils.alignRange(mWidthRange, mWidthAlignment);
+            mHeightRange = Utils.alignRange(mHeightRange, mHeightAlignment);
+        }
+
+        private void updateLimits() {
+            // pixels -> blocks <- counts
+            mHorizontalBlockRange = mHorizontalBlockRange.intersect(
+                    Utils.factorRange(mWidthRange, mBlockWidth));
+            mHorizontalBlockRange = mHorizontalBlockRange.intersect(
+                    Range.create(
+                            mBlockCountRange.getLower() / mVerticalBlockRange.getUpper(),
+                            mBlockCountRange.getUpper() / mVerticalBlockRange.getLower()));
+            mVerticalBlockRange = mVerticalBlockRange.intersect(
+                    Utils.factorRange(mHeightRange, mBlockHeight));
+            mVerticalBlockRange = mVerticalBlockRange.intersect(
+                    Range.create(
+                            mBlockCountRange.getLower() / mHorizontalBlockRange.getUpper(),
+                            mBlockCountRange.getUpper() / mHorizontalBlockRange.getLower()));
+            mBlockCountRange = mBlockCountRange.intersect(
+                    Range.create(
+                            mHorizontalBlockRange.getLower()
+                                    * mVerticalBlockRange.getLower(),
+                            mHorizontalBlockRange.getUpper()
+                                    * mVerticalBlockRange.getUpper()));
+            mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(
+                    new Rational(
+                            mHorizontalBlockRange.getLower(), mVerticalBlockRange.getUpper()),
+                    new Rational(
+                            mHorizontalBlockRange.getUpper(), mVerticalBlockRange.getLower()));
+
+            // blocks -> pixels
+            mWidthRange = mWidthRange.intersect(
+                    (mHorizontalBlockRange.getLower() - 1) * mBlockWidth + mWidthAlignment,
+                    mHorizontalBlockRange.getUpper() * mBlockWidth);
+            mHeightRange = mHeightRange.intersect(
+                    (mVerticalBlockRange.getLower() - 1) * mBlockHeight + mHeightAlignment,
+                    mVerticalBlockRange.getUpper() * mBlockHeight);
+            mAspectRatioRange = mAspectRatioRange.intersect(
+                    new Rational(mWidthRange.getLower(), mHeightRange.getUpper()),
+                    new Rational(mWidthRange.getUpper(), mHeightRange.getLower()));
+
+            mSmallerDimensionUpperLimit = Math.min(
+                    mSmallerDimensionUpperLimit,
+                    Math.min(mWidthRange.getUpper(), mHeightRange.getUpper()));
+
+            // blocks -> rate
+            mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(
+                    mBlockCountRange.getLower() * (long)mFrameRateRange.getLower(),
+                    mBlockCountRange.getUpper() * (long)mFrameRateRange.getUpper());
+            mFrameRateRange = mFrameRateRange.intersect(
+                    (int)(mBlocksPerSecondRange.getLower()
+                            / mBlockCountRange.getUpper()),
+                    (int)(mBlocksPerSecondRange.getUpper()
+                            / (double)mBlockCountRange.getLower()));
+        }
+
+        private void applyMacroBlockLimits(
+                int maxHorizontalBlocks, int maxVerticalBlocks,
+                int maxBlocks, long maxBlocksPerSecond,
+                int blockWidth, int blockHeight,
+                int widthAlignment, int heightAlignment) {
+            applyMacroBlockLimits(
+                    1 /* minHorizontalBlocks */, 1 /* minVerticalBlocks */,
+                    maxHorizontalBlocks, maxVerticalBlocks,
+                    maxBlocks, maxBlocksPerSecond,
+                    blockWidth, blockHeight, widthAlignment, heightAlignment);
+        }
+
+        private void applyMacroBlockLimits(
+                int minHorizontalBlocks, int minVerticalBlocks,
+                int maxHorizontalBlocks, int maxVerticalBlocks,
+                int maxBlocks, long maxBlocksPerSecond,
+                int blockWidth, int blockHeight,
+                int widthAlignment, int heightAlignment) {
+            applyAlignment(widthAlignment, heightAlignment);
+            applyBlockLimits(
+                    blockWidth, blockHeight, Range.create(1, maxBlocks),
+                    Range.create(1L, maxBlocksPerSecond),
+                    Range.create(
+                            new Rational(1, maxVerticalBlocks),
+                            new Rational(maxHorizontalBlocks, 1)));
+            mHorizontalBlockRange =
+                    mHorizontalBlockRange.intersect(
+                            Utils.divUp(minHorizontalBlocks, (mBlockWidth / blockWidth)),
+                            maxHorizontalBlocks / (mBlockWidth / blockWidth));
+            mVerticalBlockRange =
+                    mVerticalBlockRange.intersect(
+                            Utils.divUp(minVerticalBlocks, (mBlockHeight / blockHeight)),
+                            maxVerticalBlocks / (mBlockHeight / blockHeight));
+        }
+
+        private void applyLevelLimits() {
+            long maxBlocksPerSecond = 0;
+            int maxBlocks = 0;
+            int maxBps = 0;
+            int maxDPBBlocks = 0;
+
+            int errors = ERROR_NONE_SUPPORTED;
+            CodecProfileLevel[] profileLevels = mParent.profileLevels;
+            String mime = mParent.getMimeType();
+
+            if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AVC)) {
+                maxBlocks = 99;
+                maxBlocksPerSecond = 1485;
+                maxBps = 64000;
+                maxDPBBlocks = 396;
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    int MBPS = 0, FS = 0, BR = 0, DPB = 0;
+                    boolean supported = true;
+                    switch (profileLevel.level) {
+                        case CodecProfileLevel.AVCLevel1:
+                            MBPS =     1485; FS =     99; BR =     64; DPB =    396; break;
+                        case CodecProfileLevel.AVCLevel1b:
+                            MBPS =     1485; FS =     99; BR =    128; DPB =    396; break;
+                        case CodecProfileLevel.AVCLevel11:
+                            MBPS =     3000; FS =    396; BR =    192; DPB =    900; break;
+                        case CodecProfileLevel.AVCLevel12:
+                            MBPS =     6000; FS =    396; BR =    384; DPB =   2376; break;
+                        case CodecProfileLevel.AVCLevel13:
+                            MBPS =    11880; FS =    396; BR =    768; DPB =   2376; break;
+                        case CodecProfileLevel.AVCLevel2:
+                            MBPS =    11880; FS =    396; BR =   2000; DPB =   2376; break;
+                        case CodecProfileLevel.AVCLevel21:
+                            MBPS =    19800; FS =    792; BR =   4000; DPB =   4752; break;
+                        case CodecProfileLevel.AVCLevel22:
+                            MBPS =    20250; FS =   1620; BR =   4000; DPB =   8100; break;
+                        case CodecProfileLevel.AVCLevel3:
+                            MBPS =    40500; FS =   1620; BR =  10000; DPB =   8100; break;
+                        case CodecProfileLevel.AVCLevel31:
+                            MBPS =   108000; FS =   3600; BR =  14000; DPB =  18000; break;
+                        case CodecProfileLevel.AVCLevel32:
+                            MBPS =   216000; FS =   5120; BR =  20000; DPB =  20480; break;
+                        case CodecProfileLevel.AVCLevel4:
+                            MBPS =   245760; FS =   8192; BR =  20000; DPB =  32768; break;
+                        case CodecProfileLevel.AVCLevel41:
+                            MBPS =   245760; FS =   8192; BR =  50000; DPB =  32768; break;
+                        case CodecProfileLevel.AVCLevel42:
+                            MBPS =   522240; FS =   8704; BR =  50000; DPB =  34816; break;
+                        case CodecProfileLevel.AVCLevel5:
+                            MBPS =   589824; FS =  22080; BR = 135000; DPB = 110400; break;
+                        case CodecProfileLevel.AVCLevel51:
+                            MBPS =   983040; FS =  36864; BR = 240000; DPB = 184320; break;
+                        case CodecProfileLevel.AVCLevel52:
+                            MBPS =  2073600; FS =  36864; BR = 240000; DPB = 184320; break;
+                        case CodecProfileLevel.AVCLevel6:
+                            MBPS =  4177920; FS = 139264; BR = 240000; DPB = 696320; break;
+                        case CodecProfileLevel.AVCLevel61:
+                            MBPS =  8355840; FS = 139264; BR = 480000; DPB = 696320; break;
+                        case CodecProfileLevel.AVCLevel62:
+                            MBPS = 16711680; FS = 139264; BR = 800000; DPB = 696320; break;
+                        default:
+                            Log.w(TAG, "Unrecognized level "
+                                    + profileLevel.level + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.AVCProfileConstrainedHigh:
+                        case CodecProfileLevel.AVCProfileHigh:
+                            BR *= 1250; break;
+                        case CodecProfileLevel.AVCProfileHigh10:
+                            BR *= 3000; break;
+                        case CodecProfileLevel.AVCProfileExtended:
+                        case CodecProfileLevel.AVCProfileHigh422:
+                        case CodecProfileLevel.AVCProfileHigh444:
+                            Log.w(TAG, "Unsupported profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNSUPPORTED;
+                            supported = false;
+                            // fall through - treat as base profile
+                        case CodecProfileLevel.AVCProfileConstrainedBaseline:
+                        case CodecProfileLevel.AVCProfileBaseline:
+                        case CodecProfileLevel.AVCProfileMain:
+                            BR *= 1000; break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                            BR *= 1000;
+                    }
+                    if (supported) {
+                        errors &= ~ERROR_NONE_SUPPORTED;
+                    }
+                    maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
+                    maxBlocks = Math.max(FS, maxBlocks);
+                    maxBps = Math.max(BR, maxBps);
+                    maxDPBBlocks = Math.max(maxDPBBlocks, DPB);
+                }
+
+                int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8));
+                applyMacroBlockLimits(
+                        maxLengthInBlocks, maxLengthInBlocks,
+                        maxBlocks, maxBlocksPerSecond,
+                        16 /* blockWidth */, 16 /* blockHeight */,
+                        1 /* widthAlignment */, 1 /* heightAlignment */);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG2)) {
+                int maxWidth = 11, maxHeight = 9, maxRate = 15;
+                maxBlocks = 99;
+                maxBlocksPerSecond = 1485;
+                maxBps = 64000;
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    int MBPS = 0, FS = 0, BR = 0, FR = 0, W = 0, H = 0;
+                    boolean supported = true;
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.MPEG2ProfileSimple:
+                            switch (profileLevel.level) {
+                                case CodecProfileLevel.MPEG2LevelML:
+                                    FR = 30; W = 45; H =  36; MBPS =  40500; FS =  1620; BR =  15000; break;
+                                default:
+                                    Log.w(TAG, "Unrecognized profile/level "
+                                            + profileLevel.profile + "/"
+                                            + profileLevel.level + " for " + mime);
+                                    errors |= ERROR_UNRECOGNIZED;
+                            }
+                            break;
+                        case CodecProfileLevel.MPEG2ProfileMain:
+                            switch (profileLevel.level) {
+                                case CodecProfileLevel.MPEG2LevelLL:
+                                    FR = 30; W = 22; H =  18; MBPS =  11880; FS =   396; BR =  4000; break;
+                                case CodecProfileLevel.MPEG2LevelML:
+                                    FR = 30; W = 45; H =  36; MBPS =  40500; FS =  1620; BR = 15000; break;
+                                case CodecProfileLevel.MPEG2LevelH14:
+                                    FR = 60; W = 90; H =  68; MBPS = 183600; FS =  6120; BR = 60000; break;
+                                case CodecProfileLevel.MPEG2LevelHL:
+                                    FR = 60; W = 120; H = 68; MBPS = 244800; FS =  8160; BR = 80000; break;
+                                case CodecProfileLevel.MPEG2LevelHP:
+                                    FR = 60; W = 120; H = 68; MBPS = 489600; FS =  8160; BR = 80000; break;
+                                default:
+                                    Log.w(TAG, "Unrecognized profile/level "
+                                            + profileLevel.profile + "/"
+                                            + profileLevel.level + " for " + mime);
+                                    errors |= ERROR_UNRECOGNIZED;
+                            }
+                            break;
+                        case CodecProfileLevel.MPEG2Profile422:
+                        case CodecProfileLevel.MPEG2ProfileSNR:
+                        case CodecProfileLevel.MPEG2ProfileSpatial:
+                        case CodecProfileLevel.MPEG2ProfileHigh:
+                            Log.i(TAG, "Unsupported profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNSUPPORTED;
+                            supported = false;
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    if (supported) {
+                        errors &= ~ERROR_NONE_SUPPORTED;
+                    }
+                    maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
+                    maxBlocks = Math.max(FS, maxBlocks);
+                    maxBps = Math.max(BR * 1000, maxBps);
+                    maxWidth = Math.max(W, maxWidth);
+                    maxHeight = Math.max(H, maxHeight);
+                    maxRate = Math.max(FR, maxRate);
+                }
+                applyMacroBlockLimits(maxWidth, maxHeight,
+                        maxBlocks, maxBlocksPerSecond,
+                        16 /* blockWidth */, 16 /* blockHeight */,
+                        1 /* widthAlignment */, 1 /* heightAlignment */);
+                mFrameRateRange = mFrameRateRange.intersect(12, maxRate);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG4)) {
+                int maxWidth = 11, maxHeight = 9, maxRate = 15;
+                maxBlocks = 99;
+                maxBlocksPerSecond = 1485;
+                maxBps = 64000;
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    int MBPS = 0, FS = 0, BR = 0, FR = 0, W = 0, H = 0;
+                    boolean strict = false; // true: W, H and FR are individual max limits
+                    boolean supported = true;
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.MPEG4ProfileSimple:
+                            switch (profileLevel.level) {
+                                case CodecProfileLevel.MPEG4Level0:
+                                    strict = true;
+                                    FR = 15; W = 11; H =  9; MBPS =  1485; FS =  99; BR =  64; break;
+                                case CodecProfileLevel.MPEG4Level1:
+                                    FR = 30; W = 11; H =  9; MBPS =  1485; FS =  99; BR =  64; break;
+                                case CodecProfileLevel.MPEG4Level0b:
+                                    strict = true;
+                                    FR = 15; W = 11; H =  9; MBPS =  1485; FS =  99; BR = 128; break;
+                                case CodecProfileLevel.MPEG4Level2:
+                                    FR = 30; W = 22; H = 18; MBPS =  5940; FS = 396; BR = 128; break;
+                                case CodecProfileLevel.MPEG4Level3:
+                                    FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 384; break;
+                                case CodecProfileLevel.MPEG4Level4a:
+                                    FR = 30; W = 40; H = 30; MBPS = 36000; FS = 1200; BR = 4000; break;
+                                case CodecProfileLevel.MPEG4Level5:
+                                    FR = 30; W = 45; H = 36; MBPS = 40500; FS = 1620; BR = 8000; break;
+                                case CodecProfileLevel.MPEG4Level6:
+                                    FR = 30; W = 80; H = 45; MBPS = 108000; FS = 3600; BR = 12000; break;
+                                default:
+                                    Log.w(TAG, "Unrecognized profile/level "
+                                            + profileLevel.profile + "/"
+                                            + profileLevel.level + " for " + mime);
+                                    errors |= ERROR_UNRECOGNIZED;
+                            }
+                            break;
+                        case CodecProfileLevel.MPEG4ProfileAdvancedSimple:
+                            switch (profileLevel.level) {
+                                case CodecProfileLevel.MPEG4Level0:
+                                case CodecProfileLevel.MPEG4Level1:
+                                    FR = 30; W = 11; H =  9; MBPS =  2970; FS =   99; BR =  128; break;
+                                case CodecProfileLevel.MPEG4Level2:
+                                    FR = 30; W = 22; H = 18; MBPS =  5940; FS =  396; BR =  384; break;
+                                case CodecProfileLevel.MPEG4Level3:
+                                    FR = 30; W = 22; H = 18; MBPS = 11880; FS =  396; BR =  768; break;
+                                case CodecProfileLevel.MPEG4Level3b:
+                                    FR = 30; W = 22; H = 18; MBPS = 11880; FS =  396; BR = 1500; break;
+                                case CodecProfileLevel.MPEG4Level4:
+                                    FR = 30; W = 44; H = 36; MBPS = 23760; FS =  792; BR = 3000; break;
+                                case CodecProfileLevel.MPEG4Level5:
+                                    FR = 30; W = 45; H = 36; MBPS = 48600; FS = 1620; BR = 8000; break;
+                                default:
+                                    Log.w(TAG, "Unrecognized profile/level "
+                                            + profileLevel.profile + "/"
+                                            + profileLevel.level + " for " + mime);
+                                    errors |= ERROR_UNRECOGNIZED;
+                            }
+                            break;
+                        case CodecProfileLevel.MPEG4ProfileMain:             // 2-4
+                        case CodecProfileLevel.MPEG4ProfileNbit:             // 2
+                        case CodecProfileLevel.MPEG4ProfileAdvancedRealTime: // 1-4
+                        case CodecProfileLevel.MPEG4ProfileCoreScalable:     // 1-3
+                        case CodecProfileLevel.MPEG4ProfileAdvancedCoding:   // 1-4
+                        case CodecProfileLevel.MPEG4ProfileCore:             // 1-2
+                        case CodecProfileLevel.MPEG4ProfileAdvancedCore:     // 1-4
+                        case CodecProfileLevel.MPEG4ProfileSimpleScalable:   // 0-2
+                        case CodecProfileLevel.MPEG4ProfileHybrid:           // 1-2
+
+                        // Studio profiles are not supported by our codecs.
+
+                        // Only profiles that can decode simple object types are considered.
+                        // The following profiles are not able to.
+                        case CodecProfileLevel.MPEG4ProfileBasicAnimated:    // 1-2
+                        case CodecProfileLevel.MPEG4ProfileScalableTexture:  // 1
+                        case CodecProfileLevel.MPEG4ProfileSimpleFace:       // 1-2
+                        case CodecProfileLevel.MPEG4ProfileAdvancedScalable: // 1-3
+                        case CodecProfileLevel.MPEG4ProfileSimpleFBA:        // 1-2
+                            Log.i(TAG, "Unsupported profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNSUPPORTED;
+                            supported = false;
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    if (supported) {
+                        errors &= ~ERROR_NONE_SUPPORTED;
+                    }
+                    maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
+                    maxBlocks = Math.max(FS, maxBlocks);
+                    maxBps = Math.max(BR * 1000, maxBps);
+                    if (strict) {
+                        maxWidth = Math.max(W, maxWidth);
+                        maxHeight = Math.max(H, maxHeight);
+                        maxRate = Math.max(FR, maxRate);
+                    } else {
+                        // assuming max 60 fps frame rate and 1:2 aspect ratio
+                        int maxDim = (int)Math.sqrt(FS * 2);
+                        maxWidth = Math.max(maxDim, maxWidth);
+                        maxHeight = Math.max(maxDim, maxHeight);
+                        maxRate = Math.max(Math.max(FR, 60), maxRate);
+                    }
+                }
+                applyMacroBlockLimits(maxWidth, maxHeight,
+                        maxBlocks, maxBlocksPerSecond,
+                        16 /* blockWidth */, 16 /* blockHeight */,
+                        1 /* widthAlignment */, 1 /* heightAlignment */);
+                mFrameRateRange = mFrameRateRange.intersect(12, maxRate);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) {
+                int maxWidth = 11, maxHeight = 9, maxRate = 15;
+                int minWidth = maxWidth, minHeight = maxHeight;
+                int minAlignment = 16;
+                maxBlocks = 99;
+                maxBlocksPerSecond = 1485;
+                maxBps = 64000;
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    int MBPS = 0, BR = 0, FR = 0, W = 0, H = 0, minW = minWidth, minH = minHeight;
+                    boolean strict = false; // true: support only sQCIF, QCIF (maybe CIF)
+                    switch (profileLevel.level) {
+                        case CodecProfileLevel.H263Level10:
+                            strict = true; // only supports sQCIF & QCIF
+                            FR = 15; W = 11; H =  9; BR =   1; MBPS =  W * H * FR; break;
+                        case CodecProfileLevel.H263Level20:
+                            strict = true; // only supports sQCIF, QCIF & CIF
+                            FR = 30; W = 22; H = 18; BR =   2; MBPS =  W * H * 15; break;
+                        case CodecProfileLevel.H263Level30:
+                            strict = true; // only supports sQCIF, QCIF & CIF
+                            FR = 30; W = 22; H = 18; BR =   6; MBPS =  W * H * FR; break;
+                        case CodecProfileLevel.H263Level40:
+                            strict = true; // only supports sQCIF, QCIF & CIF
+                            FR = 30; W = 22; H = 18; BR =  32; MBPS =  W * H * FR; break;
+                        case CodecProfileLevel.H263Level45:
+                            // only implies level 10 support
+                            strict = profileLevel.profile == CodecProfileLevel.H263ProfileBaseline
+                                    || profileLevel.profile ==
+                                            CodecProfileLevel.H263ProfileBackwardCompatible;
+                            if (!strict) {
+                                minW = 1; minH = 1; minAlignment = 4;
+                            }
+                            FR = 15; W = 11; H =  9; BR =   2; MBPS =  W * H * FR; break;
+                        case CodecProfileLevel.H263Level50:
+                            // only supports 50fps for H > 15
+                            minW = 1; minH = 1; minAlignment = 4;
+                            FR = 60; W = 22; H = 18; BR =  64; MBPS =  W * H * 50; break;
+                        case CodecProfileLevel.H263Level60:
+                            // only supports 50fps for H > 15
+                            minW = 1; minH = 1; minAlignment = 4;
+                            FR = 60; W = 45; H = 18; BR = 128; MBPS =  W * H * 50; break;
+                        case CodecProfileLevel.H263Level70:
+                            // only supports 50fps for H > 30
+                            minW = 1; minH = 1; minAlignment = 4;
+                            FR = 60; W = 45; H = 36; BR = 256; MBPS =  W * H * 50; break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile/level " + profileLevel.profile
+                                    + "/" + profileLevel.level + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.H263ProfileBackwardCompatible:
+                        case CodecProfileLevel.H263ProfileBaseline:
+                        case CodecProfileLevel.H263ProfileH320Coding:
+                        case CodecProfileLevel.H263ProfileHighCompression:
+                        case CodecProfileLevel.H263ProfileHighLatency:
+                        case CodecProfileLevel.H263ProfileInterlace:
+                        case CodecProfileLevel.H263ProfileInternet:
+                        case CodecProfileLevel.H263ProfileISWV2:
+                        case CodecProfileLevel.H263ProfileISWV3:
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    if (strict) {
+                        // Strict levels define sub-QCIF min size and enumerated sizes. We cannot
+                        // express support for "only sQCIF & QCIF (& CIF)" using VideoCapabilities
+                        // but we can express "only QCIF (& CIF)", so set minimume size at QCIF.
+                        // minW = 8; minH = 6;
+                        minW = 11; minH = 9;
+                    } else {
+                        // any support for non-strict levels (including unrecognized profiles or
+                        // levels) allow custom frame size support beyond supported limits
+                        // (other than bitrate)
+                        mAllowMbOverride = true;
+                    }
+                    errors &= ~ERROR_NONE_SUPPORTED;
+                    maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
+                    maxBlocks = Math.max(W * H, maxBlocks);
+                    maxBps = Math.max(BR * 64000, maxBps);
+                    maxWidth = Math.max(W, maxWidth);
+                    maxHeight = Math.max(H, maxHeight);
+                    maxRate = Math.max(FR, maxRate);
+                    minWidth = Math.min(minW, minWidth);
+                    minHeight = Math.min(minH, minHeight);
+                }
+                // unless we encountered custom frame size support, limit size to QCIF and CIF
+                // using aspect ratio.
+                if (!mAllowMbOverride) {
+                    mBlockAspectRatioRange =
+                        Range.create(new Rational(11, 9), new Rational(11, 9));
+                }
+                applyMacroBlockLimits(
+                        minWidth, minHeight,
+                        maxWidth, maxHeight,
+                        maxBlocks, maxBlocksPerSecond,
+                        16 /* blockWidth */, 16 /* blockHeight */,
+                        minAlignment /* widthAlignment */, minAlignment /* heightAlignment */);
+                mFrameRateRange = Range.create(1, maxRate);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8)) {
+                maxBlocks = Integer.MAX_VALUE;
+                maxBlocksPerSecond = Integer.MAX_VALUE;
+
+                // TODO: set to 100Mbps for now, need a number for VP8
+                maxBps = 100000000;
+
+                // profile levels are not indicative for VPx, but verify
+                // them nonetheless
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    switch (profileLevel.level) {
+                        case CodecProfileLevel.VP8Level_Version0:
+                        case CodecProfileLevel.VP8Level_Version1:
+                        case CodecProfileLevel.VP8Level_Version2:
+                        case CodecProfileLevel.VP8Level_Version3:
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized level "
+                                    + profileLevel.level + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.VP8ProfileMain:
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    errors &= ~ERROR_NONE_SUPPORTED;
+                }
+
+                final int blockSize = 16;
+                applyMacroBlockLimits(Short.MAX_VALUE, Short.MAX_VALUE,
+                        maxBlocks, maxBlocksPerSecond, blockSize, blockSize,
+                        1 /* widthAlignment */, 1 /* heightAlignment */);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)) {
+                maxBlocksPerSecond = 829440;
+                maxBlocks = 36864;
+                maxBps = 200000;
+                int maxDim = 512;
+
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    long SR = 0; // luma sample rate
+                    int FS = 0;  // luma picture size
+                    int BR = 0;  // bit rate kbps
+                    int D = 0;   // luma dimension
+                    switch (profileLevel.level) {
+                        case CodecProfileLevel.VP9Level1:
+                            SR =      829440; FS =    36864; BR =    200; D =   512; break;
+                        case CodecProfileLevel.VP9Level11:
+                            SR =     2764800; FS =    73728; BR =    800; D =   768; break;
+                        case CodecProfileLevel.VP9Level2:
+                            SR =     4608000; FS =   122880; BR =   1800; D =   960; break;
+                        case CodecProfileLevel.VP9Level21:
+                            SR =     9216000; FS =   245760; BR =   3600; D =  1344; break;
+                        case CodecProfileLevel.VP9Level3:
+                            SR =    20736000; FS =   552960; BR =   7200; D =  2048; break;
+                        case CodecProfileLevel.VP9Level31:
+                            SR =    36864000; FS =   983040; BR =  12000; D =  2752; break;
+                        case CodecProfileLevel.VP9Level4:
+                            SR =    83558400; FS =  2228224; BR =  18000; D =  4160; break;
+                        case CodecProfileLevel.VP9Level41:
+                            SR =   160432128; FS =  2228224; BR =  30000; D =  4160; break;
+                        case CodecProfileLevel.VP9Level5:
+                            SR =   311951360; FS =  8912896; BR =  60000; D =  8384; break;
+                        case CodecProfileLevel.VP9Level51:
+                            SR =   588251136; FS =  8912896; BR = 120000; D =  8384; break;
+                        case CodecProfileLevel.VP9Level52:
+                            SR =  1176502272; FS =  8912896; BR = 180000; D =  8384; break;
+                        case CodecProfileLevel.VP9Level6:
+                            SR =  1176502272; FS = 35651584; BR = 180000; D = 16832; break;
+                        case CodecProfileLevel.VP9Level61:
+                            SR = 2353004544L; FS = 35651584; BR = 240000; D = 16832; break;
+                        case CodecProfileLevel.VP9Level62:
+                            SR = 4706009088L; FS = 35651584; BR = 480000; D = 16832; break;
+                        default:
+                            Log.w(TAG, "Unrecognized level "
+                                    + profileLevel.level + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.VP9Profile0:
+                        case CodecProfileLevel.VP9Profile1:
+                        case CodecProfileLevel.VP9Profile2:
+                        case CodecProfileLevel.VP9Profile3:
+                        case CodecProfileLevel.VP9Profile2HDR:
+                        case CodecProfileLevel.VP9Profile3HDR:
+                        case CodecProfileLevel.VP9Profile2HDR10Plus:
+                        case CodecProfileLevel.VP9Profile3HDR10Plus:
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    errors &= ~ERROR_NONE_SUPPORTED;
+                    maxBlocksPerSecond = Math.max(SR, maxBlocksPerSecond);
+                    maxBlocks = Math.max(FS, maxBlocks);
+                    maxBps = Math.max(BR * 1000, maxBps);
+                    maxDim = Math.max(D, maxDim);
+                }
+
+                final int blockSize = 8;
+                int maxLengthInBlocks = Utils.divUp(maxDim, blockSize);
+                maxBlocks = Utils.divUp(maxBlocks, blockSize * blockSize);
+                maxBlocksPerSecond = Utils.divUp(maxBlocksPerSecond, blockSize * blockSize);
+
+                applyMacroBlockLimits(
+                        maxLengthInBlocks, maxLengthInBlocks,
+                        maxBlocks, maxBlocksPerSecond,
+                        blockSize, blockSize,
+                        1 /* widthAlignment */, 1 /* heightAlignment */);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
+                // CTBs are at least 8x8 so use 8x8 block size
+                maxBlocks = 36864 >> 6; // 192x192 pixels == 576 8x8 blocks
+                maxBlocksPerSecond = maxBlocks * 15;
+                maxBps = 128000;
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    double FR = 0;
+                    int FS = 0;
+                    int BR = 0;
+                    switch (profileLevel.level) {
+                        /* The HEVC spec talks only in a very convoluted manner about the
+                           existence of levels 1-3.1 for High tier, which could also be
+                           understood as 'decoders and encoders should treat these levels
+                           as if they were Main tier', so we do that. */
+                        case CodecProfileLevel.HEVCMainTierLevel1:
+                        case CodecProfileLevel.HEVCHighTierLevel1:
+                            FR =    15; FS =    36864; BR =    128; break;
+                        case CodecProfileLevel.HEVCMainTierLevel2:
+                        case CodecProfileLevel.HEVCHighTierLevel2:
+                            FR =    30; FS =   122880; BR =   1500; break;
+                        case CodecProfileLevel.HEVCMainTierLevel21:
+                        case CodecProfileLevel.HEVCHighTierLevel21:
+                            FR =    30; FS =   245760; BR =   3000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel3:
+                        case CodecProfileLevel.HEVCHighTierLevel3:
+                            FR =    30; FS =   552960; BR =   6000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel31:
+                        case CodecProfileLevel.HEVCHighTierLevel31:
+                            FR = 33.75; FS =   983040; BR =  10000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel4:
+                            FR =    30; FS =  2228224; BR =  12000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel4:
+                            FR =    30; FS =  2228224; BR =  30000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel41:
+                            FR =    60; FS =  2228224; BR =  20000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel41:
+                            FR =    60; FS =  2228224; BR =  50000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel5:
+                            FR =    30; FS =  8912896; BR =  25000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel5:
+                            FR =    30; FS =  8912896; BR = 100000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel51:
+                            FR =    60; FS =  8912896; BR =  40000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel51:
+                            FR =    60; FS =  8912896; BR = 160000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel52:
+                            FR =   120; FS =  8912896; BR =  60000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel52:
+                            FR =   120; FS =  8912896; BR = 240000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel6:
+                            FR =    30; FS = 35651584; BR =  60000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel6:
+                            FR =    30; FS = 35651584; BR = 240000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel61:
+                            FR =    60; FS = 35651584; BR = 120000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel61:
+                            FR =    60; FS = 35651584; BR = 480000; break;
+                        case CodecProfileLevel.HEVCMainTierLevel62:
+                            FR =   120; FS = 35651584; BR = 240000; break;
+                        case CodecProfileLevel.HEVCHighTierLevel62:
+                            FR =   120; FS = 35651584; BR = 800000; break;
+                        default:
+                            Log.w(TAG, "Unrecognized level "
+                                    + profileLevel.level + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.HEVCProfileMain:
+                        case CodecProfileLevel.HEVCProfileMain10:
+                        case CodecProfileLevel.HEVCProfileMainStill:
+                        case CodecProfileLevel.HEVCProfileMain10HDR10:
+                        case CodecProfileLevel.HEVCProfileMain10HDR10Plus:
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+
+                    /* DPB logic:
+                    if      (width * height <= FS / 4)    DPB = 16;
+                    else if (width * height <= FS / 2)    DPB = 12;
+                    else if (width * height <= FS * 0.75) DPB = 8;
+                    else                                  DPB = 6;
+                    */
+
+                    FS >>= 6; // convert pixels to blocks
+                    errors &= ~ERROR_NONE_SUPPORTED;
+                    maxBlocksPerSecond = Math.max((int)(FR * FS), maxBlocksPerSecond);
+                    maxBlocks = Math.max(FS, maxBlocks);
+                    maxBps = Math.max(BR * 1000, maxBps);
+                }
+
+                int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8));
+                applyMacroBlockLimits(
+                        maxLengthInBlocks, maxLengthInBlocks,
+                        maxBlocks, maxBlocksPerSecond,
+                        8 /* blockWidth */, 8 /* blockHeight */,
+                        1 /* widthAlignment */, 1 /* heightAlignment */);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AV1)) {
+                maxBlocksPerSecond = 829440;
+                maxBlocks = 36864;
+                maxBps = 200000;
+                int maxDim = 512;
+
+                // Sample rate, Picture Size, Bit rate and luma dimension for AV1 Codec,
+                // corresponding to the definitions in
+                // "AV1 Bitstream & Decoding Process Specification", Annex A
+                // found at https://aomedia.org/av1-bitstream-and-decoding-process-specification/
+                for (CodecProfileLevel profileLevel: profileLevels) {
+                    long SR = 0; // luma sample rate
+                    int FS = 0;  // luma picture size
+                    int BR = 0;  // bit rate kbps
+                    int D = 0;   // luma D
+                    switch (profileLevel.level) {
+                        case CodecProfileLevel.AV1Level2:
+                            SR =     5529600; FS =   147456; BR =   1500; D =  2048; break;
+                        case CodecProfileLevel.AV1Level21:
+                        case CodecProfileLevel.AV1Level22:
+                        case CodecProfileLevel.AV1Level23:
+                            SR =    10454400; FS =   278784; BR =   3000; D =  2816; break;
+
+                        case CodecProfileLevel.AV1Level3:
+                            SR =    24969600; FS =   665856; BR =   6000; D =  4352; break;
+                        case CodecProfileLevel.AV1Level31:
+                        case CodecProfileLevel.AV1Level32:
+                        case CodecProfileLevel.AV1Level33:
+                            SR =    39938400; FS =  1065024; BR =  10000; D =  5504; break;
+
+                        case CodecProfileLevel.AV1Level4:
+                            SR =    77856768; FS =  2359296; BR =  12000; D =  6144; break;
+                        case CodecProfileLevel.AV1Level41:
+                        case CodecProfileLevel.AV1Level42:
+                        case CodecProfileLevel.AV1Level43:
+                            SR =   155713536; FS =  2359296; BR =  20000; D =  6144; break;
+
+                        case CodecProfileLevel.AV1Level5:
+                            SR =   273715200; FS =  8912896; BR =  30000; D =  8192; break;
+                        case CodecProfileLevel.AV1Level51:
+                            SR =   547430400; FS =  8912896; BR =  40000; D =  8192; break;
+                        case CodecProfileLevel.AV1Level52:
+                            SR =  1094860800; FS =  8912896; BR =  60000; D =  8192; break;
+                        case CodecProfileLevel.AV1Level53:
+                            SR =  1176502272; FS =  8912896; BR =  60000; D =  8192; break;
+
+                        case CodecProfileLevel.AV1Level6:
+                            SR =  1176502272; FS = 35651584; BR =  60000; D = 16384; break;
+                        case CodecProfileLevel.AV1Level61:
+                            SR = 2189721600L; FS = 35651584; BR = 100000; D = 16384; break;
+                        case CodecProfileLevel.AV1Level62:
+                            SR = 4379443200L; FS = 35651584; BR = 160000; D = 16384; break;
+                        case CodecProfileLevel.AV1Level63:
+                            SR = 4706009088L; FS = 35651584; BR = 160000; D = 16384; break;
+
+                        default:
+                            Log.w(TAG, "Unrecognized level "
+                                    + profileLevel.level + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    switch (profileLevel.profile) {
+                        case CodecProfileLevel.AV1ProfileMain8:
+                        case CodecProfileLevel.AV1ProfileMain10:
+                        case CodecProfileLevel.AV1ProfileMain10HDR10:
+                        case CodecProfileLevel.AV1ProfileMain10HDR10Plus:
+                            break;
+                        default:
+                            Log.w(TAG, "Unrecognized profile "
+                                    + profileLevel.profile + " for " + mime);
+                            errors |= ERROR_UNRECOGNIZED;
+                    }
+                    errors &= ~ERROR_NONE_SUPPORTED;
+                    maxBlocksPerSecond = Math.max(SR, maxBlocksPerSecond);
+                    maxBlocks = Math.max(FS, maxBlocks);
+                    maxBps = Math.max(BR * 1000, maxBps);
+                    maxDim = Math.max(D, maxDim);
+                }
+
+                final int blockSize = 8;
+                int maxLengthInBlocks = Utils.divUp(maxDim, blockSize);
+                maxBlocks = Utils.divUp(maxBlocks, blockSize * blockSize);
+                maxBlocksPerSecond = Utils.divUp(maxBlocksPerSecond, blockSize * blockSize);
+                applyMacroBlockLimits(
+                        maxLengthInBlocks, maxLengthInBlocks,
+                        maxBlocks, maxBlocksPerSecond,
+                        blockSize, blockSize,
+                        1 /* widthAlignment */, 1 /* heightAlignment */);
+            } else {
+                Log.w(TAG, "Unsupported mime " + mime);
+                // using minimal bitrate here.  should be overriden by
+                // info from media_codecs.xml
+                maxBps = 64000;
+                errors |= ERROR_UNSUPPORTED;
+            }
+            mBitrateRange = Range.create(1, maxBps);
+            mParent.mError |= errors;
+        }
+    }
+
+    /**
+     * A class that supports querying the encoding capabilities of a codec.
+     */
+    public static final class EncoderCapabilities {
+        /**
+         * Returns the supported range of quality values.
+         *
+         * Quality is implementation-specific. As a general rule, a higher quality
+         * setting results in a better image quality and a lower compression ratio.
+         */
+        public Range<Integer> getQualityRange() {
+            return mQualityRange;
+        }
+
+        /**
+         * Returns the supported range of encoder complexity values.
+         * <p>
+         * Some codecs may support multiple complexity levels, where higher
+         * complexity values use more encoder tools (e.g. perform more
+         * intensive calculations) to improve the quality or the compression
+         * ratio.  Use a lower value to save power and/or time.
+         */
+        public Range<Integer> getComplexityRange() {
+            return mComplexityRange;
+        }
+
+        /** Constant quality mode */
+        public static final int BITRATE_MODE_CQ = 0;
+        /** Variable bitrate mode */
+        public static final int BITRATE_MODE_VBR = 1;
+        /** Constant bitrate mode */
+        public static final int BITRATE_MODE_CBR = 2;
+        /** Constant bitrate mode with frame drops */
+        public static final int BITRATE_MODE_CBR_FD =  3;
+
+        private static final Feature[] bitrates = new Feature[] {
+            new Feature("VBR", BITRATE_MODE_VBR, true),
+            new Feature("CBR", BITRATE_MODE_CBR, false),
+            new Feature("CQ",  BITRATE_MODE_CQ,  false),
+            new Feature("CBR-FD", BITRATE_MODE_CBR_FD, false)
+        };
+
+        private static int parseBitrateMode(String mode) {
+            for (Feature feat: bitrates) {
+                if (feat.mName.equalsIgnoreCase(mode)) {
+                    return feat.mValue;
+                }
+            }
+            return 0;
+        }
+
+        /**
+         * Query whether a bitrate mode is supported.
+         */
+        public boolean isBitrateModeSupported(int mode) {
+            for (Feature feat: bitrates) {
+                if (mode == feat.mValue) {
+                    return (mBitControl & (1 << mode)) != 0;
+                }
+            }
+            return false;
+        }
+
+        private Range<Integer> mQualityRange;
+        private Range<Integer> mComplexityRange;
+        private CodecCapabilities mParent;
+
+        /* no public constructor */
+        private EncoderCapabilities() { }
+
+        /** @hide */
+        public static EncoderCapabilities create(
+                MediaFormat info, CodecCapabilities parent) {
+            EncoderCapabilities caps = new EncoderCapabilities();
+            caps.init(info, parent);
+            return caps;
+        }
+
+        private void init(MediaFormat info, CodecCapabilities parent) {
+            // no support for complexity or quality yet
+            mParent = parent;
+            mComplexityRange = Range.create(0, 0);
+            mQualityRange = Range.create(0, 0);
+            mBitControl = (1 << BITRATE_MODE_VBR);
+
+            applyLevelLimits();
+            parseFromInfo(info);
+        }
+
+        private void applyLevelLimits() {
+            String mime = mParent.getMimeType();
+            if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
+                mComplexityRange = Range.create(0, 8);
+                mBitControl = (1 << BITRATE_MODE_CQ);
+            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB)
+                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB)
+                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW)
+                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW)
+                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM)) {
+                mBitControl = (1 << BITRATE_MODE_CBR);
+            }
+        }
+
+        private int mBitControl;
+        private Integer mDefaultComplexity;
+        private Integer mDefaultQuality;
+        private String mQualityScale;
+
+        private void parseFromInfo(MediaFormat info) {
+            Map<String, Object> map = info.getMap();
+
+            if (info.containsKey("complexity-range")) {
+                mComplexityRange = Utils
+                        .parseIntRange(info.getString("complexity-range"), mComplexityRange);
+                // TODO should we limit this to level limits?
+            }
+            if (info.containsKey("quality-range")) {
+                mQualityRange = Utils
+                        .parseIntRange(info.getString("quality-range"), mQualityRange);
+            }
+            if (info.containsKey("feature-bitrate-modes")) {
+                for (String mode: info.getString("feature-bitrate-modes").split(",")) {
+                    mBitControl |= (1 << parseBitrateMode(mode));
+                }
+            }
+
+            try {
+                mDefaultComplexity = Integer.parseInt((String)map.get("complexity-default"));
+            } catch (NumberFormatException e) { }
+
+            try {
+                mDefaultQuality = Integer.parseInt((String)map.get("quality-default"));
+            } catch (NumberFormatException e) { }
+
+            mQualityScale = (String)map.get("quality-scale");
+        }
+
+        private boolean supports(
+                Integer complexity, Integer quality, Integer profile) {
+            boolean ok = true;
+            if (ok && complexity != null) {
+                ok = mComplexityRange.contains(complexity);
+            }
+            if (ok && quality != null) {
+                ok = mQualityRange.contains(quality);
+            }
+            if (ok && profile != null) {
+                for (CodecProfileLevel pl: mParent.profileLevels) {
+                    if (pl.profile == profile) {
+                        profile = null;
+                        break;
+                    }
+                }
+                ok = profile == null;
+            }
+            return ok;
+        }
+
+        /** @hide */
+        public void getDefaultFormat(MediaFormat format) {
+            // don't list trivial quality/complexity as default for now
+            if (!mQualityRange.getUpper().equals(mQualityRange.getLower())
+                    && mDefaultQuality != null) {
+                format.setInteger(MediaFormat.KEY_QUALITY, mDefaultQuality);
+            }
+            if (!mComplexityRange.getUpper().equals(mComplexityRange.getLower())
+                    && mDefaultComplexity != null) {
+                format.setInteger(MediaFormat.KEY_COMPLEXITY, mDefaultComplexity);
+            }
+            // bitrates are listed in order of preference
+            for (Feature feat: bitrates) {
+                if ((mBitControl & (1 << feat.mValue)) != 0) {
+                    format.setInteger(MediaFormat.KEY_BITRATE_MODE, feat.mValue);
+                    break;
+                }
+            }
+        }
+
+        /** @hide */
+        public boolean supportsFormat(MediaFormat format) {
+            final Map<String, Object> map = format.getMap();
+            final String mime = mParent.getMimeType();
+
+            Integer mode = (Integer)map.get(MediaFormat.KEY_BITRATE_MODE);
+            if (mode != null && !isBitrateModeSupported(mode)) {
+                return false;
+            }
+
+            Integer complexity = (Integer)map.get(MediaFormat.KEY_COMPLEXITY);
+            if (MediaFormat.MIMETYPE_AUDIO_FLAC.equalsIgnoreCase(mime)) {
+                Integer flacComplexity =
+                    (Integer)map.get(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL);
+                if (complexity == null) {
+                    complexity = flacComplexity;
+                } else if (flacComplexity != null && !complexity.equals(flacComplexity)) {
+                    throw new IllegalArgumentException(
+                            "conflicting values for complexity and " +
+                            "flac-compression-level");
+                }
+            }
+
+            // other audio parameters
+            Integer profile = (Integer)map.get(MediaFormat.KEY_PROFILE);
+            if (MediaFormat.MIMETYPE_AUDIO_AAC.equalsIgnoreCase(mime)) {
+                Integer aacProfile = (Integer)map.get(MediaFormat.KEY_AAC_PROFILE);
+                if (profile == null) {
+                    profile = aacProfile;
+                } else if (aacProfile != null && !aacProfile.equals(profile)) {
+                    throw new IllegalArgumentException(
+                            "conflicting values for profile and aac-profile");
+                }
+            }
+
+            Integer quality = (Integer)map.get(MediaFormat.KEY_QUALITY);
+
+            return supports(complexity, quality, profile);
+        }
+    };
+
+    /**
+     * Encapsulates the profiles available for a codec component.
+     * <p>You can get a set of {@link MediaCodecInfo.CodecProfileLevel} objects for a given
+     * {@link MediaCodecInfo} object from the
+     * {@link MediaCodecInfo.CodecCapabilities#profileLevels} field.
+     */
+    public static final class CodecProfileLevel {
+        // These constants were originally in-line with OMX values, but this
+        // correspondence is no longer maintained.
+
+        // Profiles and levels for AVC Codec, corresponding to the definitions in
+        // "SERIES H: AUDIOVISUAL AND MULTIMEDIA SYSTEMS,
+        // Infrastructure of audiovisual services – Coding of moving video
+        // Advanced video coding for generic audiovisual services"
+        // found at
+        // https://www.itu.int/rec/T-REC-H.264-201704-I
+
+        /**
+         * AVC Baseline profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
+        public static final int AVCProfileBaseline = 0x01;
+
+        /**
+         * AVC Main profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
+        public static final int AVCProfileMain     = 0x02;
+
+        /**
+         * AVC Extended profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
+        public static final int AVCProfileExtended = 0x04;
+
+        /**
+         * AVC High profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
+        public static final int AVCProfileHigh     = 0x08;
+
+        /**
+         * AVC High 10 profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
+        public static final int AVCProfileHigh10   = 0x10;
+
+        /**
+         * AVC High 4:2:2 profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
+        public static final int AVCProfileHigh422  = 0x20;
+
+        /**
+         * AVC High 4:4:4 profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
+        public static final int AVCProfileHigh444  = 0x40;
+
+        /**
+         * AVC Constrained Baseline profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
+        public static final int AVCProfileConstrainedBaseline = 0x10000;
+
+        /**
+         * AVC Constrained High profile.
+         * See definition in
+         * <a href="https://www.itu.int/rec/T-REC-H.264-201704-I">H.264 recommendation</a>,
+         * Annex A.
+         */
+        public static final int AVCProfileConstrainedHigh     = 0x80000;
+
+        public static final int AVCLevel1       = 0x01;
+        public static final int AVCLevel1b      = 0x02;
+        public static final int AVCLevel11      = 0x04;
+        public static final int AVCLevel12      = 0x08;
+        public static final int AVCLevel13      = 0x10;
+        public static final int AVCLevel2       = 0x20;
+        public static final int AVCLevel21      = 0x40;
+        public static final int AVCLevel22      = 0x80;
+        public static final int AVCLevel3       = 0x100;
+        public static final int AVCLevel31      = 0x200;
+        public static final int AVCLevel32      = 0x400;
+        public static final int AVCLevel4       = 0x800;
+        public static final int AVCLevel41      = 0x1000;
+        public static final int AVCLevel42      = 0x2000;
+        public static final int AVCLevel5       = 0x4000;
+        public static final int AVCLevel51      = 0x8000;
+        public static final int AVCLevel52      = 0x10000;
+        public static final int AVCLevel6       = 0x20000;
+        public static final int AVCLevel61      = 0x40000;
+        public static final int AVCLevel62      = 0x80000;
+
+        public static final int H263ProfileBaseline             = 0x01;
+        public static final int H263ProfileH320Coding           = 0x02;
+        public static final int H263ProfileBackwardCompatible   = 0x04;
+        public static final int H263ProfileISWV2                = 0x08;
+        public static final int H263ProfileISWV3                = 0x10;
+        public static final int H263ProfileHighCompression      = 0x20;
+        public static final int H263ProfileInternet             = 0x40;
+        public static final int H263ProfileInterlace            = 0x80;
+        public static final int H263ProfileHighLatency          = 0x100;
+
+        public static final int H263Level10      = 0x01;
+        public static final int H263Level20      = 0x02;
+        public static final int H263Level30      = 0x04;
+        public static final int H263Level40      = 0x08;
+        public static final int H263Level45      = 0x10;
+        public static final int H263Level50      = 0x20;
+        public static final int H263Level60      = 0x40;
+        public static final int H263Level70      = 0x80;
+
+        public static final int MPEG4ProfileSimple              = 0x01;
+        public static final int MPEG4ProfileSimpleScalable      = 0x02;
+        public static final int MPEG4ProfileCore                = 0x04;
+        public static final int MPEG4ProfileMain                = 0x08;
+        public static final int MPEG4ProfileNbit                = 0x10;
+        public static final int MPEG4ProfileScalableTexture     = 0x20;
+        public static final int MPEG4ProfileSimpleFace          = 0x40;
+        public static final int MPEG4ProfileSimpleFBA           = 0x80;
+        public static final int MPEG4ProfileBasicAnimated       = 0x100;
+        public static final int MPEG4ProfileHybrid              = 0x200;
+        public static final int MPEG4ProfileAdvancedRealTime    = 0x400;
+        public static final int MPEG4ProfileCoreScalable        = 0x800;
+        public static final int MPEG4ProfileAdvancedCoding      = 0x1000;
+        public static final int MPEG4ProfileAdvancedCore        = 0x2000;
+        public static final int MPEG4ProfileAdvancedScalable    = 0x4000;
+        public static final int MPEG4ProfileAdvancedSimple      = 0x8000;
+
+        public static final int MPEG4Level0      = 0x01;
+        public static final int MPEG4Level0b     = 0x02;
+        public static final int MPEG4Level1      = 0x04;
+        public static final int MPEG4Level2      = 0x08;
+        public static final int MPEG4Level3      = 0x10;
+        public static final int MPEG4Level3b     = 0x18;
+        public static final int MPEG4Level4      = 0x20;
+        public static final int MPEG4Level4a     = 0x40;
+        public static final int MPEG4Level5      = 0x80;
+        public static final int MPEG4Level6      = 0x100;
+
+        public static final int MPEG2ProfileSimple              = 0x00;
+        public static final int MPEG2ProfileMain                = 0x01;
+        public static final int MPEG2Profile422                 = 0x02;
+        public static final int MPEG2ProfileSNR                 = 0x03;
+        public static final int MPEG2ProfileSpatial             = 0x04;
+        public static final int MPEG2ProfileHigh                = 0x05;
+
+        public static final int MPEG2LevelLL     = 0x00;
+        public static final int MPEG2LevelML     = 0x01;
+        public static final int MPEG2LevelH14    = 0x02;
+        public static final int MPEG2LevelHL     = 0x03;
+        public static final int MPEG2LevelHP     = 0x04;
+
+        public static final int AACObjectMain       = 1;
+        public static final int AACObjectLC         = 2;
+        public static final int AACObjectSSR        = 3;
+        public static final int AACObjectLTP        = 4;
+        public static final int AACObjectHE         = 5;
+        public static final int AACObjectScalable   = 6;
+        public static final int AACObjectERLC       = 17;
+        public static final int AACObjectERScalable = 20;
+        public static final int AACObjectLD         = 23;
+        public static final int AACObjectHE_PS      = 29;
+        public static final int AACObjectELD        = 39;
+        /** xHE-AAC (includes USAC) */
+        public static final int AACObjectXHE        = 42;
+
+        public static final int VP8Level_Version0 = 0x01;
+        public static final int VP8Level_Version1 = 0x02;
+        public static final int VP8Level_Version2 = 0x04;
+        public static final int VP8Level_Version3 = 0x08;
+
+        public static final int VP8ProfileMain = 0x01;
+
+        /** VP9 Profile 0 4:2:0 8-bit */
+        public static final int VP9Profile0 = 0x01;
+
+        /** VP9 Profile 1 4:2:2 8-bit */
+        public static final int VP9Profile1 = 0x02;
+
+        /** VP9 Profile 2 4:2:0 10-bit */
+        public static final int VP9Profile2 = 0x04;
+
+        /** VP9 Profile 3 4:2:2 10-bit */
+        public static final int VP9Profile3 = 0x08;
+
+        // HDR profiles also support passing HDR metadata
+        /** VP9 Profile 2 4:2:0 10-bit HDR */
+        public static final int VP9Profile2HDR = 0x1000;
+
+        /** VP9 Profile 3 4:2:2 10-bit HDR */
+        public static final int VP9Profile3HDR = 0x2000;
+
+        /** VP9 Profile 2 4:2:0 10-bit HDR10Plus */
+        public static final int VP9Profile2HDR10Plus = 0x4000;
+
+        /** VP9 Profile 3 4:2:2 10-bit HDR10Plus */
+        public static final int VP9Profile3HDR10Plus = 0x8000;
+
+        public static final int VP9Level1  = 0x1;
+        public static final int VP9Level11 = 0x2;
+        public static final int VP9Level2  = 0x4;
+        public static final int VP9Level21 = 0x8;
+        public static final int VP9Level3  = 0x10;
+        public static final int VP9Level31 = 0x20;
+        public static final int VP9Level4  = 0x40;
+        public static final int VP9Level41 = 0x80;
+        public static final int VP9Level5  = 0x100;
+        public static final int VP9Level51 = 0x200;
+        public static final int VP9Level52 = 0x400;
+        public static final int VP9Level6  = 0x800;
+        public static final int VP9Level61 = 0x1000;
+        public static final int VP9Level62 = 0x2000;
+
+        public static final int HEVCProfileMain        = 0x01;
+        public static final int HEVCProfileMain10      = 0x02;
+        public static final int HEVCProfileMainStill   = 0x04;
+        public static final int HEVCProfileMain10HDR10 = 0x1000;
+        public static final int HEVCProfileMain10HDR10Plus = 0x2000;
+
+        public static final int HEVCMainTierLevel1  = 0x1;
+        public static final int HEVCHighTierLevel1  = 0x2;
+        public static final int HEVCMainTierLevel2  = 0x4;
+        public static final int HEVCHighTierLevel2  = 0x8;
+        public static final int HEVCMainTierLevel21 = 0x10;
+        public static final int HEVCHighTierLevel21 = 0x20;
+        public static final int HEVCMainTierLevel3  = 0x40;
+        public static final int HEVCHighTierLevel3  = 0x80;
+        public static final int HEVCMainTierLevel31 = 0x100;
+        public static final int HEVCHighTierLevel31 = 0x200;
+        public static final int HEVCMainTierLevel4  = 0x400;
+        public static final int HEVCHighTierLevel4  = 0x800;
+        public static final int HEVCMainTierLevel41 = 0x1000;
+        public static final int HEVCHighTierLevel41 = 0x2000;
+        public static final int HEVCMainTierLevel5  = 0x4000;
+        public static final int HEVCHighTierLevel5  = 0x8000;
+        public static final int HEVCMainTierLevel51 = 0x10000;
+        public static final int HEVCHighTierLevel51 = 0x20000;
+        public static final int HEVCMainTierLevel52 = 0x40000;
+        public static final int HEVCHighTierLevel52 = 0x80000;
+        public static final int HEVCMainTierLevel6  = 0x100000;
+        public static final int HEVCHighTierLevel6  = 0x200000;
+        public static final int HEVCMainTierLevel61 = 0x400000;
+        public static final int HEVCHighTierLevel61 = 0x800000;
+        public static final int HEVCMainTierLevel62 = 0x1000000;
+        public static final int HEVCHighTierLevel62 = 0x2000000;
+
+        private static final int HEVCHighTierLevels =
+            HEVCHighTierLevel1 | HEVCHighTierLevel2 | HEVCHighTierLevel21 | HEVCHighTierLevel3 |
+            HEVCHighTierLevel31 | HEVCHighTierLevel4 | HEVCHighTierLevel41 | HEVCHighTierLevel5 |
+            HEVCHighTierLevel51 | HEVCHighTierLevel52 | HEVCHighTierLevel6 | HEVCHighTierLevel61 |
+            HEVCHighTierLevel62;
+
+        public static final int DolbyVisionProfileDvavPer = 0x1;
+        public static final int DolbyVisionProfileDvavPen = 0x2;
+        public static final int DolbyVisionProfileDvheDer = 0x4;
+        public static final int DolbyVisionProfileDvheDen = 0x8;
+        public static final int DolbyVisionProfileDvheDtr = 0x10;
+        public static final int DolbyVisionProfileDvheStn = 0x20;
+        public static final int DolbyVisionProfileDvheDth = 0x40;
+        public static final int DolbyVisionProfileDvheDtb = 0x80;
+        public static final int DolbyVisionProfileDvheSt  = 0x100;
+        public static final int DolbyVisionProfileDvavSe  = 0x200;
+        /** Dolby Vision AV1 profile */
+        @SuppressLint("AllUpper")
+        public static final int DolbyVisionProfileDvav110 = 0x400;
+
+        public static final int DolbyVisionLevelHd24    = 0x1;
+        public static final int DolbyVisionLevelHd30    = 0x2;
+        public static final int DolbyVisionLevelFhd24   = 0x4;
+        public static final int DolbyVisionLevelFhd30   = 0x8;
+        public static final int DolbyVisionLevelFhd60   = 0x10;
+        public static final int DolbyVisionLevelUhd24   = 0x20;
+        public static final int DolbyVisionLevelUhd30   = 0x40;
+        public static final int DolbyVisionLevelUhd48   = 0x80;
+        public static final int DolbyVisionLevelUhd60   = 0x100;
+
+        // Profiles and levels for AV1 Codec, corresponding to the definitions in
+        // "AV1 Bitstream & Decoding Process Specification", Annex A
+        // found at https://aomedia.org/av1-bitstream-and-decoding-process-specification/
+
+        /**
+         * AV1 Main profile 4:2:0 8-bit
+         *
+         * See definition in
+         * <a href="https://aomedia.org/av1-bitstream-and-decoding-process-specification/">AV1 Specification</a>
+         * Annex A.
+         */
+        public static final int AV1ProfileMain8   = 0x1;
+
+        /**
+         * AV1 Main profile 4:2:0 10-bit
+         *
+         * See definition in
+         * <a href="https://aomedia.org/av1-bitstream-and-decoding-process-specification/">AV1 Specification</a>
+         * Annex A.
+         */
+        public static final int AV1ProfileMain10  = 0x2;
+
+
+        /** AV1 Main profile 4:2:0 10-bit with HDR10. */
+        public static final int AV1ProfileMain10HDR10 = 0x1000;
+
+        /** AV1 Main profile 4:2:0 10-bit with HDR10Plus. */
+        public static final int AV1ProfileMain10HDR10Plus = 0x2000;
+
+        public static final int AV1Level2       = 0x1;
+        public static final int AV1Level21      = 0x2;
+        public static final int AV1Level22      = 0x4;
+        public static final int AV1Level23      = 0x8;
+        public static final int AV1Level3       = 0x10;
+        public static final int AV1Level31      = 0x20;
+        public static final int AV1Level32      = 0x40;
+        public static final int AV1Level33      = 0x80;
+        public static final int AV1Level4       = 0x100;
+        public static final int AV1Level41      = 0x200;
+        public static final int AV1Level42      = 0x400;
+        public static final int AV1Level43      = 0x800;
+        public static final int AV1Level5       = 0x1000;
+        public static final int AV1Level51      = 0x2000;
+        public static final int AV1Level52      = 0x4000;
+        public static final int AV1Level53      = 0x8000;
+        public static final int AV1Level6       = 0x10000;
+        public static final int AV1Level61      = 0x20000;
+        public static final int AV1Level62      = 0x40000;
+        public static final int AV1Level63      = 0x80000;
+        public static final int AV1Level7       = 0x100000;
+        public static final int AV1Level71      = 0x200000;
+        public static final int AV1Level72      = 0x400000;
+        public static final int AV1Level73      = 0x800000;
+
+        /**
+         * The profile of the media content. Depending on the type of media this can be
+         * one of the profile values defined in this class.
+         */
+        public int profile;
+
+        /**
+         * The level of the media content. Depending on the type of media this can be
+         * one of the level values defined in this class.
+         *
+         * Note that VP9 decoder on platforms before {@link android.os.Build.VERSION_CODES#N} may
+         * not advertise a profile level support. For those VP9 decoders, please use
+         * {@link VideoCapabilities} to determine the codec capabilities.
+         */
+        public int level;
+
+        @Override
+        public boolean equals(Object obj) {
+            if (obj == null) {
+                return false;
+            }
+            if (obj instanceof CodecProfileLevel) {
+                CodecProfileLevel other = (CodecProfileLevel)obj;
+                return other.profile == profile && other.level == level;
+            }
+            return false;
+        }
+
+        @Override
+        public int hashCode() {
+            return Long.hashCode(((long)profile << Integer.SIZE) | level);
+        }
+    };
+
+    /**
+     * Enumerates the capabilities of the codec component. Since a single
+     * component can support data of a variety of types, the type has to be
+     * specified to yield a meaningful result.
+     * @param type The MIME type to query
+     */
+    public final CodecCapabilities getCapabilitiesForType(
+            String type) {
+        CodecCapabilities caps = mCaps.get(type);
+        if (caps == null) {
+            throw new IllegalArgumentException("codec does not support type");
+        }
+        // clone writable object
+        return caps.dup();
+    }
+
+    /** @hide */
+    public MediaCodecInfo makeRegular() {
+        ArrayList<CodecCapabilities> caps = new ArrayList<CodecCapabilities>();
+        for (CodecCapabilities c: mCaps.values()) {
+            if (c.isRegular()) {
+                caps.add(c);
+            }
+        }
+        if (caps.size() == 0) {
+            return null;
+        } else if (caps.size() == mCaps.size()) {
+            return this;
+        }
+
+        return new MediaCodecInfo(
+                mName, mCanonicalName, mFlags,
+                caps.toArray(new CodecCapabilities[caps.size()]));
+    }
+}
diff --git a/android/media/MediaCodecList.java b/android/media/MediaCodecList.java
new file mode 100644
index 0000000..a460954
--- /dev/null
+++ b/android/media/MediaCodecList.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright (C) 2012 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.util.Log;
+
+import android.media.MediaCodecInfo;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Map;
+
+/**
+ * Allows you to enumerate available codecs, each specified as a {@link MediaCodecInfo} object,
+ * find a codec supporting a given format and query the capabilities
+ * of a given codec.
+ * <p>See {@link MediaCodecInfo} for sample usage.
+ */
+final public class MediaCodecList {
+    private static final String TAG = "MediaCodecList";
+
+    /**
+     * Count the number of available (regular) codecs.
+     *
+     * @deprecated Use {@link #getCodecInfos} instead.
+     *
+     * @see #REGULAR_CODECS
+     */
+    public static final int getCodecCount() {
+        initCodecList();
+        return sRegularCodecInfos.length;
+    }
+
+    private static native final int native_getCodecCount();
+
+    /**
+     * Return the {@link MediaCodecInfo} object for the codec at
+     * the given {@code index} in the regular list.
+     *
+     * @deprecated Use {@link #getCodecInfos} instead.
+     *
+     * @see #REGULAR_CODECS
+     */
+    public static final MediaCodecInfo getCodecInfoAt(int index) {
+        initCodecList();
+        if (index < 0 || index > sRegularCodecInfos.length) {
+            throw new IllegalArgumentException();
+        }
+        return sRegularCodecInfos[index];
+    }
+
+    /* package private */ static final Map<String, Object> getGlobalSettings() {
+        synchronized (sInitLock) {
+            if (sGlobalSettings == null) {
+                sGlobalSettings = native_getGlobalSettings();
+            }
+        }
+        return sGlobalSettings;
+    }
+
+    private static Object sInitLock = new Object();
+    private static MediaCodecInfo[] sAllCodecInfos;
+    private static MediaCodecInfo[] sRegularCodecInfos;
+    private static Map<String, Object> sGlobalSettings;
+
+    private static final void initCodecList() {
+        synchronized (sInitLock) {
+            if (sRegularCodecInfos == null) {
+                int count = native_getCodecCount();
+                ArrayList<MediaCodecInfo> regulars = new ArrayList<MediaCodecInfo>();
+                ArrayList<MediaCodecInfo> all = new ArrayList<MediaCodecInfo>();
+                for (int index = 0; index < count; index++) {
+                    try {
+                        MediaCodecInfo info = getNewCodecInfoAt(index);
+                        all.add(info);
+                        info = info.makeRegular();
+                        if (info != null) {
+                            regulars.add(info);
+                        }
+                    } catch (Exception e) {
+                        Log.e(TAG, "Could not get codec capabilities", e);
+                    }
+                }
+                sRegularCodecInfos =
+                    regulars.toArray(new MediaCodecInfo[regulars.size()]);
+                sAllCodecInfos =
+                    all.toArray(new MediaCodecInfo[all.size()]);
+            }
+        }
+    }
+
+    private static MediaCodecInfo getNewCodecInfoAt(int index) {
+        String[] supportedTypes = getSupportedTypes(index);
+        MediaCodecInfo.CodecCapabilities[] caps =
+            new MediaCodecInfo.CodecCapabilities[supportedTypes.length];
+        int typeIx = 0;
+        for (String type: supportedTypes) {
+            caps[typeIx++] = getCodecCapabilities(index, type);
+        }
+        return new MediaCodecInfo(
+                getCodecName(index), getCanonicalName(index), getAttributes(index), caps);
+    }
+
+    /* package private */ static native final String getCodecName(int index);
+
+    /* package private */ static native final String getCanonicalName(int index);
+
+    /* package private */ static native final int getAttributes(int index);
+
+    /* package private */ static native final String[] getSupportedTypes(int index);
+
+    /* package private */ static native final MediaCodecInfo.CodecCapabilities
+        getCodecCapabilities(int index, String type);
+
+    /* package private */ static native final Map<String, Object> native_getGlobalSettings();
+
+    /* package private */ static native final int findCodecByName(String codec);
+
+    /** @hide */
+    public static MediaCodecInfo getInfoFor(String codec) {
+        initCodecList();
+        return sAllCodecInfos[findCodecByName(codec)];
+    }
+
+    private static native final void native_init();
+
+    /**
+     * Use in {@link #MediaCodecList} to enumerate only codecs that are suitable
+     * for regular (buffer-to-buffer) decoding or encoding.
+     *
+     * <em>NOTE:</em> These are the codecs that are returned prior to API 21,
+     * using the now deprecated static methods.
+     */
+    public static final int REGULAR_CODECS = 0;
+
+    /**
+     * Use in {@link #MediaCodecList} to enumerate all codecs, even ones that are
+     * not suitable for regular (buffer-to-buffer) decoding or encoding.  These
+     * include codecs, for example, that only work with special input or output
+     * surfaces, such as secure-only or tunneled-only codecs.
+     *
+     * @see MediaCodecInfo.CodecCapabilities#isFormatSupported
+     * @see MediaCodecInfo.CodecCapabilities#FEATURE_SecurePlayback
+     * @see MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback
+     */
+    public static final int ALL_CODECS = 1;
+
+    private MediaCodecList() {
+        this(REGULAR_CODECS);
+    }
+
+    private MediaCodecInfo[] mCodecInfos;
+
+    /**
+     * Create a list of media-codecs of a specific kind.
+     * @param kind Either {@code REGULAR_CODECS} or {@code ALL_CODECS}.
+     */
+    public MediaCodecList(int kind) {
+        initCodecList();
+        if (kind == REGULAR_CODECS) {
+            mCodecInfos = sRegularCodecInfos;
+        } else {
+            mCodecInfos = sAllCodecInfos;
+        }
+    }
+
+    /**
+     * Returns the list of {@link MediaCodecInfo} objects for the list
+     * of media-codecs.
+     */
+    public final MediaCodecInfo[] getCodecInfos() {
+        return Arrays.copyOf(mCodecInfos, mCodecInfos.length);
+    }
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+
+        // mediaserver is not yet alive here
+    }
+
+    /**
+     * Find a decoder supporting a given {@link MediaFormat} in the list
+     * of media-codecs.
+     *
+     * <p class=note>
+     * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP},
+     * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE
+     * frame rate}. Use
+     * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
+     * to clear any existing frame rate setting in the format.
+     *
+     * @see MediaCodecInfo.CodecCapabilities#isFormatSupported(MediaFormat) for format keys
+     * considered per android versions when evaluating suitable codecs.
+     *
+     * @param format A decoder media format with optional feature directives.
+     * @throws IllegalArgumentException if format is not a valid media format.
+     * @throws NullPointerException if format is null.
+     * @return the name of a decoder that supports the given format and feature
+     *         requests, or {@code null} if no such codec has been found.
+     */
+    public final String findDecoderForFormat(MediaFormat format) {
+        return findCodecForFormat(false /* encoder */, format);
+    }
+
+    /**
+     * Find an encoder supporting a given {@link MediaFormat} in the list
+     * of media-codecs.
+     *
+     * <p class=note>
+     * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP},
+     * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE
+     * frame rate}. Use
+     * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
+     * to clear any existing frame rate setting in the format.
+     *
+     * @see MediaCodecInfo.CodecCapabilities#isFormatSupported(MediaFormat) for format keys
+     * considered per android versions when evaluating suitable codecs.
+     *
+     * @param format An encoder media format with optional feature directives.
+     * @throws IllegalArgumentException if format is not a valid media format.
+     * @throws NullPointerException if format is null.
+     * @return the name of an encoder that supports the given format and feature
+     *         requests, or {@code null} if no such codec has been found.
+     */
+    public final String findEncoderForFormat(MediaFormat format) {
+        return findCodecForFormat(true /* encoder */, format);
+    }
+
+    private String findCodecForFormat(boolean encoder, MediaFormat format) {
+        String mime = format.getString(MediaFormat.KEY_MIME);
+        for (MediaCodecInfo info: mCodecInfos) {
+            if (info.isEncoder() != encoder) {
+                continue;
+            }
+            try {
+                MediaCodecInfo.CodecCapabilities caps = info.getCapabilitiesForType(mime);
+                if (caps != null && caps.isFormatSupported(format)) {
+                    return info.getName();
+                }
+            } catch (IllegalArgumentException e) {
+                // type is not supported
+            }
+        }
+        return null;
+    }
+}
diff --git a/android/media/MediaCommunicationManager.java b/android/media/MediaCommunicationManager.java
new file mode 100644
index 0000000..f39bcfb
--- /dev/null
+++ b/android/media/MediaCommunicationManager.java
@@ -0,0 +1,288 @@
+/*
+ * Copyright 2020 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.Manifest.permission.MEDIA_CONTENT_CONTROL;
+import static android.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.content.Context;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionManager;
+import android.os.Build;
+import android.os.RemoteException;
+import android.os.UserHandle;
+import android.service.media.MediaBrowserService;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.modules.annotation.MinSdk;
+import com.android.modules.utils.build.SdkLevel;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+
+/**
+ * Provides support for interacting with {@link android.media.MediaSession2 MediaSession2s}
+ * that applications have published to express their ongoing media playback state.
+ */
+@MinSdk(Build.VERSION_CODES.S)
+@SystemService(Context.MEDIA_COMMUNICATION_SERVICE)
+public class MediaCommunicationManager {
+    private static final String TAG = "MediaCommunicationManager";
+
+    /**
+     * The manager version used from beginning.
+     */
+    private static final int VERSION_1 = 1;
+
+    /**
+     * Current manager version.
+     */
+    private static final int CURRENT_VERSION = VERSION_1;
+
+    private final Context mContext;
+    private final IMediaCommunicationService mService;
+
+    private final Object mLock = new Object();
+    private final CopyOnWriteArrayList<SessionCallbackRecord> mTokenCallbackRecords =
+            new CopyOnWriteArrayList<>();
+
+    @GuardedBy("mLock")
+    private MediaCommunicationServiceCallbackStub mCallbackStub;
+
+    /**
+     * @hide
+     */
+    public MediaCommunicationManager(@NonNull Context context) {
+        if (!SdkLevel.isAtLeastS()) {
+            throw new UnsupportedOperationException("Android version must be S or greater.");
+        }
+        mContext = context;
+        mService = IMediaCommunicationService.Stub.asInterface(
+                MediaFrameworkInitializer.getMediaServiceManager()
+                        .getMediaCommunicationServiceRegisterer()
+                        .get());
+    }
+
+    /**
+     * Gets the version of this {@link MediaCommunicationManager}.
+     */
+    public @IntRange(from = 1) int getVersion() {
+        return CURRENT_VERSION;
+    }
+
+    /**
+     * Notifies that a new {@link MediaSession2} with type {@link Session2Token#TYPE_SESSION} is
+     * created.
+     * @param token newly created session2 token
+     * @hide
+     */
+    public void notifySession2Created(@NonNull Session2Token token) {
+        Objects.requireNonNull(token, "token shouldn't be null");
+        if (token.getType() != Session2Token.TYPE_SESSION) {
+            throw new IllegalArgumentException("token's type should be TYPE_SESSION");
+        }
+        try {
+            mService.notifySession2Created(token);
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Checks whether the remote user is a trusted app.
+     * <p>
+     * An app is trusted if the app holds the
+     * {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL} permission or has an enabled
+     * notification listener.
+     *
+     * @param userInfo The remote user info from either
+     *            {@link MediaSession#getCurrentControllerInfo()} or
+     *            {@link MediaBrowserService#getCurrentBrowserInfo()}.
+     * @return {@code true} if the remote user is trusted or {@code false} otherwise.
+     * @hide
+     */
+    public boolean isTrustedForMediaControl(@NonNull MediaSessionManager.RemoteUserInfo userInfo) {
+        Objects.requireNonNull(userInfo, "userInfo shouldn't be null");
+        if (userInfo.getPackageName() == null) {
+            return false;
+        }
+        try {
+            return mService.isTrusted(
+                    userInfo.getPackageName(), userInfo.getPid(), userInfo.getUid());
+        } catch (RemoteException e) {
+            Log.w(TAG, "Cannot communicate with the service.", e);
+        }
+        return false;
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Gets a list of {@link Session2Token} with type {@link Session2Token#TYPE_SESSION} for the
+     * current user.
+     * <p>
+     * Although this API can be used without any restriction, each session owners can accept or
+     * reject your uses of {@link MediaSession2}.
+     *
+     * @return A list of {@link Session2Token}.
+     */
+    @NonNull
+    public List<Session2Token> getSession2Tokens() {
+        return getSession2Tokens(UserHandle.myUserId());
+    }
+
+    /**
+     * Adds a callback to be notified when the list of active sessions changes.
+     * <p>
+     * This requires the {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL} permission be
+     * held by the calling app.
+     * </p>
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    @RequiresPermission(MEDIA_CONTENT_CONTROL)
+    public void registerSessionCallback(@CallbackExecutor @NonNull Executor executor,
+            @NonNull SessionCallback callback) {
+        Objects.requireNonNull(executor, "executor must not be null");
+        Objects.requireNonNull(callback, "callback must not be null");
+
+        if (!mTokenCallbackRecords.addIfAbsent(
+                new SessionCallbackRecord(executor, callback))) {
+            Log.w(TAG, "registerSession2TokenCallback: Ignoring the same callback");
+            return;
+        }
+        synchronized (mLock) {
+            if (mCallbackStub == null) {
+                MediaCommunicationServiceCallbackStub callbackStub =
+                        new MediaCommunicationServiceCallbackStub();
+                try {
+                    mService.registerCallback(callbackStub, mContext.getPackageName());
+                    mCallbackStub = callbackStub;
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Failed to register callback.", ex);
+                }
+            }
+        }
+    }
+
+    /**
+     * Stops receiving active sessions updates on the specified callback.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public void unregisterSessionCallback(@NonNull SessionCallback callback) {
+        if (!mTokenCallbackRecords.remove(
+                new SessionCallbackRecord(null, callback))) {
+            Log.w(TAG, "unregisterSession2TokenCallback: Ignoring an unknown callback.");
+            return;
+        }
+        synchronized (mLock) {
+            if (mCallbackStub != null && mTokenCallbackRecords.isEmpty()) {
+                try {
+                    mService.unregisterCallback(mCallbackStub);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Failed to unregister callback.", ex);
+                }
+                mCallbackStub = null;
+            }
+        }
+    }
+
+    private List<Session2Token> getSession2Tokens(int userId) {
+        try {
+            MediaParceledListSlice slice = mService.getSession2Tokens(userId);
+            return slice == null ? Collections.emptyList() : slice.getList();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to get session tokens", e);
+        }
+        return Collections.emptyList();
+    }
+
+    /**
+     * Callback for listening to changes to the sessions.
+     * @see #registerSessionCallback(Executor, SessionCallback)
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public interface SessionCallback {
+        /**
+         * Called when a new {@link MediaSession2 media session2} is created.
+         * @param token the newly created token
+         */
+        default void onSession2TokenCreated(@NonNull Session2Token token) {}
+
+        /**
+         * Called when {@link #getSession2Tokens() session tokens} are changed.
+         */
+        default void onSession2TokensChanged(@NonNull List<Session2Token> tokens) {}
+    }
+
+    private static final class SessionCallbackRecord {
+        public final Executor executor;
+        public final SessionCallback callback;
+
+        SessionCallbackRecord(Executor executor, SessionCallback callback) {
+            this.executor = executor;
+            this.callback = callback;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(callback);
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (!(obj instanceof SessionCallbackRecord)) {
+                return false;
+            }
+            return Objects.equals(this.callback, ((SessionCallbackRecord) obj).callback);
+        }
+    }
+
+    class MediaCommunicationServiceCallbackStub extends IMediaCommunicationServiceCallback.Stub {
+        @Override
+        public void onSession2Created(Session2Token token) throws RemoteException {
+            for (SessionCallbackRecord record : mTokenCallbackRecords) {
+                record.executor.execute(() -> record.callback.onSession2TokenCreated(token));
+            }
+        }
+
+        @Override
+        public void onSession2Changed(MediaParceledListSlice tokens) throws RemoteException {
+            List<Session2Token> tokenList = tokens.getList();
+            for (SessionCallbackRecord record : mTokenCallbackRecords) {
+                record.executor.execute(() -> record.callback.onSession2TokensChanged(tokenList));
+            }
+        }
+    }
+}
diff --git a/android/media/MediaConstants.java b/android/media/MediaConstants.java
new file mode 100644
index 0000000..ce10889
--- /dev/null
+++ b/android/media/MediaConstants.java
@@ -0,0 +1,35 @@
+/*
+ * 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;
+
+class MediaConstants {
+    // Bundle key for int
+    static final String KEY_PID = "android.media.key.PID";
+
+    // Bundle key for String
+    static final String KEY_PACKAGE_NAME = "android.media.key.PACKAGE_NAME";
+
+    // Bundle key for Parcelable
+    static final String KEY_SESSION2LINK = "android.media.key.SESSION2LINK";
+    static final String KEY_ALLOWED_COMMANDS = "android.media.key.ALLOWED_COMMANDS";
+    static final String KEY_PLAYBACK_ACTIVE = "android.media.key.PLAYBACK_ACTIVE";
+    static final String KEY_TOKEN_EXTRAS = "android.media.key.TOKEN_EXTRAS";
+    static final String KEY_CONNECTION_HINTS = "android.media.key.CONNECTION_HINTS";
+
+    private MediaConstants() {
+    }
+}
diff --git a/android/media/MediaController2.java b/android/media/MediaController2.java
new file mode 100644
index 0000000..159e8e5
--- /dev/null
+++ b/android/media/MediaController2.java
@@ -0,0 +1,637 @@
+/*
+ * 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.MediaConstants.KEY_ALLOWED_COMMANDS;
+import static android.media.MediaConstants.KEY_CONNECTION_HINTS;
+import static android.media.MediaConstants.KEY_PACKAGE_NAME;
+import static android.media.MediaConstants.KEY_PID;
+import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE;
+import static android.media.MediaConstants.KEY_SESSION2LINK;
+import static android.media.MediaConstants.KEY_TOKEN_EXTRAS;
+import static android.media.Session2Command.Result.RESULT_ERROR_UNKNOWN_ERROR;
+import static android.media.Session2Command.Result.RESULT_INFO_SKIPPED;
+import static android.media.Session2Token.TYPE_SESSION;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+
+import java.util.concurrent.Executor;
+
+/**
+ * This API is not generally intended for third party application developers.
+ * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+ * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+ * Library</a> for consistent behavior across all devices.
+ *
+ * Allows an app to interact with an active {@link MediaSession2} or a
+ * {@link MediaSession2Service} which would provide {@link MediaSession2}. Media buttons and other
+ * commands can be sent to the session.
+ */
+public class MediaController2 implements AutoCloseable {
+    static final String TAG = "MediaController2";
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final ControllerCallback mCallback;
+
+    private final IBinder.DeathRecipient mDeathRecipient = () -> close();
+    private final Context mContext;
+    private final Session2Token mSessionToken;
+    private final Executor mCallbackExecutor;
+    private final Controller2Link mControllerStub;
+    private final Handler mResultHandler;
+    private final SessionServiceConnection mServiceConnection;
+
+    private final Object mLock = new Object();
+    //@GuardedBy("mLock")
+    private boolean mClosed;
+    //@GuardedBy("mLock")
+    private int mNextSeqNumber;
+    //@GuardedBy("mLock")
+    private Session2Link mSessionBinder;
+    //@GuardedBy("mLock")
+    private Session2CommandGroup mAllowedCommands;
+    //@GuardedBy("mLock")
+    private Session2Token mConnectedToken;
+    //@GuardedBy("mLock")
+    private ArrayMap<ResultReceiver, Integer> mPendingCommands;
+    //@GuardedBy("mLock")
+    private ArraySet<Integer> mRequestedCommandSeqNumbers;
+    //@GuardedBy("mLock")
+    private boolean mPlaybackActive;
+
+    /**
+     * Create a {@link MediaController2} from the {@link Session2Token}.
+     * This connects to the session and may wake up the service if it's not available.
+     *
+     * @param context context
+     * @param token token to connect to
+     * @param connectionHints a session-specific argument to send to the session when connecting.
+     *                        The contents of this bundle may affect the connection result.
+     * @param executor executor to run callbacks on.
+     * @param callback controller callback to receive changes in.
+     */
+    MediaController2(@NonNull Context context, @NonNull Session2Token token,
+            @NonNull Bundle connectionHints, @NonNull Executor executor,
+            @NonNull ControllerCallback callback) {
+        if (context == null) {
+            throw new IllegalArgumentException("context shouldn't be null");
+        }
+        if (token == null) {
+            throw new IllegalArgumentException("token shouldn't be null");
+        }
+        mContext = context;
+        mSessionToken = token;
+        mCallbackExecutor = (executor == null) ? context.getMainExecutor() : executor;
+        mCallback = (callback == null) ? new ControllerCallback() {} : callback;
+        mControllerStub = new Controller2Link(this);
+        // NOTE: mResultHandler uses main looper, so this MUST NOT be blocked.
+        mResultHandler = new Handler(context.getMainLooper());
+
+        mNextSeqNumber = 0;
+        mPendingCommands = new ArrayMap<>();
+        mRequestedCommandSeqNumbers = new ArraySet<>();
+
+        boolean connectRequested;
+        if (token.getType() == TYPE_SESSION) {
+            mServiceConnection = null;
+            connectRequested = requestConnectToSession(connectionHints);
+        } else {
+            mServiceConnection = new SessionServiceConnection(connectionHints);
+            connectRequested = requestConnectToService();
+        }
+        if (!connectRequested) {
+            close();
+        }
+    }
+
+    @Override
+    public void close() {
+        synchronized (mLock) {
+            if (mClosed) {
+                // Already closed. Ignore rest of clean up code.
+                // Note: unbindService() throws IllegalArgumentException when it's called twice.
+                return;
+            }
+            if (DEBUG) {
+                Log.d(TAG, "closing " + this);
+            }
+            mClosed = true;
+            if (mServiceConnection != null) {
+                // Note: This should be called even when the bindService() has returned false.
+                mContext.unbindService(mServiceConnection);
+            }
+            if (mSessionBinder != null) {
+                try {
+                    mSessionBinder.disconnect(mControllerStub, getNextSeqNumber());
+                    mSessionBinder.unlinkToDeath(mDeathRecipient, 0);
+                } catch (RuntimeException e) {
+                    // No-op
+                }
+            }
+            mConnectedToken = null;
+            mPendingCommands.clear();
+            mRequestedCommandSeqNumbers.clear();
+            mCallbackExecutor.execute(() -> {
+                mCallback.onDisconnected(MediaController2.this);
+            });
+            mSessionBinder = null;
+        }
+    }
+
+    /**
+     * Returns {@link Session2Token} of the connected session.
+     * If it is not connected yet, it returns {@code null}.
+     * <p>
+     * This may differ with the {@link Session2Token} from the constructor. For example, if the
+     * controller is created with the token for {@link MediaSession2Service}, this would return
+     * token for the {@link MediaSession2} in the service.
+     *
+     * @return Session2Token of the connected session, or {@code null} if not connected
+     */
+    @Nullable
+    public Session2Token getConnectedToken() {
+        synchronized (mLock) {
+            return mConnectedToken;
+        }
+    }
+
+    /**
+     * Returns whether the session's playback is active.
+     *
+     * @return {@code true} if playback active. {@code false} otherwise.
+     * @see ControllerCallback#onPlaybackActiveChanged(MediaController2, boolean)
+     */
+    public boolean isPlaybackActive() {
+        synchronized (mLock) {
+            return mPlaybackActive;
+        }
+    }
+
+    /**
+     * Sends a session command to the session
+     * <p>
+     * @param command the session command
+     * @param args optional arguments
+     * @return a token which will be sent together in {@link ControllerCallback#onCommandResult}
+     *        when its result is received.
+     */
+    @NonNull
+    public Object sendSessionCommand(@NonNull Session2Command command, @Nullable Bundle args) {
+        if (command == null) {
+            throw new IllegalArgumentException("command shouldn't be null");
+        }
+
+        ResultReceiver resultReceiver = new ResultReceiver(mResultHandler) {
+            protected void onReceiveResult(int resultCode, Bundle resultData) {
+                synchronized (mLock) {
+                    mPendingCommands.remove(this);
+                }
+                mCallbackExecutor.execute(() -> {
+                    mCallback.onCommandResult(MediaController2.this, this,
+                            command, new Session2Command.Result(resultCode, resultData));
+                });
+            }
+        };
+
+        synchronized (mLock) {
+            if (mSessionBinder != null) {
+                int seq = getNextSeqNumber();
+                mPendingCommands.put(resultReceiver, seq);
+                try {
+                    mSessionBinder.sendSessionCommand(mControllerStub, seq, command, args,
+                            resultReceiver);
+                } catch (RuntimeException e)  {
+                    mPendingCommands.remove(resultReceiver);
+                    resultReceiver.send(RESULT_ERROR_UNKNOWN_ERROR, null);
+                }
+            }
+        }
+        return resultReceiver;
+    }
+
+    /**
+     * Cancels the session command previously sent.
+     *
+     * @param token the token which is returned from {@link #sendSessionCommand}.
+     */
+    public void cancelSessionCommand(@NonNull Object token) {
+        if (token == null) {
+            throw new IllegalArgumentException("token shouldn't be null");
+        }
+        synchronized (mLock) {
+            if (mSessionBinder == null) return;
+            Integer seq = mPendingCommands.remove(token);
+            if (seq != null) {
+                mSessionBinder.cancelSessionCommand(mControllerStub, seq);
+            }
+        }
+    }
+
+    // Called by Controller2Link.onConnected
+    void onConnected(int seq, Bundle connectionResult) {
+        Session2Link sessionBinder = connectionResult.getParcelable(KEY_SESSION2LINK);
+        Session2CommandGroup allowedCommands =
+                connectionResult.getParcelable(KEY_ALLOWED_COMMANDS);
+        boolean playbackActive = connectionResult.getBoolean(KEY_PLAYBACK_ACTIVE);
+
+        Bundle tokenExtras = connectionResult.getBundle(KEY_TOKEN_EXTRAS);
+        if (tokenExtras == null) {
+            Log.w(TAG, "extras shouldn't be null.");
+            tokenExtras = Bundle.EMPTY;
+        } else if (MediaSession2.hasCustomParcelable(tokenExtras)) {
+            Log.w(TAG, "extras contain custom parcelable. Ignoring.");
+            tokenExtras = Bundle.EMPTY;
+        }
+
+        if (DEBUG) {
+            Log.d(TAG, "notifyConnected sessionBinder=" + sessionBinder
+                    + ", allowedCommands=" + allowedCommands);
+        }
+        if (sessionBinder == null || allowedCommands == null) {
+            // Connection rejected.
+            close();
+            return;
+        }
+        synchronized (mLock) {
+            mSessionBinder = sessionBinder;
+            mAllowedCommands = allowedCommands;
+            mPlaybackActive = playbackActive;
+
+            // Implementation for the local binder is no-op,
+            // so can be used without worrying about deadlock.
+            sessionBinder.linkToDeath(mDeathRecipient, 0);
+            mConnectedToken = new Session2Token(mSessionToken.getUid(), TYPE_SESSION,
+                    mSessionToken.getPackageName(), sessionBinder, tokenExtras);
+        }
+        mCallbackExecutor.execute(() -> {
+            mCallback.onConnected(MediaController2.this, allowedCommands);
+        });
+    }
+
+    // Called by Controller2Link.onDisconnected
+    void onDisconnected(int seq) {
+        // close() will call mCallback.onDisconnected
+        close();
+    }
+
+    // Called by Controller2Link.onPlaybackActiveChanged
+    void onPlaybackActiveChanged(int seq, boolean playbackActive) {
+        synchronized (mLock) {
+            mPlaybackActive = playbackActive;
+        }
+        mCallbackExecutor.execute(() -> {
+            mCallback.onPlaybackActiveChanged(MediaController2.this, playbackActive);
+        });
+    }
+
+    // Called by Controller2Link.onSessionCommand
+    void onSessionCommand(int seq, Session2Command command, Bundle args,
+            @Nullable ResultReceiver resultReceiver) {
+        synchronized (mLock) {
+            mRequestedCommandSeqNumbers.add(seq);
+        }
+        mCallbackExecutor.execute(() -> {
+            boolean isCanceled;
+            synchronized (mLock) {
+                isCanceled = !mRequestedCommandSeqNumbers.remove(seq);
+            }
+            if (isCanceled) {
+                if (resultReceiver != null) {
+                    resultReceiver.send(RESULT_INFO_SKIPPED, null);
+                }
+                return;
+            }
+            Session2Command.Result result = mCallback.onSessionCommand(
+                    MediaController2.this, command, args);
+            if (resultReceiver != null) {
+                if (result == null) {
+                    resultReceiver.send(RESULT_INFO_SKIPPED, null);
+                } else {
+                    resultReceiver.send(result.getResultCode(), result.getResultData());
+                }
+            }
+        });
+    }
+
+    // Called by Controller2Link.onSessionCommand
+    void onCancelCommand(int seq) {
+        synchronized (mLock) {
+            mRequestedCommandSeqNumbers.remove(seq);
+        }
+    }
+
+    private int getNextSeqNumber() {
+        synchronized (mLock) {
+            return mNextSeqNumber++;
+        }
+    }
+
+    private Bundle createConnectionRequest(@NonNull Bundle connectionHints) {
+        Bundle connectionRequest = new Bundle();
+        connectionRequest.putString(KEY_PACKAGE_NAME, mContext.getPackageName());
+        connectionRequest.putInt(KEY_PID, Process.myPid());
+        connectionRequest.putBundle(KEY_CONNECTION_HINTS, connectionHints);
+        return connectionRequest;
+    }
+
+    private boolean requestConnectToSession(@NonNull Bundle connectionHints) {
+        Session2Link sessionBinder = mSessionToken.getSessionLink();
+        Bundle connectionRequest = createConnectionRequest(connectionHints);
+        try {
+            sessionBinder.connect(mControllerStub, getNextSeqNumber(), connectionRequest);
+        } catch (RuntimeException e) {
+            Log.w(TAG, "Failed to call connection request", e);
+            return false;
+        }
+        return true;
+    }
+
+    private boolean requestConnectToService() {
+        // Service. Needs to get fresh binder whenever connection is needed.
+        final Intent intent = new Intent(MediaSession2Service.SERVICE_INTERFACE);
+        intent.setClassName(mSessionToken.getPackageName(), mSessionToken.getServiceName());
+
+        // Use bindService() instead of startForegroundService() to start session service for three
+        // reasons.
+        // 1. Prevent session service owner's stopSelf() from destroying service.
+        //    With the startForegroundService(), service's call of stopSelf() will trigger immediate
+        //    onDestroy() calls on the main thread even when onConnect() is running in another
+        //    thread.
+        // 2. Minimize APIs for developers to take care about.
+        //    With bindService(), developers only need to take care about Service.onBind()
+        //    but Service.onStartCommand() should be also taken care about with the
+        //    startForegroundService().
+        // 3. Future support for UI-less playback
+        //    If a service wants to keep running, it should be either foreground service or
+        //    bound service. But there had been request for the feature for system apps
+        //    and using bindService() will be better fit with it.
+        synchronized (mLock) {
+            boolean result = mContext.bindService(
+                    intent, mServiceConnection, Context.BIND_AUTO_CREATE);
+            if (!result) {
+                Log.w(TAG, "bind to " + mSessionToken + " failed");
+                return false;
+            } else if (DEBUG) {
+                Log.d(TAG, "bind to " + mSessionToken + " succeeded");
+            }
+        }
+        return true;
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Builder for {@link MediaController2}.
+     * <p>
+     * Any incoming event from the {@link MediaSession2} will be handled on the callback
+     * executor. If it's not set, {@link Context#getMainExecutor()} will be used by default.
+     */
+    public static final class Builder {
+        private Context mContext;
+        private Session2Token mToken;
+        private Bundle mConnectionHints;
+        private Executor mCallbackExecutor;
+        private ControllerCallback mCallback;
+
+        /**
+         * Creates a builder for {@link MediaController2}.
+         *
+         * @param context context
+         * @param token token of the session to connect to
+         */
+        public Builder(@NonNull Context context, @NonNull Session2Token token) {
+            if (context == null) {
+                throw new IllegalArgumentException("context shouldn't be null");
+            }
+            if (token == null) {
+                throw new IllegalArgumentException("token shouldn't be null");
+            }
+            mContext = context;
+            mToken = token;
+        }
+
+        /**
+         * Set the connection hints for the controller.
+         * <p>
+         * {@code connectionHints} is a session-specific argument to send to the session when
+         * connecting. The contents of this bundle may affect the connection result.
+         * <p>
+         * An {@link IllegalArgumentException} will be thrown if the bundle contains any
+         * non-framework Parcelable objects.
+         *
+         * @param connectionHints a bundle which contains the connection hints
+         * @return The Builder to allow chaining
+         */
+        @NonNull
+        public Builder setConnectionHints(@NonNull Bundle connectionHints) {
+            if (connectionHints == null) {
+                throw new IllegalArgumentException("connectionHints shouldn't be null");
+            }
+            if (MediaSession2.hasCustomParcelable(connectionHints)) {
+                throw new IllegalArgumentException("connectionHints shouldn't contain any custom "
+                        + "parcelables");
+            }
+            mConnectionHints = new Bundle(connectionHints);
+            return this;
+        }
+
+        /**
+         * Set callback for the controller and its executor.
+         *
+         * @param executor callback executor
+         * @param callback session callback.
+         * @return The Builder to allow chaining
+         */
+        @NonNull
+        public Builder setControllerCallback(@NonNull Executor executor,
+                @NonNull ControllerCallback callback) {
+            if (executor == null) {
+                throw new IllegalArgumentException("executor shouldn't be null");
+            }
+            if (callback == null) {
+                throw new IllegalArgumentException("callback shouldn't be null");
+            }
+            mCallbackExecutor = executor;
+            mCallback = callback;
+            return this;
+        }
+
+        /**
+         * Build {@link MediaController2}.
+         *
+         * @return a new controller
+         */
+        @NonNull
+        public MediaController2 build() {
+            if (mCallbackExecutor == null) {
+                mCallbackExecutor = mContext.getMainExecutor();
+            }
+            if (mCallback == null) {
+                mCallback = new ControllerCallback() {};
+            }
+            if (mConnectionHints == null) {
+                mConnectionHints = Bundle.EMPTY;
+            }
+            return new MediaController2(
+                    mContext, mToken, mConnectionHints, mCallbackExecutor, mCallback);
+        }
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Interface for listening to change in activeness of the {@link MediaSession2}.
+     */
+    public abstract static class ControllerCallback {
+        /**
+         * Called when the controller is successfully connected to the session. The controller
+         * becomes available afterwards.
+         *
+         * @param controller the controller for this event
+         * @param allowedCommands commands that's allowed by the session.
+         */
+        public void onConnected(@NonNull MediaController2 controller,
+                @NonNull Session2CommandGroup allowedCommands) {}
+
+        /**
+         * Called when the session refuses the controller or the controller is disconnected from
+         * the session. The controller becomes unavailable afterwards and the callback wouldn't
+         * be called.
+         * <p>
+         * It will be also called after the {@link #close()}, so you can put clean up code here.
+         * You don't need to call {@link #close()} after this.
+         *
+         * @param controller the controller for this event
+         */
+        public void onDisconnected(@NonNull MediaController2 controller) {}
+
+        /**
+         * Called when the session's playback activeness is changed.
+         *
+         * @param controller the controller for this event
+         * @param playbackActive {@code true} if the session's playback is active.
+         *                       {@code false} otherwise.
+         * @see MediaController2#isPlaybackActive()
+         */
+        public void onPlaybackActiveChanged(@NonNull MediaController2 controller,
+                boolean playbackActive) {}
+
+        /**
+         * Called when the connected session sent a session command.
+         *
+         * @param controller the controller for this event
+         * @param command the session command
+         * @param args optional arguments
+         * @return the result for the session command. If {@code null}, RESULT_INFO_SKIPPED
+         *         will be sent to the session.
+         */
+        @Nullable
+        public Session2Command.Result onSessionCommand(@NonNull MediaController2 controller,
+                @NonNull Session2Command command, @Nullable Bundle args) {
+            return null;
+        }
+
+        /**
+         * Called when the command sent to the connected session is finished.
+         *
+         * @param controller the controller for this event
+         * @param token the token got from {@link MediaController2#sendSessionCommand}
+         * @param command the session command
+         * @param result the result of the session command
+         */
+        public void onCommandResult(@NonNull MediaController2 controller, @NonNull Object token,
+                @NonNull Session2Command command, @NonNull Session2Command.Result result) {}
+    }
+
+    // This will be called on the main thread.
+    private class SessionServiceConnection implements ServiceConnection {
+        private final Bundle mConnectionHints;
+
+        SessionServiceConnection(@Nullable Bundle connectionHints) {
+            mConnectionHints = connectionHints;
+        }
+
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            // Note that it's always main-thread.
+            boolean connectRequested = false;
+            try {
+                if (DEBUG) {
+                    Log.d(TAG, "onServiceConnected " + name + " " + this);
+                }
+                if (!mSessionToken.getPackageName().equals(name.getPackageName())) {
+                    Log.wtf(TAG, "Expected connection to " + mSessionToken.getPackageName()
+                            + " but is connected to " + name);
+                    return;
+                }
+                IMediaSession2Service iService = IMediaSession2Service.Stub.asInterface(service);
+                if (iService == null) {
+                    Log.wtf(TAG, "Service interface is missing.");
+                    return;
+                }
+                Bundle connectionRequest = createConnectionRequest(mConnectionHints);
+                iService.connect(mControllerStub, getNextSeqNumber(), connectionRequest);
+                connectRequested = true;
+            } catch (RemoteException e) {
+                Log.w(TAG, "Service " + name + " has died prematurely", e);
+            } finally {
+                if (!connectRequested) {
+                    close();
+                }
+            }
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+            // Temporal lose of the binding because of the service crash. System will automatically
+            // rebind, so just no-op.
+            if (DEBUG) {
+                Log.w(TAG, "Session service " + name + " is disconnected.");
+            }
+            close();
+        }
+
+        @Override
+        public void onBindingDied(ComponentName name) {
+            // Permanent lose of the binding because of the service package update or removed.
+            // This SessionServiceRecord will be removed accordingly, but forget session binder here
+            // for sure.
+            close();
+        }
+    }
+}
diff --git a/android/media/MediaCrypto.java b/android/media/MediaCrypto.java
new file mode 100644
index 0000000..889a5f7
--- /dev/null
+++ b/android/media/MediaCrypto.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2012 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.annotation.NonNull;
+import android.media.MediaCryptoException;
+import java.util.UUID;
+
+/**
+ * MediaCrypto class can be used in conjunction with {@link android.media.MediaCodec}
+ * to decode encrypted media data.
+ *
+ * Crypto schemes are assigned 16 byte UUIDs,
+ * the method {@link #isCryptoSchemeSupported} can be used to query if a given
+ * scheme is supported on the device.
+ *
+ */
+public final class MediaCrypto {
+    /**
+     * Query if the given scheme identified by its UUID is supported on
+     * this device.
+     * @param uuid The UUID of the crypto scheme.
+     */
+    public static final boolean isCryptoSchemeSupported(@NonNull UUID uuid) {
+        return isCryptoSchemeSupportedNative(getByteArrayFromUUID(uuid));
+    }
+
+    @NonNull
+    private static final byte[] getByteArrayFromUUID(@NonNull UUID uuid) {
+        long msb = uuid.getMostSignificantBits();
+        long lsb = uuid.getLeastSignificantBits();
+
+        byte[] uuidBytes = new byte[16];
+        for (int i = 0; i < 8; ++i) {
+            uuidBytes[i] = (byte)(msb >>> (8 * (7 - i)));
+            uuidBytes[8 + i] = (byte)(lsb >>> (8 * (7 - i)));
+        }
+
+        return uuidBytes;
+    }
+
+    private static final native boolean isCryptoSchemeSupportedNative(@NonNull byte[] uuid);
+
+    /**
+     * Instantiate a MediaCrypto object and associate it with a MediaDrm session
+     *
+     * @param uuid The UUID of the crypto scheme.
+     * @param sessionId The MediaDrm sessionId to associate with this
+     * MediaCrypto session. The sessionId may be changed after the MediaCrypto
+     * is created using {@link #setMediaDrmSession}
+     */
+    public MediaCrypto(@NonNull UUID uuid, @NonNull byte[] sessionId) throws MediaCryptoException {
+        native_setup(getByteArrayFromUUID(uuid), sessionId);
+    }
+
+    /**
+     * Query if the crypto scheme requires the use of a secure decoder
+     * to decode data of the given mime type.
+     * @param mime The mime type of the media data
+     */
+    public final native boolean requiresSecureDecoderComponent(@NonNull String mime);
+
+    /**
+     * Associate a MediaDrm session with this MediaCrypto instance.  The
+     * MediaDrm session is used to securely load decryption keys for a
+     * crypto scheme.  The crypto keys loaded through the MediaDrm session
+     * may be selected for use during the decryption operation performed
+     * by {@link android.media.MediaCodec#queueSecureInputBuffer} by specifying
+     * their key ids in the {@link android.media.MediaCodec.CryptoInfo#key} field.
+     * @param sessionId the MediaDrm sessionId to associate with this
+     * MediaCrypto instance
+     * @throws MediaCryptoException on failure to set the sessionId
+     */
+    public final native void setMediaDrmSession(@NonNull byte[] sessionId)
+        throws MediaCryptoException;
+
+    @Override
+    protected void finalize() {
+        native_finalize();
+    }
+
+    public native final void release();
+    private static native final void native_init();
+
+    private native final void native_setup(@NonNull byte[] uuid, @NonNull byte[] initData)
+        throws MediaCryptoException;
+
+    private native final void native_finalize();
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    private long mNativeContext;
+}
diff --git a/android/media/MediaCryptoException.java b/android/media/MediaCryptoException.java
new file mode 100644
index 0000000..32ddf47
--- /dev/null
+++ b/android/media/MediaCryptoException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2012 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.annotation.Nullable;
+
+/**
+ * Exception thrown if MediaCrypto object could not be instantiated or
+ * if unable to perform an operation on the MediaCrypto object.
+ */
+public final class MediaCryptoException extends Exception {
+    public MediaCryptoException(@Nullable String detailMessage) {
+        super(detailMessage);
+    }
+}
diff --git a/android/media/MediaDataSource.java b/android/media/MediaDataSource.java
new file mode 100644
index 0000000..4bdc1ad
--- /dev/null
+++ b/android/media/MediaDataSource.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2012 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 java.io.Closeable;
+import java.io.IOException;
+
+/**
+ * For supplying media data to the framework. Implement this if your app has
+ * special requirements for the way media data is obtained.
+ *
+ * <p class="note">Methods of this interface may be called on multiple different
+ * threads. There will be a thread synchronization point between each call to ensure that
+ * modifications to the state of your MediaDataSource are visible to future calls. This means
+ * you don't need to do your own synchronization unless you're modifying the
+ * MediaDataSource from another thread while it's being used by the framework.</p>
+ */
+public abstract class MediaDataSource implements Closeable {
+    /**
+     * Called to request data from the given position.
+     *
+     * Implementations should fill {@code buffer} with up to {@code size}
+     * bytes of data, and return the number of valid bytes in the buffer.
+     *
+     * Return {@code 0} if size is zero (thus no bytes are read).
+     *
+     * Return {@code -1} to indicate that end of stream is reached.
+     *
+     * @param position the position in the data source to read from.
+     * @param buffer the buffer to read the data into.
+     * @param offset the offset within buffer to read the data into.
+     * @param size the number of bytes to read.
+     * @throws IOException on fatal errors.
+     * @return the number of bytes read, or -1 if end of stream is reached.
+     */
+    public abstract int readAt(long position, byte[] buffer, int offset, int size)
+            throws IOException;
+
+    /**
+     * Called to get the size of the data source.
+     *
+     * @throws IOException on fatal errors
+     * @return the size of data source in bytes, or -1 if the size is unknown.
+     */
+    public abstract long getSize() throws IOException;
+}
diff --git a/android/media/MediaDescrambler.java b/android/media/MediaDescrambler.java
new file mode 100644
index 0000000..99bd254
--- /dev/null
+++ b/android/media/MediaDescrambler.java
@@ -0,0 +1,259 @@
+/*
+ * Copyright (C) 2017 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.annotation.NonNull;
+import android.hardware.cas.V1_0.*;
+import android.media.MediaCasException.UnsupportedCasException;
+import android.os.IHwBinder;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+
+/**
+ * MediaDescrambler class can be used in conjunction with {@link android.media.MediaCodec}
+ * and {@link android.media.MediaExtractor} to decode media data scrambled by conditional
+ * access (CA) systems such as those in the ISO/IEC13818-1.
+ *
+ * A MediaDescrambler object is initialized from a session opened by a MediaCas object,
+ * and can be used to descramble media streams scrambled with that session's keys.
+ *
+ * Scrambling schemes are identified by 16-bit unsigned integer as in CA_system_id.
+ *
+ */
+public final class MediaDescrambler implements AutoCloseable {
+    private static final String TAG = "MediaDescrambler";
+    private IDescramblerBase mIDescrambler;
+
+    private final void validateInternalStates() {
+        if (mIDescrambler == null) {
+            throw new IllegalStateException();
+        }
+    }
+
+    private final void cleanupAndRethrowIllegalState() {
+        mIDescrambler = null;
+        throw new IllegalStateException();
+    }
+
+    /**
+     * Instantiate a MediaDescrambler.
+     *
+     * @param CA_system_id The system id of the scrambling scheme.
+     *
+     * @throws UnsupportedCasException if the scrambling scheme is not supported.
+     */
+    public MediaDescrambler(int CA_system_id) throws UnsupportedCasException {
+        try {
+            mIDescrambler = MediaCas.getService().createDescrambler(CA_system_id);
+        } catch(Exception e) {
+            Log.e(TAG, "Failed to create descrambler: " + e);
+            mIDescrambler = null;
+        } finally {
+            if (mIDescrambler == null) {
+                throw new UnsupportedCasException("Unsupported CA_system_id " + CA_system_id);
+            }
+        }
+        native_setup(mIDescrambler.asBinder());
+    }
+
+    IHwBinder getBinder() {
+        validateInternalStates();
+
+        return mIDescrambler.asBinder();
+    }
+
+    /**
+     * Query if the scrambling scheme requires the use of a secure decoder
+     * to decode data of the given mime type.
+     *
+     * @param mime The mime type of the media data
+     *
+     * @throws IllegalStateException if the descrambler instance is not valid.
+     */
+    public final boolean requiresSecureDecoderComponent(@NonNull String mime) {
+        validateInternalStates();
+
+        try {
+            return mIDescrambler.requiresSecureDecoderComponent(mime);
+        } catch (RemoteException e) {
+            cleanupAndRethrowIllegalState();
+        }
+        return true;
+    }
+
+    /**
+     * Associate a MediaCas session with this MediaDescrambler instance.
+     * The MediaCas session is used to securely load decryption keys for
+     * the descrambler. The crypto keys loaded through the MediaCas session
+     * may be selected for use during the descrambling operation performed
+     * by {@link android.media.MediaExtractor or @link
+     * android.media.MediaCodec#queueSecureInputBuffer} by specifying even
+     * or odd key in the {@link android.media.MediaCodec.CryptoInfo#key} field.
+     *
+     * @param session the MediaCas session to associate with this
+     * MediaDescrambler instance.
+     *
+     * @throws IllegalStateException if the descrambler instance is not valid.
+     * @throws MediaCasStateException for CAS-specific state exceptions.
+     */
+    public final void setMediaCasSession(@NonNull MediaCas.Session session) {
+        validateInternalStates();
+
+        try {
+            MediaCasStateException.throwExceptionIfNeeded(
+                    mIDescrambler.setMediaCasSession(session.mSessionId));
+        } catch (RemoteException e) {
+            cleanupAndRethrowIllegalState();
+        }
+    }
+
+    /**
+     * Scramble control value indicating that the samples are not scrambled.
+     * @see #descramble(ByteBuffer, ByteBuffer, android.media.MediaCodec.CryptoInfo)
+     */
+    public static final byte SCRAMBLE_CONTROL_UNSCRAMBLED = 0;
+
+    /**
+     * Scramble control value reserved and shouldn't be used currently.
+     * @see #descramble(ByteBuffer, ByteBuffer, android.media.MediaCodec.CryptoInfo)
+     */
+    public static final byte SCRAMBLE_CONTROL_RESERVED    = 1;
+
+    /**
+     * Scramble control value indicating that the even key is used.
+     * @see #descramble(ByteBuffer, ByteBuffer, android.media.MediaCodec.CryptoInfo)
+     */
+    public static final byte SCRAMBLE_CONTROL_EVEN_KEY     = 2;
+
+    /**
+     * Scramble control value indicating that the odd key is used.
+     * @see #descramble(ByteBuffer, ByteBuffer, android.media.MediaCodec.CryptoInfo)
+     */
+    public static final byte SCRAMBLE_CONTROL_ODD_KEY      = 3;
+
+    /**
+     * Scramble flag for a hint indicating that the descrambling request is for
+     * retrieving the PES header info only.
+     *
+     * @see #descramble(ByteBuffer, ByteBuffer, android.media.MediaCodec.CryptoInfo)
+     */
+    public static final byte SCRAMBLE_FLAG_PES_HEADER = (1 << 0);
+
+    /**
+     * Descramble a ByteBuffer of data described by a
+     * {@link android.media.MediaCodec.CryptoInfo} structure.
+     *
+     * @param srcBuf ByteBuffer containing the scrambled data, which starts at
+     * srcBuf.position().
+     * @param dstBuf ByteBuffer to hold the descrambled data, which starts at
+     * dstBuf.position().
+     * @param cryptoInfo a {@link android.media.MediaCodec.CryptoInfo} structure
+     * describing the subsamples contained in srcBuf. The iv and mode fields in
+     * CryptoInfo are not used. key[0] contains the MPEG2TS scrambling control bits
+     * (as defined in ETSI TS 100 289 (2011): "Digital Video Broadcasting (DVB);
+     * Support for use of the DVB Scrambling Algorithm version 3 within digital
+     * broadcasting systems"), and the value must be one of {@link #SCRAMBLE_CONTROL_UNSCRAMBLED},
+     * {@link #SCRAMBLE_CONTROL_RESERVED}, {@link #SCRAMBLE_CONTROL_EVEN_KEY} or
+     * {@link #SCRAMBLE_CONTROL_ODD_KEY}. key[1] is a set of bit flags, with the
+     * only possible bit being {@link #SCRAMBLE_FLAG_PES_HEADER} currently.
+     * key[2~15] are not used.
+     *
+     * @return number of bytes that have been successfully descrambled, with negative
+     * values indicating errors.
+     *
+     * @throws IllegalStateException if the descrambler instance is not valid.
+     * @throws MediaCasStateException for CAS-specific state exceptions.
+     */
+    public final int descramble(
+            @NonNull ByteBuffer srcBuf, @NonNull ByteBuffer dstBuf,
+            @NonNull MediaCodec.CryptoInfo cryptoInfo) {
+        validateInternalStates();
+
+        if (cryptoInfo.numSubSamples <= 0) {
+            throw new IllegalArgumentException(
+                    "Invalid CryptoInfo: invalid numSubSamples=" + cryptoInfo.numSubSamples);
+        } else if (cryptoInfo.numBytesOfClearData == null
+                && cryptoInfo.numBytesOfEncryptedData == null) {
+            throw new IllegalArgumentException(
+                    "Invalid CryptoInfo: clearData and encryptedData size arrays are both null!");
+        } else if (cryptoInfo.numBytesOfClearData != null
+                && cryptoInfo.numBytesOfClearData.length < cryptoInfo.numSubSamples) {
+            throw new IllegalArgumentException(
+                    "Invalid CryptoInfo: numBytesOfClearData is too small!");
+        } else if (cryptoInfo.numBytesOfEncryptedData != null
+                && cryptoInfo.numBytesOfEncryptedData.length < cryptoInfo.numSubSamples) {
+            throw new IllegalArgumentException(
+                    "Invalid CryptoInfo: numBytesOfEncryptedData is too small!");
+        } else if (cryptoInfo.key == null || cryptoInfo.key.length != 16) {
+            throw new IllegalArgumentException(
+                    "Invalid CryptoInfo: key array is invalid!");
+        }
+
+        try {
+            return native_descramble(
+                    cryptoInfo.key[0],
+                    cryptoInfo.key[1],
+                    cryptoInfo.numSubSamples,
+                    cryptoInfo.numBytesOfClearData,
+                    cryptoInfo.numBytesOfEncryptedData,
+                    srcBuf, srcBuf.position(), srcBuf.limit(),
+                    dstBuf, dstBuf.position(), dstBuf.limit());
+        } catch (ServiceSpecificException e) {
+            MediaCasStateException.throwExceptionIfNeeded(e.errorCode, e.getMessage());
+        } catch (RemoteException e) {
+            cleanupAndRethrowIllegalState();
+        }
+        return -1;
+    }
+
+    @Override
+    public void close() {
+        if (mIDescrambler != null) {
+            try {
+                mIDescrambler.release();
+            } catch (RemoteException e) {
+            } finally {
+                mIDescrambler = null;
+            }
+        }
+        native_release();
+    }
+
+    @Override
+    protected void finalize() {
+        close();
+    }
+
+    private static native final void native_init();
+    private native final void native_setup(@NonNull IHwBinder decramblerBinder);
+    private native final void native_release();
+    private native final int native_descramble(
+            byte key, byte flags, int numSubSamples,
+            int[] numBytesOfClearData, int[] numBytesOfEncryptedData,
+            @NonNull ByteBuffer srcBuf, int srcOffset, int srcLimit,
+            ByteBuffer dstBuf, int dstOffset, int dstLimit) throws RemoteException;
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    private long mNativeContext;
+}
\ No newline at end of file
diff --git a/android/media/MediaDescription.java b/android/media/MediaDescription.java
new file mode 100644
index 0000000..458562a
--- /dev/null
+++ b/android/media/MediaDescription.java
@@ -0,0 +1,404 @@
+/*
+ * Copyright 2019 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.annotation.Nullable;
+import android.graphics.Bitmap;
+import android.media.browse.MediaBrowser;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+/**
+ * A simple set of metadata for a media item suitable for display. This can be
+ * created using the Builder or retrieved from existing metadata using
+ * {@link MediaMetadata#getDescription()}.
+ */
+public class MediaDescription implements Parcelable {
+    /**
+     * A unique persistent id for the content or null.
+     */
+    private final String mMediaId;
+    /**
+     * A primary title suitable for display or null.
+     */
+    private final CharSequence mTitle;
+    /**
+     * A subtitle suitable for display or null.
+     */
+    private final CharSequence mSubtitle;
+    /**
+     * A description suitable for display or null.
+     */
+    private final CharSequence mDescription;
+    /**
+     * A bitmap icon suitable for display or null.
+     */
+    private final Bitmap mIcon;
+    /**
+     * A Uri for an icon suitable for display or null.
+     */
+    private final Uri mIconUri;
+    /**
+     * Extras for opaque use by apps/system.
+     */
+    private final Bundle mExtras;
+    /**
+     * A Uri to identify this content.
+     */
+    private final Uri mMediaUri;
+
+    /**
+     * Used as a long extra field to indicate the bluetooth folder type of the media item as
+     * specified in the section 6.10.2.2 of the Bluetooth AVRCP 1.5. This is valid only for
+     * {@link MediaBrowser.MediaItem} with {@link MediaBrowser.MediaItem#FLAG_BROWSABLE}. The value
+     * should be one of the following:
+     * <ul>
+     * <li>{@link #BT_FOLDER_TYPE_MIXED}</li>
+     * <li>{@link #BT_FOLDER_TYPE_TITLES}</li>
+     * <li>{@link #BT_FOLDER_TYPE_ALBUMS}</li>
+     * <li>{@link #BT_FOLDER_TYPE_ARTISTS}</li>
+     * <li>{@link #BT_FOLDER_TYPE_GENRES}</li>
+     * <li>{@link #BT_FOLDER_TYPE_PLAYLISTS}</li>
+     * <li>{@link #BT_FOLDER_TYPE_YEARS}</li>
+     * </ul>
+     *
+     * @see #getExtras()
+     */
+    public static final String EXTRA_BT_FOLDER_TYPE = "android.media.extra.BT_FOLDER_TYPE";
+
+    /**
+     * The type of folder that is unknown or contains media elements of mixed types as specified in
+     * the section 6.10.2.2 of the Bluetooth AVRCP 1.5.
+     */
+    public static final long BT_FOLDER_TYPE_MIXED = 0;
+
+    /**
+     * The type of folder that contains media elements only as specified in the section 6.10.2.2 of
+     * the Bluetooth AVRCP 1.5.
+     */
+    public static final long BT_FOLDER_TYPE_TITLES = 1;
+
+    /**
+     * The type of folder that contains folders categorized by album as specified in the section
+     * 6.10.2.2 of the Bluetooth AVRCP 1.5.
+     */
+    public static final long BT_FOLDER_TYPE_ALBUMS = 2;
+
+    /**
+     * The type of folder that contains folders categorized by artist as specified in the section
+     * 6.10.2.2 of the Bluetooth AVRCP 1.5.
+     */
+    public static final long BT_FOLDER_TYPE_ARTISTS = 3;
+
+    /**
+     * The type of folder that contains folders categorized by genre as specified in the section
+     * 6.10.2.2 of the Bluetooth AVRCP 1.5.
+     */
+    public static final long BT_FOLDER_TYPE_GENRES = 4;
+
+    /**
+     * The type of folder that contains folders categorized by playlist as specified in the section
+     * 6.10.2.2 of the Bluetooth AVRCP 1.5.
+     */
+    public static final long BT_FOLDER_TYPE_PLAYLISTS = 5;
+
+    /**
+     * The type of folder that contains folders categorized by year as specified in the section
+     * 6.10.2.2 of the Bluetooth AVRCP 1.5.
+     */
+    public static final long BT_FOLDER_TYPE_YEARS = 6;
+
+    private MediaDescription(String mediaId, CharSequence title, CharSequence subtitle,
+            CharSequence description, Bitmap icon, Uri iconUri, Bundle extras, Uri mediaUri) {
+        mMediaId = mediaId;
+        mTitle = title;
+        mSubtitle = subtitle;
+        mDescription = description;
+        mIcon = icon;
+        mIconUri = iconUri;
+        mExtras = extras;
+        mMediaUri = mediaUri;
+    }
+
+    private MediaDescription(Parcel in) {
+        mMediaId = in.readString();
+        mTitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+        mSubtitle = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+        mDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+        mIcon = in.readParcelable(null);
+        mIconUri = in.readParcelable(null);
+        mExtras = in.readBundle();
+        mMediaUri = in.readParcelable(null);
+    }
+
+    /**
+     * Returns the media id or null. See
+     * {@link MediaMetadata#METADATA_KEY_MEDIA_ID}.
+     */
+    public @Nullable String getMediaId() {
+        return mMediaId;
+    }
+
+    /**
+     * Returns a title suitable for display or null.
+     *
+     * @return A title or null.
+     */
+    public @Nullable CharSequence getTitle() {
+        return mTitle;
+    }
+
+    /**
+     * Returns a subtitle suitable for display or null.
+     *
+     * @return A subtitle or null.
+     */
+    public @Nullable CharSequence getSubtitle() {
+        return mSubtitle;
+    }
+
+    /**
+     * Returns a description suitable for display or null.
+     *
+     * @return A description or null.
+     */
+    public @Nullable CharSequence getDescription() {
+        return mDescription;
+    }
+
+    /**
+     * Returns a bitmap icon suitable for display or null.
+     *
+     * @return An icon or null.
+     */
+    public @Nullable Bitmap getIconBitmap() {
+        return mIcon;
+    }
+
+    /**
+     * Returns a Uri for an icon suitable for display or null.
+     *
+     * @return An icon uri or null.
+     */
+    public @Nullable Uri getIconUri() {
+        return mIconUri;
+    }
+
+    /**
+     * Returns any extras that were added to the description.
+     *
+     * @return A bundle of extras or null.
+     */
+    public @Nullable Bundle getExtras() {
+        return mExtras;
+    }
+
+    /**
+     * Returns a Uri representing this content or null.
+     *
+     * @return A media Uri or null.
+     */
+    public @Nullable Uri getMediaUri() {
+        return mMediaUri;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeString(mMediaId);
+        TextUtils.writeToParcel(mTitle, dest, 0);
+        TextUtils.writeToParcel(mSubtitle, dest, 0);
+        TextUtils.writeToParcel(mDescription, dest, 0);
+        dest.writeParcelable(mIcon, flags);
+        dest.writeParcelable(mIconUri, flags);
+        dest.writeBundle(mExtras);
+        dest.writeParcelable(mMediaUri, flags);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == null) {
+            return false;
+        }
+
+        if (!(o instanceof MediaDescription)) {
+            return false;
+        }
+
+        final MediaDescription d = (MediaDescription) o;
+
+        if (!String.valueOf(mTitle).equals(String.valueOf(d.mTitle))) {
+            return false;
+        }
+
+        if (!String.valueOf(mSubtitle).equals(String.valueOf(d.mSubtitle))) {
+            return false;
+        }
+
+        if (!String.valueOf(mDescription).equals(String.valueOf(d.mDescription))) {
+            return false;
+        }
+
+        return true;
+    }
+
+    @Override
+    public String toString() {
+        return mTitle + ", " + mSubtitle + ", " + mDescription;
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<MediaDescription> CREATOR =
+            new Parcelable.Creator<MediaDescription>() {
+                @Override
+                public MediaDescription createFromParcel(Parcel in) {
+                    return new MediaDescription(in);
+                }
+
+                @Override
+                public MediaDescription[] newArray(int size) {
+                    return new MediaDescription[size];
+                }
+            };
+
+    /**
+     * Builder for {@link MediaDescription} objects.
+     */
+    public static class Builder {
+        private String mMediaId;
+        private CharSequence mTitle;
+        private CharSequence mSubtitle;
+        private CharSequence mDescription;
+        private Bitmap mIcon;
+        private Uri mIconUri;
+        private Bundle mExtras;
+        private Uri mMediaUri;
+
+        /**
+         * Creates an initially empty builder.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Sets the media id.
+         *
+         * @param mediaId The unique id for the item or null.
+         * @return this
+         */
+        public Builder setMediaId(@Nullable String mediaId) {
+            mMediaId = mediaId;
+            return this;
+        }
+
+        /**
+         * Sets the title.
+         *
+         * @param title A title suitable for display to the user or null.
+         * @return this
+         */
+        public Builder setTitle(@Nullable CharSequence title) {
+            mTitle = title;
+            return this;
+        }
+
+        /**
+         * Sets the subtitle.
+         *
+         * @param subtitle A subtitle suitable for display to the user or null.
+         * @return this
+         */
+        public Builder setSubtitle(@Nullable CharSequence subtitle) {
+            mSubtitle = subtitle;
+            return this;
+        }
+
+        /**
+         * Sets the description.
+         *
+         * @param description A description suitable for display to the user or
+         *            null.
+         * @return this
+         */
+        public Builder setDescription(@Nullable CharSequence description) {
+            mDescription = description;
+            return this;
+        }
+
+        /**
+         * Sets the icon.
+         *
+         * @param icon A {@link Bitmap} icon suitable for display to the user or
+         *            null.
+         * @return this
+         */
+        public Builder setIconBitmap(@Nullable Bitmap icon) {
+            mIcon = icon;
+            return this;
+        }
+
+        /**
+         * Sets the icon uri.
+         *
+         * @param iconUri A {@link Uri} for an icon suitable for display to the
+         *            user or null.
+         * @return this
+         */
+        public Builder setIconUri(@Nullable Uri iconUri) {
+            mIconUri = iconUri;
+            return this;
+        }
+
+        /**
+         * Sets a bundle of extras.
+         *
+         * @param extras The extras to include with this description or null.
+         * @return this
+         */
+        public Builder setExtras(@Nullable Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Sets the media uri.
+         *
+         * @param mediaUri The content's {@link Uri} for the item or null.
+         * @return this
+         */
+        public Builder setMediaUri(@Nullable Uri mediaUri) {
+            mMediaUri = mediaUri;
+            return this;
+        }
+
+        /**
+         * Build {@link MediaDescription}.
+         *
+         * @return a new media description.
+         */
+        public MediaDescription build() {
+            return new MediaDescription(mMediaId, mTitle, mSubtitle, mDescription, mIcon, mIconUri,
+                    mExtras, mMediaUri);
+        }
+    }
+}
diff --git a/android/media/MediaDrm.java b/android/media/MediaDrm.java
new file mode 100644
index 0000000..3a19b13
--- /dev/null
+++ b/android/media/MediaDrm.java
@@ -0,0 +1,3067 @@
+/*
+ * Copyright (C) 2013 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.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.StringDef;
+import android.app.ActivityThread;
+import android.app.Application;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.Signature;
+import android.media.metrics.LogSessionId;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.Looper;
+import android.os.Parcel;
+import android.os.PersistableBundle;
+import android.util.Log;
+
+import dalvik.system.CloseGuard;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.time.Instant;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.Base64;
+import java.util.HashMap;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.function.Consumer;
+import java.util.function.Function;
+
+/**
+ * MediaDrm can be used to obtain keys for decrypting protected media streams, in
+ * conjunction with {@link android.media.MediaCrypto}.  The MediaDrm APIs
+ * are designed to support the ISO/IEC 23001-7: Common Encryption standard, but
+ * may also be used to implement other encryption schemes.
+ * <p>
+ * Encrypted content is prepared using an encryption server and stored in a content
+ * library. The encrypted content is streamed or downloaded from the content library to
+ * client devices via content servers.  Licenses to view the content are obtained from
+ * a License Server.
+ * <p>
+ * <p><img src="../../../images/mediadrm_overview.png"
+ *      alt="MediaDrm Overview diagram"
+ *      border="0" /></p>
+ * <p>
+ * Keys are requested from the license server using a key request. The key
+ * response is delivered to the client app, which provides the response to the
+ * MediaDrm API.
+ * <p>
+ * A Provisioning server may be required to distribute device-unique credentials to
+ * the devices.
+ * <p>
+ * Enforcing requirements related to the number of devices that may play content
+ * simultaneously can be performed either through key renewal or using the secure
+ * stop methods.
+ * <p>
+ * The following sequence diagram shows the interactions between the objects
+ * involved while playing back encrypted content:
+ * <p>
+ * <p><img src="../../../images/mediadrm_decryption_sequence.png"
+ *         alt="MediaDrm Overview diagram"
+ *         border="0" /></p>
+ * <p>
+ * The app first constructs {@link android.media.MediaExtractor} and
+ * {@link android.media.MediaCodec} objects. It accesses the DRM-scheme-identifying UUID,
+ * typically from metadata in the content, and uses this UUID to construct an instance
+ * of a MediaDrm object that is able to support the DRM scheme required by the content.
+ * Crypto schemes are assigned 16 byte UUIDs.  The method {@link #isCryptoSchemeSupported}
+ * can be used to query if a given scheme is supported on the device.
+ * <p>
+ * The app calls {@link #openSession} to generate a sessionId that will uniquely identify
+ * the session in subsequent interactions. The app next uses the MediaDrm object to
+ * obtain a key request message and send it to the license server, then provide
+ * the server's response to the MediaDrm object.
+ * <p>
+ * Once the app has a sessionId, it can construct a MediaCrypto object from the UUID and
+ * sessionId.  The MediaCrypto object is registered with the MediaCodec in the
+ * {@link MediaCodec#configure} method to enable the codec to decrypt content.
+ * <p>
+ * When the app has constructed {@link android.media.MediaExtractor},
+ * {@link android.media.MediaCodec} and {@link android.media.MediaCrypto} objects,
+ * it proceeds to pull samples from the extractor and queue them into the decoder.  For
+ * encrypted content, the samples returned from the extractor remain encrypted, they
+ * are only decrypted when the samples are delivered to the decoder.
+ * <p>
+ * MediaDrm methods throw {@link android.media.MediaDrm.MediaDrmStateException}
+ * when a method is called on a MediaDrm object that has had an unrecoverable failure
+ * in the DRM plugin or security hardware.
+ * {@link android.media.MediaDrm.MediaDrmStateException} extends
+ * {@link java.lang.IllegalStateException} with the addition of a developer-readable
+ * diagnostic information string associated with the exception.
+ * <p>
+ * In the event of a mediaserver process crash or restart while a MediaDrm object
+ * is active, MediaDrm methods may throw {@link android.media.MediaDrmResetException}.
+ * To recover, the app must release the MediaDrm object, then create and initialize
+ * a new one.
+ * <p>
+ * As {@link android.media.MediaDrmResetException} and
+ * {@link android.media.MediaDrm.MediaDrmStateException} both extend
+ * {@link java.lang.IllegalStateException}, they should be in an earlier catch()
+ * block than {@link java.lang.IllegalStateException} if handled separately.
+ * <p>
+ * <a name="Callbacks"></a>
+ * <h3>Callbacks</h3>
+ * <p>Applications should register for informational events in order
+ * to be informed of key state updates during playback or streaming.
+ * Registration for these events is done via a call to
+ * {@link #setOnEventListener}. In order to receive the respective
+ * callback associated with this listener, applications are required to create
+ * MediaDrm objects on a thread with its own Looper running (main UI
+ * thread by default has a Looper running).
+ */
+public final class MediaDrm implements AutoCloseable {
+
+    private static final String TAG = "MediaDrm";
+
+    private final AtomicBoolean mClosed = new AtomicBoolean();
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
+    private static final String PERMISSION = android.Manifest.permission.ACCESS_DRM_CERTIFICATES;
+
+    private long mNativeContext;
+    private final String mAppPackageName;
+
+    /**
+     * Specify no certificate type
+     *
+     * @hide - not part of the public API at this time
+     */
+    public static final int CERTIFICATE_TYPE_NONE = 0;
+
+    /**
+     * Specify X.509 certificate type
+     *
+     * @hide - not part of the public API at this time
+     */
+    public static final int CERTIFICATE_TYPE_X509 = 1;
+
+    /** @hide */
+    @IntDef({
+        CERTIFICATE_TYPE_NONE,
+        CERTIFICATE_TYPE_X509,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CertificateType {}
+
+    /**
+     * Query if the given scheme identified by its UUID is supported on
+     * this device.
+     * @param uuid The UUID of the crypto scheme.
+     */
+    public static final boolean isCryptoSchemeSupported(@NonNull UUID uuid) {
+        return isCryptoSchemeSupportedNative(getByteArrayFromUUID(uuid), null,
+                SECURITY_LEVEL_UNKNOWN);
+    }
+
+    /**
+     * Query if the given scheme identified by its UUID is supported on
+     * this device, and whether the DRM plugin is able to handle the
+     * media container format specified by mimeType.
+     * @param uuid The UUID of the crypto scheme.
+     * @param mimeType The MIME type of the media container, e.g. "video/mp4"
+     *   or "video/webm"
+     */
+    public static final boolean isCryptoSchemeSupported(
+            @NonNull UUID uuid, @NonNull String mimeType) {
+        return isCryptoSchemeSupportedNative(getByteArrayFromUUID(uuid),
+                mimeType, SECURITY_LEVEL_UNKNOWN);
+    }
+
+    /**
+     * Query if the given scheme identified by its UUID is supported on
+     * this device, and whether the DRM plugin is able to handle the
+     * media container format specified by mimeType at the requested
+     * security level.
+     *
+     * @param uuid The UUID of the crypto scheme.
+     * @param mimeType The MIME type of the media container, e.g. "video/mp4"
+     *   or "video/webm"
+     * @param securityLevel the security level requested
+     */
+    public static final boolean isCryptoSchemeSupported(
+            @NonNull UUID uuid, @NonNull String mimeType, @SecurityLevel int securityLevel) {
+        return isCryptoSchemeSupportedNative(getByteArrayFromUUID(uuid), mimeType,
+                securityLevel);
+    }
+
+    /**
+     * @return list of crypto schemes (as {@link UUID}s) for which
+     * {@link #isCryptoSchemeSupported(UUID)} returns true; each {@link UUID}
+     * can be used as input to create {@link MediaDrm} objects via {@link #MediaDrm(UUID)}.
+     */
+    public static final @NonNull List<UUID> getSupportedCryptoSchemes(){
+        byte[] uuidBytes = getSupportedCryptoSchemesNative();
+        return getUUIDsFromByteArray(uuidBytes);
+    }
+
+    private static final byte[] getByteArrayFromUUID(@NonNull UUID uuid) {
+        long msb = uuid.getMostSignificantBits();
+        long lsb = uuid.getLeastSignificantBits();
+
+        byte[] uuidBytes = new byte[16];
+        for (int i = 0; i < 8; ++i) {
+            uuidBytes[i] = (byte)(msb >>> (8 * (7 - i)));
+            uuidBytes[8 + i] = (byte)(lsb >>> (8 * (7 - i)));
+        }
+
+        return uuidBytes;
+    }
+
+    private static final UUID getUUIDFromByteArray(@NonNull byte[] uuidBytes, int off) {
+        long msb = 0;
+        long lsb = 0;
+
+        for (int i = 0; i < 8; ++i) {
+            msb = (msb << 8) | (0xffl & uuidBytes[off + i]);
+            lsb = (lsb << 8) | (0xffl & uuidBytes[off + i + 8]);
+        }
+
+        return new UUID(msb, lsb);
+    }
+
+    private static final List<UUID> getUUIDsFromByteArray(@NonNull byte[] uuidBytes) {
+        Set<UUID> uuids = new LinkedHashSet<>();
+        for (int off = 0; off < uuidBytes.length; off+=16) {
+            uuids.add(getUUIDFromByteArray(uuidBytes, off));
+        }
+        return new ArrayList<>(uuids);
+    }
+
+    private static final native byte[] getSupportedCryptoSchemesNative();
+
+    private static final native boolean isCryptoSchemeSupportedNative(
+            @NonNull byte[] uuid, @Nullable String mimeType, @SecurityLevel int securityLevel);
+
+    private Handler createHandler() {
+        Looper looper;
+        Handler handler;
+        if ((looper = Looper.myLooper()) != null) {
+            handler = new Handler(looper);
+        } else if ((looper = Looper.getMainLooper()) != null) {
+            handler = new Handler(looper);
+        } else {
+            handler = null;
+        }
+        return handler;
+    }
+
+    /**
+     * Instantiate a MediaDrm object
+     *
+     * @param uuid The UUID of the crypto scheme.
+     *
+     * @throws UnsupportedSchemeException if the device does not support the
+     * specified scheme UUID
+     */
+    public MediaDrm(@NonNull UUID uuid) throws UnsupportedSchemeException {
+        /* Native setup requires a weak reference to our object.
+         * It's easier to create it here than in C++.
+         */
+        mAppPackageName = ActivityThread.currentOpPackageName();
+        native_setup(new WeakReference<MediaDrm>(this),
+                getByteArrayFromUUID(uuid), mAppPackageName);
+
+        mCloseGuard.open("release");
+    }
+
+    /**
+     * Error codes that may be returned from {@link
+     * MediaDrmStateException#getErrorCode()} and {@link
+     * MediaCodec.CryptoException#getErrorCode()}
+     * <p>
+     * The description of each error code includes steps that may be taken to
+     * resolve the error condition. For some errors however, a recovery action
+     * cannot be predetermined. The description of those codes refers to a
+     * general strategy for handling the error condition programmatically, which
+     * is to try the following in listed order until successful:
+     * <ol>
+     * <li> retry the operation </li>
+     * <li> if the operation is related to a session, {@link
+     * #closeSession(byte[]) close} the session, {@link #openSession() open} a
+     * new session, and retry the operation </li>
+     * <li> {@link #close() close} the {@link MediaDrm} instance and any other
+     * related components such as the {@link MediaCodec codec} and retry
+     * playback, or </li>
+     * <li> try using a different configuration of the {@link MediaDrm} plugin,
+     * such as a different {@link #openSession(int) security level}. </li>
+     * </ol>
+     * <p>
+     * If the problem still persists after all the aforementioned steps, please
+     * report the failure to the {@link MediaDrm} plugin vendor along with the
+     * {@link LogMessage log messages} returned by {@link
+     * MediaDrm#getLogMessages()}, and a bugreport if possible.
+     */
+    public final static class ErrorCodes {
+        private ErrorCodes() {}
+
+        /**
+         * ERROR_UNKNOWN is used where no other defined error code is applicable
+         * to the current failure.
+         * <p>
+         * Please see the general error handling strategy for unexpected errors
+         * described in {@link ErrorCodes}.
+         */
+        public static final int ERROR_UNKNOWN = 0;
+
+        /**
+         * The requested key was not found when trying to perform a decrypt
+         * operation.
+         * <p>
+         * The operation can be retried after adding the correct decryption key.
+         */
+        public static final int ERROR_NO_KEY = 1;
+
+        /**
+         * The key used for decryption is no longer valid due to license term
+         * expiration.
+         * <p>
+         * The operation can be retried after updating the expired keys.
+         */
+        public static final int ERROR_KEY_EXPIRED = 2;
+
+        /**
+         * A required crypto resource was not able to be allocated while
+         * attempting the requested operation.
+         * <p>
+         * The operation can be retried if the app is able to release resources.
+         */
+        public static final int ERROR_RESOURCE_BUSY = 3;
+
+        /**
+         * The output protection levels supported by the device are not
+         * sufficient to meet the requirements set by the content owner in the
+         * license policy.
+         */
+        public static final int ERROR_INSUFFICIENT_OUTPUT_PROTECTION = 4;
+
+        /**
+         * Decryption was attempted on a session that is not opened, which could
+         * be due to a failure to open the session, closing the session
+         * prematurely, the session being reclaimed by the resource manager, or
+         * a non-existent session id.
+         */
+        public static final int ERROR_SESSION_NOT_OPENED = 5;
+
+        /**
+         * An operation was attempted that could not be supported by the crypto
+         * system of the device in its current configuration.
+         * <p>
+         * This may occur when the license policy requires device security
+         * features that aren't supported by the device, or due to an internal
+         * error in the crypto system that prevents the specified security
+         * policy from being met.
+         */
+        public static final int ERROR_UNSUPPORTED_OPERATION = 6;
+
+        /**
+         * The security level of the device is not sufficient to meet the
+         * requirements set by the content owner in the license policy.
+         */
+        public static final int ERROR_INSUFFICIENT_SECURITY = 7;
+
+        /**
+         * The video frame being decrypted exceeds the size of the device's
+         * protected output buffers.
+         * <p>
+         * When encountering this error the app should try playing content
+         * of a lower resolution or skipping the problematic frame.
+         */
+        public static final int ERROR_FRAME_TOO_LARGE = 8;
+
+        /**
+         * The session state has been invalidated. This can occur on devices
+         * that are not capable of retaining crypto session state across device
+         * suspend/resume.
+         * <p>
+         * The session must be closed and a new session opened to resume
+         * operation.
+         */
+        public static final int ERROR_LOST_STATE = 9;
+
+        /**
+         * Certificate is malformed or is of the wrong type.
+         * <p>
+         * Ensure the certificate provided by the app or returned from the
+         * license server is valid. Check with the {@link MediaDrm} plugin
+         * vendor for the expected certificate format.
+         */
+        public static final int ERROR_CERTIFICATE_MALFORMED = 10;
+
+        /**
+         * Certificate has not been set.
+         * <p>
+         * Ensure the certificate has been provided by the app. Check with the
+         * {@link MediaDrm} plugin vendor for the expected method to provide
+         * {@link MediaDrm} a certificate.
+         */
+        public static final int ERROR_CERTIFICATE_MISSING = 11;
+
+        /**
+         * An error happened within the crypto library used by the drm plugin.
+         */
+        public static final int ERROR_CRYPTO_LIBRARY = 12;
+
+        /**
+         * Unexpected error reported by the device OEM subsystem.
+         * <p>
+         * Please see the general error handling strategy for unexpected errors
+         * described in {@link ErrorCodes}.
+         */
+        public static final int ERROR_GENERIC_OEM = 13;
+
+        /**
+         * Unexpected internal failure in {@link MediaDrm}/{@link MediaCrypto}.
+         * <p>
+         * Please see the general error handling strategy for unexpected errors
+         * described in {@link ErrorCodes}.
+         */
+        public static final int ERROR_GENERIC_PLUGIN = 14;
+
+        /**
+         * The init data parameter passed to {@link MediaDrm#getKeyRequest} is
+         * empty or invalid.
+         * <p>
+         * Init data is typically obtained from {@link
+         * MediaExtractor#getPsshInfo()} or {@link
+         * MediaExtractor#getDrmInitData()}. Check with the {@link MediaDrm}
+         * plugin vendor for the expected init data format.
+         */
+        public static final int ERROR_INIT_DATA = 15;
+
+        /**
+         * Either the key was not loaded from the license before attempting the
+         * operation, or the key ID parameter provided by the app is incorrect.
+         * <p>
+         * Ensure the proper keys are in the license, and check the key ID
+         * parameter provided by the app is correct. Check with the {@link
+         * MediaDrm} plugin vendor for the expected license format.
+         */
+        public static final int ERROR_KEY_NOT_LOADED = 16;
+
+        /**
+         * The license response was empty, fields are missing or otherwise
+         * unable to be parsed or decrypted.
+         * <p>
+         * Check for mistakes such as empty or overwritten buffers. Otherwise,
+         * check with the {@link MediaDrm} plugin vendor for the expected
+         * license format.
+         */
+        public static final int ERROR_LICENSE_PARSE = 17;
+
+        /**
+         * The operation (e.g. to renew or persist a license) is prohibited by
+         * the license policy.
+         * <p>
+         * Check the license policy configuration on the license server.
+         */
+        public static final int ERROR_LICENSE_POLICY = 18;
+
+        /**
+         * Failed to generate a release request because a field in the offline
+         * license is empty or malformed.
+         * <p>
+         * The license can't be released on the server, but the app may remove
+         * the offline license explicitly using {@link
+         * MediaDrm#removeOfflineLicense}.
+         */
+        public static final int ERROR_LICENSE_RELEASE = 19;
+
+        /**
+         * The license server detected an error in the license request.
+         * <p>
+         * Check for errors on the license server.
+         */
+        public static final int ERROR_LICENSE_REQUEST_REJECTED = 20;
+
+        /**
+         * Failed to restore an offline license because a field in the offline
+         * license is empty or malformed.
+         * <p>
+         * Try requesting the license again if the device is online.
+         */
+        public static final int ERROR_LICENSE_RESTORE = 21;
+
+        /**
+         * Offline license is in an invalid state for the attempted operation.
+         * <p>
+         * Check the sequence of API calls made that can affect offline license
+         * state. For example, this could happen when the app attempts to
+         * restore a license after it has been released.
+         */
+        public static final int ERROR_LICENSE_STATE = 22;
+
+        /**
+         * Failure in the media framework.
+         * <p>
+         * Try releasing media resources (e.g. {@link MediaCodec}, {@link
+         * MediaDrm}), and restarting playback.
+         */
+        public static final int ERROR_MEDIA_FRAMEWORK = 23;
+
+        /**
+         * Error loading the provisioned certificate.
+         * <p>
+         * Re-provisioning may resolve the problem; check with the {@link
+         * MediaDrm} plugin vendor for re-provisioning instructions. Otherwise,
+         * using a different security level may resolve the issue.
+         */
+        public static final int ERROR_PROVISIONING_CERTIFICATE = 24;
+
+        /**
+         * Required steps were not performed before provisioning was attempted.
+         * <p>
+         * Ask the {@link MediaDrm} plugin vendor for situations where this
+         * error may occur.
+         */
+        public static final int ERROR_PROVISIONING_CONFIG = 25;
+
+        /**
+         * The provisioning response was empty, fields are missing or otherwise
+         * unable to be parsed.
+         * <p>
+         * Check for mistakes such as empty or overwritten buffers. Otherwise,
+         * check with the {@link MediaDrm} plugin vendor for the expected
+         * provisioning response format.
+         */
+        public static final int ERROR_PROVISIONING_PARSE = 26;
+
+        /**
+         * The provisioning server detected an error in the provisioning
+         * request.
+         * <p>
+         * Check for errors on the provisioning server.
+         */
+        public static final int ERROR_PROVISIONING_REQUEST_REJECTED = 27;
+
+        /**
+         * Provisioning failed in a way that is likely to succeed on a
+         * subsequent attempt.
+         * <p>
+         * The app should retry the operation.
+         */
+        public static final int ERROR_PROVISIONING_RETRY = 28;
+
+        /**
+         * This indicates that apps using MediaDrm sessions are
+         * temporarily exceeding the capacity of available crypto
+         * resources.
+         * <p>
+         * The app should retry the operation later.
+         */
+        public static final int ERROR_RESOURCE_CONTENTION = 29;
+
+        /**
+         * Failed to generate a secure stop request because a field in the
+         * stored license is empty or malformed.
+         * <p>
+         * The secure stop can't be released on the server, but the app may
+         * remove it explicitly using {@link MediaDrm#removeSecureStop}.
+         */
+        public static final int ERROR_SECURE_STOP_RELEASE = 30;
+
+        /**
+         * The plugin was unable to read data from the filesystem.
+         * <p>
+         * Please see the general error handling strategy for unexpected errors
+         * described in {@link ErrorCodes}.
+         */
+        public static final int ERROR_STORAGE_READ = 31;
+
+        /**
+         * The plugin was unable to write data to the filesystem.
+         * <p>
+         * Please see the general error handling strategy for unexpected errors
+         * described in {@link ErrorCodes}.
+         */
+        public static final int ERROR_STORAGE_WRITE = 32;
+
+        /**
+         * {@link MediaCodec#queueSecureInputBuffer} called with 0 subsamples.
+         * <p>
+         * Check the {@link MediaCodec.CryptoInfo} object passed to {@link
+         * MediaCodec#queueSecureInputBuffer}.
+         */
+        public static final int ERROR_ZERO_SUBSAMPLES = 33;
+
+    }
+
+    /** @hide */
+    @IntDef({
+        ErrorCodes.ERROR_NO_KEY,
+        ErrorCodes.ERROR_KEY_EXPIRED,
+        ErrorCodes.ERROR_RESOURCE_BUSY,
+        ErrorCodes.ERROR_INSUFFICIENT_OUTPUT_PROTECTION,
+        ErrorCodes.ERROR_SESSION_NOT_OPENED,
+        ErrorCodes.ERROR_UNSUPPORTED_OPERATION,
+        ErrorCodes.ERROR_INSUFFICIENT_SECURITY,
+        ErrorCodes.ERROR_FRAME_TOO_LARGE,
+        ErrorCodes.ERROR_LOST_STATE,
+        ErrorCodes.ERROR_CERTIFICATE_MALFORMED,
+        ErrorCodes.ERROR_CERTIFICATE_MISSING,
+        ErrorCodes.ERROR_CRYPTO_LIBRARY,
+        ErrorCodes.ERROR_GENERIC_OEM,
+        ErrorCodes.ERROR_GENERIC_PLUGIN,
+        ErrorCodes.ERROR_INIT_DATA,
+        ErrorCodes.ERROR_KEY_NOT_LOADED,
+        ErrorCodes.ERROR_LICENSE_PARSE,
+        ErrorCodes.ERROR_LICENSE_POLICY,
+        ErrorCodes.ERROR_LICENSE_RELEASE,
+        ErrorCodes.ERROR_LICENSE_REQUEST_REJECTED,
+        ErrorCodes.ERROR_LICENSE_RESTORE,
+        ErrorCodes.ERROR_LICENSE_STATE,
+        ErrorCodes.ERROR_MEDIA_FRAMEWORK,
+        ErrorCodes.ERROR_PROVISIONING_CERTIFICATE,
+        ErrorCodes.ERROR_PROVISIONING_CONFIG,
+        ErrorCodes.ERROR_PROVISIONING_PARSE,
+        ErrorCodes.ERROR_PROVISIONING_REQUEST_REJECTED,
+        ErrorCodes.ERROR_PROVISIONING_RETRY,
+        ErrorCodes.ERROR_SECURE_STOP_RELEASE,
+        ErrorCodes.ERROR_STORAGE_READ,
+        ErrorCodes.ERROR_STORAGE_WRITE,
+        ErrorCodes.ERROR_ZERO_SUBSAMPLES
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MediaDrmErrorCode {}
+
+    /**
+     * Thrown when a general failure occurs during a MediaDrm operation.
+     * Extends {@link IllegalStateException} with the addition of an error
+     * code that may be useful in diagnosing the failure.
+     * <p>
+     * Please refer to {@link ErrorCodes} for the general error handling
+     * strategy and details about each possible return value from {@link
+     * MediaDrmStateException#getErrorCode()}.
+     */
+    public static final class MediaDrmStateException extends java.lang.IllegalStateException {
+        private final int mErrorCode;
+        private final String mDiagnosticInfo;
+
+        /**
+         * @hide
+         */
+        public MediaDrmStateException(int errorCode, @Nullable String detailMessage) {
+            super(detailMessage);
+            mErrorCode = errorCode;
+
+            // TODO get this from DRM session
+            final String sign = errorCode < 0 ? "neg_" : "";
+            mDiagnosticInfo =
+                "android.media.MediaDrm.error_" + sign + Math.abs(errorCode);
+
+        }
+
+        /**
+         * Returns error code associated with this {@link
+         * MediaDrmStateException}.
+         * <p>
+         * Please refer to {@link ErrorCodes} for the general error handling
+         * strategy and details about each possible return value.
+         *
+         * @return an error code defined in {@link MediaDrm.ErrorCodes}.
+         */
+        @MediaDrmErrorCode
+        public int getErrorCode() {
+            return mErrorCode;
+        }
+
+        /**
+         * Returns true if the {@link MediaDrmStateException} is a transient
+         * issue, perhaps due to resource constraints, and that the operation
+         * (e.g. provisioning) may succeed on a subsequent attempt.
+         */
+        public boolean isTransient() {
+            return mErrorCode == ErrorCodes.ERROR_PROVISIONING_RETRY
+                    || mErrorCode == ErrorCodes.ERROR_RESOURCE_CONTENTION;
+        }
+
+        /**
+         * Retrieve a developer-readable diagnostic information string
+         * associated with the exception. Do not show this to end-users,
+         * since this string will not be localized or generally comprehensible
+         * to end-users.
+         */
+        @NonNull
+        public String getDiagnosticInfo() {
+            return mDiagnosticInfo;
+        }
+    }
+
+    /**
+     * {@link SessionException} is a misnomer because it may occur in methods
+     * <b>without</b> a session context.
+     * <p>
+     * A {@link SessionException} is most likely to be thrown when an operation
+     * failed in a way that is likely to succeed on a subsequent attempt; call
+     * {@link #isTransient()} to determine whether the app should retry the
+     * failing operation.
+     */
+    public static final class SessionException extends RuntimeException {
+        public SessionException(int errorCode, @Nullable String detailMessage) {
+            super(detailMessage);
+            mErrorCode = errorCode;
+        }
+
+        /**
+         * The SessionException has an unknown error code.
+         * @deprecated Unused.
+         */
+        public static final int ERROR_UNKNOWN = 0;
+
+        /**
+         * This indicates that apps using MediaDrm sessions are
+         * temporarily exceeding the capacity of available crypto
+         * resources. The app should retry the operation later.
+         *
+         * @deprecated Please use {@link #isTransient()} instead of comparing
+         * the return value of {@link #getErrorCode()} against
+         * {@link SessionException#ERROR_RESOURCE_CONTENTION}.
+         */
+        public static final int ERROR_RESOURCE_CONTENTION = 1;
+
+        /** @hide */
+        @IntDef({
+            ERROR_RESOURCE_CONTENTION,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface SessionErrorCode {}
+
+        /**
+         * Retrieve the error code associated with the SessionException
+         *
+         * @deprecated Please use {@link #isTransient()} instead of comparing
+         * the return value of {@link #getErrorCode()} against
+         * {@link SessionException#ERROR_RESOURCE_CONTENTION}.
+         */
+        @SessionErrorCode
+        public int getErrorCode() {
+            return mErrorCode;
+        }
+
+        /**
+         * Returns true if the {@link SessionException} is a transient
+         * issue, perhaps due to resource constraints, and that the operation
+         * (e.g. provisioning, generating requests) may succeed on a subsequent
+         * attempt.
+         */
+        public boolean isTransient() {
+            return mErrorCode == ERROR_RESOURCE_CONTENTION;
+        }
+
+        private final int mErrorCode;
+    }
+
+    /**
+     * Register a callback to be invoked when a session expiration update
+     * occurs.  The app's OnExpirationUpdateListener will be notified
+     * when the expiration time of the keys in the session have changed.
+     * @param listener the callback that will be run, or {@code null} to unregister the
+     *     previously registered callback.
+     * @param handler the handler on which the listener should be invoked, or
+     *     {@code null} if the listener should be invoked on the calling thread's looper.
+     */
+    public void setOnExpirationUpdateListener(
+            @Nullable OnExpirationUpdateListener listener, @Nullable Handler handler) {
+        setListenerWithHandler(EXPIRATION_UPDATE, handler, listener,
+                this::createOnExpirationUpdateListener);
+    }
+    /**
+     * Register a callback to be invoked when a session expiration update
+     * occurs.
+     *
+     * @see #setOnExpirationUpdateListener(OnExpirationUpdateListener, Handler)
+     *
+     * @param executor the executor through which the listener should be invoked
+     * @param listener the callback that will be run.
+     */
+    public void setOnExpirationUpdateListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnExpirationUpdateListener listener) {
+        setListenerWithExecutor(EXPIRATION_UPDATE, executor, listener,
+                this::createOnExpirationUpdateListener);
+    }
+
+    /**
+     * Clear the {@link OnExpirationUpdateListener}.
+     */
+    public void clearOnExpirationUpdateListener() {
+        clearGenericListener(EXPIRATION_UPDATE);
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when a drm session
+     * expiration update occurs
+     */
+    public interface OnExpirationUpdateListener
+    {
+        /**
+         * Called when a session expiration update occurs, to inform the app
+         * about the change in expiration time
+         *
+         * @param md the MediaDrm object on which the event occurred
+         * @param sessionId the DRM session ID on which the event occurred
+         * @param expirationTime the new expiration time for the keys in the session.
+         *     The time is in milliseconds, relative to the Unix epoch.  A time of
+         *     0 indicates that the keys never expire.
+         */
+        void onExpirationUpdate(
+                @NonNull MediaDrm md, @NonNull byte[] sessionId, long expirationTime);
+    }
+
+    /**
+     * Register a callback to be invoked when the state of keys in a session
+     * change, e.g. when a license update occurs or when a license expires.
+     *
+     * @param listener the callback that will be run when key status changes, or
+     *     {@code null} to unregister the previously registered callback.
+     * @param handler the handler on which the listener should be invoked, or
+     *     null if the listener should be invoked on the calling thread's looper.
+     */
+    public void setOnKeyStatusChangeListener(
+            @Nullable OnKeyStatusChangeListener listener, @Nullable Handler handler) {
+        setListenerWithHandler(KEY_STATUS_CHANGE, handler, listener,
+                this::createOnKeyStatusChangeListener);
+    }
+
+    /**
+     * Register a callback to be invoked when the state of keys in a session
+     * change.
+     *
+     * @see #setOnKeyStatusChangeListener(OnKeyStatusChangeListener, Handler)
+     *
+     * @param listener the callback that will be run when key status changes.
+     * @param executor the executor on which the listener should be invoked.
+     */
+    public void setOnKeyStatusChangeListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnKeyStatusChangeListener listener) {
+        setListenerWithExecutor(KEY_STATUS_CHANGE, executor, listener,
+                this::createOnKeyStatusChangeListener);
+    }
+
+    /**
+     * Clear the {@link OnKeyStatusChangeListener}.
+     */
+    public void clearOnKeyStatusChangeListener() {
+        clearGenericListener(KEY_STATUS_CHANGE);
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when the keys in a drm
+     * session change states.
+     */
+    public interface OnKeyStatusChangeListener
+    {
+        /**
+         * Called when the keys in a session change status, such as when the license
+         * is renewed or expires.
+         *
+         * @param md the MediaDrm object on which the event occurred
+         * @param sessionId the DRM session ID on which the event occurred
+         * @param keyInformation a list of {@link MediaDrm.KeyStatus}
+         *     instances indicating the status for each key in the session
+         * @param hasNewUsableKey indicates if a key has been added that is usable,
+         *     which may trigger an attempt to resume playback on the media stream
+         *     if it is currently blocked waiting for a key.
+         */
+        void onKeyStatusChange(
+                @NonNull MediaDrm md, @NonNull byte[] sessionId,
+                @NonNull List<KeyStatus> keyInformation,
+                boolean hasNewUsableKey);
+    }
+
+    /**
+     * Register a callback to be invoked when session state has been
+     * lost. This event can occur on devices that are not capable of
+     * retaining crypto session state across device suspend/resume
+     * cycles.  When this event occurs, the session must be closed and
+     * a new session opened to resume operation.
+     *
+     * @param listener the callback that will be run, or {@code null} to unregister the
+     *     previously registered callback.
+     * @param handler the handler on which the listener should be invoked, or
+     *     {@code null} if the listener should be invoked on the calling thread's looper.
+     */
+    public void setOnSessionLostStateListener(
+            @Nullable OnSessionLostStateListener listener, @Nullable Handler handler) {
+        setListenerWithHandler(SESSION_LOST_STATE, handler, listener,
+                this::createOnSessionLostStateListener);
+    }
+
+    /**
+     * Register a callback to be invoked when session state has been
+     * lost.
+     *
+     * @see #setOnSessionLostStateListener(OnSessionLostStateListener, Handler)
+     *
+     * @param listener the callback that will be run.
+     * @param executor the executor on which the listener should be invoked.
+     */
+    public void setOnSessionLostStateListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @Nullable OnSessionLostStateListener listener) {
+        setListenerWithExecutor(SESSION_LOST_STATE, executor, listener,
+                this::createOnSessionLostStateListener);
+    }
+
+    /**
+     * Clear the {@link OnSessionLostStateListener}.
+     */
+    public void clearOnSessionLostStateListener() {
+        clearGenericListener(SESSION_LOST_STATE);
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when the
+     * session state has been lost and is now invalid
+     */
+    public interface OnSessionLostStateListener
+    {
+        /**
+         * Called when session state has lost state, to inform the app
+         * about the condition so it can close the session and open a new
+         * one to resume operation.
+         *
+         * @param md the MediaDrm object on which the event occurred
+         * @param sessionId the DRM session ID on which the event occurred
+         */
+        void onSessionLostState(
+                @NonNull MediaDrm md, @NonNull byte[] sessionId);
+    }
+
+    /**
+     * Defines the status of a key.
+     * A KeyStatus for each key in a session is provided to the
+     * {@link OnKeyStatusChangeListener#onKeyStatusChange}
+     * listener.
+     */
+    public static final class KeyStatus {
+        private final byte[] mKeyId;
+        private final int mStatusCode;
+
+        /**
+         * The key is currently usable to decrypt media data
+         */
+        public static final int STATUS_USABLE = 0;
+
+        /**
+         * The key is no longer usable to decrypt media data because its
+         * expiration time has passed.
+         */
+        public static final int STATUS_EXPIRED = 1;
+
+        /**
+         * The key is not currently usable to decrypt media data because its
+         * output requirements cannot currently be met.
+         */
+        public static final int STATUS_OUTPUT_NOT_ALLOWED = 2;
+
+        /**
+         * The status of the key is not yet known and is being determined.
+         * The status will be updated with the actual status when it has
+         * been determined.
+         */
+        public static final int STATUS_PENDING = 3;
+
+        /**
+         * The key is not currently usable to decrypt media data because of an
+         * internal error in processing unrelated to input parameters.  This error
+         * is not actionable by an app.
+         */
+        public static final int STATUS_INTERNAL_ERROR = 4;
+
+        /**
+         * The key is not yet usable to decrypt media because the start
+         * time is in the future. The key will become usable when
+         * its start time is reached.
+         */
+        public static final int STATUS_USABLE_IN_FUTURE = 5;
+
+        /** @hide */
+        @IntDef({
+            STATUS_USABLE,
+            STATUS_EXPIRED,
+            STATUS_OUTPUT_NOT_ALLOWED,
+            STATUS_PENDING,
+            STATUS_INTERNAL_ERROR,
+            STATUS_USABLE_IN_FUTURE,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface KeyStatusCode {}
+
+        KeyStatus(@NonNull byte[] keyId, @KeyStatusCode int statusCode) {
+            mKeyId = keyId;
+            mStatusCode = statusCode;
+        }
+
+        /**
+         * Returns the status code for the key
+         */
+        @KeyStatusCode
+        public int getStatusCode() { return mStatusCode; }
+
+        /**
+         * Returns the id for the key
+         */
+        @NonNull
+        public byte[] getKeyId() { return mKeyId; }
+    }
+
+    /**
+     * Register a callback to be invoked when an event occurs
+     *
+     * @see #setOnEventListener(OnEventListener, Handler)
+     *
+     * @param listener the callback that will be run.  Use {@code null} to
+     *        stop receiving event callbacks.
+     */
+    public void setOnEventListener(@Nullable OnEventListener listener)
+    {
+        setOnEventListener(listener, null);
+    }
+
+    /**
+     * Register a callback to be invoked when an event occurs
+     *
+     * @param listener the callback that will be run.  Use {@code null} to
+     *        stop receiving event callbacks.
+     * @param handler the handler on which the listener should be invoked, or
+     *        null if the listener should be invoked on the calling thread's looper.
+     */
+
+    public void setOnEventListener(@Nullable OnEventListener listener, @Nullable Handler handler)
+    {
+        setListenerWithHandler(DRM_EVENT, handler, listener, this::createOnEventListener);
+    }
+
+    /**
+     * Register a callback to be invoked when an event occurs
+     *
+     * @see #setOnEventListener(OnEventListener)
+     *
+     * @param executor the executor through which the listener should be invoked
+     * @param listener the callback that will be run.
+     */
+    public void setOnEventListener(@NonNull @CallbackExecutor Executor executor,
+            @NonNull OnEventListener listener) {
+        setListenerWithExecutor(DRM_EVENT, executor, listener, this::createOnEventListener);
+    }
+
+    /**
+     * Clear the {@link OnEventListener}.
+     */
+    public void clearOnEventListener() {
+        clearGenericListener(DRM_EVENT);
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when a drm event
+     * occurs
+     */
+    public interface OnEventListener
+    {
+        /**
+         * Called when an event occurs that requires the app to be notified
+         *
+         * @param md the MediaDrm object on which the event occurred
+         * @param sessionId the DRM session ID on which the event occurred,
+         *        or {@code null} if there is no session ID associated with the event.
+         * @param event indicates the event type
+         * @param extra an secondary error code
+         * @param data optional byte array of data that may be associated with the event
+         */
+        void onEvent(
+                @NonNull MediaDrm md, @Nullable byte[] sessionId,
+                @DrmEvent int event, int extra,
+                @Nullable byte[] data);
+    }
+
+    /**
+     * This event type indicates that the app needs to request a certificate from
+     * the provisioning server.  The request message data is obtained using
+     * {@link #getProvisionRequest}
+     *
+     * @deprecated Handle provisioning via {@link android.media.NotProvisionedException}
+     * instead.
+     */
+    public static final int EVENT_PROVISION_REQUIRED = 1;
+
+    /**
+     * This event type indicates that the app needs to request keys from a license
+     * server.  The request message data is obtained using {@link #getKeyRequest}.
+     */
+    public static final int EVENT_KEY_REQUIRED = 2;
+
+    /**
+     * This event type indicates that the licensed usage duration for keys in a session
+     * has expired.  The keys are no longer valid.
+     * @deprecated Use {@link OnKeyStatusChangeListener#onKeyStatusChange}
+     * and check for {@link MediaDrm.KeyStatus#STATUS_EXPIRED} in the {@link MediaDrm.KeyStatus}
+     * instead.
+     */
+    public static final int EVENT_KEY_EXPIRED = 3;
+
+    /**
+     * This event may indicate some specific vendor-defined condition, see your
+     * DRM provider documentation for details
+     */
+    public static final int EVENT_VENDOR_DEFINED = 4;
+
+    /**
+     * This event indicates that a session opened by the app has been reclaimed by the resource
+     * manager.
+     */
+    public static final int EVENT_SESSION_RECLAIMED = 5;
+
+    /** @hide */
+    @IntDef({
+        EVENT_PROVISION_REQUIRED,
+        EVENT_KEY_REQUIRED,
+        EVENT_KEY_EXPIRED,
+        EVENT_VENDOR_DEFINED,
+        EVENT_SESSION_RECLAIMED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DrmEvent {}
+
+    private static final int DRM_EVENT = 200;
+    private static final int EXPIRATION_UPDATE = 201;
+    private static final int KEY_STATUS_CHANGE = 202;
+    private static final int SESSION_LOST_STATE = 203;
+
+    // Use ConcurrentMap to support concurrent read/write to listener settings.
+    // ListenerWithExecutor is immutable so we shouldn't need further locks.
+    private final Map<Integer, ListenerWithExecutor> mListenerMap = new ConcurrentHashMap<>();
+
+    // called by old-style set*Listener APIs using Handlers; listener & handler are Nullable
+    private <T> void setListenerWithHandler(int what, Handler handler, T listener,
+            Function<T, Consumer<ListenerArgs>> converter) {
+        if (listener == null) {
+            clearGenericListener(what);
+        } else {
+            handler = handler == null ? createHandler() : handler;
+            final HandlerExecutor executor = new HandlerExecutor(handler);
+            setGenericListener(what, executor, listener, converter);
+        }
+    }
+
+    // called by new-style set*Listener APIs using Executors; listener & executor must be NonNull
+    private <T> void setListenerWithExecutor(int what, Executor executor, T listener,
+            Function<T, Consumer<ListenerArgs>> converter) {
+        if (executor == null || listener == null) {
+            final String errMsg = String.format("executor %s listener %s", executor, listener);
+            throw new IllegalArgumentException(errMsg);
+        }
+        setGenericListener(what, executor, listener, converter);
+    }
+
+    private <T> void setGenericListener(int what, Executor executor, T listener,
+            Function<T, Consumer<ListenerArgs>> converter) {
+        mListenerMap.put(what, new ListenerWithExecutor(executor, converter.apply(listener)));
+    }
+
+    private void clearGenericListener(int what) {
+        mListenerMap.remove(what);
+    }
+
+    private Consumer<ListenerArgs> createOnEventListener(OnEventListener listener) {
+        return args -> {
+            byte[] sessionId = args.sessionId;
+            if (sessionId.length == 0) {
+                sessionId = null;
+            }
+            byte[] data = args.data;
+            if (data != null && data.length == 0) {
+                data = null;
+            }
+
+            Log.i(TAG, "Drm event (" + args.arg1 + "," + args.arg2 + ")");
+            listener.onEvent(this, sessionId, args.arg1, args.arg2, data);
+        };
+    }
+
+    private Consumer<ListenerArgs> createOnKeyStatusChangeListener(
+            OnKeyStatusChangeListener listener) {
+        return args -> {
+            byte[] sessionId = args.sessionId;
+            if (sessionId.length > 0) {
+                List<KeyStatus> keyStatusList = args.keyStatusList;
+                boolean hasNewUsableKey = args.hasNewUsableKey;
+
+                Log.i(TAG, "Drm key status changed");
+                listener.onKeyStatusChange(this, sessionId, keyStatusList, hasNewUsableKey);
+            }
+        };
+    }
+
+    private Consumer<ListenerArgs> createOnExpirationUpdateListener(
+            OnExpirationUpdateListener listener) {
+        return args -> {
+            byte[] sessionId = args.sessionId;
+            if (sessionId.length > 0) {
+                long expirationTime = args.expirationTime;
+
+                Log.i(TAG, "Drm key expiration update: " + expirationTime);
+                listener.onExpirationUpdate(this, sessionId, expirationTime);
+            }
+        };
+    }
+
+    private Consumer<ListenerArgs> createOnSessionLostStateListener(
+            OnSessionLostStateListener listener) {
+        return args -> {
+            byte[] sessionId = args.sessionId;
+            Log.i(TAG, "Drm session lost state event: ");
+            listener.onSessionLostState(this, sessionId);
+        };
+    }
+
+    private static class ListenerArgs {
+        private final int arg1;
+        private final int arg2;
+        private final byte[] sessionId;
+        private final byte[] data;
+        private final long expirationTime;
+        private final List<KeyStatus> keyStatusList;
+        private final boolean hasNewUsableKey;
+
+        public ListenerArgs(
+                int arg1,
+                int arg2,
+                byte[] sessionId,
+                byte[] data,
+                long expirationTime,
+                List<KeyStatus> keyStatusList,
+                boolean hasNewUsableKey) {
+            this.arg1 = arg1;
+            this.arg2 = arg2;
+            this.sessionId = sessionId;
+            this.data = data;
+            this.expirationTime = expirationTime;
+            this.keyStatusList = keyStatusList;
+            this.hasNewUsableKey = hasNewUsableKey;
+        }
+
+    }
+
+    private static class ListenerWithExecutor {
+        private final Consumer<ListenerArgs> mConsumer;
+        private final Executor mExecutor;
+
+        public ListenerWithExecutor(Executor executor, Consumer<ListenerArgs> consumer) {
+            this.mExecutor = executor;
+            this.mConsumer = consumer;
+        }
+    }
+
+    /**
+     * Parse a list of KeyStatus objects from an event parcel
+     */
+    @NonNull
+    private List<KeyStatus> keyStatusListFromParcel(@NonNull Parcel parcel) {
+        int nelems = parcel.readInt();
+        List<KeyStatus> keyStatusList = new ArrayList(nelems);
+        while (nelems-- > 0) {
+            byte[] keyId = parcel.createByteArray();
+            int keyStatusCode = parcel.readInt();
+            keyStatusList.add(new KeyStatus(keyId, keyStatusCode));
+        }
+        return keyStatusList;
+    }
+
+    /**
+     * This method is called from native code when an event occurs.  This method
+     * just uses the EventHandler system to post the event back to the main app thread.
+     * We use a weak reference to the original MediaPlayer object so that the native
+     * code is safe from the object disappearing from underneath it.  (This is
+     * the cookie passed to native_setup().)
+     */
+    private static void postEventFromNative(@NonNull Object mediadrm_ref,
+            int what, int eventType, int extra,
+            byte[] sessionId, byte[] data, long expirationTime,
+            List<KeyStatus> keyStatusList, boolean hasNewUsableKey)
+    {
+        MediaDrm md = (MediaDrm)((WeakReference<MediaDrm>)mediadrm_ref).get();
+        if (md == null) {
+            return;
+        }
+        switch (what) {
+            case DRM_EVENT:
+            case EXPIRATION_UPDATE:
+            case KEY_STATUS_CHANGE:
+            case SESSION_LOST_STATE:
+                ListenerWithExecutor listener  = md.mListenerMap.get(what);
+                if (listener != null) {
+                    final Runnable command = () -> {
+                        if (md.mNativeContext == 0) {
+                            Log.w(TAG, "MediaDrm went away with unhandled events");
+                            return;
+                        }
+                        ListenerArgs args = new ListenerArgs(eventType, extra,
+                                sessionId, data, expirationTime,
+                                keyStatusList, hasNewUsableKey);
+                        listener.mConsumer.accept(args);
+                    };
+                    listener.mExecutor.execute(command);
+                }
+                break;
+            default:
+                Log.e(TAG, "Unknown message type " + what);
+                break;
+        }
+    }
+
+    /**
+     * Open a new session with the MediaDrm object. A session ID is returned.
+     * By default, sessions are opened at the native security level of the device.
+     *
+     * @throws NotProvisionedException if provisioning is needed
+     * @throws ResourceBusyException if required resources are in use
+     */
+    @NonNull
+    public byte[] openSession() throws NotProvisionedException,
+            ResourceBusyException {
+        return openSession(getMaxSecurityLevel());
+    }
+
+    /**
+     * Open a new session at a requested security level. The security level
+     * represents the robustness of the device's DRM implementation. By default,
+     * sessions are opened at the native security level of the device.
+     * Overriding the security level is necessary when the decrypted frames need
+     * to be manipulated, such as for image compositing. The security level
+     * parameter must be lower than the native level. Reducing the security
+     * level will typically limit the content to lower resolutions, as
+     * determined by the license policy. If the requested level is not
+     * supported, the next lower supported security level will be set. The level
+     * can be queried using {@link #getSecurityLevel}. A session
+     * ID is returned.
+     *
+     * @param level the new security level
+     * @throws NotProvisionedException if provisioning is needed
+     * @throws ResourceBusyException if required resources are in use
+     * @throws IllegalArgumentException if the requested security level is
+     * higher than the native level or lower than the lowest supported level or
+     * if the device does not support specifying the security level when opening
+     * a session
+     */
+    @NonNull
+    public byte[] openSession(@SecurityLevel int level) throws
+            NotProvisionedException, ResourceBusyException {
+        byte[] sessionId = openSessionNative(level);
+        mPlaybackComponentMap.put(ByteBuffer.wrap(sessionId), new PlaybackComponent(sessionId));
+        return sessionId;
+    }
+
+    @NonNull
+    private native byte[] openSessionNative(int level) throws
+            NotProvisionedException, ResourceBusyException;
+
+    /**
+     * Close a session on the MediaDrm object that was previously opened
+     * with {@link #openSession}.
+     */
+    public void closeSession(@NonNull byte[] sessionId) {
+        closeSessionNative(sessionId);
+        mPlaybackComponentMap.remove(ByteBuffer.wrap(sessionId));
+    }
+
+    private native void closeSessionNative(@NonNull byte[] sessionId);
+
+    private final Map<ByteBuffer, PlaybackComponent> mPlaybackComponentMap
+            = new ConcurrentHashMap<>();
+
+    /**
+     * This key request type species that the keys will be for online use, they will
+     * not be saved to the device for subsequent use when the device is not connected
+     * to a network.
+     */
+    public static final int KEY_TYPE_STREAMING = 1;
+
+    /**
+     * This key request type specifies that the keys will be for offline use, they
+     * will be saved to the device for use when the device is not connected to a network.
+     */
+    public static final int KEY_TYPE_OFFLINE = 2;
+
+    /**
+     * This key request type specifies that previously saved offline keys should be released.
+     */
+    public static final int KEY_TYPE_RELEASE = 3;
+
+    /** @hide */
+    @IntDef({
+        KEY_TYPE_STREAMING,
+        KEY_TYPE_OFFLINE,
+        KEY_TYPE_RELEASE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface KeyType {}
+
+    /**
+     * Contains the opaque data an app uses to request keys from a license server.
+     * These request types may or may not be generated by a given plugin. Refer
+     * to plugin vendor documentation for more information.
+     */
+    public static final class KeyRequest {
+        private byte[] mData;
+        private String mDefaultUrl;
+        private int mRequestType;
+
+        /**
+         * Key request type is initial license request. A license request
+         * is necessary to load keys.
+         */
+        public static final int REQUEST_TYPE_INITIAL = 0;
+
+        /**
+         * Key request type is license renewal. A license request is
+         * necessary to prevent the keys from expiring.
+         */
+        public static final int REQUEST_TYPE_RENEWAL = 1;
+
+        /**
+         * Key request type is license release
+         */
+        public static final int REQUEST_TYPE_RELEASE = 2;
+
+        /**
+         * Keys are already loaded and are available for use. No license request is necessary, and
+         * no key request data is returned.
+         */
+        public static final int REQUEST_TYPE_NONE = 3;
+
+        /**
+         * Keys have been loaded but an additional license request is needed
+         * to update their values.
+         */
+        public static final int REQUEST_TYPE_UPDATE = 4;
+
+        /** @hide */
+        @IntDef({
+            REQUEST_TYPE_INITIAL,
+            REQUEST_TYPE_RENEWAL,
+            REQUEST_TYPE_RELEASE,
+            REQUEST_TYPE_NONE,
+            REQUEST_TYPE_UPDATE,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface RequestType {}
+
+        KeyRequest() {}
+
+        /**
+         * Get the opaque message data
+         */
+        @NonNull
+        public byte[] getData() {
+            if (mData == null) {
+                // this should never happen as mData is initialized in
+                // JNI after construction of the KeyRequest object. The check
+                // is needed here to guarantee @NonNull annotation.
+                throw new RuntimeException("KeyRequest is not initialized");
+            }
+            return mData;
+        }
+
+        /**
+         * Get the default URL to use when sending the key request message to a
+         * server, if known.  The app may prefer to use a different license
+         * server URL from other sources.
+         * This method returns an empty string if the default URL is not known.
+         */
+        @NonNull
+        public String getDefaultUrl() {
+            if (mDefaultUrl == null) {
+                // this should never happen as mDefaultUrl is initialized in
+                // JNI after construction of the KeyRequest object. The check
+                // is needed here to guarantee @NonNull annotation.
+                throw new RuntimeException("KeyRequest is not initialized");
+            }
+            return mDefaultUrl;
+        }
+
+        /**
+         * Get the type of the request
+         */
+        @RequestType
+        public int getRequestType() { return mRequestType; }
+    };
+
+    /**
+     * A key request/response exchange occurs between the app and a license server
+     * to obtain or release keys used to decrypt encrypted content.
+     * <p>
+     * getKeyRequest() is used to obtain an opaque key request byte array that is
+     * delivered to the license server.  The opaque key request byte array is returned
+     * in KeyRequest.data.  The recommended URL to deliver the key request to is
+     * returned in KeyRequest.defaultUrl.
+     * <p>
+     * After the app has received the key request response from the server,
+     * it should deliver to the response to the MediaDrm instance using the method
+     * {@link #provideKeyResponse}.
+     *
+     * @param scope may be a sessionId or a keySetId, depending on the specified keyType.
+     * When the keyType is KEY_TYPE_STREAMING or KEY_TYPE_OFFLINE,
+     * scope should be set to the sessionId the keys will be provided to.  When the keyType
+     * is KEY_TYPE_RELEASE, scope should be set to the keySetId of the keys
+     * being released. Releasing keys from a device invalidates them for all sessions.
+     * @param init container-specific data, its meaning is interpreted based on the
+     * mime type provided in the mimeType parameter.  It could contain, for example,
+     * the content ID, key ID or other data obtained from the content metadata that is
+     * required in generating the key request. May be null when keyType is
+     * KEY_TYPE_RELEASE or if the request is a renewal, i.e. not the first key
+     * request for the session.
+     * @param mimeType identifies the mime type of the content. May be null if the
+     * keyType is KEY_TYPE_RELEASE or if the request is a renewal, i.e. not the
+     * first key request for the session.
+     * @param keyType specifes the type of the request. The request may be to acquire
+     * keys for streaming or offline content, or to release previously acquired
+     * keys, which are identified by a keySetId.
+     * @param optionalParameters are included in the key request message to
+     * allow a client application to provide additional message parameters to the server.
+     * This may be {@code null} if no additional parameters are to be sent.
+     * @throws NotProvisionedException if reprovisioning is needed, due to a
+     * problem with the certifcate
+     */
+    @NonNull
+    public KeyRequest getKeyRequest(
+            @NonNull byte[] scope, @Nullable byte[] init,
+            @Nullable String mimeType, @KeyType int keyType,
+            @Nullable HashMap<String, String> optionalParameters)
+            throws NotProvisionedException {
+        HashMap<String, String> internalParams;
+        if (optionalParameters == null) {
+            internalParams = new HashMap<>();
+        } else {
+            internalParams = new HashMap<>(optionalParameters);
+        }
+        byte[] rawBytes = getNewestAvailablePackageCertificateRawBytes();
+        byte[] hashBytes = null;
+        if (rawBytes != null) {
+            hashBytes = getDigestBytes(rawBytes, "SHA-256");
+        }
+        if (hashBytes != null) {
+            Base64.Encoder encoderB64 = Base64.getEncoder();
+            String hashBytesB64 = encoderB64.encodeToString(hashBytes);
+            internalParams.put("package_certificate_hash_bytes", hashBytesB64);
+        }
+        return getKeyRequestNative(scope, init, mimeType, keyType, internalParams);
+    }
+
+    @Nullable
+    private byte[] getNewestAvailablePackageCertificateRawBytes() {
+        Application application = ActivityThread.currentApplication();
+        if (application == null) {
+            Log.w(TAG, "pkg cert: Application is null");
+            return null;
+        }
+        PackageManager pm = application.getPackageManager();
+        if (pm == null) {
+            Log.w(TAG, "pkg cert: PackageManager is null");
+            return null;
+        }
+        PackageInfo packageInfo = null;
+        try {
+            packageInfo = pm.getPackageInfo(mAppPackageName,
+                    PackageManager.GET_SIGNING_CERTIFICATES);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.w(TAG, mAppPackageName, e);
+        }
+        if (packageInfo == null || packageInfo.signingInfo == null) {
+            Log.w(TAG, "pkg cert: PackageInfo or SigningInfo is null");
+            return null;
+        }
+        Signature[] signers = packageInfo.signingInfo.getApkContentsSigners();
+        if (signers != null && signers.length == 1) {
+            return signers[0].toByteArray();
+        }
+        Log.w(TAG, "pkg cert: " + signers.length + " signers");
+        return null;
+    }
+
+    @Nullable
+    private static byte[] getDigestBytes(@NonNull byte[] rawBytes, @NonNull String algorithm) {
+        try {
+            MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
+            return messageDigest.digest(rawBytes);
+        } catch (NoSuchAlgorithmException e) {
+            Log.w(TAG, algorithm, e);
+        }
+        return null;
+    }
+
+    @NonNull
+    private native KeyRequest getKeyRequestNative(
+            @NonNull byte[] scope, @Nullable byte[] init,
+            @Nullable String mimeType, @KeyType int keyType,
+            @Nullable HashMap<String, String> optionalParameters)
+            throws NotProvisionedException;
+
+    /**
+     * A key response is received from the license server by the app, then it is
+     * provided to the MediaDrm instance using provideKeyResponse.  When the
+     * response is for an offline key request, a keySetId is returned that can be
+     * used to later restore the keys to a new session with the method
+     * {@link #restoreKeys}.
+     * When the response is for a streaming or release request, an empty byte array
+     * is returned.
+     *
+     * @param scope may be a sessionId or keySetId depending on the type of the
+     * response.  Scope should be set to the sessionId when the response is for either
+     * streaming or offline key requests.  Scope should be set to the keySetId when
+     * the response is for a release request.
+     * @param response the byte array response from the server
+     * @return If the response is for an offline request, the keySetId for the offline
+     * keys will be returned. If the response is for a streaming or release request
+     * an empty byte array will be returned.
+     *
+     * @throws NotProvisionedException if the response indicates that
+     * reprovisioning is required
+     * @throws DeniedByServerException if the response indicates that the
+     * server rejected the request
+     */
+    @Nullable
+    public native byte[] provideKeyResponse(
+            @NonNull byte[] scope, @NonNull byte[] response)
+            throws NotProvisionedException, DeniedByServerException;
+
+
+    /**
+     * Restore persisted offline keys into a new session.  keySetId identifies the
+     * keys to load, obtained from a prior call to {@link #provideKeyResponse}.
+     *
+     * @param sessionId the session ID for the DRM session
+     * @param keySetId identifies the saved key set to restore
+     */
+    public native void restoreKeys(@NonNull byte[] sessionId, @NonNull byte[] keySetId);
+
+    /**
+     * Remove the current keys from a session.
+     *
+     * @param sessionId the session ID for the DRM session
+     */
+    public native void removeKeys(@NonNull byte[] sessionId);
+
+    /**
+     * Request an informative description of the key status for the session.  The status is
+     * in the form of {name, value} pairs.  Since DRM license policies vary by vendor,
+     * the specific status field names are determined by each DRM vendor.  Refer to your
+     * DRM provider documentation for definitions of the field names for a particular
+     * DRM plugin.
+     *
+     * @param sessionId the session ID for the DRM session
+     */
+    @NonNull
+    public native HashMap<String, String> queryKeyStatus(@NonNull byte[] sessionId);
+
+    /**
+     * Contains the opaque data an app uses to request a certificate from a provisioning
+     * server
+     */
+    public static final class ProvisionRequest {
+        ProvisionRequest() {}
+
+        /**
+         * Get the opaque message data
+         */
+        @NonNull
+        public byte[] getData() {
+            if (mData == null) {
+                // this should never happen as mData is initialized in
+                // JNI after construction of the KeyRequest object. The check
+                // is needed here to guarantee @NonNull annotation.
+                throw new RuntimeException("ProvisionRequest is not initialized");
+            }
+            return mData;
+        }
+
+        /**
+         * Get the default URL to use when sending the provision request
+         * message to a server, if known. The app may prefer to use a different
+         * provisioning server URL obtained from other sources.
+         * This method returns an empty string if the default URL is not known.
+         */
+        @NonNull
+        public String getDefaultUrl() {
+            if (mDefaultUrl == null) {
+                // this should never happen as mDefaultUrl is initialized in
+                // JNI after construction of the ProvisionRequest object. The check
+                // is needed here to guarantee @NonNull annotation.
+                throw new RuntimeException("ProvisionRequest is not initialized");
+            }
+            return mDefaultUrl;
+        }
+
+        private byte[] mData;
+        private String mDefaultUrl;
+    }
+
+    /**
+     * A provision request/response exchange occurs between the app and a provisioning
+     * server to retrieve a device certificate.  If provisionining is required, the
+     * EVENT_PROVISION_REQUIRED event will be sent to the event handler.
+     * getProvisionRequest is used to obtain the opaque provision request byte array that
+     * should be delivered to the provisioning server. The provision request byte array
+     * is returned in ProvisionRequest.data. The recommended URL to deliver the provision
+     * request to is returned in ProvisionRequest.defaultUrl.
+     */
+    @NonNull
+    public ProvisionRequest getProvisionRequest() {
+        return getProvisionRequestNative(CERTIFICATE_TYPE_NONE, "");
+    }
+
+    @NonNull
+    private native ProvisionRequest getProvisionRequestNative(int certType,
+           @NonNull String certAuthority);
+
+    /**
+     * After a provision response is received by the app, it is provided to the
+     * MediaDrm instance using this method.
+     *
+     * @param response the opaque provisioning response byte array to provide to the
+     * MediaDrm instance.
+     *
+     * @throws DeniedByServerException if the response indicates that the
+     * server rejected the request
+     */
+    public void provideProvisionResponse(@NonNull byte[] response)
+            throws DeniedByServerException {
+        provideProvisionResponseNative(response);
+    }
+
+    @NonNull
+    private native Certificate provideProvisionResponseNative(@NonNull byte[] response)
+            throws DeniedByServerException;
+
+    /**
+     * The keys in an offline license allow protected content to be played even
+     * if the device is not connected to a network. Offline licenses are stored
+     * on the device after a key request/response exchange when the key request
+     * KeyType is OFFLINE. Normally each app is responsible for keeping track of
+     * the keySetIds it has created. If an app loses the keySetId for any stored
+     * licenses that it created, however, it must be able to recover the stored
+     * keySetIds so those licenses can be removed when they expire or when the
+     * app is uninstalled.
+     * <p>
+     * This method returns a list of the keySetIds for all offline licenses.
+     * The offline license keySetId may be used to query the status of an
+     * offline license with {@link #getOfflineLicenseState} or remove it with
+     * {@link #removeOfflineLicense}.
+     *
+     * @return a list of offline license keySetIds
+     */
+    @NonNull
+    public native List<byte[]> getOfflineLicenseKeySetIds();
+
+    /**
+     * Normally offline licenses are released using a key request/response
+     * exchange using {@link #getKeyRequest} where the key type is
+     * KEY_TYPE_RELEASE, followed by {@link #provideKeyResponse}. This allows
+     * the server to cryptographically confirm that the license has been removed
+     * and then adjust the count of offline licenses allocated to the device.
+     * <p>
+     * In some exceptional situations it may be necessary to directly remove
+     * offline licenses without notifying the server, which may be performed
+     * using this method.
+     *
+     * @param keySetId the id of the offline license to remove
+     * @throws IllegalArgumentException if the keySetId does not refer to an
+     * offline license.
+     */
+    public native void removeOfflineLicense(@NonNull byte[] keySetId);
+
+    /**
+     * Offline license state is unknown, an error occurred while trying
+     * to access it.
+     */
+    public static final int OFFLINE_LICENSE_STATE_UNKNOWN = 0;
+
+    /**
+     * Offline license is usable, the keys may be used for decryption.
+     */
+    public static final int OFFLINE_LICENSE_STATE_USABLE = 1;
+
+    /**
+     * Offline license is released, the keys have been marked for
+     * release using {@link #getKeyRequest} with KEY_TYPE_RELEASE but
+     * the key response has not been received.
+     */
+    public static final int OFFLINE_LICENSE_STATE_RELEASED = 2;
+
+    /** @hide */
+    @IntDef({
+        OFFLINE_LICENSE_STATE_UNKNOWN,
+        OFFLINE_LICENSE_STATE_USABLE,
+        OFFLINE_LICENSE_STATE_RELEASED,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface OfflineLicenseState {}
+
+    /**
+     * Request the state of an offline license. An offline license may be usable
+     * or inactive. The keys in a usable offline license are available for
+     * decryption. When the offline license state is inactive, the keys have
+     * been marked for release using {@link #getKeyRequest} with
+     * KEY_TYPE_RELEASE but the key response has not been received. The keys in
+     * an inactive offline license are not usable for decryption.
+     *
+     * @param keySetId selects the offline license
+     * @return the offline license state
+     * @throws IllegalArgumentException if the keySetId does not refer to an
+     * offline license.
+     */
+    @OfflineLicenseState
+    public native int getOfflineLicenseState(@NonNull byte[] keySetId);
+
+    /**
+     * Secure stops are a way to enforce limits on the number of concurrent
+     * streams per subscriber across devices. They provide secure monitoring of
+     * the lifetime of content decryption keys in MediaDrm sessions.
+     * <p>
+     * A secure stop is written to secure persistent memory when keys are loaded
+     * into a MediaDrm session. The secure stop state indicates that the keys
+     * are available for use. When playback completes and the keys are removed
+     * or the session is destroyed, the secure stop state is updated to indicate
+     * that keys are no longer usable.
+     * <p>
+     * After playback, the app can query the secure stop and send it in a
+     * message to the license server confirming that the keys are no longer
+     * active. The license server returns a secure stop release response
+     * message to the app which then deletes the secure stop from persistent
+     * memory using {@link #releaseSecureStops}.
+     * <p>
+     * Each secure stop has a unique ID that can be used to identify it during
+     * enumeration, access and removal.
+     * @return a list of all secure stops from secure persistent memory
+     */
+    @NonNull
+    public native List<byte[]> getSecureStops();
+
+    /**
+     * Return a list of all secure stop IDs currently in persistent memory.
+     * The secure stop ID can be used to access or remove the corresponding
+     * secure stop.
+     *
+     * @return a list of secure stop IDs
+     */
+    @NonNull
+    public native List<byte[]> getSecureStopIds();
+
+    /**
+     * Access a specific secure stop given its secure stop ID.
+     * Each secure stop has a unique ID.
+     *
+     * @param ssid the ID of the secure stop to return
+     * @return the secure stop identified by ssid
+     */
+    @NonNull
+    public native byte[] getSecureStop(@NonNull byte[] ssid);
+
+    /**
+     * Process the secure stop server response message ssRelease.  After
+     * authenticating the message, remove the secure stops identified in the
+     * response.
+     *
+     * @param ssRelease the server response indicating which secure stops to release
+     */
+    public native void releaseSecureStops(@NonNull byte[] ssRelease);
+
+    /**
+     * Remove a specific secure stop without requiring a secure stop release message
+     * from the license server.
+     * @param ssid the ID of the secure stop to remove
+     */
+    public native void removeSecureStop(@NonNull byte[] ssid);
+
+    /**
+     * Remove all secure stops without requiring a secure stop release message from
+     * the license server.
+     *
+     * This method was added in API 28. In API versions 18 through 27,
+     * {@link #releaseAllSecureStops} should be called instead. There is no need to
+     * do anything for API versions prior to 18.
+     */
+    public native void removeAllSecureStops();
+
+    /**
+     * Remove all secure stops without requiring a secure stop release message from
+     * the license server.
+     *
+     * @deprecated Remove all secure stops using {@link #removeAllSecureStops} instead.
+     */
+    public void releaseAllSecureStops() {
+        removeAllSecureStops();;
+    }
+
+    /**
+     * @deprecated Not of any use for application development;
+     * please note that the related integer constants remain supported:
+     * {@link #HDCP_LEVEL_UNKNOWN},
+     * {@link #HDCP_NONE},
+     * {@link #HDCP_V1},
+     * {@link #HDCP_V2},
+     * {@link #HDCP_V2_1},
+     * {@link #HDCP_V2_2},
+     * {@link #HDCP_V2_3}
+     */
+    @Deprecated
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({HDCP_LEVEL_UNKNOWN, HDCP_NONE, HDCP_V1, HDCP_V2,
+                        HDCP_V2_1, HDCP_V2_2, HDCP_V2_3, HDCP_NO_DIGITAL_OUTPUT})
+    public @interface HdcpLevel {}
+
+
+    /**
+     * The DRM plugin did not report an HDCP level, or an error
+     * occurred accessing it
+     */
+    public static final int HDCP_LEVEL_UNKNOWN = 0;
+
+    /**
+     * HDCP is not supported on this device, content is unprotected
+     */
+    public static final int HDCP_NONE = 1;
+
+    /**
+     * HDCP version 1.0
+     */
+    public static final int HDCP_V1 = 2;
+
+    /**
+     * HDCP version 2.0 Type 1.
+     */
+    public static final int HDCP_V2 = 3;
+
+    /**
+     * HDCP version 2.1 Type 1.
+     */
+    public static final int HDCP_V2_1 = 4;
+
+    /**
+     *  HDCP version 2.2 Type 1.
+     */
+    public static final int HDCP_V2_2 = 5;
+
+    /**
+     *  HDCP version 2.3 Type 1.
+     */
+    public static final int HDCP_V2_3 = 6;
+
+    /**
+     * No digital output, implicitly secure
+     */
+    public static final int HDCP_NO_DIGITAL_OUTPUT = Integer.MAX_VALUE;
+
+    /**
+     * Return the HDCP level negotiated with downstream receivers the
+     * device is connected to. If multiple HDCP-capable displays are
+     * simultaneously connected to separate interfaces, this method
+     * returns the lowest negotiated level of all interfaces.
+     * <p>
+     * This method should only be used for informational purposes, not for
+     * enforcing compliance with HDCP requirements. Trusted enforcement of
+     * HDCP policies must be handled by the DRM system.
+     * <p>
+     * @return the connected HDCP level
+     */
+    @HdcpLevel
+    public native int getConnectedHdcpLevel();
+
+    /**
+     * Return the maximum supported HDCP level. The maximum HDCP level is a
+     * constant for a given device, it does not depend on downstream receivers
+     * that may be connected. If multiple HDCP-capable interfaces are present,
+     * it indicates the highest of the maximum HDCP levels of all interfaces.
+     * <p>
+     * @return the maximum supported HDCP level
+     */
+    @HdcpLevel
+    public native int getMaxHdcpLevel();
+
+    /**
+     * Return the number of MediaDrm sessions that are currently opened
+     * simultaneously among all MediaDrm instances for the active DRM scheme.
+     * @return the number of open sessions.
+     */
+    public native int getOpenSessionCount();
+
+    /**
+     * Return the maximum number of MediaDrm sessions that may be opened
+     * simultaneosly among all MediaDrm instances for the active DRM
+     * scheme. The maximum number of sessions is not affected by any
+     * sessions that may have already been opened.
+     * @return maximum sessions.
+     */
+    public native int getMaxSessionCount();
+
+    /**
+     * Security level indicates the robustness of the device's DRM
+     * implementation.
+     *
+     * @deprecated Not of any use for application development;
+     * please note that the related integer constants remain supported:
+     * {@link #SECURITY_LEVEL_UNKNOWN},
+     * {@link #SECURITY_LEVEL_SW_SECURE_CRYPTO},
+     * {@link #SECURITY_LEVEL_SW_SECURE_DECODE},
+     * {@link #SECURITY_LEVEL_HW_SECURE_CRYPTO},
+     * {@link #SECURITY_LEVEL_HW_SECURE_DECODE},
+     * {@link #SECURITY_LEVEL_HW_SECURE_ALL}
+     */
+    @Deprecated
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({SECURITY_LEVEL_UNKNOWN, SECURITY_LEVEL_SW_SECURE_CRYPTO,
+            SECURITY_LEVEL_SW_SECURE_DECODE, SECURITY_LEVEL_HW_SECURE_CRYPTO,
+            SECURITY_LEVEL_HW_SECURE_DECODE, SECURITY_LEVEL_HW_SECURE_ALL})
+    public @interface SecurityLevel {}
+
+    /**
+     * The DRM plugin did not report a security level, or an error occurred
+     * accessing it
+     */
+    public static final int SECURITY_LEVEL_UNKNOWN = 0;
+
+    /**
+     * DRM key management uses software-based whitebox crypto.
+     */
+    public static final int SECURITY_LEVEL_SW_SECURE_CRYPTO = 1;
+
+    /**
+     * DRM key management and decoding use software-based whitebox crypto.
+     */
+    public static final int SECURITY_LEVEL_SW_SECURE_DECODE = 2;
+
+    /**
+     * DRM key management and crypto operations are performed within a hardware
+     * backed trusted execution environment.
+     */
+    public static final int SECURITY_LEVEL_HW_SECURE_CRYPTO = 3;
+
+    /**
+     * DRM key management, crypto operations and decoding of content are
+     * performed within a hardware backed trusted execution environment.
+     */
+    public static final int SECURITY_LEVEL_HW_SECURE_DECODE = 4;
+
+    /**
+     * DRM key management, crypto operations, decoding of content and all
+     * handling of the media (compressed and uncompressed) is handled within a
+     * hardware backed trusted execution environment.
+     */
+    public static final int SECURITY_LEVEL_HW_SECURE_ALL = 5;
+
+    /**
+     * Indicates that the maximum security level supported by the device should
+     * be used when opening a session. This is the default security level
+     * selected when a session is opened.
+     * @hide
+     */
+    public static final int SECURITY_LEVEL_MAX = 6;
+
+    /**
+     * Returns a value that may be passed as a parameter to {@link #openSession(int)}
+     * requesting that the session be opened at the maximum security level of
+     * the device.
+     */
+    public static final int getMaxSecurityLevel() {
+        return SECURITY_LEVEL_MAX;
+    }
+
+    /**
+     * Return the current security level of a session. A session has an initial
+     * security level determined by the robustness of the DRM system's
+     * implementation on the device. The security level may be changed at the
+     * time a session is opened using {@link #openSession}.
+     * @param sessionId the session to query.
+     * <p>
+     * @return the security level of the session
+     */
+    @SecurityLevel
+    public native int getSecurityLevel(@NonNull byte[] sessionId);
+
+    /**
+     * String property name: identifies the maker of the DRM plugin
+     */
+    public static final String PROPERTY_VENDOR = "vendor";
+
+    /**
+     * String property name: identifies the version of the DRM plugin
+     */
+    public static final String PROPERTY_VERSION = "version";
+
+    /**
+     * String property name: describes the DRM plugin
+     */
+    public static final String PROPERTY_DESCRIPTION = "description";
+
+    /**
+     * String property name: a comma-separated list of cipher and mac algorithms
+     * supported by CryptoSession.  The list may be empty if the DRM
+     * plugin does not support CryptoSession operations.
+     */
+    public static final String PROPERTY_ALGORITHMS = "algorithms";
+
+    /** @hide */
+    @StringDef(prefix = { "PROPERTY_" }, value = {
+        PROPERTY_VENDOR,
+        PROPERTY_VERSION,
+        PROPERTY_DESCRIPTION,
+        PROPERTY_ALGORITHMS,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface StringProperty {}
+
+    /**
+     * Read a MediaDrm String property value, given the property name string.
+     * <p>
+     * Standard fields names are:
+     * {@link #PROPERTY_VENDOR}, {@link #PROPERTY_VERSION},
+     * {@link #PROPERTY_DESCRIPTION}, {@link #PROPERTY_ALGORITHMS}
+     */
+    @NonNull
+    public native String getPropertyString(@NonNull String propertyName);
+
+    /**
+     * Set a MediaDrm String property value, given the property name string
+     * and new value for the property.
+     */
+    public native void setPropertyString(@NonNull String propertyName,
+            @NonNull String value);
+
+    /**
+     * Byte array property name: the device unique identifier is established during
+     * device provisioning and provides a means of uniquely identifying each device.
+     */
+    public static final String PROPERTY_DEVICE_UNIQUE_ID = "deviceUniqueId";
+
+    /** @hide */
+    @StringDef(prefix = { "PROPERTY_" }, value = {
+        PROPERTY_DEVICE_UNIQUE_ID,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ArrayProperty {}
+
+    /**
+     * Read a MediaDrm byte array property value, given the property name string.
+     * <p>
+     * Standard fields names are {@link #PROPERTY_DEVICE_UNIQUE_ID}
+     */
+    @NonNull
+    public native byte[] getPropertyByteArray(String propertyName);
+
+    /**
+    * Set a MediaDrm byte array property value, given the property name string
+    * and new value for the property.
+    */
+    public native void setPropertyByteArray(
+            @NonNull String propertyName, @NonNull byte[] value);
+
+    private static final native void setCipherAlgorithmNative(
+            @NonNull MediaDrm drm, @NonNull byte[] sessionId, @NonNull String algorithm);
+
+    private static final native void setMacAlgorithmNative(
+            @NonNull MediaDrm drm, @NonNull byte[] sessionId, @NonNull String algorithm);
+
+    @NonNull
+    private static final native byte[] encryptNative(
+            @NonNull MediaDrm drm, @NonNull byte[] sessionId,
+            @NonNull byte[] keyId, @NonNull byte[] input, @NonNull byte[] iv);
+
+    @NonNull
+    private static final native byte[] decryptNative(
+            @NonNull MediaDrm drm, @NonNull byte[] sessionId,
+            @NonNull byte[] keyId, @NonNull byte[] input, @NonNull byte[] iv);
+
+    @NonNull
+    private static final native byte[] signNative(
+            @NonNull MediaDrm drm, @NonNull byte[] sessionId,
+            @NonNull byte[] keyId, @NonNull byte[] message);
+
+    private static final native boolean verifyNative(
+            @NonNull MediaDrm drm, @NonNull byte[] sessionId,
+            @NonNull byte[] keyId, @NonNull byte[] message, @NonNull byte[] signature);
+
+    /**
+     * Return Metrics data about the current MediaDrm instance.
+     *
+     * @return a {@link PersistableBundle} containing the set of attributes and values
+     * available for this instance of MediaDrm.
+     * The attributes are described in {@link MetricsConstants}.
+     *
+     * Additional vendor-specific fields may also be present in
+     * the return value.
+     */
+    public PersistableBundle getMetrics() {
+        PersistableBundle bundle = getMetricsNative();
+        return bundle;
+    }
+
+    private native PersistableBundle getMetricsNative();
+
+    /**
+     * In addition to supporting decryption of DASH Common Encrypted Media, the
+     * MediaDrm APIs provide the ability to securely deliver session keys from
+     * an operator's session key server to a client device, based on the factory-installed
+     * root of trust, and then perform encrypt, decrypt, sign and verify operations
+     * with the session key on arbitrary user data.
+     * <p>
+     * The CryptoSession class implements generic encrypt/decrypt/sign/verify methods
+     * based on the established session keys.  These keys are exchanged using the
+     * getKeyRequest/provideKeyResponse methods.
+     * <p>
+     * Applications of this capability could include securing various types of
+     * purchased or private content, such as applications, books and other media,
+     * photos or media delivery protocols.
+     * <p>
+     * Operators can create session key servers that are functionally similar to a
+     * license key server, except that instead of receiving license key requests and
+     * providing encrypted content keys which are used specifically to decrypt A/V media
+     * content, the session key server receives session key requests and provides
+     * encrypted session keys which can be used for general purpose crypto operations.
+     * <p>
+     * A CryptoSession is obtained using {@link #getCryptoSession}
+     */
+    public final class CryptoSession {
+        private byte[] mSessionId;
+
+        CryptoSession(@NonNull byte[] sessionId,
+                      @NonNull String cipherAlgorithm,
+                      @NonNull String macAlgorithm)
+        {
+            mSessionId = sessionId;
+            setCipherAlgorithmNative(MediaDrm.this, sessionId, cipherAlgorithm);
+            setMacAlgorithmNative(MediaDrm.this, sessionId, macAlgorithm);
+        }
+
+        /**
+         * Encrypt data using the CryptoSession's cipher algorithm
+         *
+         * @param keyid specifies which key to use
+         * @param input the data to encrypt
+         * @param iv the initialization vector to use for the cipher
+         */
+        @NonNull
+        public byte[] encrypt(
+                @NonNull byte[] keyid, @NonNull byte[] input, @NonNull byte[] iv) {
+            return encryptNative(MediaDrm.this, mSessionId, keyid, input, iv);
+        }
+
+        /**
+         * Decrypt data using the CryptoSessions's cipher algorithm
+         *
+         * @param keyid specifies which key to use
+         * @param input the data to encrypt
+         * @param iv the initialization vector to use for the cipher
+         */
+        @NonNull
+        public byte[] decrypt(
+                @NonNull byte[] keyid, @NonNull byte[] input, @NonNull byte[] iv) {
+            return decryptNative(MediaDrm.this, mSessionId, keyid, input, iv);
+        }
+
+        /**
+         * Sign data using the CryptoSessions's mac algorithm.
+         *
+         * @param keyid specifies which key to use
+         * @param message the data for which a signature is to be computed
+         */
+        @NonNull
+        public byte[] sign(@NonNull byte[] keyid, @NonNull byte[] message) {
+            return signNative(MediaDrm.this, mSessionId, keyid, message);
+        }
+
+        /**
+         * Verify a signature using the CryptoSessions's mac algorithm. Return true
+         * if the signatures match, false if they do no.
+         *
+         * @param keyid specifies which key to use
+         * @param message the data to verify
+         * @param signature the reference signature which will be compared with the
+         *        computed signature
+         */
+        public boolean verify(
+                @NonNull byte[] keyid, @NonNull byte[] message, @NonNull byte[] signature) {
+            return verifyNative(MediaDrm.this, mSessionId, keyid, message, signature);
+        }
+    };
+
+    /**
+     * Obtain a CryptoSession object which can be used to encrypt, decrypt,
+     * sign and verify messages or data using the session keys established
+     * for the session using methods {@link #getKeyRequest} and
+     * {@link #provideKeyResponse} using a session key server.
+     *
+     * @param sessionId the session ID for the session containing keys
+     * to be used for encrypt, decrypt, sign and/or verify
+     * @param cipherAlgorithm the algorithm to use for encryption and
+     * decryption ciphers. The algorithm string conforms to JCA Standard
+     * Names for Cipher Transforms and is case insensitive.  For example
+     * "AES/CBC/NoPadding".
+     * @param macAlgorithm the algorithm to use for sign and verify
+     * The algorithm string conforms to JCA Standard Names for Mac
+     * Algorithms and is case insensitive.  For example "HmacSHA256".
+     * <p>
+     * The list of supported algorithms for a DRM plugin can be obtained
+     * using the method {@link #getPropertyString} with the property name
+     * "algorithms".
+     */
+    public CryptoSession getCryptoSession(
+            @NonNull byte[] sessionId,
+            @NonNull String cipherAlgorithm, @NonNull String macAlgorithm)
+    {
+        return new CryptoSession(sessionId, cipherAlgorithm, macAlgorithm);
+    }
+
+    /**
+     * Contains the opaque data an app uses to request a certificate from a provisioning
+     * server
+     *
+     * @hide - not part of the public API at this time
+     */
+    public static final class CertificateRequest {
+        private byte[] mData;
+        private String mDefaultUrl;
+
+        CertificateRequest(@NonNull byte[] data, @NonNull String defaultUrl) {
+            mData = data;
+            mDefaultUrl = defaultUrl;
+        }
+
+        /**
+         * Get the opaque message data
+         */
+        @NonNull
+        @UnsupportedAppUsage
+        public byte[] getData() { return mData; }
+
+        /**
+         * Get the default URL to use when sending the certificate request
+         * message to a server, if known. The app may prefer to use a different
+         * certificate server URL obtained from other sources.
+         */
+        @NonNull
+        @UnsupportedAppUsage
+        public String getDefaultUrl() { return mDefaultUrl; }
+    }
+
+    /**
+     * Generate a certificate request, specifying the certificate type
+     * and authority. The response received should be passed to
+     * provideCertificateResponse.
+     *
+     * @param certType Specifies the certificate type.
+     *
+     * @param certAuthority is passed to the certificate server to specify
+     * the chain of authority.
+     *
+     * @hide - not part of the public API at this time
+     */
+    @NonNull
+    @UnsupportedAppUsage
+    public CertificateRequest getCertificateRequest(
+            @CertificateType int certType, @NonNull String certAuthority)
+    {
+        ProvisionRequest provisionRequest = getProvisionRequestNative(certType, certAuthority);
+        return new CertificateRequest(provisionRequest.getData(),
+                provisionRequest.getDefaultUrl());
+    }
+
+    /**
+     * Contains the wrapped private key and public certificate data associated
+     * with a certificate.
+     *
+     * @hide - not part of the public API at this time
+     */
+    public static final class Certificate {
+        Certificate() {}
+
+        /**
+         * Get the wrapped private key data
+         */
+        @NonNull
+        @UnsupportedAppUsage
+        public byte[] getWrappedPrivateKey() {
+            if (mWrappedKey == null) {
+                // this should never happen as mWrappedKey is initialized in
+                // JNI after construction of the KeyRequest object. The check
+                // is needed here to guarantee @NonNull annotation.
+                throw new RuntimeException("Certificate is not initialized");
+            }
+            return mWrappedKey;
+        }
+
+        /**
+         * Get the PEM-encoded certificate chain
+         */
+        @NonNull
+        @UnsupportedAppUsage
+        public byte[] getContent() {
+            if (mCertificateData == null) {
+                // this should never happen as mCertificateData is initialized in
+                // JNI after construction of the KeyRequest object. The check
+                // is needed here to guarantee @NonNull annotation.
+                throw new RuntimeException("Certificate is not initialized");
+            }
+            return mCertificateData;
+        }
+
+        private byte[] mWrappedKey;
+        private byte[] mCertificateData;
+    }
+
+
+    /**
+     * Process a response from the certificate server.  The response
+     * is obtained from an HTTP Post to the url provided by getCertificateRequest.
+     * <p>
+     * The public X509 certificate chain and wrapped private key are returned
+     * in the returned Certificate objec.  The certificate chain is in PEM format.
+     * The wrapped private key should be stored in application private
+     * storage, and used when invoking the signRSA method.
+     *
+     * @param response the opaque certificate response byte array to provide to the
+     * MediaDrm instance.
+     *
+     * @throws DeniedByServerException if the response indicates that the
+     * server rejected the request
+     *
+     * @hide - not part of the public API at this time
+     */
+    @NonNull
+    @UnsupportedAppUsage
+    public Certificate provideCertificateResponse(@NonNull byte[] response)
+            throws DeniedByServerException {
+        return provideProvisionResponseNative(response);
+    }
+
+    @NonNull
+    private static final native byte[] signRSANative(
+            @NonNull MediaDrm drm, @NonNull byte[] sessionId,
+            @NonNull String algorithm, @NonNull byte[] wrappedKey, @NonNull byte[] message);
+
+    /**
+     * Sign data using an RSA key
+     *
+     * @param sessionId a sessionId obtained from openSession on the MediaDrm object
+     * @param algorithm the signing algorithm to use, e.g. "PKCS1-BlockType1"
+     * @param wrappedKey - the wrapped (encrypted) RSA private key obtained
+     * from provideCertificateResponse
+     * @param message the data for which a signature is to be computed
+     *
+     * @hide - not part of the public API at this time
+     */
+    @NonNull
+    @UnsupportedAppUsage
+    public byte[] signRSA(
+            @NonNull byte[] sessionId, @NonNull String algorithm,
+            @NonNull byte[] wrappedKey, @NonNull byte[] message) {
+        return signRSANative(this, sessionId, algorithm, wrappedKey, message);
+    }
+
+    /**
+     * Query if the crypto scheme requires the use of a secure decoder
+     * to decode data of the given mime type at the default security level.
+     * The default security level is defined as the highest security level
+     * supported on the device.
+     *
+     * @param mime The mime type of the media data. Please use {@link
+     *             #isCryptoSchemeSupported(UUID, String)} to query mime type support separately;
+     *             for unsupported mime types the return value of {@link
+     *             #requiresSecureDecoder(String)} is crypto scheme dependent.
+     */
+    public boolean requiresSecureDecoder(@NonNull String mime) {
+        return requiresSecureDecoder(mime, getMaxSecurityLevel());
+    }
+
+    /**
+     * Query if the crypto scheme requires the use of a secure decoder
+     * to decode data of the given mime type at the given security level.
+     *
+     * @param mime The mime type of the media data. Please use {@link
+     *             #isCryptoSchemeSupported(UUID, String, int)} to query mime type support
+     *             separately; for unsupported mime types the return value of {@link
+     *             #requiresSecureDecoder(String, int)} is crypto scheme dependent.
+     * @param level a security level between {@link #SECURITY_LEVEL_SW_SECURE_CRYPTO}
+     *              and {@link #SECURITY_LEVEL_HW_SECURE_ALL}. Otherwise the special value
+     *              {@link #getMaxSecurityLevel()} is also permitted;
+     *              use {@link #getMaxSecurityLevel()} to indicate the maximum security level
+     *              supported by the device.
+     * @throws IllegalArgumentException if the requested security level is none of the documented
+     * values for the parameter {@code level}.
+     */
+    public native boolean requiresSecureDecoder(@NonNull String mime, @SecurityLevel int level);
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+            release();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Releases resources associated with the current session of
+     * MediaDrm. It is considered good practice to call this method when
+     * the {@link MediaDrm} object is no longer needed in your
+     * application. After this method is called, {@link MediaDrm} is no
+     * longer usable since it has lost all of its required resource.
+     *
+     * This method was added in API 28. In API versions 18 through 27, release()
+     * should be called instead. There is no need to do anything for API
+     * versions prior to 18.
+     */
+    @Override
+    public void close() {
+        release();
+    }
+
+    /**
+     * @deprecated replaced by {@link #close()}.
+     */
+    @Deprecated
+    public void release() {
+        mCloseGuard.close();
+        if (mClosed.compareAndSet(false, true)) {
+            native_release();
+            mPlaybackComponentMap.clear();
+        }
+    }
+
+    /** @hide */
+    public native final void native_release();
+
+    private static native final void native_init();
+
+    private native final void native_setup(Object mediadrm_this, byte[] uuid,
+            String appPackageName);
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    /**
+     * Definitions for the metrics that are reported via the
+     * {@link #getMetrics} call.
+     */
+    public final static class MetricsConstants
+    {
+        private MetricsConstants() {}
+
+        /**
+         * Key to extract the number of successful {@link #openSession} calls
+         * from the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String OPEN_SESSION_OK_COUNT
+            = "drm.mediadrm.open_session.ok.count";
+
+        /**
+         * Key to extract the number of failed {@link #openSession} calls
+         * from the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String OPEN_SESSION_ERROR_COUNT
+            = "drm.mediadrm.open_session.error.count";
+
+        /**
+         * Key to extract the list of error codes that were returned from
+         * {@link #openSession} calls. The key is used to lookup the list
+         * in the {@link PersistableBundle} returned by a {@link #getMetrics}
+         * call.
+         * The list is an array of Long values
+         * ({@link android.os.BaseBundle#getLongArray}).
+         */
+        public static final String OPEN_SESSION_ERROR_LIST
+            = "drm.mediadrm.open_session.error.list";
+
+        /**
+         * Key to extract the number of successful {@link #closeSession} calls
+         * from the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String CLOSE_SESSION_OK_COUNT
+            = "drm.mediadrm.close_session.ok.count";
+
+        /**
+         * Key to extract the number of failed {@link #closeSession} calls
+         * from the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String CLOSE_SESSION_ERROR_COUNT
+            = "drm.mediadrm.close_session.error.count";
+
+        /**
+         * Key to extract the list of error codes that were returned from
+         * {@link #closeSession} calls. The key is used to lookup the list
+         * in the {@link PersistableBundle} returned by a {@link #getMetrics}
+         * call.
+         * The list is an array of Long values
+         * ({@link android.os.BaseBundle#getLongArray}).
+         */
+        public static final String CLOSE_SESSION_ERROR_LIST
+            = "drm.mediadrm.close_session.error.list";
+
+        /**
+         * Key to extract the start times of sessions. Times are
+         * represented as milliseconds since epoch (1970-01-01T00:00:00Z).
+         * The start times are returned from the {@link PersistableBundle}
+         * from a {@link #getMetrics} call.
+         * The start times are returned as another {@link PersistableBundle}
+         * containing the session ids as keys and the start times as long
+         * values. Use {@link android.os.BaseBundle#keySet} to get the list of
+         * session ids, and then {@link android.os.BaseBundle#getLong} to get
+         * the start time for each session.
+         */
+        public static final String SESSION_START_TIMES_MS
+            = "drm.mediadrm.session_start_times_ms";
+
+        /**
+         * Key to extract the end times of sessions. Times are
+         * represented as milliseconds since epoch (1970-01-01T00:00:00Z).
+         * The end times are returned from the {@link PersistableBundle}
+         * from a {@link #getMetrics} call.
+         * The end times are returned as another {@link PersistableBundle}
+         * containing the session ids as keys and the end times as long
+         * values. Use {@link android.os.BaseBundle#keySet} to get the list of
+         * session ids, and then {@link android.os.BaseBundle#getLong} to get
+         * the end time for each session.
+         */
+        public static final String SESSION_END_TIMES_MS
+            = "drm.mediadrm.session_end_times_ms";
+
+        /**
+         * Key to extract the number of successful {@link #getKeyRequest} calls
+         * from the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String GET_KEY_REQUEST_OK_COUNT
+            = "drm.mediadrm.get_key_request.ok.count";
+
+        /**
+         * Key to extract the number of failed {@link #getKeyRequest}
+         * calls from the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String GET_KEY_REQUEST_ERROR_COUNT
+            = "drm.mediadrm.get_key_request.error.count";
+
+        /**
+         * Key to extract the list of error codes that were returned from
+         * {@link #getKeyRequest} calls. The key is used to lookup the list
+         * in the {@link PersistableBundle} returned by a {@link #getMetrics}
+         * call.
+         * The list is an array of Long values
+         * ({@link android.os.BaseBundle#getLongArray}).
+         */
+        public static final String GET_KEY_REQUEST_ERROR_LIST
+            = "drm.mediadrm.get_key_request.error.list";
+
+        /**
+         * Key to extract the average time in microseconds of calls to
+         * {@link #getKeyRequest}. The value is retrieved from the
+         * {@link PersistableBundle} returned from {@link #getMetrics}.
+         * The time is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String GET_KEY_REQUEST_OK_TIME_MICROS
+            = "drm.mediadrm.get_key_request.ok.average_time_micros";
+
+        /**
+         * Key to extract the number of successful {@link #provideKeyResponse}
+         * calls from the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String PROVIDE_KEY_RESPONSE_OK_COUNT
+            = "drm.mediadrm.provide_key_response.ok.count";
+
+        /**
+         * Key to extract the number of failed {@link #provideKeyResponse}
+         * calls from the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String PROVIDE_KEY_RESPONSE_ERROR_COUNT
+            = "drm.mediadrm.provide_key_response.error.count";
+
+        /**
+         * Key to extract the list of error codes that were returned from
+         * {@link #provideKeyResponse} calls. The key is used to lookup the
+         * list in the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The list is an array of Long values
+         * ({@link android.os.BaseBundle#getLongArray}).
+         */
+        public static final String PROVIDE_KEY_RESPONSE_ERROR_LIST
+            = "drm.mediadrm.provide_key_response.error.list";
+
+        /**
+         * Key to extract the average time in microseconds of calls to
+         * {@link #provideKeyResponse}. The valus is retrieved from the
+         * {@link PersistableBundle} returned from {@link #getMetrics}.
+         * The time is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String PROVIDE_KEY_RESPONSE_OK_TIME_MICROS
+            = "drm.mediadrm.provide_key_response.ok.average_time_micros";
+
+        /**
+         * Key to extract the number of successful {@link #getProvisionRequest}
+         * calls from the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String GET_PROVISION_REQUEST_OK_COUNT
+            = "drm.mediadrm.get_provision_request.ok.count";
+
+        /**
+         * Key to extract the number of failed {@link #getProvisionRequest}
+         * calls from the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String GET_PROVISION_REQUEST_ERROR_COUNT
+            = "drm.mediadrm.get_provision_request.error.count";
+
+        /**
+         * Key to extract the list of error codes that were returned from
+         * {@link #getProvisionRequest} calls. The key is used to lookup the
+         * list in the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The list is an array of Long values
+         * ({@link android.os.BaseBundle#getLongArray}).
+         */
+        public static final String GET_PROVISION_REQUEST_ERROR_LIST
+            = "drm.mediadrm.get_provision_request.error.list";
+
+        /**
+         * Key to extract the number of successful
+         * {@link #provideProvisionResponse} calls from the
+         * {@link PersistableBundle} returned by a {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String PROVIDE_PROVISION_RESPONSE_OK_COUNT
+            = "drm.mediadrm.provide_provision_response.ok.count";
+
+        /**
+         * Key to extract the number of failed
+         * {@link #provideProvisionResponse} calls from the
+         * {@link PersistableBundle} returned by a {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String PROVIDE_PROVISION_RESPONSE_ERROR_COUNT
+            = "drm.mediadrm.provide_provision_response.error.count";
+
+        /**
+         * Key to extract the list of error codes that were returned from
+         * {@link #provideProvisionResponse} calls. The key is used to lookup
+         * the list in the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The list is an array of Long values
+         * ({@link android.os.BaseBundle#getLongArray}).
+         */
+        public static final String PROVIDE_PROVISION_RESPONSE_ERROR_LIST
+            = "drm.mediadrm.provide_provision_response.error.list";
+
+        /**
+         * Key to extract the number of successful
+         * {@link #getPropertyByteArray} calls were made with the
+         * {@link #PROPERTY_DEVICE_UNIQUE_ID} value. The key is used to lookup
+         * the value in the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String GET_DEVICE_UNIQUE_ID_OK_COUNT
+            = "drm.mediadrm.get_device_unique_id.ok.count";
+
+        /**
+         * Key to extract the number of failed
+         * {@link #getPropertyByteArray} calls were made with the
+         * {@link #PROPERTY_DEVICE_UNIQUE_ID} value. The key is used to lookup
+         * the value in the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String GET_DEVICE_UNIQUE_ID_ERROR_COUNT
+            = "drm.mediadrm.get_device_unique_id.error.count";
+
+        /**
+         * Key to extract the list of error codes that were returned from
+         * {@link #getPropertyByteArray} calls with the
+         * {@link #PROPERTY_DEVICE_UNIQUE_ID} value. The key is used to lookup
+         * the list in the {@link PersistableBundle} returned by a
+         * {@link #getMetrics} call.
+         * The list is an array of Long values
+         * ({@link android.os.BaseBundle#getLongArray}).
+         */
+        public static final String GET_DEVICE_UNIQUE_ID_ERROR_LIST
+            = "drm.mediadrm.get_device_unique_id.error.list";
+
+        /**
+         * Key to extraact the count of {@link KeyStatus#STATUS_EXPIRED} events
+         * that occured. The count is extracted from the
+         * {@link PersistableBundle} returned from a {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String KEY_STATUS_EXPIRED_COUNT
+            = "drm.mediadrm.key_status.EXPIRED.count";
+
+        /**
+         * Key to extract the count of {@link KeyStatus#STATUS_INTERNAL_ERROR}
+         * events that occured. The count is extracted from the
+         * {@link PersistableBundle} returned from a {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String KEY_STATUS_INTERNAL_ERROR_COUNT
+            = "drm.mediadrm.key_status.INTERNAL_ERROR.count";
+
+        /**
+         * Key to extract the count of
+         * {@link KeyStatus#STATUS_OUTPUT_NOT_ALLOWED} events that occured.
+         * The count is extracted from the
+         * {@link PersistableBundle} returned from a {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String KEY_STATUS_OUTPUT_NOT_ALLOWED_COUNT
+            = "drm.mediadrm.key_status_change.OUTPUT_NOT_ALLOWED.count";
+
+        /**
+         * Key to extract the count of {@link KeyStatus#STATUS_PENDING}
+         * events that occured. The count is extracted from the
+         * {@link PersistableBundle} returned from a {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String KEY_STATUS_PENDING_COUNT
+            = "drm.mediadrm.key_status_change.PENDING.count";
+
+        /**
+         * Key to extract the count of {@link KeyStatus#STATUS_USABLE}
+         * events that occured. The count is extracted from the
+         * {@link PersistableBundle} returned from a {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String KEY_STATUS_USABLE_COUNT
+            = "drm.mediadrm.key_status_change.USABLE.count";
+
+        /**
+         * Key to extract the count of {@link OnEventListener#onEvent}
+         * calls of type PROVISION_REQUIRED occured. The count is
+         * extracted from the {@link PersistableBundle} returned from a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String EVENT_PROVISION_REQUIRED_COUNT
+            = "drm.mediadrm.event.PROVISION_REQUIRED.count";
+
+        /**
+         * Key to extract the count of {@link OnEventListener#onEvent}
+         * calls of type KEY_NEEDED occured. The count is
+         * extracted from the {@link PersistableBundle} returned from a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String EVENT_KEY_NEEDED_COUNT
+            = "drm.mediadrm.event.KEY_NEEDED.count";
+
+        /**
+         * Key to extract the count of {@link OnEventListener#onEvent}
+         * calls of type KEY_EXPIRED occured. The count is
+         * extracted from the {@link PersistableBundle} returned from a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String EVENT_KEY_EXPIRED_COUNT
+            = "drm.mediadrm.event.KEY_EXPIRED.count";
+
+        /**
+         * Key to extract the count of {@link OnEventListener#onEvent}
+         * calls of type VENDOR_DEFINED. The count is
+         * extracted from the {@link PersistableBundle} returned from a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String EVENT_VENDOR_DEFINED_COUNT
+            = "drm.mediadrm.event.VENDOR_DEFINED.count";
+
+        /**
+         * Key to extract the count of {@link OnEventListener#onEvent}
+         * calls of type SESSION_RECLAIMED. The count is
+         * extracted from the {@link PersistableBundle} returned from a
+         * {@link #getMetrics} call.
+         * The count is a Long value ({@link android.os.BaseBundle#getLong}).
+         */
+        public static final String EVENT_SESSION_RECLAIMED_COUNT
+            = "drm.mediadrm.event.SESSION_RECLAIMED.count";
+    }
+
+    /**
+     * Obtain a {@link PlaybackComponent} associated with a DRM session.
+     * Call {@link PlaybackComponent#setLogSessionId(LogSessionId)} on
+     * the returned object to associate a playback session with the DRM session.
+     *
+     * @param sessionId a DRM session ID obtained from {@link #openSession()}
+     * @return a {@link PlaybackComponent} associated with the session,
+     * or {@code null} if the session is closed or does not exist.
+     * @see PlaybackComponent
+     */
+    @Nullable
+    public PlaybackComponent getPlaybackComponent(@NonNull byte[] sessionId) {
+        if (sessionId == null) {
+            throw new IllegalArgumentException("sessionId is null");
+        }
+        return mPlaybackComponentMap.get(ByteBuffer.wrap(sessionId));
+    }
+
+    private native void setPlaybackId(byte[] sessionId, String logSessionId);
+
+    /** This class contains the Drm session ID and log session ID */
+    public final class PlaybackComponent {
+        private final byte[] mSessionId;
+        @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;
+
+        /** @hide */
+        public PlaybackComponent(byte[] sessionId) {
+            mSessionId = sessionId;
+        }
+
+
+        /**
+         * Gets the {@link LogSessionId}.
+         */
+        public void setLogSessionId(@NonNull LogSessionId logSessionId) {
+            Objects.requireNonNull(logSessionId);
+            if (logSessionId.getStringId() == null) {
+                throw new IllegalArgumentException("playbackId is null");
+            }
+            MediaDrm.this.setPlaybackId(mSessionId, logSessionId.getStringId());
+            mLogSessionId = logSessionId;
+        }
+
+
+        /**
+         * Returns the {@link LogSessionId}.
+         */
+        @NonNull public LogSessionId getLogSessionId() {
+            return mLogSessionId;
+        }
+    }
+
+    /**
+     * Returns recent {@link LogMessage LogMessages} associated with this {@link MediaDrm}
+     * instance.
+     */
+    @NonNull
+    public native List<LogMessage> getLogMessages();
+
+    /**
+     * A {@link LogMessage} records an event in the {@link MediaDrm} framework
+     * or vendor plugin.
+     */
+    public static final class LogMessage {
+        private final long timestampMillis;
+        private final int priority;
+        private final String message;
+
+        /**
+         * Timing of the recorded event measured in milliseconds since the Epoch,
+         * 1970-01-01 00:00:00 +0000 (UTC).
+         */
+        public final long getTimestampMillis() { return timestampMillis; }
+
+        /**
+         * Priority of the recorded event.
+         * <p>
+         * Possible priority constants are defined in {@link Log}, e.g.:
+         * <ul>
+         *     <li>{@link Log#ASSERT}</li>
+         *     <li>{@link Log#ERROR}</li>
+         *     <li>{@link Log#WARN}</li>
+         *     <li>{@link Log#INFO}</li>
+         *     <li>{@link Log#DEBUG}</li>
+         *     <li>{@link Log#VERBOSE}</li>
+         * </ul>
+         */
+        @Log.Level
+        public final int getPriority() { return priority; }
+
+        /**
+         * Description of the recorded event.
+         */
+        @NonNull
+        public final String getMessage() { return message; }
+
+        private LogMessage(long timestampMillis, int priority, String message) {
+            this.timestampMillis = timestampMillis;
+            if (priority < Log.VERBOSE || priority > Log.ASSERT) {
+                throw new IllegalArgumentException("invalid log priority " + priority);
+            }
+            this.priority = priority;
+            this.message = message;
+        }
+
+        private char logPriorityChar() {
+            switch (priority) {
+                case Log.VERBOSE:
+                    return 'V';
+                case Log.DEBUG:
+                    return 'D';
+                case Log.INFO:
+                    return 'I';
+                case Log.WARN:
+                    return 'W';
+                case Log.ERROR:
+                    return 'E';
+                case Log.ASSERT:
+                    return 'F';
+                default:
+            }
+            return 'U';
+        }
+
+        @Override
+        public String toString() {
+            return String.format("LogMessage{%s %c %s}",
+                    Instant.ofEpochMilli(timestampMillis), logPriorityChar(), message);
+        }
+    }
+}
diff --git a/android/media/MediaDrmException.java b/android/media/MediaDrmException.java
new file mode 100644
index 0000000..d547574
--- /dev/null
+++ b/android/media/MediaDrmException.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2013 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;
+
+/**
+ * Base class for MediaDrm exceptions
+ */
+public class MediaDrmException extends Exception {
+    public MediaDrmException(String detailMessage) {
+        super(detailMessage);
+    }
+}
diff --git a/android/media/MediaDrmResetException.java b/android/media/MediaDrmResetException.java
new file mode 100644
index 0000000..3b2da1e
--- /dev/null
+++ b/android/media/MediaDrmResetException.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2015 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;
+
+/**
+ * This exception is thrown when the MediaDrm instance has become unusable
+ * due to a restart of the mediaserver process.  To continue, the app must
+ * release the MediaDrm object, then create and initialize a new one.
+ */
+public class MediaDrmResetException extends IllegalStateException {
+    public MediaDrmResetException(String detailMessage) {
+        super(detailMessage);
+    }
+}
diff --git a/android/media/MediaExtractor.java b/android/media/MediaExtractor.java
new file mode 100644
index 0000000..5f56a73
--- /dev/null
+++ b/android/media/MediaExtractor.java
@@ -0,0 +1,849 @@
+/*
+ * Copyright (C) 2012 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.media.metrics.LogSessionId;
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.IHwBinder;
+import android.os.PersistableBundle;
+
+import com.android.internal.util.Preconditions;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.stream.Collectors;
+
+/**
+ * MediaExtractor facilitates extraction of demuxed, typically encoded,  media data
+ * from a data source.
+ * <p>It is generally used like this:
+ * <pre>
+ * MediaExtractor extractor = new MediaExtractor();
+ * extractor.setDataSource(...);
+ * int numTracks = extractor.getTrackCount();
+ * for (int i = 0; i &lt; numTracks; ++i) {
+ *   MediaFormat format = extractor.getTrackFormat(i);
+ *   String mime = format.getString(MediaFormat.KEY_MIME);
+ *   if (weAreInterestedInThisTrack) {
+ *     extractor.selectTrack(i);
+ *   }
+ * }
+ * ByteBuffer inputBuffer = ByteBuffer.allocate(...)
+ * while (extractor.readSampleData(inputBuffer, ...) &gt;= 0) {
+ *   int trackIndex = extractor.getSampleTrackIndex();
+ *   long presentationTimeUs = extractor.getSampleTime();
+ *   ...
+ *   extractor.advance();
+ * }
+ *
+ * extractor.release();
+ * extractor = null;
+ * </pre>
+ *
+ * <p>This class requires the {@link android.Manifest.permission#INTERNET} permission
+ * when used with network-based content.
+ */
+public final class MediaExtractor {
+    public MediaExtractor() {
+        native_setup();
+    }
+
+    /**
+     * Sets the data source (MediaDataSource) to use.
+     *
+     * @param dataSource the MediaDataSource for the media you want to extract from
+     *
+     * @throws IllegalArgumentException if dataSource is invalid.
+     */
+    public native final void setDataSource(@NonNull MediaDataSource dataSource)
+        throws IOException;
+
+    /**
+     * Sets the data source as a content Uri.
+     *
+     * @param context the Context to use when resolving the Uri
+     * @param uri the Content URI of the data you want to extract from.
+     *
+     * <p>When <code>uri</code> refers to a network file the
+     * {@link android.Manifest.permission#INTERNET} permission is required.
+     *
+     * @param headers the headers to be sent together with the request for the data.
+     *        This can be {@code null} if no specific headers are to be sent with the
+     *        request.
+     */
+    public final void setDataSource(
+            @NonNull Context context, @NonNull Uri uri, @Nullable Map<String, String> headers)
+        throws IOException {
+        String scheme = uri.getScheme();
+        if (scheme == null || scheme.equals("file")) {
+            setDataSource(uri.getPath());
+            return;
+        }
+
+        AssetFileDescriptor fd = null;
+        try {
+            ContentResolver resolver = context.getContentResolver();
+            fd = resolver.openAssetFileDescriptor(uri, "r");
+            if (fd == null) {
+                return;
+            }
+            // Note: using getDeclaredLength so that our behavior is the same
+            // as previous versions when the content provider is returning
+            // a full file.
+            if (fd.getDeclaredLength() < 0) {
+                setDataSource(fd.getFileDescriptor());
+            } else {
+                setDataSource(
+                        fd.getFileDescriptor(),
+                        fd.getStartOffset(),
+                        fd.getDeclaredLength());
+            }
+            return;
+        } catch (SecurityException ex) {
+        } catch (IOException ex) {
+        } finally {
+            if (fd != null) {
+                fd.close();
+            }
+        }
+
+        setDataSource(uri.toString(), headers);
+    }
+
+    /**
+     * Sets the data source (file-path or http URL) to use.
+     *
+     * @param path the path of the file, or the http URL
+     *
+     * <p>When <code>path</code> refers to a network file the
+     * {@link android.Manifest.permission#INTERNET} permission is required.
+     *
+     * @param headers the headers associated with the http request for the stream you want to play.
+     *        This can be {@code null} if no specific headers are to be sent with the
+     *        request.
+     */
+    public final void setDataSource(@NonNull String path, @Nullable Map<String, String> headers)
+        throws IOException {
+        String[] keys = null;
+        String[] values = null;
+
+        if (headers != null) {
+            keys = new String[headers.size()];
+            values = new String[headers.size()];
+
+            int i = 0;
+            for (Map.Entry<String, String> entry: headers.entrySet()) {
+                keys[i] = entry.getKey();
+                values[i] = entry.getValue();
+                ++i;
+            }
+        }
+
+        nativeSetDataSource(
+                MediaHTTPService.createHttpServiceBinderIfNecessary(path),
+                path,
+                keys,
+                values);
+    }
+
+    private native final void nativeSetDataSource(
+            @NonNull IBinder httpServiceBinder,
+            @NonNull String path,
+            @Nullable String[] keys,
+            @Nullable String[] values) throws IOException;
+
+    /**
+     * Sets the data source (file-path or http URL) to use.
+     *
+     * @param path the path of the file, or the http URL of the stream
+     *
+     * <p>When <code>path</code> refers to a local file, the file may actually be opened by a
+     * process other than the calling application.  This implies that the pathname
+     * should be an absolute path (as any other process runs with unspecified current working
+     * directory), and that the pathname should reference a world-readable file.
+     * As an alternative, the application could first open the file for reading,
+     * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}.
+     *
+     * <p>When <code>path</code> refers to a network file the
+     * {@link android.Manifest.permission#INTERNET} permission is required.
+     */
+    public final void setDataSource(@NonNull String path) throws IOException {
+        nativeSetDataSource(
+                MediaHTTPService.createHttpServiceBinderIfNecessary(path),
+                path,
+                null,
+                null);
+    }
+
+    /**
+     * Sets the data source (AssetFileDescriptor) to use. It is the caller's
+     * responsibility to close the file descriptor. It is safe to do so as soon
+     * as this call returns.
+     *
+     * @param afd the AssetFileDescriptor for the file you want to extract from.
+     */
+    public final void setDataSource(@NonNull AssetFileDescriptor afd)
+            throws IOException, IllegalArgumentException, IllegalStateException {
+        Preconditions.checkNotNull(afd);
+        // Note: using getDeclaredLength so that our behavior is the same
+        // as previous versions when the content provider is returning
+        // a full file.
+        if (afd.getDeclaredLength() < 0) {
+            setDataSource(afd.getFileDescriptor());
+        } else {
+            setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
+        }
+    }
+
+    /**
+     * Sets the data source (FileDescriptor) to use. It is the caller's responsibility
+     * to close the file descriptor. It is safe to do so as soon as this call returns.
+     *
+     * @param fd the FileDescriptor for the file you want to extract from.
+     */
+    public final void setDataSource(@NonNull FileDescriptor fd) throws IOException {
+        setDataSource(fd, 0, 0x7ffffffffffffffL);
+    }
+
+    /**
+     * Sets the data source (FileDescriptor) to use.  The FileDescriptor must be
+     * seekable (N.B. a LocalSocket is not seekable). It is the caller's responsibility
+     * to close the file descriptor. It is safe to do so as soon as this call returns.
+     *
+     * @param fd the FileDescriptor for the file you want to extract from.
+     * @param offset the offset into the file where the data to be extracted starts, in bytes
+     * @param length the length in bytes of the data to be extracted
+     */
+    public native final void setDataSource(
+            @NonNull FileDescriptor fd, long offset, long length) throws IOException;
+
+    /**
+     * Sets the MediaCas instance to use. This should be called after a
+     * successful setDataSource() if at least one track reports mime type
+     * of {@link android.media.MediaFormat#MIMETYPE_AUDIO_SCRAMBLED}
+     * or {@link android.media.MediaFormat#MIMETYPE_VIDEO_SCRAMBLED}.
+     * Stream parsing will not proceed until a valid MediaCas object
+     * is provided.
+     *
+     * @param mediaCas the MediaCas object to use.
+     */
+    public final void setMediaCas(@NonNull MediaCas mediaCas) {
+        mMediaCas = mediaCas;
+        nativeSetMediaCas(mediaCas.getBinder());
+    }
+
+    private native final void nativeSetMediaCas(@NonNull IHwBinder casBinder);
+
+    /**
+     * Describes the conditional access system used to scramble a track.
+     */
+    public static final class CasInfo {
+        private final int mSystemId;
+        private final MediaCas.Session mSession;
+        private final byte[] mPrivateData;
+
+        CasInfo(int systemId, @Nullable MediaCas.Session session, @Nullable byte[] privateData) {
+            mSystemId = systemId;
+            mSession = session;
+            mPrivateData = privateData;
+        }
+
+        /**
+         * Retrieves the system id of the conditional access system.
+         *
+         * @return CA system id of the CAS used to scramble the track.
+         */
+        public int getSystemId() {
+            return mSystemId;
+        }
+
+        /**
+         * Retrieves the private data in the CA_Descriptor associated with a track.
+         * Some CAS systems may need this to initialize the CAS plugin object. This
+         * private data can only be retrieved before a valid {@link MediaCas} object
+         * is set on the extractor.
+         * <p>
+         * @see MediaExtractor#setMediaCas
+         * <p>
+         * @return a byte array containing the private data. A null return value
+         *         indicates that the private data is unavailable. An empty array,
+         *         on the other hand, indicates that the private data is empty
+         *         (zero in length).
+         */
+        @Nullable
+        public byte[] getPrivateData() {
+            return mPrivateData;
+        }
+
+        /**
+         * Retrieves the {@link MediaCas.Session} associated with a track. The
+         * session is needed to initialize a descrambler in order to decode the
+         * scrambled track. The session object can only be retrieved after a valid
+         * {@link MediaCas} object is set on the extractor.
+         * <p>
+         * @see MediaExtractor#setMediaCas
+         * @see MediaDescrambler#setMediaCasSession
+         * <p>
+         * @return a {@link MediaCas.Session} object associated with a track.
+         */
+        public MediaCas.Session getSession() {
+            return mSession;
+        }
+    }
+
+    private ArrayList<Byte> toByteArray(@NonNull byte[] data) {
+        ArrayList<Byte> byteArray = new ArrayList<Byte>(data.length);
+        for (int i = 0; i < data.length; i++) {
+            byteArray.add(i, Byte.valueOf(data[i]));
+        }
+        return byteArray;
+    }
+
+    /**
+     * Retrieves the information about the conditional access system used to scramble
+     * a track.
+     *
+     * @param index of the track.
+     * @return an {@link CasInfo} object describing the conditional access system.
+     */
+    public CasInfo getCasInfo(int index) {
+        Map<String, Object> formatMap = getTrackFormatNative(index);
+        if (formatMap.containsKey(MediaFormat.KEY_CA_SYSTEM_ID)) {
+            int systemId = ((Integer)formatMap.get(MediaFormat.KEY_CA_SYSTEM_ID)).intValue();
+            MediaCas.Session session = null;
+            byte[] privateData = null;
+            if (formatMap.containsKey(MediaFormat.KEY_CA_PRIVATE_DATA)) {
+                ByteBuffer buf = (ByteBuffer) formatMap.get(MediaFormat.KEY_CA_PRIVATE_DATA);
+                buf.rewind();
+                privateData = new byte[buf.remaining()];
+                buf.get(privateData);
+            }
+            if (mMediaCas != null && formatMap.containsKey(MediaFormat.KEY_CA_SESSION_ID)) {
+                ByteBuffer buf = (ByteBuffer) formatMap.get(MediaFormat.KEY_CA_SESSION_ID);
+                buf.rewind();
+                final byte[] sessionId = new byte[buf.remaining()];
+                buf.get(sessionId);
+                session = mMediaCas.createFromSessionId(toByteArray(sessionId));
+            }
+            return new CasInfo(systemId, session, privateData);
+        }
+        return null;
+    }
+
+    @Override
+    protected void finalize() {
+        native_finalize();
+    }
+
+    /**
+     * Make sure you call this when you're done to free up any resources
+     * instead of relying on the garbage collector to do this for you at
+     * some point in the future.
+     */
+    public native final void release();
+
+    /**
+     * Count the number of tracks found in the data source.
+     */
+    public native final int getTrackCount();
+
+    /**
+     * Extract DRM initialization data if it exists
+     *
+     * @return DRM initialization data in the content, or {@code null}
+     * if no recognizable DRM format is found;
+     * @see DrmInitData
+     */
+    public DrmInitData getDrmInitData() {
+        Map<String, Object> formatMap = getFileFormatNative();
+        if (formatMap == null) {
+            return null;
+        }
+        if (formatMap.containsKey("pssh")) {
+            Map<UUID, byte[]> psshMap = getPsshInfo();
+            DrmInitData.SchemeInitData[] schemeInitDatas =
+                    psshMap.entrySet().stream().map(
+                            entry -> new DrmInitData.SchemeInitData(
+                                    entry.getKey(), /* mimeType= */ "cenc", entry.getValue()))
+                            .toArray(DrmInitData.SchemeInitData[]::new);
+            final Map<UUID, DrmInitData.SchemeInitData> initDataMap =
+                    Arrays.stream(schemeInitDatas).collect(
+                            Collectors.toMap(initData -> initData.uuid, initData -> initData));
+            return new DrmInitData() {
+                public SchemeInitData get(UUID schemeUuid) {
+                    return initDataMap.get(schemeUuid);
+                }
+
+                @Override
+                public int getSchemeInitDataCount() {
+                    return schemeInitDatas.length;
+                }
+
+                @Override
+                public SchemeInitData getSchemeInitDataAt(int index) {
+                    return schemeInitDatas[index];
+                }
+            };
+        } else {
+            int numTracks = getTrackCount();
+            for (int i = 0; i < numTracks; ++i) {
+                Map<String, Object> trackFormatMap = getTrackFormatNative(i);
+                if (!trackFormatMap.containsKey("crypto-key")) {
+                    continue;
+                }
+                ByteBuffer buf = (ByteBuffer) trackFormatMap.get("crypto-key");
+                buf.rewind();
+                final byte[] data = new byte[buf.remaining()];
+                buf.get(data);
+                // Webm scheme init data is not uuid-specific.
+                DrmInitData.SchemeInitData webmSchemeInitData =
+                        new DrmInitData.SchemeInitData(
+                                DrmInitData.SchemeInitData.UUID_NIL, "webm", data);
+                return new DrmInitData() {
+                    public SchemeInitData get(UUID schemeUuid) {
+                        return webmSchemeInitData;
+                    }
+
+                    @Override
+                    public int getSchemeInitDataCount() {
+                        return 1;
+                    }
+
+                    @Override
+                    public SchemeInitData getSchemeInitDataAt(int index) {
+                        return webmSchemeInitData;
+                    }
+                };
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Get the list of available audio presentations for the track.
+     * @param trackIndex index of the track.
+     * @return a list of available audio presentations for a given valid audio track index.
+     * The list will be empty if the source does not contain any audio presentations.
+     */
+    @NonNull
+    public List<AudioPresentation> getAudioPresentations(int trackIndex) {
+        return native_getAudioPresentations(trackIndex);
+    }
+
+    @NonNull
+    private native List<AudioPresentation> native_getAudioPresentations(int trackIndex);
+
+    /**
+     * Get the PSSH info if present.
+     * @return a map of uuid-to-bytes, with the uuid specifying
+     * the crypto scheme, and the bytes being the data specific to that scheme.
+     * This can be {@code null} if the source does not contain PSSH info.
+     */
+    @Nullable
+    public Map<UUID, byte[]> getPsshInfo() {
+        Map<UUID, byte[]> psshMap = null;
+        Map<String, Object> formatMap = getFileFormatNative();
+        if (formatMap != null && formatMap.containsKey("pssh")) {
+            ByteBuffer rawpssh = (ByteBuffer) formatMap.get("pssh");
+            rawpssh.order(ByteOrder.nativeOrder());
+            rawpssh.rewind();
+            formatMap.remove("pssh");
+            // parse the flat pssh bytebuffer into something more manageable
+            psshMap = new HashMap<UUID, byte[]>();
+            while (rawpssh.remaining() > 0) {
+                rawpssh.order(ByteOrder.BIG_ENDIAN);
+                long msb = rawpssh.getLong();
+                long lsb = rawpssh.getLong();
+                UUID uuid = new UUID(msb, lsb);
+                rawpssh.order(ByteOrder.nativeOrder());
+                int datalen = rawpssh.getInt();
+                byte [] psshdata = new byte[datalen];
+                rawpssh.get(psshdata);
+                psshMap.put(uuid, psshdata);
+            }
+        }
+        return psshMap;
+    }
+
+    @NonNull
+    private native Map<String, Object> getFileFormatNative();
+
+    /**
+     * Get the track format at the specified index.
+     *
+     * More detail on the representation can be found at {@link android.media.MediaCodec}
+     * <p>
+     * The following table summarizes support for format keys across android releases:
+     *
+     * <table style="width: 0%">
+     *  <thead>
+     *   <tr>
+     *    <th rowspan=2>OS Version(s)</th>
+     *    <td colspan=3>{@code MediaFormat} keys used for</th>
+     *   </tr><tr>
+     *    <th>All Tracks</th>
+     *    <th>Audio Tracks</th>
+     *    <th>Video Tracks</th>
+     *   </tr>
+     *  </thead>
+     *  <tbody>
+     *   <tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#JELLY_BEAN}</td>
+     *    <td rowspan=8>{@link MediaFormat#KEY_MIME},<br>
+     *        {@link MediaFormat#KEY_DURATION},<br>
+     *        {@link MediaFormat#KEY_MAX_INPUT_SIZE}</td>
+     *    <td rowspan=5>{@link MediaFormat#KEY_SAMPLE_RATE},<br>
+     *        {@link MediaFormat#KEY_CHANNEL_COUNT},<br>
+     *        {@link MediaFormat#KEY_CHANNEL_MASK},<br>
+     *        gapless playback information<sup>.mp3, .mp4</sup>,<br>
+     *        {@link MediaFormat#KEY_IS_ADTS}<sup>AAC if streaming</sup>,<br>
+     *        codec-specific data<sup>AAC, Vorbis</sup></td>
+     *    <td rowspan=2>{@link MediaFormat#KEY_WIDTH},<br>
+     *        {@link MediaFormat#KEY_HEIGHT},<br>
+     *        codec-specific data<sup>AVC, MPEG4</sup></td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR1}</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}</td>
+     *    <td rowspan=3>as above, plus<br>
+     *        Pixel aspect ratio information<sup>AVC, *</sup></td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#KITKAT}</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#KITKAT_WATCH}</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP}</td>
+     *    <td rowspan=2>as above, plus<br>
+     *        {@link MediaFormat#KEY_BIT_RATE}<sup>AAC</sup>,<br>
+     *        codec-specific data<sup>Opus</sup></td>
+     *    <td rowspan=2>as above, plus<br>
+     *        {@link MediaFormat#KEY_ROTATION}<sup>.mp4</sup>,<br>
+     *        {@link MediaFormat#KEY_BIT_RATE}<sup>MPEG4</sup>,<br>
+     *        codec-specific data<sup>HEVC</sup></td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#M}</td>
+     *    <td>as above, plus<br>
+     *        gapless playback information<sup>Opus</sup></td>
+     *    <td>as above, plus<br>
+     *        {@link MediaFormat#KEY_FRAME_RATE} (integer)</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#N}</td>
+     *    <td>as above, plus<br>
+     *        {@link MediaFormat#KEY_TRACK_ID},<br>
+     *        <!-- {link MediaFormat#KEY_MAX_BIT_RATE}<sup>#, .mp4</sup>,<br> -->
+     *        {@link MediaFormat#KEY_BIT_RATE}<sup>#, .mp4</sup></td>
+     *    <td>as above, plus<br>
+     *        {@link MediaFormat#KEY_PCM_ENCODING},<br>
+     *        {@link MediaFormat#KEY_PROFILE}<sup>AAC</sup></td>
+     *    <td>as above, plus<br>
+     *        {@link MediaFormat#KEY_HDR_STATIC_INFO}<sup>#, .webm</sup>,<br>
+     *        {@link MediaFormat#KEY_COLOR_STANDARD}<sup>#</sup>,<br>
+     *        {@link MediaFormat#KEY_COLOR_TRANSFER}<sup>#</sup>,<br>
+     *        {@link MediaFormat#KEY_COLOR_RANGE}<sup>#</sup>,<br>
+     *        {@link MediaFormat#KEY_PROFILE}<sup>MPEG2, H.263, MPEG4, AVC, HEVC, VP9</sup>,<br>
+     *        {@link MediaFormat#KEY_LEVEL}<sup>H.263, MPEG4, AVC, HEVC, VP9</sup>,<br>
+     *        codec-specific data<sup>VP9</sup></td>
+     *   </tr>
+     *   <tr>
+     *    <td colspan=4>
+     *     <p class=note><strong>Notes:</strong><br>
+     *      #: container-specified value only.<br>
+     *      .mp4, .webm&hellip;: for listed containers<br>
+     *      MPEG4, AAC&hellip;: for listed codecs
+     *    </td>
+     *   </tr><tr>
+     *    <td colspan=4>
+     *     <p class=note>Note that that level information contained in the container many times
+     *     does not match the level of the actual bitstream. You may want to clear the level using
+     *     {@code MediaFormat.setString(KEY_LEVEL, null)} before using the track format to find a
+     *     decoder that can play back a particular track.
+     *    </td>
+     *   </tr><tr>
+     *    <td colspan=4>
+     *     <p class=note><strong>*Pixel (sample) aspect ratio</strong> is returned in the following
+     *     keys. The display width can be calculated for example as:
+     *     <p align=center>
+     *     display-width = display-height * crop-width / crop-height * sar-width / sar-height
+     *    </td>
+     *   </tr><tr>
+     *    <th>Format Key</th><th>Value Type</th><th colspan=2>Description</th>
+     *   </tr><tr>
+     *    <td>{@code "sar-width"}</td><td>Integer</td><td colspan=2>Pixel aspect ratio width</td>
+     *   </tr><tr>
+     *    <td>{@code "sar-height"}</td><td>Integer</td><td colspan=2>Pixel aspect ratio height</td>
+     *   </tr>
+     *  </tbody>
+     * </table>
+     *
+     */
+    @NonNull
+    public MediaFormat getTrackFormat(int index) {
+        return new MediaFormat(getTrackFormatNative(index));
+    }
+
+    @NonNull
+    private native Map<String, Object> getTrackFormatNative(int index);
+
+    /**
+     * Subsequent calls to {@link #readSampleData}, {@link #getSampleTrackIndex} and
+     * {@link #getSampleTime} only retrieve information for the subset of tracks
+     * selected.
+     * Selecting the same track multiple times has no effect, the track is
+     * only selected once.
+     */
+    public native void selectTrack(int index);
+
+    /**
+     * Subsequent calls to {@link #readSampleData}, {@link #getSampleTrackIndex} and
+     * {@link #getSampleTime} only retrieve information for the subset of tracks
+     * selected.
+     */
+    public native void unselectTrack(int index);
+
+    /**
+     * If possible, seek to a sync sample at or before the specified time
+     */
+    public static final int SEEK_TO_PREVIOUS_SYNC       = 0;
+    /**
+     * If possible, seek to a sync sample at or after the specified time
+     */
+    public static final int SEEK_TO_NEXT_SYNC           = 1;
+    /**
+     * If possible, seek to the sync sample closest to the specified time
+     */
+    public static final int SEEK_TO_CLOSEST_SYNC        = 2;
+
+    /** @hide */
+    @IntDef({
+        SEEK_TO_PREVIOUS_SYNC,
+        SEEK_TO_NEXT_SYNC,
+        SEEK_TO_CLOSEST_SYNC,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SeekMode {}
+
+    /**
+     * All selected tracks seek near the requested time according to the
+     * specified mode.
+     */
+    public native void seekTo(long timeUs, @SeekMode int mode);
+
+    /**
+     * Advance to the next sample. Returns false if no more sample data
+     * is available (end of stream).
+     *
+     * When extracting a local file, the behaviors of {@link #advance} and
+     * {@link #readSampleData} are undefined in presence of concurrent
+     * writes to the same local file; more specifically, end of stream
+     * could be signalled earlier than expected.
+     */
+    public native boolean advance();
+
+    /**
+     * Retrieve the current encoded sample and store it in the byte buffer
+     * starting at the given offset.
+     * <p>
+     * <b>Note:</b>As of API 21, on success the position and limit of
+     * {@code byteBuf} is updated to point to the data just read.
+     * @param byteBuf the destination byte buffer
+     * @return the sample size (or -1 if no more samples are available).
+     */
+    public native int readSampleData(@NonNull ByteBuffer byteBuf, int offset);
+
+    /**
+     * Returns the track index the current sample originates from (or -1
+     * if no more samples are available)
+     */
+    public native int getSampleTrackIndex();
+
+    /**
+     * Returns the current sample's presentation time in microseconds.
+     * or -1 if no more samples are available.
+     */
+    public native long getSampleTime();
+
+    /**
+     * @return size of the current sample in bytes or -1 if no more
+     * samples are available.
+     */
+    public native long getSampleSize();
+
+    // Keep these in sync with their equivalents in NuMediaExtractor.h
+    /**
+     * The sample is a sync sample (or in {@link MediaCodec}'s terminology
+     * it is a key frame.)
+     *
+     * @see MediaCodec#BUFFER_FLAG_KEY_FRAME
+     */
+    public static final int SAMPLE_FLAG_SYNC      = 1;
+
+    /**
+     * The sample is (at least partially) encrypted, see also the documentation
+     * for {@link android.media.MediaCodec#queueSecureInputBuffer}
+     */
+    public static final int SAMPLE_FLAG_ENCRYPTED = 2;
+
+    /**
+     * This indicates that the buffer only contains part of a frame,
+     * and the decoder should batch the data until a buffer without
+     * this flag appears before decoding the frame.
+     *
+     * @see MediaCodec#BUFFER_FLAG_PARTIAL_FRAME
+     */
+    public static final int SAMPLE_FLAG_PARTIAL_FRAME = 4;
+
+    /** @hide */
+    @IntDef(
+        flag = true,
+        value = {
+            SAMPLE_FLAG_SYNC,
+            SAMPLE_FLAG_ENCRYPTED,
+            SAMPLE_FLAG_PARTIAL_FRAME,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SampleFlag {}
+
+    /**
+     * Returns the current sample's flags.
+     */
+    @SampleFlag
+    public native int getSampleFlags();
+
+    /**
+     * If the sample flags indicate that the current sample is at least
+     * partially encrypted, this call returns relevant information about
+     * the structure of the sample data required for decryption.
+     * @param info The android.media.MediaCodec.CryptoInfo structure
+     *             to be filled in.
+     * @return true iff the sample flags contain {@link #SAMPLE_FLAG_ENCRYPTED}
+     */
+    public native boolean getSampleCryptoInfo(@NonNull MediaCodec.CryptoInfo info);
+
+    /**
+     * Returns an estimate of how much data is presently cached in memory
+     * expressed in microseconds. Returns -1 if that information is unavailable
+     * or not applicable (no cache).
+     */
+    public native long getCachedDuration();
+
+    /**
+     * Returns true iff we are caching data and the cache has reached the
+     * end of the data stream (for now, a future seek may of course restart
+     * the fetching of data).
+     * This API only returns a meaningful result if {@link #getCachedDuration}
+     * indicates the presence of a cache, i.e. does NOT return -1.
+     */
+    public native boolean hasCacheReachedEndOfStream();
+
+    /**
+     * Sets the {@link LogSessionId} for MediaExtractor.
+     */
+    public void setLogSessionId(@NonNull LogSessionId logSessionId) {
+        mLogSessionId = Objects.requireNonNull(logSessionId);
+        native_setLogSessionId(logSessionId.getStringId());
+    }
+
+    /**
+     * Returns the {@link LogSessionId} for MediaExtractor.
+     */
+    @NonNull
+    public LogSessionId getLogSessionId() {
+        return mLogSessionId;
+    }
+
+    /**
+     *  Return Metrics data about the current media container.
+     *
+     * @return a {@link PersistableBundle} containing the set of attributes and values
+     * available for the media container being handled by this instance
+     * of MediaExtractor.
+     * The attributes are descibed in {@link MetricsConstants}.
+     *
+     *  Additional vendor-specific fields may also be present in
+     *  the return value.
+     */
+
+    public PersistableBundle getMetrics() {
+        PersistableBundle bundle = native_getMetrics();
+        return bundle;
+    }
+
+    private native void native_setLogSessionId(String logSessionId);
+    private native PersistableBundle native_getMetrics();
+
+    private static native final void native_init();
+    private native final void native_setup();
+    private native final void native_finalize();
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    private MediaCas mMediaCas;
+    @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;
+
+    private long mNativeContext;
+
+    public final static class MetricsConstants
+    {
+        private MetricsConstants() {}
+
+        /**
+         * Key to extract the container format
+         * from the {@link MediaExtractor#getMetrics} return value.
+         * The value is a String.
+         */
+        public static final String FORMAT = "android.media.mediaextractor.fmt";
+
+        /**
+         * Key to extract the container MIME type
+         * from the {@link MediaExtractor#getMetrics} return value.
+         * The value is a String.
+         */
+        public static final String MIME_TYPE = "android.media.mediaextractor.mime";
+
+        /**
+         * Key to extract the number of tracks in the container
+         * from the {@link MediaExtractor#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String TRACKS = "android.media.mediaextractor.ntrk";
+
+    }
+
+}
diff --git a/android/media/MediaFeature.java b/android/media/MediaFeature.java
new file mode 100644
index 0000000..8d1b159
--- /dev/null
+++ b/android/media/MediaFeature.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2020 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.annotation.StringDef;
+import android.os.Build;
+
+import com.android.modules.annotation.MinSdk;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * MediaFeature defines various media features, e.g. hdr type.
+ */
+@MinSdk(Build.VERSION_CODES.S)
+public final class MediaFeature {
+     /**
+     * Defines tye type of HDR(high dynamic range) video.
+     */
+    public static final class HdrType {
+        private HdrType() {
+        }
+
+        /**
+         * HDR type for dolby-vision.
+         */
+        public static final String DOLBY_VISION = "android.media.feature.hdr.dolby_vision";
+        /**
+         * HDR type for hdr10.
+         */
+        public static final String HDR10 = "android.media.feature.hdr.hdr10";
+        /**
+         * HDR type for hdr10+.
+         */
+        public static final String HDR10_PLUS = "android.media.feature.hdr.hdr10_plus";
+        /**
+         * HDR type for hlg.
+         */
+        public static final String HLG = "android.media.feature.hdr.hlg";
+    }
+
+    /** @hide */
+    @StringDef({
+            HdrType.DOLBY_VISION,
+            HdrType.HDR10,
+            HdrType.HDR10_PLUS,
+            HdrType.HLG,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MediaHdrType {
+    }
+}
diff --git a/android/media/MediaFile.java b/android/media/MediaFile.java
new file mode 100644
index 0000000..70d7937
--- /dev/null
+++ b/android/media/MediaFile.java
@@ -0,0 +1,445 @@
+/*
+ * Copyright (C) 2007 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.content.ContentResolver.MIME_TYPE_DEFAULT;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.mtp.MtpConstants;
+
+import libcore.content.type.MimeMap;
+
+import java.util.HashMap;
+import java.util.Locale;
+
+/**
+ * MediaScanner helper class.
+ * <p>
+ * This heavily relies upon extension to MIME type mappings which are maintained
+ * in {@link MimeMap}, to ensure consistency across the OS.
+ * <p>
+ * When adding a new file type, first add the MIME type mapping to
+ * {@link MimeMap}, and then add the MTP format mapping here.
+ *
+ * @hide
+ */
+public class MediaFile {
+
+    /** @deprecated file types no longer exist */
+    @Deprecated
+    @UnsupportedAppUsage
+    private static final int FIRST_AUDIO_FILE_TYPE = 1;
+    /** @deprecated file types no longer exist */
+    @Deprecated
+    @UnsupportedAppUsage
+    private static final int LAST_AUDIO_FILE_TYPE = 10;
+
+    /** @deprecated file types no longer exist */
+    @Deprecated
+    public static class MediaFileType {
+        @UnsupportedAppUsage
+        public final int fileType;
+        @UnsupportedAppUsage
+        public final String mimeType;
+
+        MediaFileType(int fileType, String mimeType) {
+            this.fileType = fileType;
+            this.mimeType = mimeType;
+        }
+    }
+
+    /** @deprecated file types no longer exist */
+    @Deprecated
+    @UnsupportedAppUsage
+    private static final HashMap<String, MediaFileType> sFileTypeMap = new HashMap<>();
+    /** @deprecated file types no longer exist */
+    @Deprecated
+    @UnsupportedAppUsage
+    private static final HashMap<String, Integer> sFileTypeToFormatMap = new HashMap<>();
+
+    // maps mime type to MTP format code
+    @UnsupportedAppUsage
+    private static final HashMap<String, Integer> sMimeTypeToFormatMap = new HashMap<>();
+    // maps MTP format code to mime type
+    @UnsupportedAppUsage
+    private static final HashMap<Integer, String> sFormatToMimeTypeMap = new HashMap<>();
+
+    @UnsupportedAppUsage
+    public MediaFile() {
+    }
+
+    /** @deprecated file types no longer exist */
+    @Deprecated
+    @UnsupportedAppUsage
+    static void addFileType(String extension, int fileType, String mimeType) {
+    }
+
+    private static void addFileType(int mtpFormatCode, @NonNull String mimeType) {
+        if (!sMimeTypeToFormatMap.containsKey(mimeType)) {
+            sMimeTypeToFormatMap.put(mimeType, Integer.valueOf(mtpFormatCode));
+        }
+        if (!sFormatToMimeTypeMap.containsKey(mtpFormatCode)) {
+            sFormatToMimeTypeMap.put(mtpFormatCode, mimeType);
+        }
+    }
+
+    static {
+        addFileType(MtpConstants.FORMAT_MP3, "audio/mpeg");
+        addFileType(MtpConstants.FORMAT_WAV, "audio/x-wav");
+        addFileType(MtpConstants.FORMAT_WMA, "audio/x-ms-wma");
+        addFileType(MtpConstants.FORMAT_OGG, "audio/ogg");
+        addFileType(MtpConstants.FORMAT_AAC, "audio/aac");
+        addFileType(MtpConstants.FORMAT_FLAC, "audio/flac");
+        addFileType(MtpConstants.FORMAT_AIFF, "audio/x-aiff");
+        addFileType(MtpConstants.FORMAT_MP2, "audio/mpeg");
+
+        addFileType(MtpConstants.FORMAT_MPEG, "video/mpeg");
+        addFileType(MtpConstants.FORMAT_MP4_CONTAINER, "video/mp4");
+        addFileType(MtpConstants.FORMAT_3GP_CONTAINER, "video/3gpp");
+        addFileType(MtpConstants.FORMAT_3GP_CONTAINER, "video/3gpp2");
+        addFileType(MtpConstants.FORMAT_AVI, "video/avi");
+        addFileType(MtpConstants.FORMAT_WMV, "video/x-ms-wmv");
+        addFileType(MtpConstants.FORMAT_ASF, "video/x-ms-asf");
+
+        addFileType(MtpConstants.FORMAT_EXIF_JPEG, "image/jpeg");
+        addFileType(MtpConstants.FORMAT_GIF, "image/gif");
+        addFileType(MtpConstants.FORMAT_PNG, "image/png");
+        addFileType(MtpConstants.FORMAT_BMP, "image/x-ms-bmp");
+        addFileType(MtpConstants.FORMAT_HEIF, "image/heif");
+        addFileType(MtpConstants.FORMAT_DNG, "image/x-adobe-dng");
+        addFileType(MtpConstants.FORMAT_TIFF, "image/tiff");
+        addFileType(MtpConstants.FORMAT_TIFF, "image/x-canon-cr2");
+        addFileType(MtpConstants.FORMAT_TIFF, "image/x-nikon-nrw");
+        addFileType(MtpConstants.FORMAT_TIFF, "image/x-sony-arw");
+        addFileType(MtpConstants.FORMAT_TIFF, "image/x-panasonic-rw2");
+        addFileType(MtpConstants.FORMAT_TIFF, "image/x-olympus-orf");
+        addFileType(MtpConstants.FORMAT_TIFF, "image/x-pentax-pef");
+        addFileType(MtpConstants.FORMAT_TIFF, "image/x-samsung-srw");
+        addFileType(MtpConstants.FORMAT_TIFF_EP, "image/tiff");
+        addFileType(MtpConstants.FORMAT_TIFF_EP, "image/x-nikon-nef");
+        addFileType(MtpConstants.FORMAT_JP2, "image/jp2");
+        addFileType(MtpConstants.FORMAT_JPX, "image/jpx");
+
+        addFileType(MtpConstants.FORMAT_M3U_PLAYLIST, "audio/x-mpegurl");
+        addFileType(MtpConstants.FORMAT_PLS_PLAYLIST, "audio/x-scpls");
+        addFileType(MtpConstants.FORMAT_WPL_PLAYLIST, "application/vnd.ms-wpl");
+        addFileType(MtpConstants.FORMAT_ASX_PLAYLIST, "video/x-ms-asf");
+
+        addFileType(MtpConstants.FORMAT_TEXT, "text/plain");
+        addFileType(MtpConstants.FORMAT_HTML, "text/html");
+        addFileType(MtpConstants.FORMAT_XML_DOCUMENT, "text/xml");
+
+        addFileType(MtpConstants.FORMAT_MS_WORD_DOCUMENT,
+                "application/msword");
+        addFileType(MtpConstants.FORMAT_MS_WORD_DOCUMENT,
+                "application/vnd.openxmlformats-officedocument.wordprocessingml.document");
+        addFileType(MtpConstants.FORMAT_MS_EXCEL_SPREADSHEET,
+                "application/vnd.ms-excel");
+        addFileType(MtpConstants.FORMAT_MS_EXCEL_SPREADSHEET,
+                "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
+        addFileType(MtpConstants.FORMAT_MS_POWERPOINT_PRESENTATION,
+                "application/vnd.ms-powerpoint");
+        addFileType(MtpConstants.FORMAT_MS_POWERPOINT_PRESENTATION,
+                "application/vnd.openxmlformats-officedocument.presentationml.presentation");
+    }
+
+    /** @deprecated file types no longer exist */
+    @Deprecated
+    @UnsupportedAppUsage
+    public static boolean isAudioFileType(int fileType) {
+        return false;
+    }
+
+    /** @deprecated file types no longer exist */
+    @Deprecated
+    @UnsupportedAppUsage
+    public static boolean isVideoFileType(int fileType) {
+        return false;
+    }
+
+    /** @deprecated file types no longer exist */
+    @Deprecated
+    @UnsupportedAppUsage
+    public static boolean isImageFileType(int fileType) {
+        return false;
+    }
+
+    /** @deprecated file types no longer exist */
+    @Deprecated
+    @UnsupportedAppUsage
+    public static boolean isPlayListFileType(int fileType) {
+        return false;
+    }
+
+    /** @deprecated file types no longer exist */
+    @Deprecated
+    @UnsupportedAppUsage
+    public static boolean isDrmFileType(int fileType) {
+        return false;
+    }
+
+    /** @deprecated file types no longer exist */
+    @Deprecated
+    @UnsupportedAppUsage
+    public static MediaFileType getFileType(String path) {
+        return null;
+    }
+
+    /**
+     * Check whether the mime type is document or not.
+     * @param mimeType the mime type to check
+     * @return true, if the mimeType is matched. Otherwise, false.
+     */
+    public static boolean isDocumentMimeType(@Nullable String mimeType) {
+        if (mimeType == null) {
+            return false;
+        }
+
+        final String normalizedMimeType = normalizeMimeType(mimeType);
+        if (normalizedMimeType.startsWith("text/")) {
+            return true;
+        }
+
+        switch (normalizedMimeType.toLowerCase(Locale.ROOT)) {
+            case "application/epub+zip":
+            case "application/msword":
+            case "application/pdf":
+            case "application/rtf":
+            case "application/vnd.ms-excel":
+            case "application/vnd.ms-excel.addin.macroenabled.12":
+            case "application/vnd.ms-excel.sheet.binary.macroenabled.12":
+            case "application/vnd.ms-excel.sheet.macroenabled.12":
+            case "application/vnd.ms-excel.template.macroenabled.12":
+            case "application/vnd.ms-powerpoint":
+            case "application/vnd.ms-powerpoint.addin.macroenabled.12":
+            case "application/vnd.ms-powerpoint.presentation.macroenabled.12":
+            case "application/vnd.ms-powerpoint.slideshow.macroenabled.12":
+            case "application/vnd.ms-powerpoint.template.macroenabled.12":
+            case "application/vnd.ms-word.document.macroenabled.12":
+            case "application/vnd.ms-word.template.macroenabled.12":
+            case "application/vnd.oasis.opendocument.chart":
+            case "application/vnd.oasis.opendocument.database":
+            case "application/vnd.oasis.opendocument.formula":
+            case "application/vnd.oasis.opendocument.graphics":
+            case "application/vnd.oasis.opendocument.graphics-template":
+            case "application/vnd.oasis.opendocument.presentation":
+            case "application/vnd.oasis.opendocument.presentation-template":
+            case "application/vnd.oasis.opendocument.spreadsheet":
+            case "application/vnd.oasis.opendocument.spreadsheet-template":
+            case "application/vnd.oasis.opendocument.text":
+            case "application/vnd.oasis.opendocument.text-master":
+            case "application/vnd.oasis.opendocument.text-template":
+            case "application/vnd.oasis.opendocument.text-web":
+            case "application/vnd.openxmlformats-officedocument.presentationml.presentation":
+            case "application/vnd.openxmlformats-officedocument.presentationml.slideshow":
+            case "application/vnd.openxmlformats-officedocument.presentationml.template":
+            case "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet":
+            case "application/vnd.openxmlformats-officedocument.spreadsheetml.template":
+            case "application/vnd.openxmlformats-officedocument.wordprocessingml.document":
+            case "application/vnd.openxmlformats-officedocument.wordprocessingml.template":
+            case "application/vnd.stardivision.calc":
+            case "application/vnd.stardivision.chart":
+            case "application/vnd.stardivision.draw":
+            case "application/vnd.stardivision.impress":
+            case "application/vnd.stardivision.impress-packed":
+            case "application/vnd.stardivision.mail":
+            case "application/vnd.stardivision.math":
+            case "application/vnd.stardivision.writer":
+            case "application/vnd.stardivision.writer-global":
+            case "application/vnd.sun.xml.calc":
+            case "application/vnd.sun.xml.calc.template":
+            case "application/vnd.sun.xml.draw":
+            case "application/vnd.sun.xml.draw.template":
+            case "application/vnd.sun.xml.impress":
+            case "application/vnd.sun.xml.impress.template":
+            case "application/vnd.sun.xml.math":
+            case "application/vnd.sun.xml.writer":
+            case "application/vnd.sun.xml.writer.global":
+            case "application/vnd.sun.xml.writer.template":
+            case "application/x-mspublisher":
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    public static boolean isExifMimeType(@Nullable String mimeType) {
+        // For simplicity, assume that all image files might have EXIF data
+        return isImageMimeType(mimeType);
+    }
+
+    public static boolean isAudioMimeType(@Nullable String mimeType) {
+        return normalizeMimeType(mimeType).startsWith("audio/");
+    }
+
+    public static boolean isVideoMimeType(@Nullable String mimeType) {
+        return normalizeMimeType(mimeType).startsWith("video/");
+    }
+
+    public static boolean isImageMimeType(@Nullable String mimeType) {
+        return normalizeMimeType(mimeType).startsWith("image/");
+    }
+
+    public static boolean isPlayListMimeType(@Nullable String mimeType) {
+        switch (normalizeMimeType(mimeType)) {
+            case "application/vnd.ms-wpl":
+            case "audio/x-mpegurl":
+            case "audio/mpegurl":
+            case "application/x-mpegurl":
+            case "application/vnd.apple.mpegurl":
+            case "audio/x-scpls":
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    public static boolean isDrmMimeType(@Nullable String mimeType) {
+        return normalizeMimeType(mimeType).equals("application/x-android-drm-fl");
+    }
+
+    // generates a title based on file name
+    @UnsupportedAppUsage
+    public static @NonNull String getFileTitle(@NonNull String path) {
+        // extract file name after last slash
+        int lastSlash = path.lastIndexOf('/');
+        if (lastSlash >= 0) {
+            lastSlash++;
+            if (lastSlash < path.length()) {
+                path = path.substring(lastSlash);
+            }
+        }
+        // truncate the file extension (if any)
+        int lastDot = path.lastIndexOf('.');
+        if (lastDot > 0) {
+            path = path.substring(0, lastDot);
+        }
+        return path;
+    }
+
+    public static @Nullable String getFileExtension(@Nullable String path) {
+        if (path == null) {
+            return null;
+        }
+        int lastDot = path.lastIndexOf('.');
+        if (lastDot >= 0) {
+            return path.substring(lastDot + 1);
+        } else {
+            return null;
+        }
+    }
+
+    /** @deprecated file types no longer exist */
+    @Deprecated
+    @UnsupportedAppUsage
+    public static int getFileTypeForMimeType(String mimeType) {
+        return 0;
+    }
+
+    /**
+     * Find the best MIME type for the given item. Prefers mappings from file
+     * extensions, since they're more accurate than format codes.
+     */
+    public static @NonNull String getMimeType(@Nullable String path, int formatCode) {
+        // First look for extension mapping
+        String mimeType = getMimeTypeForFile(path);
+        if (!MIME_TYPE_DEFAULT.equals(mimeType)) {
+            return mimeType;
+        }
+
+        // Otherwise look for format mapping
+        return getMimeTypeForFormatCode(formatCode);
+    }
+
+    @UnsupportedAppUsage
+    public static @NonNull String getMimeTypeForFile(@Nullable String path) {
+        String ext = getFileExtension(path);
+        final String mimeType = MimeMap.getDefault().guessMimeTypeFromExtension(ext);
+        return (mimeType != null) ? mimeType : MIME_TYPE_DEFAULT;
+    }
+
+    public static @NonNull String getMimeTypeForFormatCode(int formatCode) {
+        final String mimeType = sFormatToMimeTypeMap.get(formatCode);
+        return (mimeType != null) ? mimeType : MIME_TYPE_DEFAULT;
+    }
+
+    /**
+     * Find the best MTP format code mapping for the given item. Prefers
+     * mappings from MIME types, since they're more accurate than file
+     * extensions.
+     */
+    public static int getFormatCode(@Nullable String path, @Nullable String mimeType) {
+        // First look for MIME type mapping
+        int formatCode = getFormatCodeForMimeType(mimeType);
+        if (formatCode != MtpConstants.FORMAT_UNDEFINED) {
+            return formatCode;
+        }
+
+        // Otherwise look for extension mapping
+        return getFormatCodeForFile(path);
+    }
+
+    public static int getFormatCodeForFile(@Nullable String path) {
+        return getFormatCodeForMimeType(getMimeTypeForFile(path));
+    }
+
+    public static int getFormatCodeForMimeType(@Nullable String mimeType) {
+        if (mimeType == null) {
+            return MtpConstants.FORMAT_UNDEFINED;
+        }
+
+        // First look for direct mapping
+        Integer value = sMimeTypeToFormatMap.get(mimeType);
+        if (value != null) {
+            return value.intValue();
+        }
+
+        // Otherwise look for indirect mapping
+        mimeType = normalizeMimeType(mimeType);
+        value = sMimeTypeToFormatMap.get(mimeType);
+        if (value != null) {
+            return value.intValue();
+        } else if (mimeType.startsWith("audio/")) {
+            return MtpConstants.FORMAT_UNDEFINED_AUDIO;
+        } else if (mimeType.startsWith("video/")) {
+            return MtpConstants.FORMAT_UNDEFINED_VIDEO;
+        } else if (mimeType.startsWith("image/")) {
+            return MtpConstants.FORMAT_DEFINED;
+        } else {
+            return MtpConstants.FORMAT_UNDEFINED;
+        }
+    }
+
+    /**
+     * Normalize the given MIME type by bouncing through a default file
+     * extension, if defined. This handles cases like "application/x-flac" to
+     * ".flac" to "audio/flac".
+     */
+    private static @NonNull String normalizeMimeType(@Nullable String mimeType) {
+        MimeMap mimeMap = MimeMap.getDefault();
+        final String extension = mimeMap.guessExtensionFromMimeType(mimeType);
+        if (extension != null) {
+            final String extensionMimeType = mimeMap.guessMimeTypeFromExtension(extension);
+            if (extensionMimeType != null) {
+                return extensionMimeType;
+            }
+        }
+        return (mimeType != null) ? mimeType : MIME_TYPE_DEFAULT;
+    }
+}
diff --git a/android/media/MediaFormat.java b/android/media/MediaFormat.java
new file mode 100644
index 0000000..9bf0db5
--- /dev/null
+++ b/android/media/MediaFormat.java
@@ -0,0 +1,1933 @@
+/*
+ * Copyright (C) 2012 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.AbstractSet;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Encapsulates the information describing the format of media data, be it audio or video, as
+ * well as optional feature metadata.
+ * <p>
+ * The format of the media data is specified as key/value pairs. Keys are strings. Values can
+ * be integer, long, float, String or ByteBuffer.
+ * <p>
+ * The feature metadata is specificed as string/boolean pairs.
+ * <p>
+ * Keys common to all audio/video formats, <b>all keys not marked optional are mandatory</b>:
+ *
+ * <table>
+ * <tr><th>Name</th><th>Value Type</th><th>Description</th></tr>
+ * <tr><td>{@link #KEY_MIME}</td><td>String</td><td>The type of the format.</td></tr>
+ * <tr><td>{@link #KEY_CODECS_STRING}</td><td>String</td><td>optional, the RFC 6381 codecs string of the MediaFormat</td></tr>
+ * <tr><td>{@link #KEY_MAX_INPUT_SIZE}</td><td>Integer</td><td>optional, maximum size of a buffer of input data</td></tr>
+ * <tr><td>{@link #KEY_PIXEL_ASPECT_RATIO_WIDTH}</td><td>Integer</td><td>optional, the pixel aspect ratio width</td></tr>
+ * <tr><td>{@link #KEY_PIXEL_ASPECT_RATIO_HEIGHT}</td><td>Integer</td><td>optional, the pixel aspect ratio height</td></tr>
+ * <tr><td>{@link #KEY_BIT_RATE}</td><td>Integer</td><td><b>encoder-only</b>, desired bitrate in bits/second</td></tr>
+ * <tr><td>{@link #KEY_DURATION}</td><td>long</td><td>the duration of the content (in microseconds)</td></tr>
+ * </table>
+ *
+ * Video formats have the following keys:
+ * <table>
+ * <tr><th>Name</th><th>Value Type</th><th>Description</th></tr>
+ * <tr><td>{@link #KEY_WIDTH}</td><td>Integer</td><td></td></tr>
+ * <tr><td>{@link #KEY_HEIGHT}</td><td>Integer</td><td></td></tr>
+ * <tr><td>{@link #KEY_COLOR_FORMAT}</td><td>Integer</td><td>set by the user
+ *         for encoders, readable in the output format of decoders</b></td></tr>
+ * <tr><td>{@link #KEY_FRAME_RATE}</td><td>Integer or Float</td><td>required for <b>encoders</b>,
+ *         optional for <b>decoders</b></td></tr>
+ * <tr><td>{@link #KEY_CAPTURE_RATE}</td><td>Integer</td><td></td></tr>
+ * <tr><td>{@link #KEY_I_FRAME_INTERVAL}</td><td>Integer (or Float)</td><td><b>encoder-only</b>,
+ *         time-interval between key frames.
+ *         Float support added in {@link android.os.Build.VERSION_CODES#N_MR1}</td></tr>
+ * <tr><td>{@link #KEY_INTRA_REFRESH_PERIOD}</td><td>Integer</td><td><b>encoder-only</b>, optional</td></tr>
+ * <tr><td>{@link #KEY_LATENCY}</td><td>Integer</td><td><b>encoder-only</b>, optional</td></tr>
+ * <tr><td>{@link #KEY_MAX_WIDTH}</td><td>Integer</td><td><b>decoder-only</b>, optional, max-resolution width</td></tr>
+ * <tr><td>{@link #KEY_MAX_HEIGHT}</td><td>Integer</td><td><b>decoder-only</b>, optional, max-resolution height</td></tr>
+ * <tr><td>{@link #KEY_REPEAT_PREVIOUS_FRAME_AFTER}</td><td>Long</td><td><b>encoder in surface-mode
+ *         only</b>, optional</td></tr>
+ * <tr><td>{@link #KEY_PUSH_BLANK_BUFFERS_ON_STOP}</td><td>Integer(1)</td><td><b>decoder rendering
+ *         to a surface only</b>, optional</td></tr>
+ * <tr><td>{@link #KEY_TEMPORAL_LAYERING}</td><td>String</td><td><b>encoder only</b>, optional,
+ *         temporal-layering schema</td></tr>
+ * </table>
+ * Specify both {@link #KEY_MAX_WIDTH} and {@link #KEY_MAX_HEIGHT} to enable
+ * adaptive playback (seamless resolution change) for a video decoder that
+ * supports it ({@link MediaCodecInfo.CodecCapabilities#FEATURE_AdaptivePlayback}).
+ * The values are used as hints for the codec: they are the maximum expected
+ * resolution to prepare for.  Depending on codec support, preparing for larger
+ * maximum resolution may require more memory even if that resolution is never
+ * reached.  These fields have no effect for codecs that do not support adaptive
+ * playback.<br /><br />
+ *
+ * Audio formats have the following keys:
+ * <table>
+ * <tr><th>Name</th><th>Value Type</th><th>Description</th></tr>
+ * <tr><td>{@link #KEY_CHANNEL_COUNT}</td><td>Integer</td><td></td></tr>
+ * <tr><td>{@link #KEY_SAMPLE_RATE}</td><td>Integer</td><td></td></tr>
+ * <tr><td>{@link #KEY_PCM_ENCODING}</td><td>Integer</td><td>optional</td></tr>
+ * <tr><td>{@link #KEY_IS_ADTS}</td><td>Integer</td><td>optional, if <em>decoding</em> AAC audio content, setting this key to 1 indicates that each audio frame is prefixed by the ADTS header.</td></tr>
+ * <tr><td>{@link #KEY_AAC_PROFILE}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is AAC audio, specifies the desired profile.</td></tr>
+ * <tr><td>{@link #KEY_AAC_SBR_MODE}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is AAC audio, specifies the desired SBR mode.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_TARGET_REFERENCE_LEVEL}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the target reference level.</td></tr>
+ * <tr><td>{@link #KEY_AAC_ENCODED_TARGET_LEVEL}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the target reference level used at encoder.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_BOOST_FACTOR}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the DRC boost factor.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_ATTENUATION_FACTOR}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the DRC attenuation factor.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_HEAVY_COMPRESSION}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies whether to use heavy compression.</td></tr>
+ * <tr><td>{@link #KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the maximum number of channels the decoder outputs.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_EFFECT_TYPE}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the MPEG-D DRC effect type to use.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_OUTPUT_LOUDNESS}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, returns the DRC output loudness.</td></tr>
+ * <tr><td>{@link #KEY_AAC_DRC_ALBUM_MODE}</td><td>Integer</td><td><b>decoder-only</b>, optional, if content is AAC audio, specifies the whether MPEG-D DRC Album Mode is active or not.</td></tr>
+ * <tr><td>{@link #KEY_CHANNEL_MASK}</td><td>Integer</td><td>optional, a mask of audio channel assignments</td></tr>
+ * <tr><td>{@link #KEY_ENCODER_DELAY}</td><td>Integer</td><td>optional, the number of frames to trim from the start of the decoded audio stream.</td></tr>
+ * <tr><td>{@link #KEY_ENCODER_PADDING}</td><td>Integer</td><td>optional, the number of frames to trim from the end of the decoded audio stream.</td></tr>
+ * <tr><td>{@link #KEY_FLAC_COMPRESSION_LEVEL}</td><td>Integer</td><td><b>encoder-only</b>, optional, if content is FLAC audio, specifies the desired compression level.</td></tr>
+ * <tr><td>{@link #KEY_MPEGH_PROFILE_LEVEL_INDICATION}</td><td>Integer</td>
+ *     <td><b>decoder-only</b>, optional, if content is MPEG-H audio,
+ *         specifies the profile and level of the stream.</td></tr>
+ * <tr><td>{@link #KEY_MPEGH_COMPATIBLE_SETS}</td><td>ByteBuffer</td>
+ *     <td><b>decoder-only</b>, optional, if content is MPEG-H audio,
+ *         specifies the compatible sets (profile and level) of the stream.</td></tr>
+ * <tr><td>{@link #KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT}</td>
+ *     <td>Integer</td><td><b>decoder-only</b>, optional, if content is MPEG-H audio,
+ *         specifies the preferred reference channel layout of the stream.</td></tr>
+ * </table>
+ *
+ * Subtitle formats have the following keys:
+ * <table>
+ * <tr><td>{@link #KEY_MIME}</td><td>String</td><td>The type of the format.</td></tr>
+ * <tr><td>{@link #KEY_LANGUAGE}</td><td>String</td><td>The language of the content.</td></tr>
+ * <tr><td>{@link #KEY_CAPTION_SERVICE_NUMBER}</td><td>int</td><td>optional, the closed-caption service or channel number.</td></tr>
+ * </table>
+ *
+ * Image formats have the following keys:
+ * <table>
+ * <tr><td>{@link #KEY_MIME}</td><td>String</td><td>The type of the format.</td></tr>
+ * <tr><td>{@link #KEY_WIDTH}</td><td>Integer</td><td></td></tr>
+ * <tr><td>{@link #KEY_HEIGHT}</td><td>Integer</td><td></td></tr>
+ * <tr><td>{@link #KEY_COLOR_FORMAT}</td><td>Integer</td><td>set by the user
+ *         for encoders, readable in the output format of decoders</b></td></tr>
+ * <tr><td>{@link #KEY_TILE_WIDTH}</td><td>Integer</td><td>required if the image has grid</td></tr>
+ * <tr><td>{@link #KEY_TILE_HEIGHT}</td><td>Integer</td><td>required if the image has grid</td></tr>
+ * <tr><td>{@link #KEY_GRID_ROWS}</td><td>Integer</td><td>required if the image has grid</td></tr>
+ * <tr><td>{@link #KEY_GRID_COLUMNS}</td><td>Integer</td><td>required if the image has grid</td></tr>
+ * </table>
+ */
+public final class MediaFormat {
+    public static final String MIMETYPE_VIDEO_VP8 = "video/x-vnd.on2.vp8";
+    public static final String MIMETYPE_VIDEO_VP9 = "video/x-vnd.on2.vp9";
+    public static final String MIMETYPE_VIDEO_AV1 = "video/av01";
+    public static final String MIMETYPE_VIDEO_AVC = "video/avc";
+    public static final String MIMETYPE_VIDEO_HEVC = "video/hevc";
+    public static final String MIMETYPE_VIDEO_MPEG4 = "video/mp4v-es";
+    public static final String MIMETYPE_VIDEO_H263 = "video/3gpp";
+    public static final String MIMETYPE_VIDEO_MPEG2 = "video/mpeg2";
+    public static final String MIMETYPE_VIDEO_RAW = "video/raw";
+    public static final String MIMETYPE_VIDEO_DOLBY_VISION = "video/dolby-vision";
+    public static final String MIMETYPE_VIDEO_SCRAMBLED = "video/scrambled";
+
+    public static final String MIMETYPE_AUDIO_AMR_NB = "audio/3gpp";
+    public static final String MIMETYPE_AUDIO_AMR_WB = "audio/amr-wb";
+    public static final String MIMETYPE_AUDIO_MPEG = "audio/mpeg";
+    public static final String MIMETYPE_AUDIO_AAC = "audio/mp4a-latm";
+    public static final String MIMETYPE_AUDIO_QCELP = "audio/qcelp";
+    public static final String MIMETYPE_AUDIO_VORBIS = "audio/vorbis";
+    public static final String MIMETYPE_AUDIO_OPUS = "audio/opus";
+    public static final String MIMETYPE_AUDIO_G711_ALAW = "audio/g711-alaw";
+    public static final String MIMETYPE_AUDIO_G711_MLAW = "audio/g711-mlaw";
+    public static final String MIMETYPE_AUDIO_RAW = "audio/raw";
+    public static final String MIMETYPE_AUDIO_FLAC = "audio/flac";
+    public static final String MIMETYPE_AUDIO_MSGSM = "audio/gsm";
+    public static final String MIMETYPE_AUDIO_AC3 = "audio/ac3";
+    public static final String MIMETYPE_AUDIO_EAC3 = "audio/eac3";
+    public static final String MIMETYPE_AUDIO_EAC3_JOC = "audio/eac3-joc";
+    public static final String MIMETYPE_AUDIO_AC4 = "audio/ac4";
+    public static final String MIMETYPE_AUDIO_SCRAMBLED = "audio/scrambled";
+    /** MIME type for MPEG-H Audio single stream */
+    public static final String MIMETYPE_AUDIO_MPEGH_MHA1 = "audio/mha1";
+    /** MIME type for MPEG-H Audio single stream, encapsulated in MHAS */
+    public static final String MIMETYPE_AUDIO_MPEGH_MHM1 = "audio/mhm1";
+
+    /**
+     * MIME type for HEIF still image data encoded in HEVC.
+     *
+     * To decode such an image, {@link MediaCodec} decoder for
+     * {@link #MIMETYPE_VIDEO_HEVC} shall be used. The client needs to form
+     * the correct {@link #MediaFormat} based on additional information in
+     * the track format, and send it to {@link MediaCodec#configure}.
+     *
+     * The track's MediaFormat will come with {@link #KEY_WIDTH} and
+     * {@link #KEY_HEIGHT} keys, which describes the width and height
+     * of the image. If the image doesn't contain grid (i.e. none of
+     * {@link #KEY_TILE_WIDTH}, {@link #KEY_TILE_HEIGHT},
+     * {@link #KEY_GRID_ROWS}, {@link #KEY_GRID_COLUMNS} are present}), the
+     * track will contain a single sample of coded data for the entire image,
+     * and the image width and height should be used to set up the decoder.
+     *
+     * If the image does come with grid, each sample from the track will
+     * contain one tile in the grid, of which the size is described by
+     * {@link #KEY_TILE_WIDTH} and {@link #KEY_TILE_HEIGHT}. This size
+     * (instead of {@link #KEY_WIDTH} and {@link #KEY_HEIGHT}) should be
+     * used to set up the decoder. The track contains {@link #KEY_GRID_ROWS}
+     * by {@link #KEY_GRID_COLUMNS} samples in row-major, top-row first,
+     * left-to-right order. The output image should be reconstructed by
+     * first tiling the decoding results of the tiles in the correct order,
+     * then trimming (before rotation is applied) on the bottom and right
+     * side, if the tiled area is larger than the image width and height.
+     */
+    public static final String MIMETYPE_IMAGE_ANDROID_HEIC = "image/vnd.android.heic";
+
+    /**
+     * MIME type for WebVTT subtitle data.
+     */
+    public static final String MIMETYPE_TEXT_VTT = "text/vtt";
+
+    /**
+     * MIME type for SubRip (SRT) container.
+     */
+    public static final String MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
+
+    /**
+     * MIME type for CEA-608 closed caption data.
+     */
+    public static final String MIMETYPE_TEXT_CEA_608 = "text/cea-608";
+
+    /**
+     * MIME type for CEA-708 closed caption data.
+     */
+    public static final String MIMETYPE_TEXT_CEA_708 = "text/cea-708";
+
+    @UnsupportedAppUsage
+    private Map<String, Object> mMap;
+
+    /**
+     * A key describing the log session ID for MediaCodec. The log session ID is a random 32-byte
+     * hexadecimal string that is used to associate metrics from multiple media codec instances
+     * to the same playback or recording session.
+     * The associated value is a string.
+     * @hide
+     */
+    public static final String LOG_SESSION_ID = "log-session-id";
+
+    /**
+     * A key describing the mime type of the MediaFormat.
+     * The associated value is a string.
+     */
+    public static final String KEY_MIME = "mime";
+
+    /**
+     * A key describing the codecs string of the MediaFormat. See RFC 6381 section 3.2 for the
+     * syntax of the value. The value does not hold {@link MediaCodec}-exposed codec names.
+     * The associated value is a string.
+     *
+     * @see MediaParser.TrackData#mediaFormat
+     */
+    public static final String KEY_CODECS_STRING = "codecs-string";
+
+    /**
+     * An optional key describing the low latency decoding mode. This is an optional parameter
+     * that applies only to decoders. If enabled, the decoder doesn't hold input and output
+     * data more than required by the codec standards.
+     * The associated value is an integer (0 or 1): 1 when low-latency decoding is enabled,
+     * 0 otherwise. The default value is 0.
+     */
+    public static final String KEY_LOW_LATENCY = "low-latency";
+
+    /**
+     * A key describing the language of the content, using either ISO 639-1
+     * or 639-2/T codes.  The associated value is a string.
+     */
+    public static final String KEY_LANGUAGE = "language";
+
+    /**
+     * A key describing the closed caption service number. For CEA-608 caption tracks, holds the
+     * channel number. For CEA-708, holds the service number.
+     * The associated value is an int.
+     */
+    public static final String KEY_CAPTION_SERVICE_NUMBER = "caption-service-number";
+
+    /**
+     * A key describing the sample rate of an audio format.
+     * The associated value is an integer
+     */
+    public static final String KEY_SAMPLE_RATE = "sample-rate";
+
+    /**
+     * A key describing the number of channels in an audio format.
+     * The associated value is an integer
+     */
+    public static final String KEY_CHANNEL_COUNT = "channel-count";
+
+    /**
+     * A key describing the width of the content in a video format.
+     * The associated value is an integer
+     */
+    public static final String KEY_WIDTH = "width";
+
+    /**
+     * A key describing the height of the content in a video format.
+     * The associated value is an integer
+     */
+    public static final String KEY_HEIGHT = "height";
+
+    /**
+     * A key describing the maximum expected width of the content in a video
+     * decoder format, in case there are resolution changes in the video content.
+     * The associated value is an integer
+     */
+    public static final String KEY_MAX_WIDTH = "max-width";
+
+    /**
+     * A key describing the maximum expected height of the content in a video
+     * decoder format, in case there are resolution changes in the video content.
+     * The associated value is an integer
+     */
+    public static final String KEY_MAX_HEIGHT = "max-height";
+
+    /** A key describing the maximum size in bytes of a buffer of data
+     * described by this MediaFormat.
+     * The associated value is an integer
+     */
+    public static final String KEY_MAX_INPUT_SIZE = "max-input-size";
+
+    /**
+     * A key describing the pixel aspect ratio width.
+     * The associated value is an integer
+     */
+    public static final String KEY_PIXEL_ASPECT_RATIO_WIDTH = "sar-width";
+
+    /**
+     * A key describing the pixel aspect ratio height.
+     * The associated value is an integer
+     */
+    public static final String KEY_PIXEL_ASPECT_RATIO_HEIGHT = "sar-height";
+
+    /**
+     * A key describing the average bitrate in bits/sec.
+     * The associated value is an integer
+     */
+    public static final String KEY_BIT_RATE = "bitrate";
+
+    /**
+     * A key describing the hardware AV sync id.
+     * The associated value is an integer
+     *
+     * See android.media.tv.tuner.Tuner#getAvSyncHwId.
+     */
+    public static final String KEY_HARDWARE_AV_SYNC_ID = "hw-av-sync-id";
+
+    /**
+     * A key describing the max bitrate in bits/sec.
+     * This is usually over a one-second sliding window (e.g. over any window of one second).
+     * The associated value is an integer
+     * @hide
+     */
+    public static final String KEY_MAX_BIT_RATE = "max-bitrate";
+
+    /**
+     * A key describing the color format of the content in a video format.
+     * Constants are declared in {@link android.media.MediaCodecInfo.CodecCapabilities}.
+     */
+    public static final String KEY_COLOR_FORMAT = "color-format";
+
+    /**
+     * A key describing the frame rate of a video format in frames/sec.
+     * The associated value is normally an integer when the value is used by the platform,
+     * but video codecs also accept float configuration values.
+     * Specifically, {@link MediaExtractor#getTrackFormat MediaExtractor} provides an integer
+     * value corresponding to the frame rate information of the track if specified and non-zero.
+     * Otherwise, this key is not present. {@link MediaCodec#configure MediaCodec} accepts both
+     * float and integer values. This represents the desired operating frame rate if the
+     * {@link #KEY_OPERATING_RATE} is not present and {@link #KEY_PRIORITY} is {@code 0}
+     * (realtime). For video encoders this value corresponds to the intended frame rate,
+     * although encoders are expected
+     * to support variable frame rate based on {@link MediaCodec.BufferInfo#presentationTimeUs
+     * buffer timestamp}. This key is not used in the {@code MediaCodec}
+     * {@link MediaCodec#getInputFormat input}/{@link MediaCodec#getOutputFormat output} formats,
+     * nor by {@link MediaMuxer#addTrack MediaMuxer}.
+     */
+    public static final String KEY_FRAME_RATE = "frame-rate";
+
+    /**
+     * A key describing the width (in pixels) of each tile of the content in a
+     * {@link #MIMETYPE_IMAGE_ANDROID_HEIC} track. The associated value is an integer.
+     *
+     * Refer to {@link #MIMETYPE_IMAGE_ANDROID_HEIC} on decoding instructions of such tracks.
+     *
+     * @see #KEY_TILE_HEIGHT
+     * @see #KEY_GRID_ROWS
+     * @see #KEY_GRID_COLUMNS
+     */
+    public static final String KEY_TILE_WIDTH = "tile-width";
+
+    /**
+     * A key describing the height (in pixels) of each tile of the content in a
+     * {@link #MIMETYPE_IMAGE_ANDROID_HEIC} track. The associated value is an integer.
+     *
+     * Refer to {@link #MIMETYPE_IMAGE_ANDROID_HEIC} on decoding instructions of such tracks.
+     *
+     * @see #KEY_TILE_WIDTH
+     * @see #KEY_GRID_ROWS
+     * @see #KEY_GRID_COLUMNS
+     */
+    public static final String KEY_TILE_HEIGHT = "tile-height";
+
+    /**
+     * A key describing the number of grid rows in the content in a
+     * {@link #MIMETYPE_IMAGE_ANDROID_HEIC} track. The associated value is an integer.
+     *
+     * Refer to {@link #MIMETYPE_IMAGE_ANDROID_HEIC} on decoding instructions of such tracks.
+     *
+     * @see #KEY_TILE_WIDTH
+     * @see #KEY_TILE_HEIGHT
+     * @see #KEY_GRID_COLUMNS
+     */
+    public static final String KEY_GRID_ROWS = "grid-rows";
+
+    /**
+     * A key describing the number of grid columns in the content in a
+     * {@link #MIMETYPE_IMAGE_ANDROID_HEIC} track. The associated value is an integer.
+     *
+     * Refer to {@link #MIMETYPE_IMAGE_ANDROID_HEIC} on decoding instructions of such tracks.
+     *
+     * @see #KEY_TILE_WIDTH
+     * @see #KEY_TILE_HEIGHT
+     * @see #KEY_GRID_ROWS
+     */
+    public static final String KEY_GRID_COLUMNS = "grid-cols";
+
+    /**
+     * A key describing the raw audio sample encoding/format.
+     *
+     * <p>The associated value is an integer, using one of the
+     * {@link AudioFormat}.ENCODING_PCM_ values.</p>
+     *
+     * <p>This is an optional key for audio decoders and encoders specifying the
+     * desired raw audio sample format during {@link MediaCodec#configure
+     * MediaCodec.configure(&hellip;)} call. Use {@link MediaCodec#getInputFormat
+     * MediaCodec.getInput}/{@link MediaCodec#getOutputFormat OutputFormat(&hellip;)}
+     * to confirm the actual format. For the PCM decoder this key specifies both
+     * input and output sample encodings.</p>
+     *
+     * <p>This key is also used by {@link MediaExtractor} to specify the sample
+     * format of audio data, if it is specified.</p>
+     *
+     * <p>If this key is missing, the raw audio sample format is signed 16-bit short.</p>
+     */
+    public static final String KEY_PCM_ENCODING = "pcm-encoding";
+
+    /**
+     * A key describing the capture rate of a video format in frames/sec.
+     * <p>
+     * When capture rate is different than the frame rate, it means that the
+     * video is acquired at a different rate than the playback, which produces
+     * slow motion or timelapse effect during playback. Application can use the
+     * value of this key to tell the relative speed ratio between capture and
+     * playback rates when the video was recorded.
+     * </p>
+     * <p>
+     * The associated value is an integer or a float.
+     * </p>
+     */
+    public static final String KEY_CAPTURE_RATE = "capture-rate";
+
+    /**
+     * A key for retrieving the slow-motion marker information associated with a video track.
+     * <p>
+     * The associated value is a ByteBuffer in {@link ByteOrder#BIG_ENDIAN}
+     * (networking order) of the following format:
+     * </p>
+     * <pre class="prettyprint">
+     *     float(32) playbackRate;
+     *     unsigned int(32) numMarkers;
+     *     for (i = 0;i < numMarkers; i++) {
+     *         int(64) timestampUs;
+     *         float(32) speedRatio;
+     *     }</pre>
+     * The meaning of each field is as follows:
+     * <table border="1" width="90%" align="center" cellpadding="5">
+     *     <tbody>
+     *     <tr>
+     *         <td>playbackRate</td>
+     *         <td>The frame rate at which the playback should happen (or the flattened
+     *             clip should be).</td>
+     *     </tr>
+     *     <tr>
+     *         <td>numMarkers</td>
+     *         <td>The number of slow-motion markers that follows.</td>
+     *     </tr>
+     *     <tr>
+     *         <td>timestampUs</td>
+     *         <td>The starting point of a new segment.</td>
+     *     </tr>
+     *     <tr>
+     *         <td>speedRatio</td>
+     *         <td>The playback speed for that segment. The playback speed is a floating
+     *             point number, indicating how fast the time progresses relative to that
+     *             written in the container. (Eg. 4.0 means time goes 4x as fast, which
+     *             makes 30fps become 120fps.)</td>
+     *     </tr>
+     * </table>
+     * <p>
+     * The following constraints apply to the timestampUs of the markers:
+     * </p>
+     * <li>The timestampUs shall be monotonically increasing.</li>
+     * <li>The timestampUs shall fall within the time span of the video track.</li>
+     * <li>The first timestampUs should match that of the first video sample.</li>
+     */
+    public static final String KEY_SLOW_MOTION_MARKERS = "slow-motion-markers";
+
+    /**
+     * A key describing the frequency of key frames expressed in seconds between key frames.
+     * <p>
+     * This key is used by video encoders.
+     * A negative value means no key frames are requested after the first frame.
+     * A zero value means a stream containing all key frames is requested.
+     * <p class=note>
+     * Most video encoders will convert this value of the number of non-key-frames between
+     * key-frames, using the {@linkplain #KEY_FRAME_RATE frame rate} information; therefore,
+     * if the actual frame rate differs (e.g. input frames are dropped or the frame rate
+     * changes), the <strong>time interval</strong> between key frames will not be the
+     * configured value.
+     * <p>
+     * The associated value is an integer (or float since
+     * {@link android.os.Build.VERSION_CODES#N_MR1}).
+     */
+    public static final String KEY_I_FRAME_INTERVAL = "i-frame-interval";
+
+    /**
+    * An optional key describing the period of intra refresh in frames. This is an
+    * optional parameter that applies only to video encoders. If encoder supports it
+    * ({@link MediaCodecInfo.CodecCapabilities#FEATURE_IntraRefresh}), the whole
+    * frame is completely refreshed after the specified period. Also for each frame,
+    * a fix subset of macroblocks must be intra coded which leads to more constant bitrate
+    * than inserting a key frame. This key is recommended for video streaming applications
+    * as it provides low-delay and good error-resilience. This key is ignored if the
+    * video encoder does not support the intra refresh feature. Use the output format to
+    * verify that this feature was enabled.
+    * The associated value is an integer.
+    */
+    public static final String KEY_INTRA_REFRESH_PERIOD = "intra-refresh-period";
+
+    /**
+     * An optional key describing whether encoders prepend headers to sync frames (e.g.
+     * SPS and PPS to IDR frames for H.264). This is an optional parameter that applies only
+     * to video encoders. A video encoder may not support this feature; the component will fail
+     * to configure in that case. For other components, this key is ignored.
+     *
+     * The value is an integer, with 1 indicating to prepend headers to every sync frames,
+     * or 0 otherwise. The default value is 0.
+     */
+    public static final String KEY_PREPEND_HEADER_TO_SYNC_FRAMES = "prepend-sps-pps-to-idr-frames";
+
+    /**
+     * A key describing the temporal layering schema.  This is an optional parameter
+     * that applies only to video encoders.  Use {@link MediaCodec#getOutputFormat}
+     * after {@link MediaCodec#configure configure} to query if the encoder supports
+     * the desired schema. Supported values are {@code webrtc.vp8.N-layer},
+     * {@code android.generic.N}, {@code android.generic.N+M} and {@code none}, where
+     * {@code N} denotes the total number of non-bidirectional layers (which must be at least 1)
+     * and {@code M} denotes the total number of bidirectional layers (which must be non-negative).
+     * <p class=note>{@code android.generic.*} schemas have been added in {@link
+     * android.os.Build.VERSION_CODES#N_MR1}.
+     * <p>
+     * The encoder may support fewer temporal layers, in which case the output format
+     * will contain the configured schema. If the encoder does not support temporal
+     * layering, the output format will not have an entry with this key.
+     * The associated value is a string.
+     */
+    public static final String KEY_TEMPORAL_LAYERING = "ts-schema";
+
+    /**
+     * A key describing the stride of the video bytebuffer layout.
+     * Stride (or row increment) is the difference between the index of a pixel
+     * and that of the pixel directly underneath. For YUV 420 formats, the
+     * stride corresponds to the Y plane; the stride of the U and V planes can
+     * be calculated based on the color format, though it is generally undefined
+     * and depends on the device and release.
+     * The associated value is an integer, representing number of bytes.
+     */
+    public static final String KEY_STRIDE = "stride";
+
+    /**
+     * A key describing the plane height of a multi-planar (YUV) video bytebuffer layout.
+     * Slice height (or plane height/vertical stride) is the number of rows that must be skipped
+     * to get from the top of the Y plane to the top of the U plane in the bytebuffer. In essence
+     * the offset of the U plane is sliceHeight * stride. The height of the U/V planes
+     * can be calculated based on the color format, though it is generally undefined
+     * and depends on the device and release.
+     * The associated value is an integer, representing number of rows.
+     */
+    public static final String KEY_SLICE_HEIGHT = "slice-height";
+
+    /**
+     * Applies only when configuring a video encoder in "surface-input" mode.
+     * The associated value is a long and gives the time in microseconds
+     * after which the frame previously submitted to the encoder will be
+     * repeated (once) if no new frame became available since.
+     */
+    public static final String KEY_REPEAT_PREVIOUS_FRAME_AFTER
+        = "repeat-previous-frame-after";
+
+    /**
+     * Instruct the video encoder in "surface-input" mode to drop excessive
+     * frames from the source, so that the input frame rate to the encoder
+     * does not exceed the specified fps.
+     *
+     * The associated value is a float, representing the max frame rate to
+     * feed the encoder at.
+     *
+     */
+    public static final String KEY_MAX_FPS_TO_ENCODER
+        = "max-fps-to-encoder";
+
+    /**
+     * Instruct the video encoder in "surface-input" mode to limit the gap of
+     * timestamp between any two adjacent frames fed to the encoder to the
+     * specified amount (in micro-second).
+     *
+     * The associated value is a long int. When positive, it represents the max
+     * timestamp gap between two adjacent frames fed to the encoder. When negative,
+     * the absolute value represents a fixed timestamp gap between any two adjacent
+     * frames fed to the encoder. Note that this will also apply even when the
+     * original timestamp goes backward in time. Under normal conditions, such frames
+     * would be dropped and not sent to the encoder.
+     *
+     * The output timestamp will be restored to the original timestamp and will
+     * not be affected.
+     *
+     * This is used in some special scenarios where input frames arrive sparingly
+     * but it's undesirable to allocate more bits to any single frame, or when it's
+     * important to ensure all frames are captured (rather than captured in the
+     * correct order).
+     *
+     */
+    public static final String KEY_MAX_PTS_GAP_TO_ENCODER
+        = "max-pts-gap-to-encoder";
+
+    /**
+     * If specified when configuring a video encoder that's in "surface-input"
+     * mode, it will instruct the encoder to put the surface source in suspended
+     * state when it's connected. No video frames will be accepted until a resume
+     * operation (see {@link MediaCodec#PARAMETER_KEY_SUSPEND}), optionally with
+     * timestamp specified via {@link MediaCodec#PARAMETER_KEY_SUSPEND_TIME}, is
+     * received.
+     *
+     * The value is an integer, with 1 indicating to create with the surface
+     * source suspended, or 0 otherwise. The default value is 0.
+     *
+     * If this key is not set or set to 0, the surface source will accept buffers
+     * as soon as it's connected to the encoder (although they may not be encoded
+     * immediately). This key can be used when the client wants to prepare the
+     * encoder session in advance, but do not want to accept buffers immediately.
+     */
+    public static final String KEY_CREATE_INPUT_SURFACE_SUSPENDED
+        = "create-input-buffers-suspended";
+
+    /**
+     * If specified when configuring a video decoder rendering to a surface,
+     * causes the decoder to output "blank", i.e. black frames to the surface
+     * when stopped to clear out any previously displayed contents.
+     * The associated value is an integer of value 1.
+     */
+    public static final String KEY_PUSH_BLANK_BUFFERS_ON_STOP
+        = "push-blank-buffers-on-shutdown";
+
+    /**
+     * A key describing the duration (in microseconds) of the content.
+     * The associated value is a long.
+     */
+    public static final String KEY_DURATION = "durationUs";
+
+    /**
+     * A key mapping to a value of 1 if the content is AAC audio and
+     * audio frames are prefixed with an ADTS header.
+     * The associated value is an integer (0 or 1).
+     * This key is only supported when _decoding_ content, it cannot
+     * be used to configure an encoder to emit ADTS output.
+     */
+    public static final String KEY_IS_ADTS = "is-adts";
+
+    /**
+     * A key describing the channel composition of audio content. This mask
+     * is composed of bits drawn from channel mask definitions in {@link android.media.AudioFormat}.
+     * The associated value is an integer.
+     */
+    public static final String KEY_CHANNEL_MASK = "channel-mask";
+
+    /**
+     * A key describing the number of frames to trim from the start of the decoded audio stream.
+     * The associated value is an integer.
+     */
+    public static final String KEY_ENCODER_DELAY = "encoder-delay";
+
+    /**
+     * A key describing the number of frames to trim from the end of the decoded audio stream.
+     * The associated value is an integer.
+     */
+    public static final String KEY_ENCODER_PADDING = "encoder-padding";
+
+    /**
+     * A key describing the AAC profile to be used (AAC audio formats only).
+     * Constants are declared in {@link android.media.MediaCodecInfo.CodecProfileLevel}.
+     */
+    public static final String KEY_AAC_PROFILE = "aac-profile";
+
+    /**
+     * A key describing the AAC SBR mode to be used (AAC audio formats only).
+     * The associated value is an integer and can be set to following values:
+     * <ul>
+     * <li>0 - no SBR should be applied</li>
+     * <li>1 - single rate SBR</li>
+     * <li>2 - double rate SBR</li>
+     * </ul>
+     * Note: If this key is not defined the default SRB mode for the desired AAC profile will
+     * be used.
+     * <p>This key is only used during encoding.
+     */
+    public static final String KEY_AAC_SBR_MODE = "aac-sbr-mode";
+
+    /**
+     * A key describing the maximum number of channels that can be output by the AAC decoder.
+     * By default, the decoder will output the same number of channels as present in the encoded
+     * stream, if supported. Set this value to limit the number of output channels, and use
+     * the downmix information in the stream, if available.
+     * <p>Values larger than the number of channels in the content to decode are ignored.
+     * <p>This key is only used during decoding.
+     */
+    public static final String KEY_AAC_MAX_OUTPUT_CHANNEL_COUNT = "aac-max-output-channel_count";
+
+    /**
+     * A key describing the Target Reference Level (Target Loudness).
+     * <p>For normalizing loudness across program items, a gain is applied to the audio output so
+     * that the output loudness matches the Target Reference Level. The gain is derived as the
+     * difference between the Target Reference Level and the Program Reference Level (Program
+     * Loudness). The latter can be given in the bitstream and indicates the actual loudness value
+     * of the program item.</p>
+     * <p>The Target Reference Level controls loudness normalization for both MPEG-4 DRC and
+     * MPEG-D DRC.
+     * <p>The value is given as an integer value between
+     * 40 and 127, and is calculated as -4 * Target Reference Level in LKFS.
+     * Therefore, it represents the range of -10 to -31.75 LKFS.
+     * <p>For MPEG-4 DRC, a value of -1 switches off loudness normalization and DRC processing.</p>
+     * <p>For MPEG-D DRC, a value of -1 switches off loudness normalization only. For DRC processing
+     * options of MPEG-D DRC, see {@link #KEY_AAC_DRC_EFFECT_TYPE}</p>
+     * <p>The default value on mobile devices is 64 (-16 LKFS).
+     * <p>This key is only used during decoding.
+     */
+    public static final String KEY_AAC_DRC_TARGET_REFERENCE_LEVEL = "aac-target-ref-level";
+
+    /**
+     * A key describing for selecting the DRC effect type for MPEG-D DRC.
+     * The supported values are defined in ISO/IEC 23003-4:2015 and are described as follows:
+     * <table>
+     * <tr><th>Value</th><th>Effect</th></tr>
+     * <tr><th>-1</th><th>Off</th></tr>
+     * <tr><th>0</th><th>None</th></tr>
+     * <tr><th>1</th><th>Late night</th></tr>
+     * <tr><th>2</th><th>Noisy environment</th></tr>
+     * <tr><th>3</th><th>Limited playback range</th></tr>
+     * <tr><th>4</th><th>Low playback level</th></tr>
+     * <tr><th>5</th><th>Dialog enhancement</th></tr>
+     * <tr><th>6</th><th>General compression</th></tr>
+     * </table>
+     * <p>The value -1 (Off) disables DRC processing, while loudness normalization may still be
+     * active and dependent on {@link #KEY_AAC_DRC_TARGET_REFERENCE_LEVEL}.<br>
+     * The value 0 (None) automatically enables DRC processing if necessary to prevent signal
+     * clipping<br>
+     * The value 6 (General compression) can be used for enabling MPEG-D DRC without particular
+     * DRC effect type request.<br>
+     * The default DRC effect type is 3 ("Limited playback range") on mobile devices.
+     * <p>This key is only used during decoding.
+     */
+    public static final String KEY_AAC_DRC_EFFECT_TYPE = "aac-drc-effect-type";
+
+    /**
+     * A key describing the target reference level that was assumed at the encoder for
+     * calculation of attenuation gains for clipping prevention.
+     * <p>If it is known, this information can be provided as an integer value between
+     * 0 and 127, which is calculated as -4 * Encoded Target Level in LKFS.
+     * If the Encoded Target Level is unknown, the value can be set to -1.
+     * <p>The default value is -1 (unknown).
+     * <p>The value is ignored when heavy compression (see {@link #KEY_AAC_DRC_HEAVY_COMPRESSION})
+     * or MPEG-D DRC is used.
+     * <p>This key is only used during decoding.
+     */
+    public static final String KEY_AAC_ENCODED_TARGET_LEVEL = "aac-encoded-target-level";
+
+    /**
+     * A key describing the boost factor allowing to adapt the dynamics of the output to the
+     * actual listening requirements. This relies on DRC gain sequences that can be transmitted in
+     * the encoded bitstream to be able to reduce the dynamics of the output signal upon request.
+     * This factor enables the user to select how much of the gains are applied.
+     * <p>Positive gains (boost) and negative gains (attenuation, see
+     * {@link #KEY_AAC_DRC_ATTENUATION_FACTOR}) can be controlled separately for a better match
+     * to different use-cases.
+     * <p>Typically, attenuation gains are sent for loud signal segments, and boost gains are sent
+     * for soft signal segments. If the output is listened to in a noisy environment, for example,
+     * the boost factor is used to enable the positive gains, i.e. to amplify soft signal segments
+     * beyond the noise floor. But for listening late at night, the attenuation
+     * factor is used to enable the negative gains, to prevent loud signal from surprising
+     * the listener. In applications which generally need a low dynamic range, both the boost factor
+     * and the attenuation factor are used in order to enable all DRC gains.
+     * <p>In order to prevent clipping, it is also recommended to apply the attenuation gains
+     * in case of a downmix and/or loudness normalization to high target reference levels.
+     * <p>Both the boost and the attenuation factor parameters are given as integer values
+     * between 0 and 127, representing the range of the factor of 0 (i.e. don't apply)
+     * to 1 (i.e. fully apply boost/attenuation gains respectively).
+     * <p>The default value is 127 (fully apply boost DRC gains).
+     * <p>This key is only used during decoding.
+     */
+    public static final String KEY_AAC_DRC_BOOST_FACTOR = "aac-drc-boost-level";
+
+    /**
+     * A key describing the attenuation factor allowing to adapt the dynamics of the output to the
+     * actual listening requirements.
+     * See {@link #KEY_AAC_DRC_BOOST_FACTOR} for a description of the role of this attenuation
+     * factor and the value range.
+     * <p>The default value is 127 (fully apply attenuation DRC gains).
+     * <p>This key is only used during decoding.
+     */
+    public static final String KEY_AAC_DRC_ATTENUATION_FACTOR = "aac-drc-cut-level";
+
+    /**
+     * A key describing the selection of the heavy compression profile for MPEG-4 DRC.
+     * <p>Two separate DRC gain sequences can be transmitted in one bitstream: light compression
+     * and heavy compression. When selecting the application of the heavy compression, one of
+     * the sequences is selected:
+     * <ul>
+     * <li>0 enables light compression,</li>
+     * <li>1 enables heavy compression instead.
+     * </ul>
+     * Note that heavy compression doesn't offer the features of scaling of DRC gains
+     * (see {@link #KEY_AAC_DRC_BOOST_FACTOR} and {@link #KEY_AAC_DRC_ATTENUATION_FACTOR} for the
+     * boost and attenuation factors), and frequency-selective (multiband) DRC.
+     * Light compression usually contains clipping prevention for stereo downmixing while heavy
+     * compression, if additionally provided in the bitstream, is usually stronger, and contains
+     * clipping prevention for stereo and mono downmixing.
+     * <p>The default is 1 (heavy compression).
+     * <p>This key is only used during decoding.
+     */
+    public static final String KEY_AAC_DRC_HEAVY_COMPRESSION = "aac-drc-heavy-compression";
+
+    /**
+     * A key to retrieve the output loudness of a decoded bitstream.
+     * <p>If loudness normalization is active, the value corresponds to the Target Reference Level
+     * (see {@link #KEY_AAC_DRC_TARGET_REFERENCE_LEVEL}).<br>
+     * If loudness normalization is not active, the value corresponds to the loudness metadata
+     * given in the bitstream.
+     * <p>The value is retrieved with getInteger() and is given as an integer value between 0 and
+     * 231. It is calculated as -4 * Output Loudness in LKFS. Therefore, it represents the range of
+     * 0 to -57.75 LKFS.
+     * <p>A value of -1 indicates that no loudness metadata is present in the bitstream.
+     * <p>Loudness metadata can originate from MPEG-4 DRC or MPEG-D DRC.
+     * <p>This key is only used during decoding.
+     */
+    public static final String KEY_AAC_DRC_OUTPUT_LOUDNESS = "aac-drc-output-loudness";
+
+    /**
+     * A key describing the album mode for MPEG-D DRC as defined in ISO/IEC 23003-4.
+     * <p>The associated value is an integer and can be set to following values:
+     * <table>
+     * <tr><th>Value</th><th>Album Mode</th></tr>
+     * <tr><th>0</th><th>disabled</th></tr>
+     * <tr><th>1</th><th>enabled</th></tr>
+     * </table>
+     * <p>Disabled album mode leads to application of gain sequences for fading in and out, if
+     * provided in the bitstream. Enabled album mode makes use of dedicated album loudness
+     * information, if provided in the bitstream.
+     * <p>The default value is 0 (album mode disabled).
+     * <p>This key is only used during decoding.
+     */
+    public static final String KEY_AAC_DRC_ALBUM_MODE = "aac-drc-album-mode";
+
+    /**
+     * A key describing the FLAC compression level to be used (FLAC audio format only).
+     * The associated value is an integer ranging from 0 (fastest, least compression)
+     * to 8 (slowest, most compression).
+     */
+    public static final String KEY_FLAC_COMPRESSION_LEVEL = "flac-compression-level";
+
+    /**
+     * A key describing the MPEG-H stream profile-level indication.
+     *
+     * See ISO_IEC_23008-3;2019 MHADecoderConfigurationRecord mpegh3daProfileLevelIndication.
+     */
+    public static final String KEY_MPEGH_PROFILE_LEVEL_INDICATION =
+            "mpegh-profile-level-indication";
+
+    /**
+     * A key describing the MPEG-H stream compatible sets.
+     *
+     * See FDAmd_2 of ISO_IEC_23008-3;2019 MHAProfileAndLevelCompatibilitySetBox.
+     */
+    public static final String KEY_MPEGH_COMPATIBLE_SETS = "mpegh-compatible-sets";
+
+    /**
+     * A key describing the MPEG-H stream reference channel layout.
+     *
+     * See ISO_IEC_23008-3;2019 MHADecoderConfigurationRecord referenceChannelLayout
+     * and ISO_IEC_23001‐8 ChannelConfiguration value.
+     */
+    public static final String KEY_MPEGH_REFERENCE_CHANNEL_LAYOUT =
+            "mpegh-reference-channel-layout";
+
+    /**
+     * A key describing the encoding complexity.
+     * The associated value is an integer.  These values are device and codec specific,
+     * but lower values generally result in faster and/or less power-hungry encoding.
+     *
+     * @see MediaCodecInfo.EncoderCapabilities#getComplexityRange()
+     */
+    public static final String KEY_COMPLEXITY = "complexity";
+
+    /**
+     * A key describing the desired encoding quality.
+     * The associated value is an integer.  This key is only supported for encoders
+     * that are configured in constant-quality mode.  These values are device and
+     * codec specific, but lower values generally result in more efficient
+     * (smaller-sized) encoding.
+     *
+     * @see MediaCodecInfo.EncoderCapabilities#getQualityRange()
+     */
+    public static final String KEY_QUALITY = "quality";
+
+    /**
+     * A key describing the desired codec priority.
+     * <p>
+     * The associated value is an integer. Higher value means lower priority.
+     * <p>
+     * Currently, only two levels are supported:<br>
+     * 0: realtime priority - meaning that the codec shall support the given
+     *    performance configuration (e.g. framerate) at realtime. This should
+     *    only be used by media playback, capture, and possibly by realtime
+     *    communication scenarios if best effort performance is not suitable.<br>
+     * 1: non-realtime priority (best effort).
+     * <p>
+     * This is a hint used at codec configuration and resource planning - to understand
+     * the realtime requirements of the application; however, due to the nature of
+     * media components, performance is not guaranteed.
+     *
+     */
+    public static final String KEY_PRIORITY = "priority";
+
+    /**
+     * A key describing the desired operating frame rate for video or sample rate for audio
+     * that the codec will need to operate at.
+     * <p>
+     * The associated value is an integer or a float representing frames-per-second or
+     * samples-per-second
+     * <p>
+     * This is used for cases like high-speed/slow-motion video capture, where the video encoder
+     * format contains the target playback rate (e.g. 30fps), but the component must be able to
+     * handle the high operating capture rate (e.g. 240fps).
+     * <p>
+     * This rate will be used by codec for resource planning and setting the operating points.
+     *
+     */
+    public static final String KEY_OPERATING_RATE = "operating-rate";
+
+    /**
+     * A key describing the desired profile to be used by an encoder.
+     * The associated value is an integer.
+     * Constants are declared in {@link MediaCodecInfo.CodecProfileLevel}.
+     * This key is used as a hint, and is only supported for codecs
+     * that specify a profile. Note: Codecs are free to use all the available
+     * coding tools at the specified profile.
+     *
+     * @see MediaCodecInfo.CodecCapabilities#profileLevels
+     */
+    public static final String KEY_PROFILE = "profile";
+
+    /**
+     * A key describing the desired profile to be used by an encoder.
+     * The associated value is an integer.
+     * Constants are declared in {@link MediaCodecInfo.CodecProfileLevel}.
+     * This key is used as a further hint when specifying a desired profile,
+     * and is only supported for codecs that specify a level.
+     * <p>
+     * This key is ignored if the {@link #KEY_PROFILE profile} is not specified.
+     *
+     * @see MediaCodecInfo.CodecCapabilities#profileLevels
+     */
+    public static final String KEY_LEVEL = "level";
+
+    /**
+    * An optional key describing the desired encoder latency in frames. This is an optional
+    * parameter that applies only to video encoders. If encoder supports it, it should ouput
+    * at least one output frame after being queued the specified number of frames. This key
+    * is ignored if the video encoder does not support the latency feature. Use the output
+    * format to verify that this feature was enabled and the actual value used by the encoder.
+    * <p>
+    * If the key is not specified, the default latency will be implenmentation specific.
+    * The associated value is an integer.
+    */
+    public static final String KEY_LATENCY = "latency";
+
+    /**
+     * An optional key describing the maximum number of non-display-order coded frames.
+     * This is an optional parameter that applies only to video encoders. Application should
+     * check the value for this key in the output format to see if codec will produce
+     * non-display-order coded frames. If encoder supports it, the output frames' order will be
+     * different from the display order and each frame's display order could be retrived from
+     * {@link MediaCodec.BufferInfo#presentationTimeUs}. Before API level 27, application may
+     * receive non-display-order coded frames even though the application did not request it.
+     * Note: Application should not rearrange the frames to display order before feeding them
+     * to {@link MediaMuxer#writeSampleData}.
+     * <p>
+     * The default value is 0.
+     */
+    public static final String KEY_OUTPUT_REORDER_DEPTH = "output-reorder-depth";
+
+    /**
+     * A key describing the desired clockwise rotation on an output surface.
+     * This key is only used when the codec is configured using an output surface.
+     * The associated value is an integer, representing degrees. Supported values
+     * are 0, 90, 180 or 270. This is an optional field; if not specified, rotation
+     * defaults to 0.
+     *
+     * @see MediaCodecInfo.CodecCapabilities#profileLevels
+     */
+    public static final String KEY_ROTATION = "rotation-degrees";
+
+    /**
+     * A key describing the desired bitrate mode to be used by an encoder.
+     * Constants are declared in {@link MediaCodecInfo.CodecCapabilities}.
+     *
+     * @see MediaCodecInfo.EncoderCapabilities#isBitrateModeSupported(int)
+     */
+    public static final String KEY_BITRATE_MODE = "bitrate-mode";
+
+    /**
+     * A key describing the maximum Quantization Parameter allowed for encoding video.
+     * This key applies to all three video picture types (I, P, and B).
+     * The value is used directly for picture type I; a per-mime formula is used
+     * to calculate the value for the remaining picture types.
+     *
+     * This calculation can be avoided by directly specifying values for each picture type
+     * using the type-specific keys {@link #KEY_VIDEO_QP_I_MAX}, {@link #KEY_VIDEO_QP_P_MAX},
+     * and {@link #KEY_VIDEO_QP_B_MAX}.
+     *
+     * The associated value is an integer.
+     */
+    public static final String KEY_VIDEO_QP_MAX = "video-qp-max";
+
+    /**
+     * A key describing the minimum Quantization Parameter allowed for encoding video.
+     * This key applies to all three video frame types (I, P, and B).
+     * The value is used directly for picture type I; a per-mime formula is used
+     * to calculate the value for the remaining picture types.
+     *
+     * This calculation can be avoided by directly specifying values for each picture type
+     * using the type-specific keys {@link #KEY_VIDEO_QP_I_MIN}, {@link #KEY_VIDEO_QP_P_MIN},
+     * and {@link #KEY_VIDEO_QP_B_MIN}.
+     *
+     * The associated value is an integer.
+     */
+    public static final String KEY_VIDEO_QP_MIN = "video-qp-min";
+
+    /**
+     * A key describing the maximum Quantization Parameter allowed for encoding video.
+     * This value applies to video I-frames.
+     *
+     * The associated value is an integer.
+     */
+    public static final String KEY_VIDEO_QP_I_MAX = "video-qp-i-max";
+
+    /**
+     * A key describing the minimum Quantization Parameter allowed for encoding video.
+     * This value applies to video I-frames.
+     *
+     * The associated value is an integer.
+     */
+    public static final String KEY_VIDEO_QP_I_MIN = "video-qp-i-min";
+
+    /**
+     * A key describing the maximum Quantization Parameter allowed for encoding video.
+     * This value applies to video P-frames.
+     *
+     * The associated value is an integer.
+     */
+    public static final String KEY_VIDEO_QP_P_MAX = "video-qp-p-max";
+
+    /**
+     * A key describing the minimum Quantization Parameter allowed for encoding video.
+     * This value applies to video P-frames.
+     *
+     * The associated value is an integer.
+     */
+    public static final String KEY_VIDEO_QP_P_MIN = "video-qp-p-min";
+
+    /**
+     * A key describing the maximum Quantization Parameter allowed for encoding video.
+     * This value applies to video B-frames.
+     *
+     * The associated value is an integer.
+     */
+    public static final String KEY_VIDEO_QP_B_MAX = "video-qp-b-max";
+
+    /**
+     * A key describing the minimum Quantization Parameter allowed for encoding video.
+     * This value applies to video B-frames.
+     *
+     * The associated value is an integer.
+     */
+    public static final String KEY_VIDEO_QP_B_MIN = "video-qp-b-min";
+
+    /**
+     * A key describing the audio session ID of the AudioTrack associated
+     * to a tunneled video codec.
+     * The associated value is an integer.
+     *
+     * @see MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback
+     */
+    public static final String KEY_AUDIO_SESSION_ID = "audio-session-id";
+
+    /**
+     * A key describing the audio hardware sync ID of the AudioTrack associated
+     * to a tunneled video codec. The associated value is an integer.
+     *
+     * @hide
+     *
+     * @see MediaCodecInfo.CodecCapabilities#FEATURE_TunneledPlayback
+     * @see AudioManager#getAudioHwSyncForSession
+     */
+    public static final String KEY_AUDIO_HW_SYNC = "audio-hw-sync";
+
+    /**
+     * A key for boolean AUTOSELECT behavior for the track. Tracks with AUTOSELECT=true
+     * are considered when automatically selecting a track without specific user
+     * choice, based on the current locale.
+     * This is currently only used for subtitle tracks, when the user selected
+     * 'Default' for the captioning locale.
+     * The associated value is an integer, where non-0 means TRUE.  This is an optional
+     * field; if not specified, AUTOSELECT defaults to TRUE.
+     */
+    public static final String KEY_IS_AUTOSELECT = "is-autoselect";
+
+    /**
+     * A key for boolean DEFAULT behavior for the track. The track with DEFAULT=true is
+     * selected in the absence of a specific user choice.
+     * This is currently used in two scenarios:
+     * 1) for subtitle tracks, when the user selected 'Default' for the captioning locale.
+     * 2) for a {@link #MIMETYPE_IMAGE_ANDROID_HEIC} track, indicating the image is the
+     * primary item in the file.
+
+     * The associated value is an integer, where non-0 means TRUE.  This is an optional
+     * field; if not specified, DEFAULT is considered to be FALSE.
+     */
+    public static final String KEY_IS_DEFAULT = "is-default";
+
+    /**
+     * A key for the FORCED field for subtitle tracks. True if it is a
+     * forced subtitle track.  Forced subtitle tracks are essential for the
+     * content and are shown even when the user turns off Captions.  They
+     * are used for example to translate foreign/alien dialogs or signs.
+     * The associated value is an integer, where non-0 means TRUE.  This is an
+     * optional field; if not specified, FORCED defaults to FALSE.
+     */
+    public static final String KEY_IS_FORCED_SUBTITLE = "is-forced-subtitle";
+
+    /**
+     * A key describing the number of haptic channels in an audio format.
+     * The associated value is an integer.
+     */
+    public static final String KEY_HAPTIC_CHANNEL_COUNT = "haptic-channel-count";
+
+    /** @hide */
+    public static final String KEY_IS_TIMED_TEXT = "is-timed-text";
+
+    // The following color aspect values must be in sync with the ones in HardwareAPI.h.
+    /**
+     * An optional key describing the color primaries, white point and
+     * luminance factors for video content.
+     *
+     * The associated value is an integer: 0 if unspecified, or one of the
+     * COLOR_STANDARD_ values.
+     */
+    public static final String KEY_COLOR_STANDARD = "color-standard";
+
+    /** BT.709 color chromacity coordinates with KR = 0.2126, KB = 0.0722. */
+    public static final int COLOR_STANDARD_BT709 = 1;
+
+    /** BT.601 625 color chromacity coordinates with KR = 0.299, KB = 0.114. */
+    public static final int COLOR_STANDARD_BT601_PAL = 2;
+
+    /** BT.601 525 color chromacity coordinates with KR = 0.299, KB = 0.114. */
+    public static final int COLOR_STANDARD_BT601_NTSC = 4;
+
+    /** BT.2020 color chromacity coordinates with KR = 0.2627, KB = 0.0593. */
+    public static final int COLOR_STANDARD_BT2020 = 6;
+
+    /** @hide */
+    @IntDef({
+        COLOR_STANDARD_BT709,
+        COLOR_STANDARD_BT601_PAL,
+        COLOR_STANDARD_BT601_NTSC,
+        COLOR_STANDARD_BT2020,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ColorStandard {}
+
+    /**
+     * An optional key describing the opto-electronic transfer function used
+     * for the video content.
+     *
+     * The associated value is an integer: 0 if unspecified, or one of the
+     * COLOR_TRANSFER_ values.
+     */
+    public static final String KEY_COLOR_TRANSFER = "color-transfer";
+
+    /** Linear transfer characteristic curve. */
+    public static final int COLOR_TRANSFER_LINEAR = 1;
+
+    /** SMPTE 170M transfer characteristic curve used by BT.601/BT.709/BT.2020. This is the curve
+     *  used by most non-HDR video content. */
+    public static final int COLOR_TRANSFER_SDR_VIDEO = 3;
+
+    /** SMPTE ST 2084 transfer function. This is used by some HDR video content. */
+    public static final int COLOR_TRANSFER_ST2084 = 6;
+
+    /** ARIB STD-B67 hybrid-log-gamma transfer function. This is used by some HDR video content. */
+    public static final int COLOR_TRANSFER_HLG = 7;
+
+    /** @hide */
+    @IntDef({
+        COLOR_TRANSFER_LINEAR,
+        COLOR_TRANSFER_SDR_VIDEO,
+        COLOR_TRANSFER_ST2084,
+        COLOR_TRANSFER_HLG,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ColorTransfer {}
+
+    /**
+     * An optional key describing the range of the component values of the video content.
+     *
+     * The associated value is an integer: 0 if unspecified, or one of the
+     * COLOR_RANGE_ values.
+     */
+    public static final String KEY_COLOR_RANGE = "color-range";
+
+    /** Limited range. Y component values range from 16 to 235 for 8-bit content.
+     *  Cr, Cy values range from 16 to 240 for 8-bit content.
+     *  This is the default for video content. */
+    public static final int COLOR_RANGE_LIMITED = 2;
+
+    /** Full range. Y, Cr and Cb component values range from 0 to 255 for 8-bit content. */
+    public static final int COLOR_RANGE_FULL = 1;
+
+    /** @hide */
+    @IntDef({
+        COLOR_RANGE_LIMITED,
+        COLOR_RANGE_FULL,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ColorRange {}
+
+    /**
+     * An optional key describing the static metadata of HDR (high-dynamic-range) video content.
+     *
+     * The associated value is a ByteBuffer. This buffer contains the raw contents of the
+     * Static Metadata Descriptor (including the descriptor ID) of an HDMI Dynamic Range and
+     * Mastering InfoFrame as defined by CTA-861.3. This key must be provided to video decoders
+     * for HDR video content unless this information is contained in the bitstream and the video
+     * decoder supports an HDR-capable profile. This key must be provided to video encoders for
+     * HDR video content.
+     */
+    public static final String KEY_HDR_STATIC_INFO = "hdr-static-info";
+
+    /**
+     * An optional key describing the HDR10+ metadata of the video content.
+     *
+     * The associated value is a ByteBuffer containing HDR10+ metadata conforming to the
+     * user_data_registered_itu_t_t35() syntax of SEI message for ST 2094-40. This key will
+     * be present on:
+     *<p>
+     * - The formats of output buffers of a decoder configured for HDR10+ profiles (such as
+     *   {@link MediaCodecInfo.CodecProfileLevel#VP9Profile2HDR10Plus}, {@link
+     *   MediaCodecInfo.CodecProfileLevel#VP9Profile3HDR10Plus} or {@link
+     *   MediaCodecInfo.CodecProfileLevel#HEVCProfileMain10HDR10Plus}), or
+     *<p>
+     * - The formats of output buffers of an encoder configured for an HDR10+ profiles that
+     *   uses out-of-band metadata (such as {@link
+     *   MediaCodecInfo.CodecProfileLevel#VP9Profile2HDR10Plus} or {@link
+     *   MediaCodecInfo.CodecProfileLevel#VP9Profile3HDR10Plus}).
+     *
+     * @see MediaCodec#PARAMETER_KEY_HDR10_PLUS_INFO
+     */
+    public static final String KEY_HDR10_PLUS_INFO = "hdr10-plus-info";
+
+    /**
+     * An optional key describing the opto-electronic transfer function
+     * requested for the output video content.
+     *
+     * The associated value is an integer: 0 if unspecified, or one of the
+     * COLOR_TRANSFER_ values. When unspecified the component will not touch the
+     * video content; otherwise the component will tone-map the raw video frame
+     * to match the requested transfer function.
+     *
+     * After configure, component's input format will contain this key to note
+     * whether the request is supported or not. If the value in the input format
+     * is the same as the requested value, the request is supported. The value
+     * is set to 0 if unsupported.
+     */
+    public static final String KEY_COLOR_TRANSFER_REQUEST = "color-transfer-request";
+
+    /**
+     * A key describing a unique ID for the content of a media track.
+     *
+     * <p>This key is used by {@link MediaExtractor}. Some extractors provide multiple encodings
+     * of the same track (e.g. float audio tracks for FLAC and WAV may be expressed as two
+     * tracks via MediaExtractor: a normal PCM track for backward compatibility, and a float PCM
+     * track for added fidelity. Similarly, Dolby Vision extractor may provide a baseline SDR
+     * version of a DV track.) This key can be used to identify which MediaExtractor tracks refer
+     * to the same underlying content.
+     * </p>
+     *
+     * The associated value is an integer.
+     */
+    public static final String KEY_TRACK_ID = "track-id";
+
+    /**
+     * A key describing the system id of the conditional access system used to scramble
+     * a media track.
+     * <p>
+     * This key is set by {@link MediaExtractor} if the track is scrambled with a conditional
+     * access system, regardless of the presence of a valid {@link MediaCas} object.
+     * <p>
+     * The associated value is an integer.
+     * @hide
+     */
+    public static final String KEY_CA_SYSTEM_ID = "ca-system-id";
+
+    /**
+     * A key describing the {@link MediaCas.Session} object associated with a media track.
+     * <p>
+     * This key is set by {@link MediaExtractor} if the track is scrambled with a conditional
+     * access system, after it receives a valid {@link MediaCas} object.
+     * <p>
+     * The associated value is a ByteBuffer.
+     * @hide
+     */
+    public static final String KEY_CA_SESSION_ID = "ca-session-id";
+
+    /**
+     * A key describing the private data in the CA_descriptor associated with a media track.
+     * <p>
+     * This key is set by {@link MediaExtractor} if the track is scrambled with a conditional
+     * access system, before it receives a valid {@link MediaCas} object.
+     * <p>
+     * The associated value is a ByteBuffer.
+     * @hide
+     */
+    public static final String KEY_CA_PRIVATE_DATA = "ca-private-data";
+
+    /**
+     * A key describing the maximum number of B frames between I or P frames,
+     * to be used by a video encoder.
+     * The associated value is an integer. The default value is 0, which means
+     * that no B frames are allowed. Note that non-zero value does not guarantee
+     * B frames; it's up to the encoder to decide.
+     */
+    public static final String KEY_MAX_B_FRAMES = "max-bframes";
+
+    /**
+     * A key for applications to opt out of allowing
+     * a Surface to discard undisplayed/unconsumed frames
+     * as means to catch up after falling behind.
+     * This value is an integer.
+     * The value 0 indicates the surface is not allowed to drop frames.
+     * The value 1 indicates the surface is allowed to drop frames.
+     *
+     * {@link MediaCodec} describes the semantics.
+     */
+    public static final String KEY_ALLOW_FRAME_DROP = "allow-frame-drop";
+
+    /* package private */ MediaFormat(@NonNull Map<String, Object> map) {
+        mMap = map;
+    }
+
+    /**
+     * Creates an empty MediaFormat
+     */
+    public MediaFormat() {
+        mMap = new HashMap();
+    }
+
+    @UnsupportedAppUsage
+    /* package private */ Map<String, Object> getMap() {
+        return mMap;
+    }
+
+    /**
+     * Returns true iff a key of the given name exists in the format.
+     */
+    public final boolean containsKey(@NonNull String name) {
+        return mMap.containsKey(name);
+    }
+
+    /**
+     * Returns true iff a feature of the given name exists in the format.
+     */
+    public final boolean containsFeature(@NonNull String name) {
+        return mMap.containsKey(KEY_FEATURE_ + name);
+    }
+
+    public static final int TYPE_NULL = 0;
+    public static final int TYPE_INTEGER = 1;
+    public static final int TYPE_LONG = 2;
+    public static final int TYPE_FLOAT = 3;
+    public static final int TYPE_STRING = 4;
+    public static final int TYPE_BYTE_BUFFER = 5;
+
+    /** @hide */
+    @IntDef({
+        TYPE_NULL,
+        TYPE_INTEGER,
+        TYPE_LONG,
+        TYPE_FLOAT,
+        TYPE_STRING,
+        TYPE_BYTE_BUFFER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {}
+
+    /**
+     * Returns the value type for a key. If the key does not exist, it returns TYPE_NULL.
+     */
+    public final @Type int getValueTypeForKey(@NonNull String name) {
+        Object value = mMap.get(name);
+        if (value == null) {
+            return TYPE_NULL;
+        } else if (value instanceof Integer) {
+            return TYPE_INTEGER;
+        } else if (value instanceof Long) {
+            return TYPE_LONG;
+        } else if (value instanceof Float) {
+            return TYPE_FLOAT;
+        } else if (value instanceof String) {
+            return TYPE_STRING;
+        } else if (value instanceof ByteBuffer) {
+            return TYPE_BYTE_BUFFER;
+        }
+        throw new RuntimeException("invalid value for key");
+    }
+
+    /**
+     * A key prefix used together with a {@link MediaCodecInfo.CodecCapabilities}
+     * feature name describing a required or optional feature for a codec capabilities
+     * query.
+     * The associated value is an integer, where non-0 value means the feature is
+     * requested to be present, while 0 value means the feature is requested to be not
+     * present.
+     * @see MediaCodecList#findDecoderForFormat
+     * @see MediaCodecList#findEncoderForFormat
+     * @see MediaCodecInfo.CodecCapabilities#isFormatSupported
+     *
+     * @hide
+     */
+    public static final String KEY_FEATURE_ = "feature-";
+
+    /**
+     * Returns the value of a numeric key. This is provided as a convenience method for keys
+     * that may take multiple numeric types, such as {@link #KEY_FRAME_RATE}, or {@link
+     * #KEY_I_FRAME_INTERVAL}.
+     *
+     * @return null if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is ByteBuffer or String
+     */
+    public final @Nullable Number getNumber(@NonNull String name) {
+        return (Number) mMap.get(name);
+    }
+
+    /**
+     * Returns the value of a numeric key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is ByteBuffer or String
+     */
+    public final @NonNull Number getNumber(@NonNull String name, @NonNull Number defaultValue) {
+        Number ret = getNumber(name);
+        return ret == null ? defaultValue : ret;
+    }
+
+    /**
+     * Returns the value of an integer key.
+     *
+     * @throws NullPointerException if the key does not exist or the stored value for the key is
+     *         null
+     * @throws ClassCastException if the stored value for the key is long, float, ByteBuffer or
+     *         String
+     */
+    public final int getInteger(@NonNull String name) {
+        return (int) mMap.get(name);
+    }
+
+    /**
+     * Returns the value of an integer key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is long, float, ByteBuffer or
+     *         String
+     */
+    public final int getInteger(@NonNull String name, int defaultValue) {
+        try {
+            return getInteger(name);
+        } catch (NullPointerException  e) {
+            /* no such field or field is null */
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value of a long key.
+     *
+     * @throws NullPointerException if the key does not exist or the stored value for the key is
+     *         null
+     * @throws ClassCastException if the stored value for the key is int, float, ByteBuffer or
+     *         String
+     */
+    public final long getLong(@NonNull String name) {
+        return (long) mMap.get(name);
+    }
+
+    /**
+     * Returns the value of a long key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, float, ByteBuffer or
+     *         String
+     */
+    public final long getLong(@NonNull String name, long defaultValue) {
+        try {
+            return getLong(name);
+        } catch (NullPointerException  e) {
+            /* no such field or field is null */
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value of a float key.
+     *
+     * @throws NullPointerException if the key does not exist or the stored value for the key is
+     *         null
+     * @throws ClassCastException if the stored value for the key is int, long, ByteBuffer or
+     *         String
+     */
+    public final float getFloat(@NonNull String name) {
+        return (float) mMap.get(name);
+    }
+
+    /**
+     * Returns the value of a float key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, ByteBuffer or
+     *         String
+     */
+    public final float getFloat(@NonNull String name, float defaultValue) {
+        Object value = mMap.get(name);
+        return value != null ? (float) value : defaultValue;
+    }
+
+    /**
+     * Returns the value of a string key.
+     *
+     * @return null if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, float or ByteBuffer
+     */
+    public final @Nullable String getString(@NonNull String name) {
+        return (String)mMap.get(name);
+    }
+
+    /**
+     * Returns the value of a string key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, float or ByteBuffer
+     */
+    public final @NonNull String getString(@NonNull String name, @NonNull String defaultValue) {
+        String ret = getString(name);
+        return ret == null ? defaultValue : ret;
+    }
+
+    /**
+     * Returns the value of a ByteBuffer key.
+     *
+     * @return null if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, float or String
+     */
+    public final @Nullable ByteBuffer getByteBuffer(@NonNull String name) {
+        return (ByteBuffer)mMap.get(name);
+    }
+
+    /**
+     * Returns the value of a ByteBuffer key, or the default value if the key is missing.
+     *
+     * @return defaultValue if the key does not exist or the stored value for the key is null
+     * @throws ClassCastException if the stored value for the key is int, long, float or String
+     */
+    public final @NonNull ByteBuffer getByteBuffer(
+            @NonNull String name, @NonNull ByteBuffer defaultValue) {
+        ByteBuffer ret = getByteBuffer(name);
+        return ret == null ? defaultValue : ret;
+    }
+
+    /**
+     * Returns whether a feature is to be enabled ({@code true}) or disabled
+     * ({@code false}).
+     *
+     * @param feature the name of a {@link MediaCodecInfo.CodecCapabilities} feature.
+     *
+     * @throws IllegalArgumentException if the feature was neither set to be enabled
+     *         nor to be disabled.
+     */
+    public boolean getFeatureEnabled(@NonNull String feature) {
+        Integer enabled = (Integer)mMap.get(KEY_FEATURE_ + feature);
+        if (enabled == null) {
+            throw new IllegalArgumentException("feature is not specified");
+        }
+        return enabled != 0;
+    }
+
+    /**
+     * Sets the value of an integer key.
+     */
+    public final void setInteger(@NonNull String name, int value) {
+        mMap.put(name, value);
+    }
+
+    /**
+     * Sets the value of a long key.
+     */
+    public final void setLong(@NonNull String name, long value) {
+        mMap.put(name, value);
+    }
+
+    /**
+     * Sets the value of a float key.
+     */
+    public final void setFloat(@NonNull String name, float value) {
+        mMap.put(name, value);
+    }
+
+    /**
+     * Sets the value of a string key.
+     * <p>
+     * If value is {@code null}, it sets a null value that behaves similarly to a missing key.
+     * This could be used prior to API level {@link android os.Build.VERSION_CODES#Q} to effectively
+     * remove a key.
+     */
+    public final void setString(@NonNull String name, @Nullable String value) {
+        mMap.put(name, value);
+    }
+
+    /**
+     * Sets the value of a ByteBuffer key.
+     * <p>
+     * If value is {@code null}, it sets a null value that behaves similarly to a missing key.
+     * This could be used prior to API level {@link android os.Build.VERSION_CODES#Q} to effectively
+     * remove a key.
+     */
+    public final void setByteBuffer(@NonNull String name, @Nullable ByteBuffer bytes) {
+        mMap.put(name, bytes);
+    }
+
+    /**
+     * Removes a value of a given key if present. Has no effect if the key is not present.
+     */
+    public final void removeKey(@NonNull String name) {
+        // exclude feature mappings
+        if (!name.startsWith(KEY_FEATURE_)) {
+            mMap.remove(name);
+        }
+    }
+
+    /**
+     * Removes a given feature setting if present. Has no effect if the feature setting is not
+     * present.
+     */
+    public final void removeFeature(@NonNull String name) {
+        mMap.remove(KEY_FEATURE_ + name);
+    }
+
+    /**
+     * A Partial set view for a portion of the keys in a MediaFormat object.
+     *
+     * This class is needed as we want to return a portion of the actual format keys in getKeys()
+     * and another portion of the keys in getFeatures(), and still allow the view properties.
+     */
+    private abstract class FilteredMappedKeySet extends AbstractSet<String> {
+        private Set<String> mKeys;
+
+        // Returns true if this set should include this key
+        abstract protected boolean keepKey(String key);
+
+        // Maps a key from the underlying key set into its new value in this key set
+        abstract protected String mapKeyToItem(String key);
+
+        // Maps a key from this key set into its original value in the underlying key set
+        abstract protected String mapItemToKey(String item);
+
+        public FilteredMappedKeySet() {
+            mKeys = mMap.keySet();
+        }
+
+        // speed up contains and remove from abstract implementation (that would iterate
+        // over each element)
+        @Override
+        public boolean contains(Object o) {
+            if (o instanceof String) {
+                String key = mapItemToKey((String)o);
+                return keepKey(key) && mKeys.contains(key);
+            }
+            return false;
+        }
+
+        @Override
+        public boolean remove(Object o) {
+            if (o instanceof String) {
+                String key = mapItemToKey((String)o);
+                if (keepKey(key) && mKeys.remove(key)) {
+                    mMap.remove(key);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        private class KeyIterator implements Iterator<String> {
+            Iterator<String> mIterator;
+            String mLast;
+
+            public KeyIterator() {
+                // We must create a copy of the filtered stream, as remove operation has to modify
+                // the underlying data structure (mMap), so the iterator's operation is undefined.
+                // Use a list as it is likely less memory consuming than the other alternative: set.
+                mIterator =
+                    mKeys.stream().filter(k -> keepKey(k)).collect(Collectors.toList()).iterator();
+            }
+
+            @Override
+            public boolean hasNext() {
+                return mIterator.hasNext();
+            }
+
+            @Override
+            public String next() {
+                mLast = mIterator.next();
+                return mapKeyToItem(mLast);
+            }
+
+            @Override
+            public void remove() {
+                mIterator.remove();
+                mMap.remove(mLast);
+            }
+        }
+
+        @Override
+        public Iterator<String> iterator() {
+            return new KeyIterator();
+        }
+
+        @Override
+        public int size() {
+            return (int) mKeys.stream().filter(this::keepKey).count();
+        }
+    }
+
+    /**
+     * A Partial set view for a portion of the keys in a MediaFormat object for keys that
+     * don't start with a prefix, such as "feature-"
+     */
+    private class UnprefixedKeySet extends FilteredMappedKeySet {
+        private String mPrefix;
+
+        public UnprefixedKeySet(String prefix) {
+            super();
+            mPrefix = prefix;
+        }
+
+        protected boolean keepKey(String key) {
+            return !key.startsWith(mPrefix);
+        }
+
+        protected String mapKeyToItem(String key) {
+            return key;
+        }
+
+        protected String mapItemToKey(String item) {
+            return item;
+        }
+    }
+
+    /**
+     * A Partial set view for a portion of the keys in a MediaFormat object for keys that
+     * start with a prefix, such as "feature-", with the prefix removed
+     */
+    private class PrefixedKeySetWithPrefixRemoved extends FilteredMappedKeySet {
+        private String mPrefix;
+        private int mPrefixLength;
+
+        public PrefixedKeySetWithPrefixRemoved(String prefix) {
+            super();
+            mPrefix = prefix;
+            mPrefixLength = prefix.length();
+        }
+
+        protected boolean keepKey(String key) {
+            return key.startsWith(mPrefix);
+        }
+
+        protected String mapKeyToItem(String key) {
+            return key.substring(mPrefixLength);
+        }
+
+        protected String mapItemToKey(String item) {
+            return mPrefix + item;
+        }
+    }
+
+
+   /**
+     * Returns a {@link java.util.Set Set} view of the keys contained in this MediaFormat.
+     *
+     * The set is backed by the MediaFormat object, so changes to the format are reflected in the
+     * set, and vice-versa. If the format is modified while an iteration over the set is in progress
+     * (except through the iterator's own remove operation), the results of the iteration are
+     * undefined. The set supports element removal, which removes the corresponding mapping from the
+     * format, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations.
+     * It does not support the add or addAll operations.
+     */
+    public final @NonNull java.util.Set<String> getKeys() {
+        return new UnprefixedKeySet(KEY_FEATURE_);
+    }
+
+   /**
+     * Returns a {@link java.util.Set Set} view of the features contained in this MediaFormat.
+     *
+     * The set is backed by the MediaFormat object, so changes to the format are reflected in the
+     * set, and vice-versa. If the format is modified while an iteration over the set is in progress
+     * (except through the iterator's own remove operation), the results of the iteration are
+     * undefined. The set supports element removal, which removes the corresponding mapping from the
+     * format, via the Iterator.remove, Set.remove, removeAll, retainAll, and clear operations.
+     * It does not support the add or addAll operations.
+     */
+    public final @NonNull java.util.Set<String> getFeatures() {
+        return new PrefixedKeySetWithPrefixRemoved(KEY_FEATURE_);
+    }
+
+    /**
+     * Create a copy of a media format object.
+     */
+    public MediaFormat(@NonNull MediaFormat other) {
+        this();
+        mMap.putAll(other.mMap);
+    }
+
+    /**
+     * Sets whether a feature is to be enabled ({@code true}) or disabled
+     * ({@code false}).
+     *
+     * If {@code enabled} is {@code true}, the feature is requested to be present.
+     * Otherwise, the feature is requested to be not present.
+     *
+     * @param feature the name of a {@link MediaCodecInfo.CodecCapabilities} feature.
+     *
+     * @see MediaCodecList#findDecoderForFormat
+     * @see MediaCodecList#findEncoderForFormat
+     * @see MediaCodecInfo.CodecCapabilities#isFormatSupported
+     */
+    public void setFeatureEnabled(@NonNull String feature, boolean enabled) {
+        setInteger(KEY_FEATURE_ + feature, enabled ? 1 : 0);
+    }
+
+    /**
+     * Creates a minimal audio format.
+     * @param mime The mime type of the content.
+     * @param sampleRate The sampling rate of the content.
+     * @param channelCount The number of audio channels in the content.
+     */
+    public static final @NonNull MediaFormat createAudioFormat(
+            @NonNull String mime,
+            int sampleRate,
+            int channelCount) {
+        MediaFormat format = new MediaFormat();
+        format.setString(KEY_MIME, mime);
+        format.setInteger(KEY_SAMPLE_RATE, sampleRate);
+        format.setInteger(KEY_CHANNEL_COUNT, channelCount);
+
+        return format;
+    }
+
+    /**
+     * Creates a minimal subtitle format.
+     * @param mime The mime type of the content.
+     * @param language The language of the content, using either ISO 639-1 or 639-2/T
+     *        codes.  Specify null or "und" if language information is only included
+     *        in the content.  (This will also work if there are multiple language
+     *        tracks in the content.)
+     */
+    public static final @NonNull MediaFormat createSubtitleFormat(
+            @NonNull String mime,
+            String language) {
+        MediaFormat format = new MediaFormat();
+        format.setString(KEY_MIME, mime);
+        format.setString(KEY_LANGUAGE, language);
+
+        return format;
+    }
+
+    /**
+     * Creates a minimal video format.
+     * @param mime The mime type of the content.
+     * @param width The width of the content (in pixels)
+     * @param height The height of the content (in pixels)
+     */
+    public static final @NonNull MediaFormat createVideoFormat(
+            @NonNull String mime,
+            int width,
+            int height) {
+        MediaFormat format = new MediaFormat();
+        format.setString(KEY_MIME, mime);
+        format.setInteger(KEY_WIDTH, width);
+        format.setInteger(KEY_HEIGHT, height);
+
+        return format;
+    }
+
+    @Override
+    public @NonNull String toString() {
+        return mMap.toString();
+    }
+}
diff --git a/android/media/MediaFrameworkInitializer.java b/android/media/MediaFrameworkInitializer.java
new file mode 100644
index 0000000..75a56b7
--- /dev/null
+++ b/android/media/MediaFrameworkInitializer.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2020 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.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.annotation.SystemApi.Client;
+import android.app.SystemServiceRegistry;
+import android.content.Context;
+import android.os.Build;
+
+import com.android.modules.annotation.MinSdk;
+import com.android.modules.utils.build.SdkLevel;
+
+/**
+ * Class for performing registration for all media services on com.android.media apex.
+ *
+ * @hide
+ */
+@MinSdk(Build.VERSION_CODES.S)
+@SystemApi(client = Client.MODULE_LIBRARIES)
+public class MediaFrameworkInitializer {
+    private MediaFrameworkInitializer() {
+    }
+
+    private static volatile MediaServiceManager sMediaServiceManager;
+
+    /**
+     * Sets an instance of {@link MediaServiceManager} that allows
+     * the media mainline module to register/obtain media binder services. This is called
+     * by the platform during the system initialization.
+     *
+     * @param mediaServiceManager instance of {@link MediaServiceManager} that allows
+     * the media mainline module to register/obtain media binder services.
+     */
+    public static void setMediaServiceManager(
+            @NonNull MediaServiceManager mediaServiceManager) {
+        if (sMediaServiceManager != null) {
+            throw new IllegalStateException("setMediaServiceManager called twice!");
+        }
+
+        if (mediaServiceManager == null) {
+            throw new NullPointerException("mediaServiceManager is null!");
+        }
+
+        sMediaServiceManager = mediaServiceManager;
+    }
+
+    /** @hide */
+    public static MediaServiceManager getMediaServiceManager() {
+        return sMediaServiceManager;
+    }
+
+    /**
+     * Called by {@link SystemServiceRegistry}'s static initializer and registers all media
+     * services to {@link Context}, so that {@link Context#getSystemService} can return them.
+     *
+     * @throws IllegalStateException if this is called from anywhere besides
+     * {@link SystemServiceRegistry}
+     */
+    public static void registerServiceWrappers() {
+        SystemServiceRegistry.registerContextAwareService(
+                Context.MEDIA_TRANSCODING_SERVICE,
+                MediaTranscodingManager.class,
+                context -> new MediaTranscodingManager(context)
+        );
+        if (SdkLevel.isAtLeastS()) {
+            SystemServiceRegistry.registerContextAwareService(
+                    Context.MEDIA_COMMUNICATION_SERVICE,
+                    MediaCommunicationManager.class,
+                    context -> new MediaCommunicationManager(context)
+            );
+        }
+    }
+}
diff --git a/android/media/MediaFrameworkPlatformInitializer.java b/android/media/MediaFrameworkPlatformInitializer.java
new file mode 100644
index 0000000..e703669
--- /dev/null
+++ b/android/media/MediaFrameworkPlatformInitializer.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2020 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.annotation.NonNull;
+import android.app.SystemServiceRegistry;
+import android.content.Context;
+import android.media.session.MediaSessionManager;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Objects;
+
+/**
+ * Class for performing registration for all media services
+ *
+ * TODO (b/160513103): This class is still needed on platform side until
+ * MEDIA_SESSION_SERVICE is moved onto com.android.media apex.
+ * Once that's done, we can move the code that registers the service onto the
+ * MediaFrameworkInitializer class on the apex.
+ *
+ * @hide
+ */
+public class MediaFrameworkPlatformInitializer {
+    private MediaFrameworkPlatformInitializer() {
+    }
+
+    private static volatile MediaServiceManager sMediaServiceManager;
+
+    /**
+     * Sets an instance of {@link MediaServiceManager} that allows
+     * the media mainline module to register/obtain media binder services. This is called
+     * by the platform during the system initialization.
+     *
+     * @param mediaServiceManager instance of {@link MediaServiceManager} that allows
+     * the media mainline module to register/obtain media binder services.
+     */
+    public static void setMediaServiceManager(
+            @NonNull MediaServiceManager mediaServiceManager) {
+        Preconditions.checkState(sMediaServiceManager == null,
+                "setMediaServiceManager called twice!");
+        sMediaServiceManager = Objects.requireNonNull(mediaServiceManager);
+    }
+
+    /** @hide */
+    public static MediaServiceManager getMediaServiceManager() {
+        return sMediaServiceManager;
+    }
+
+    /**
+     * Called by {@link SystemServiceRegistry}'s static initializer and registers all media
+     * services to {@link Context}, so that {@link Context#getSystemService} can return them.
+     *
+     * @throws IllegalStateException if this is called from anywhere besides
+     * {@link SystemServiceRegistry}
+     */
+    public static void registerServiceWrappers() {
+        SystemServiceRegistry.registerContextAwareService(
+                Context.MEDIA_SESSION_SERVICE,
+                MediaSessionManager.class,
+                context -> new MediaSessionManager(context)
+        );
+    }
+}
diff --git a/android/media/MediaHTTPConnection.java b/android/media/MediaHTTPConnection.java
new file mode 100644
index 0000000..babc1d5
--- /dev/null
+++ b/android/media/MediaHTTPConnection.java
@@ -0,0 +1,494 @@
+/*
+ * Copyright (C) 2013 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.MediaPlayer.MEDIA_ERROR_UNSUPPORTED;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.net.InetAddresses;
+import android.os.IBinder;
+import android.os.StrictMode;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.BufferedInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.CookieHandler;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.NoRouteToHostException;
+import java.net.ProtocolException;
+import java.net.Proxy;
+import java.net.URL;
+import java.net.UnknownServiceException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/** @hide */
+public class MediaHTTPConnection extends IMediaHTTPConnection.Stub {
+    private static final String TAG = "MediaHTTPConnection";
+    private static final boolean VERBOSE = false;
+
+    // connection timeout - 30 sec
+    private static final int CONNECT_TIMEOUT_MS = 30 * 1000;
+
+    @GuardedBy("this")
+    @UnsupportedAppUsage
+    private long mCurrentOffset = -1;
+
+    @GuardedBy("this")
+    @UnsupportedAppUsage
+    private URL mURL = null;
+
+    @GuardedBy("this")
+    @UnsupportedAppUsage
+    private Map<String, String> mHeaders = null;
+
+    // volatile so that disconnect() can be called without acquiring a lock.
+    // All other access is @GuardedBy("this").
+    @UnsupportedAppUsage
+    private volatile HttpURLConnection mConnection = null;
+
+    @GuardedBy("this")
+    @UnsupportedAppUsage
+    private long mTotalSize = -1;
+
+    @GuardedBy("this")
+    private InputStream mInputStream = null;
+
+    @GuardedBy("this")
+    @UnsupportedAppUsage
+    private boolean mAllowCrossDomainRedirect = true;
+
+    @GuardedBy("this")
+    @UnsupportedAppUsage
+    private boolean mAllowCrossProtocolRedirect = true;
+
+    // from com.squareup.okhttp.internal.http
+    private final static int HTTP_TEMP_REDIRECT = 307;
+    private final static int MAX_REDIRECTS = 20;
+
+    // The number of threads that are currently running disconnect() (possibly
+    // not yet holding the synchronized lock).
+    private final AtomicInteger mNumDisconnectingThreads = new AtomicInteger(0);
+
+    @UnsupportedAppUsage
+    public MediaHTTPConnection() {
+        CookieHandler cookieHandler = CookieHandler.getDefault();
+        if (cookieHandler == null) {
+            Log.w(TAG, "MediaHTTPConnection: Unexpected. No CookieHandler found.");
+        }
+
+        native_setup();
+    }
+
+    @Override
+    @UnsupportedAppUsage
+    public synchronized IBinder connect(String uri, String headers) {
+        if (VERBOSE) {
+            Log.d(TAG, "connect: uri=" + uri + ", headers=" + headers);
+        }
+
+        try {
+            disconnect();
+            mAllowCrossDomainRedirect = true;
+            mURL = new URL(uri);
+            mHeaders = convertHeaderStringToMap(headers);
+        } catch (MalformedURLException e) {
+            return null;
+        }
+
+        return native_getIMemory();
+    }
+
+    private static boolean parseBoolean(String val) {
+        try {
+            return Long.parseLong(val) != 0;
+        } catch (NumberFormatException e) {
+            return "true".equalsIgnoreCase(val) ||
+                "yes".equalsIgnoreCase(val);
+        }
+    }
+
+    /* returns true iff header is internal */
+    private synchronized boolean filterOutInternalHeaders(String key, String val) {
+        if ("android-allow-cross-domain-redirect".equalsIgnoreCase(key)) {
+            mAllowCrossDomainRedirect = parseBoolean(val);
+            // cross-protocol redirects are also controlled by this flag
+            mAllowCrossProtocolRedirect = mAllowCrossDomainRedirect;
+        } else {
+            return false;
+        }
+        return true;
+    }
+
+    private synchronized Map<String, String> convertHeaderStringToMap(String headers) {
+        HashMap<String, String> map = new HashMap<String, String>();
+
+        String[] pairs = headers.split("\r\n");
+        for (String pair : pairs) {
+            int colonPos = pair.indexOf(":");
+            if (colonPos >= 0) {
+                String key = pair.substring(0, colonPos);
+                String val = pair.substring(colonPos + 1);
+
+                if (!filterOutInternalHeaders(key, val)) {
+                    map.put(key, val);
+                }
+            }
+        }
+
+        return map;
+    }
+
+    @Override
+    @UnsupportedAppUsage
+    public void disconnect() {
+        mNumDisconnectingThreads.incrementAndGet();
+        try {
+            HttpURLConnection connectionToDisconnect = mConnection;
+            // Call disconnect() before blocking for the lock in order to ensure that any
+            // other thread that is blocked in readAt() will return quickly.
+            if (connectionToDisconnect != null) {
+                connectionToDisconnect.disconnect();
+            }
+            synchronized (this) {
+                // It's possible that while we were waiting to acquire the lock, another thread
+                // concurrently started a new connection; if so, we're disconnecting that one
+                // here, too.
+                teardownConnection();
+                mHeaders = null;
+                mURL = null;
+            }
+        } finally {
+            mNumDisconnectingThreads.decrementAndGet();
+        }
+    }
+
+    private synchronized void teardownConnection() {
+        if (mConnection != null) {
+            if (mInputStream != null) {
+                try {
+                    mInputStream.close();
+                } catch (IOException e) {
+                }
+                mInputStream = null;
+            }
+
+            mConnection.disconnect();
+            mConnection = null;
+
+            mCurrentOffset = -1;
+        }
+    }
+
+    private static final boolean isLocalHost(URL url) {
+        if (url == null) {
+            return false;
+        }
+
+        String host = url.getHost();
+
+        if (host == null) {
+            return false;
+        }
+
+        try {
+            if (host.equalsIgnoreCase("localhost")) {
+                return true;
+            }
+            if (InetAddresses.parseNumericAddress(host).isLoopbackAddress()) {
+                return true;
+            }
+        } catch (IllegalArgumentException iex) {
+        }
+        return false;
+    }
+
+    private synchronized void seekTo(long offset) throws IOException {
+        teardownConnection();
+
+        try {
+            int response;
+            int redirectCount = 0;
+
+            URL url = mURL;
+
+            // do not use any proxy for localhost (127.0.0.1)
+            boolean noProxy = isLocalHost(url);
+
+            while (true) {
+                // If another thread is concurrently disconnect()ing, there's a race
+                // between them and us. Therefore, we check mNumDisconnectingThreads shortly
+                // (not atomically) before & after writing mConnection. This guarantees that
+                // we won't "lose" a disconnect by creating a new connection that might
+                // miss the disconnect.
+                //
+                // Note that throwing an instanceof IOException is also what this thread
+                // would have done if another thread disconnect()ed the connection while
+                // this thread was blocked reading from that connection further down in this
+                // loop.
+                if (mNumDisconnectingThreads.get() > 0) {
+                    throw new IOException("concurrently disconnecting");
+                }
+                if (noProxy) {
+                    mConnection = (HttpURLConnection)url.openConnection(Proxy.NO_PROXY);
+                } else {
+                    mConnection = (HttpURLConnection)url.openConnection();
+                }
+                // If another thread is concurrently disconnecting, throwing IOException will
+                // cause us to release the lock, giving the other thread a chance to acquire
+                // it. It also ensures that the catch block will run, which will tear down
+                // the connection even if the other thread happens to already be on its way
+                // out of disconnect().
+                if (mNumDisconnectingThreads.get() > 0) {
+                    throw new IOException("concurrently disconnecting");
+                }
+                // If we get here without having thrown, we know that other threads
+                // will see our write to mConnection. Any disconnect() on that mConnection
+                // instance will cause our read from/write to that connection instance below
+                // to encounter an instanceof IOException.
+                mConnection.setConnectTimeout(CONNECT_TIMEOUT_MS);
+
+                // handle redirects ourselves if we do not allow cross-domain redirect
+                mConnection.setInstanceFollowRedirects(mAllowCrossDomainRedirect);
+
+                if (mHeaders != null) {
+                    for (Map.Entry<String, String> entry : mHeaders.entrySet()) {
+                        mConnection.setRequestProperty(
+                                entry.getKey(), entry.getValue());
+                    }
+                }
+
+                if (offset > 0) {
+                    mConnection.setRequestProperty(
+                            "Range", "bytes=" + offset + "-");
+                }
+
+                response = mConnection.getResponseCode();
+                if (response != HttpURLConnection.HTTP_MULT_CHOICE &&
+                        response != HttpURLConnection.HTTP_MOVED_PERM &&
+                        response != HttpURLConnection.HTTP_MOVED_TEMP &&
+                        response != HttpURLConnection.HTTP_SEE_OTHER &&
+                        response != HTTP_TEMP_REDIRECT) {
+                    // not a redirect, or redirect handled by HttpURLConnection
+                    break;
+                }
+
+                if (++redirectCount > MAX_REDIRECTS) {
+                    throw new NoRouteToHostException("Too many redirects: " + redirectCount);
+                }
+
+                String method = mConnection.getRequestMethod();
+                if (response == HTTP_TEMP_REDIRECT &&
+                        !method.equals("GET") && !method.equals("HEAD")) {
+                    // "If the 307 status code is received in response to a
+                    // request other than GET or HEAD, the user agent MUST NOT
+                    // automatically redirect the request"
+                    throw new NoRouteToHostException("Invalid redirect");
+                }
+                String location = mConnection.getHeaderField("Location");
+                if (location == null) {
+                    throw new NoRouteToHostException("Invalid redirect");
+                }
+                url = new URL(mURL /* TRICKY: don't use url! */, location);
+                if (!url.getProtocol().equals("https") &&
+                        !url.getProtocol().equals("http")) {
+                    throw new NoRouteToHostException("Unsupported protocol redirect");
+                }
+                boolean sameProtocol = mURL.getProtocol().equals(url.getProtocol());
+                if (!mAllowCrossProtocolRedirect && !sameProtocol) {
+                    throw new NoRouteToHostException("Cross-protocol redirects are disallowed");
+                }
+                boolean sameHost = mURL.getHost().equals(url.getHost());
+                if (!mAllowCrossDomainRedirect && !sameHost) {
+                    throw new NoRouteToHostException("Cross-domain redirects are disallowed");
+                }
+
+                if (response != HTTP_TEMP_REDIRECT) {
+                    // update effective URL, unless it is a Temporary Redirect
+                    mURL = url;
+                }
+            }
+
+            if (mAllowCrossDomainRedirect) {
+                // remember the current, potentially redirected URL if redirects
+                // were handled by HttpURLConnection
+                mURL = mConnection.getURL();
+            }
+
+            if (response == HttpURLConnection.HTTP_PARTIAL) {
+                // Partial content, we cannot just use getContentLength
+                // because what we want is not just the length of the range
+                // returned but the size of the full content if available.
+
+                String contentRange =
+                    mConnection.getHeaderField("Content-Range");
+
+                mTotalSize = -1;
+                if (contentRange != null) {
+                    // format is "bytes xxx-yyy/zzz
+                    // where "zzz" is the total number of bytes of the
+                    // content or '*' if unknown.
+
+                    int lastSlashPos = contentRange.lastIndexOf('/');
+                    if (lastSlashPos >= 0) {
+                        String total =
+                            contentRange.substring(lastSlashPos + 1);
+
+                        try {
+                            mTotalSize = Long.parseLong(total);
+                        } catch (NumberFormatException e) {
+                        }
+                    }
+                }
+            } else if (response != HttpURLConnection.HTTP_OK) {
+                throw new IOException();
+            } else {
+                mTotalSize = mConnection.getContentLength();
+            }
+
+            if (offset > 0 && response != HttpURLConnection.HTTP_PARTIAL) {
+                // Some servers simply ignore "Range" requests and serve
+                // data from the start of the content.
+                throw new ProtocolException();
+            }
+
+            mInputStream =
+                new BufferedInputStream(mConnection.getInputStream());
+
+            mCurrentOffset = offset;
+        } catch (IOException e) {
+            mTotalSize = -1;
+            teardownConnection();
+            mCurrentOffset = -1;
+
+            throw e;
+        }
+    }
+
+    @Override
+    @UnsupportedAppUsage
+    public synchronized int readAt(long offset, int size) {
+        return native_readAt(offset, size);
+    }
+
+    private synchronized int readAt(long offset, byte[] data, int size) {
+        StrictMode.ThreadPolicy policy =
+            new StrictMode.ThreadPolicy.Builder().permitAll().build();
+
+        StrictMode.setThreadPolicy(policy);
+
+        try {
+            if (offset != mCurrentOffset) {
+                seekTo(offset);
+            }
+
+            int n = mInputStream.read(data, 0, size);
+
+            if (n == -1) {
+                // InputStream signals EOS using a -1 result, our semantics
+                // are to return a 0-length read.
+                n = 0;
+            }
+
+            mCurrentOffset += n;
+
+            if (VERBOSE) {
+                Log.d(TAG, "readAt " + offset + " / " + size + " => " + n);
+            }
+
+            return n;
+        } catch (ProtocolException e) {
+            Log.w(TAG, "readAt " + offset + " / " + size + " => " + e);
+            return MEDIA_ERROR_UNSUPPORTED;
+        } catch (NoRouteToHostException e) {
+            Log.w(TAG, "readAt " + offset + " / " + size + " => " + e);
+            return MEDIA_ERROR_UNSUPPORTED;
+        } catch (UnknownServiceException e) {
+            Log.w(TAG, "readAt " + offset + " / " + size + " => " + e);
+            return MEDIA_ERROR_UNSUPPORTED;
+        } catch (IOException e) {
+            if (VERBOSE) {
+                Log.d(TAG, "readAt " + offset + " / " + size + " => -1");
+            }
+            return -1;
+        } catch (Exception e) {
+            if (VERBOSE) {
+                Log.d(TAG, "unknown exception " + e);
+                Log.d(TAG, "readAt " + offset + " / " + size + " => -1");
+            }
+            return -1;
+        }
+    }
+
+    @Override
+    public synchronized long getSize() {
+        if (mConnection == null) {
+            try {
+                seekTo(0);
+            } catch (IOException e) {
+                return -1;
+            }
+        }
+
+        return mTotalSize;
+    }
+
+    @Override
+    @UnsupportedAppUsage
+    public synchronized String getMIMEType() {
+        if (mConnection == null) {
+            try {
+                seekTo(0);
+            } catch (IOException e) {
+                return "application/octet-stream";
+            }
+        }
+
+        return mConnection.getContentType();
+    }
+
+    @Override
+    @UnsupportedAppUsage
+    public synchronized String getUri() {
+        return mURL.toString();
+    }
+
+    @Override
+    protected void finalize() {
+        native_finalize();
+    }
+
+    private static native final void native_init();
+    private native final void native_setup();
+    private native final void native_finalize();
+
+    private native final IBinder native_getIMemory();
+    private native final int native_readAt(long offset, int size);
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    private long mNativeContext;
+
+}
diff --git a/android/media/MediaHTTPService.java b/android/media/MediaHTTPService.java
new file mode 100644
index 0000000..3008067
--- /dev/null
+++ b/android/media/MediaHTTPService.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2013 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.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.IBinder;
+import android.util.Log;
+
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.CookieStore;
+import java.net.HttpCookie;
+import java.util.List;
+
+/** @hide */
+public class MediaHTTPService extends IMediaHTTPService.Stub {
+    private static final String TAG = "MediaHTTPService";
+    @Nullable private List<HttpCookie> mCookies;
+    private Boolean mCookieStoreInitialized = new Boolean(false);
+
+    public MediaHTTPService(@Nullable List<HttpCookie> cookies) {
+        mCookies = cookies;
+        Log.v(TAG, "MediaHTTPService(" + this + "): Cookies: " + cookies);
+    }
+
+    public IMediaHTTPConnection makeHTTPConnection() {
+
+        synchronized (mCookieStoreInitialized) {
+            // Only need to do it once for all connections
+            if ( !mCookieStoreInitialized )  {
+                CookieHandler cookieHandler = CookieHandler.getDefault();
+                if (cookieHandler == null) {
+                    cookieHandler = new CookieManager();
+                    CookieHandler.setDefault(cookieHandler);
+                    Log.v(TAG, "makeHTTPConnection: CookieManager created: " + cookieHandler);
+                } else {
+                    Log.v(TAG, "makeHTTPConnection: CookieHandler (" + cookieHandler + ") exists.");
+                }
+
+                // Applying the bootstrapping cookies
+                if ( mCookies != null ) {
+                    if ( cookieHandler instanceof CookieManager ) {
+                        CookieManager cookieManager = (CookieManager)cookieHandler;
+                        CookieStore store = cookieManager.getCookieStore();
+                        for ( HttpCookie cookie : mCookies ) {
+                            try {
+                                store.add(null, cookie);
+                            } catch ( Exception e ) {
+                                Log.v(TAG, "makeHTTPConnection: CookieStore.add" + e);
+                            }
+                            //for extended debugging when needed
+                            //Log.v(TAG, "MediaHTTPConnection adding Cookie[" + cookie.getName() +
+                            //        "]: " + cookie);
+                        }
+                    } else {
+                        Log.w(TAG, "makeHTTPConnection: The installed CookieHandler is not a "
+                                + "CookieManager. Can’t add the provided cookies to the cookie "
+                                + "store.");
+                    }
+                }   // mCookies
+
+                mCookieStoreInitialized = true;
+
+                Log.v(TAG, "makeHTTPConnection(" + this + "): cookieHandler: " + cookieHandler +
+                        " Cookies: " + mCookies);
+            }   // mCookieStoreInitialized
+        }   // synchronized
+
+        return new MediaHTTPConnection();
+    }
+
+    @UnsupportedAppUsage
+    /* package private */static IBinder createHttpServiceBinderIfNecessary(
+            String path) {
+        return createHttpServiceBinderIfNecessary(path, null);
+    }
+
+    // when cookies are provided
+    static IBinder createHttpServiceBinderIfNecessary(
+            String path, List<HttpCookie> cookies) {
+        if (path.startsWith("http://") || path.startsWith("https://")) {
+            return (new MediaHTTPService(cookies)).asBinder();
+        } else if (path.startsWith("widevine://")) {
+            Log.d(TAG, "Widevine classic is no longer supported");
+        }
+
+        return null;
+    }
+}
diff --git a/android/media/MediaInserter.java b/android/media/MediaInserter.java
new file mode 100644
index 0000000..ca7a01c
--- /dev/null
+++ b/android/media/MediaInserter.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2011 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.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentProviderClient;
+import android.content.ContentValues;
+import android.net.Uri;
+import android.os.RemoteException;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * A MediaScanner helper class which enables us to do lazy insertion on the
+ * given provider. This class manages buffers internally and flushes when they
+ * are full. Note that you should call flushAll() after using this class.
+ * {@hide}
+ */
+public class MediaInserter {
+    private final HashMap<Uri, List<ContentValues>> mRowMap =
+            new HashMap<Uri, List<ContentValues>>();
+    private final HashMap<Uri, List<ContentValues>> mPriorityRowMap =
+            new HashMap<Uri, List<ContentValues>>();
+
+    private final ContentProviderClient mProvider;
+    private final int mBufferSizePerUri;
+
+    public MediaInserter(ContentProviderClient provider, int bufferSizePerUri) {
+        mProvider = provider;
+        mBufferSizePerUri = bufferSizePerUri;
+    }
+
+    public void insert(Uri tableUri, ContentValues values) throws RemoteException {
+        insert(tableUri, values, false);
+    }
+
+    public void insertwithPriority(Uri tableUri, ContentValues values) throws RemoteException {
+        insert(tableUri, values, true);
+    }
+
+    private void insert(Uri tableUri, ContentValues values, boolean priority) throws RemoteException {
+        HashMap<Uri, List<ContentValues>> rowmap = priority ? mPriorityRowMap : mRowMap;
+        List<ContentValues> list = rowmap.get(tableUri);
+        if (list == null) {
+            list = new ArrayList<ContentValues>();
+            rowmap.put(tableUri, list);
+        }
+        list.add(new ContentValues(values));
+        if (list.size() >= mBufferSizePerUri) {
+            flushAllPriority();
+            flush(tableUri, list);
+        }
+    }
+
+    @UnsupportedAppUsage
+    public void flushAll() throws RemoteException {
+        flushAllPriority();
+        for (Uri tableUri : mRowMap.keySet()){
+            List<ContentValues> list = mRowMap.get(tableUri);
+            flush(tableUri, list);
+        }
+        mRowMap.clear();
+    }
+
+    private void flushAllPriority() throws RemoteException {
+        for (Uri tableUri : mPriorityRowMap.keySet()){
+            List<ContentValues> list = mPriorityRowMap.get(tableUri);
+            flush(tableUri, list);
+        }
+        mPriorityRowMap.clear();
+    }
+
+    private void flush(Uri tableUri, List<ContentValues> list) throws RemoteException {
+        if (!list.isEmpty()) {
+            ContentValues[] valuesArray = new ContentValues[list.size()];
+            valuesArray = list.toArray(valuesArray);
+            mProvider.bulkInsert(tableUri, valuesArray);
+            list.clear();
+        }
+    }
+}
diff --git a/android/media/MediaMetadata.java b/android/media/MediaMetadata.java
new file mode 100644
index 0000000..9976fa1
--- /dev/null
+++ b/android/media/MediaMetadata.java
@@ -0,0 +1,979 @@
+/*
+ * Copyright (C) 2014 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.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.StringDef;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentResolver;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.media.browse.MediaBrowser;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.SparseArray;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * Contains metadata about an item, such as the title, artist, etc.
+ */
+public final class MediaMetadata implements Parcelable {
+    private static final String TAG = "MediaMetadata";
+
+    /**
+     * @hide
+     */
+    @StringDef(prefix = { "METADATA_KEY_" }, value = {
+            METADATA_KEY_TITLE,
+            METADATA_KEY_ARTIST,
+            METADATA_KEY_ALBUM,
+            METADATA_KEY_AUTHOR,
+            METADATA_KEY_WRITER,
+            METADATA_KEY_COMPOSER,
+            METADATA_KEY_COMPILATION,
+            METADATA_KEY_DATE,
+            METADATA_KEY_GENRE,
+            METADATA_KEY_ALBUM_ARTIST,
+            METADATA_KEY_ART_URI,
+            METADATA_KEY_ALBUM_ART_URI,
+            METADATA_KEY_DISPLAY_TITLE,
+            METADATA_KEY_DISPLAY_SUBTITLE,
+            METADATA_KEY_DISPLAY_DESCRIPTION,
+            METADATA_KEY_DISPLAY_ICON_URI,
+            METADATA_KEY_MEDIA_ID,
+            METADATA_KEY_MEDIA_URI,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TextKey {}
+
+    /**
+     * @hide
+     */
+    @StringDef(prefix = { "METADATA_KEY_" }, value = {
+            METADATA_KEY_DURATION,
+            METADATA_KEY_YEAR,
+            METADATA_KEY_TRACK_NUMBER,
+            METADATA_KEY_NUM_TRACKS,
+            METADATA_KEY_DISC_NUMBER,
+            METADATA_KEY_BT_FOLDER_TYPE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface LongKey {}
+
+    /**
+     * @hide
+     */
+    @StringDef(prefix = { "METADATA_KEY_" }, value = {
+            METADATA_KEY_ART,
+            METADATA_KEY_ALBUM_ART,
+            METADATA_KEY_DISPLAY_ICON,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface BitmapKey {}
+
+    /**
+     * @hide
+     */
+    @StringDef(prefix = { "METADATA_KEY_" }, value = {
+            METADATA_KEY_USER_RATING,
+            METADATA_KEY_RATING,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RatingKey {}
+
+    /**
+     * The title of the media.
+     */
+    public static final String METADATA_KEY_TITLE = "android.media.metadata.TITLE";
+
+    /**
+     * The artist of the media.
+     */
+    public static final String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST";
+
+    /**
+     * The duration of the media in ms. A negative duration indicates that the
+     * duration is unknown (or infinite).
+     */
+    public static final String METADATA_KEY_DURATION = "android.media.metadata.DURATION";
+
+    /**
+     * The album title for the media.
+     */
+    public static final String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM";
+
+    /**
+     * The author of the media.
+     */
+    public static final String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR";
+
+    /**
+     * The writer of the media.
+     */
+    public static final String METADATA_KEY_WRITER = "android.media.metadata.WRITER";
+
+    /**
+     * The composer of the media.
+     */
+    public static final String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER";
+
+    /**
+     * The compilation status of the media.
+     */
+    public static final String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION";
+
+    /**
+     * The date the media was created or published. The format is unspecified
+     * but RFC 3339 is recommended.
+     */
+    public static final String METADATA_KEY_DATE = "android.media.metadata.DATE";
+
+    /**
+     * The year the media was created or published as a long.
+     */
+    public static final String METADATA_KEY_YEAR = "android.media.metadata.YEAR";
+
+    /**
+     * The genre of the media.
+     */
+    public static final String METADATA_KEY_GENRE = "android.media.metadata.GENRE";
+
+    /**
+     * The track number for the media.
+     */
+    public static final String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER";
+
+    /**
+     * The number of tracks in the media's original source.
+     */
+    public static final String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS";
+
+    /**
+     * The disc number for the media's original source.
+     */
+    public static final String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER";
+
+    /**
+     * The artist for the album of the media's original source.
+     */
+    public static final String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST";
+
+    /**
+     * The artwork for the media as a {@link Bitmap}.
+     * <p>
+     * The artwork should be relatively small and may be scaled down by the
+     * system if it is too large. For higher resolution artwork
+     * {@link #METADATA_KEY_ART_URI} should be used instead.
+     */
+    public static final String METADATA_KEY_ART = "android.media.metadata.ART";
+
+    /**
+     * The artwork for the media as a Uri formatted String. The artwork can be
+     * loaded using a combination of {@link ContentResolver#openInputStream} and
+     * {@link BitmapFactory#decodeStream}.
+     * <p>
+     * For the best results, Uris should use the content:// style and support
+     * {@link ContentResolver#EXTRA_SIZE} for retrieving scaled artwork through
+     * {@link ContentResolver#openTypedAssetFileDescriptor(Uri, String, Bundle)}.
+     */
+    public static final String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI";
+
+    /**
+     * The artwork for the album of the media's original source as a
+     * {@link Bitmap}.
+     * <p>
+     * The artwork should be relatively small and may be scaled down by the
+     * system if it is too large. For higher resolution artwork
+     * {@link #METADATA_KEY_ALBUM_ART_URI} should be used instead.
+     */
+    public static final String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART";
+
+    /**
+     * The artwork for the album of the media's original source as a Uri
+     * formatted String. The artwork can be loaded using a combination of
+     * {@link ContentResolver#openInputStream} and
+     * {@link BitmapFactory#decodeStream}.
+     * <p>
+     * For the best results, Uris should use the content:// style and support
+     * {@link ContentResolver#EXTRA_SIZE} for retrieving scaled artwork through
+     * {@link ContentResolver#openTypedAssetFileDescriptor(Uri, String, Bundle)}.
+     */
+    public static final String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI";
+
+    /**
+     * The user's rating for the media.
+     *
+     * @see Rating
+     */
+    public static final String METADATA_KEY_USER_RATING = "android.media.metadata.USER_RATING";
+
+    /**
+     * The overall rating for the media.
+     *
+     * @see Rating
+     */
+    public static final String METADATA_KEY_RATING = "android.media.metadata.RATING";
+
+    /**
+     * A title that is suitable for display to the user. This will generally be
+     * the same as {@link #METADATA_KEY_TITLE} but may differ for some formats.
+     * When displaying media described by this metadata this should be preferred
+     * if present.
+     */
+    public static final String METADATA_KEY_DISPLAY_TITLE = "android.media.metadata.DISPLAY_TITLE";
+
+    /**
+     * A subtitle that is suitable for display to the user. When displaying a
+     * second line for media described by this metadata this should be preferred
+     * to other fields if present.
+     */
+    public static final String METADATA_KEY_DISPLAY_SUBTITLE =
+            "android.media.metadata.DISPLAY_SUBTITLE";
+
+    /**
+     * A description that is suitable for display to the user. When displaying
+     * more information for media described by this metadata this should be
+     * preferred to other fields if present.
+     */
+    public static final String METADATA_KEY_DISPLAY_DESCRIPTION =
+            "android.media.metadata.DISPLAY_DESCRIPTION";
+
+    /**
+     * An icon or thumbnail that is suitable for display to the user. When
+     * displaying an icon for media described by this metadata this should be
+     * preferred to other fields if present. This must be a {@link Bitmap}.
+     * <p>
+     * The icon should be relatively small and may be scaled down by the system
+     * if it is too large. For higher resolution artwork
+     * {@link #METADATA_KEY_DISPLAY_ICON_URI} should be used instead.
+     */
+    public static final String METADATA_KEY_DISPLAY_ICON =
+            "android.media.metadata.DISPLAY_ICON";
+
+    /**
+     * A Uri formatted String for an icon or thumbnail that is suitable for
+     * display to the user. When displaying more information for media described
+     * by this metadata the display description should be preferred to other
+     * fields when present. The icon can be loaded using a combination of
+     * {@link ContentResolver#openInputStream} and
+     * {@link BitmapFactory#decodeStream}.
+     * <p>
+     * For the best results, Uris should use the content:// style and support
+     * {@link ContentResolver#EXTRA_SIZE} for retrieving scaled artwork through
+     * {@link ContentResolver#openTypedAssetFileDescriptor(Uri, String, Bundle)}.
+     */
+    public static final String METADATA_KEY_DISPLAY_ICON_URI =
+            "android.media.metadata.DISPLAY_ICON_URI";
+
+    /**
+     * A String key for identifying the content. This value is specific to the
+     * service providing the content. If used, this should be a persistent
+     * unique key for the underlying content. It may be used with
+     * {@link MediaController.TransportControls#playFromMediaId(String, Bundle)}
+     * to initiate playback when provided by a {@link MediaBrowser} connected to
+     * the same app.
+     */
+    public static final String METADATA_KEY_MEDIA_ID = "android.media.metadata.MEDIA_ID";
+
+    /**
+     * A Uri formatted String representing the content. This value is specific to the
+     * service providing the content. It may be used with
+     * {@link MediaController.TransportControls#playFromUri(Uri, Bundle)}
+     * to initiate playback when provided by a {@link MediaBrowser} connected to
+     * the same app.
+     */
+    public static final String METADATA_KEY_MEDIA_URI = "android.media.metadata.MEDIA_URI";
+
+    /**
+     * The bluetooth folder type of the media specified in the section 6.10.2.2 of the Bluetooth
+     * AVRCP 1.5. It should be one of the following:
+     * <ul>
+     * <li>{@link MediaDescription#BT_FOLDER_TYPE_MIXED}</li>
+     * <li>{@link MediaDescription#BT_FOLDER_TYPE_TITLES}</li>
+     * <li>{@link MediaDescription#BT_FOLDER_TYPE_ALBUMS}</li>
+     * <li>{@link MediaDescription#BT_FOLDER_TYPE_ARTISTS}</li>
+     * <li>{@link MediaDescription#BT_FOLDER_TYPE_GENRES}</li>
+     * <li>{@link MediaDescription#BT_FOLDER_TYPE_PLAYLISTS}</li>
+     * <li>{@link MediaDescription#BT_FOLDER_TYPE_YEARS}</li>
+     * </ul>
+     */
+    public static final String METADATA_KEY_BT_FOLDER_TYPE =
+            "android.media.metadata.BT_FOLDER_TYPE";
+
+    private static final @TextKey String[] PREFERRED_DESCRIPTION_ORDER = {
+            METADATA_KEY_TITLE,
+            METADATA_KEY_ARTIST,
+            METADATA_KEY_ALBUM,
+            METADATA_KEY_ALBUM_ARTIST,
+            METADATA_KEY_WRITER,
+            METADATA_KEY_AUTHOR,
+            METADATA_KEY_COMPOSER
+    };
+
+    private static final @BitmapKey String[] PREFERRED_BITMAP_ORDER = {
+            METADATA_KEY_DISPLAY_ICON,
+            METADATA_KEY_ART,
+            METADATA_KEY_ALBUM_ART
+    };
+
+    private static final @TextKey String[] PREFERRED_URI_ORDER = {
+            METADATA_KEY_DISPLAY_ICON_URI,
+            METADATA_KEY_ART_URI,
+            METADATA_KEY_ALBUM_ART_URI
+    };
+
+    private static final int METADATA_TYPE_INVALID = -1;
+    private static final int METADATA_TYPE_LONG = 0;
+    private static final int METADATA_TYPE_TEXT = 1;
+    private static final int METADATA_TYPE_BITMAP = 2;
+    private static final int METADATA_TYPE_RATING = 3;
+    private static final ArrayMap<String, Integer> METADATA_KEYS_TYPE;
+
+    static {
+        METADATA_KEYS_TYPE = new ArrayMap<String, Integer>();
+        METADATA_KEYS_TYPE.put(METADATA_KEY_TITLE, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ARTIST, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DURATION, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_AUTHOR, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_WRITER, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_COMPOSER, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_COMPILATION, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DATE, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_YEAR, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_GENRE, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_TRACK_NUMBER, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_NUM_TRACKS, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DISC_NUMBER, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ARTIST, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ART, METADATA_TYPE_BITMAP);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ART_URI, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ART, METADATA_TYPE_BITMAP);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_ALBUM_ART_URI, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_USER_RATING, METADATA_TYPE_RATING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_RATING, METADATA_TYPE_RATING);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_TITLE, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_SUBTITLE, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_DESCRIPTION, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_ICON, METADATA_TYPE_BITMAP);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_DISPLAY_ICON_URI, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_BT_FOLDER_TYPE, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_MEDIA_ID, METADATA_TYPE_TEXT);
+        METADATA_KEYS_TYPE.put(METADATA_KEY_MEDIA_URI, METADATA_TYPE_TEXT);
+    }
+
+    private static final SparseArray<String> EDITOR_KEY_MAPPING;
+
+    static {
+        EDITOR_KEY_MAPPING = new SparseArray<String>();
+        EDITOR_KEY_MAPPING.put(MediaMetadataEditor.BITMAP_KEY_ARTWORK, METADATA_KEY_ART);
+        EDITOR_KEY_MAPPING.put(MediaMetadataEditor.RATING_KEY_BY_OTHERS, METADATA_KEY_RATING);
+        EDITOR_KEY_MAPPING.put(MediaMetadataEditor.RATING_KEY_BY_USER, METADATA_KEY_USER_RATING);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_ALBUM, METADATA_KEY_ALBUM);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST,
+                METADATA_KEY_ALBUM_ARTIST);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_ARTIST, METADATA_KEY_ARTIST);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_AUTHOR, METADATA_KEY_AUTHOR);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER,
+                METADATA_KEY_TRACK_NUMBER);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_COMPOSER, METADATA_KEY_COMPOSER);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_COMPILATION,
+                METADATA_KEY_COMPILATION);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_DATE, METADATA_KEY_DATE);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER,
+                METADATA_KEY_DISC_NUMBER);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_DURATION, METADATA_KEY_DURATION);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_GENRE, METADATA_KEY_GENRE);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS,
+                METADATA_KEY_NUM_TRACKS);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_TITLE, METADATA_KEY_TITLE);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_WRITER, METADATA_KEY_WRITER);
+        EDITOR_KEY_MAPPING.put(MediaMetadataRetriever.METADATA_KEY_YEAR, METADATA_KEY_YEAR);
+    }
+
+    private final Bundle mBundle;
+    private final int mBitmapDimensionLimit;
+    private MediaDescription mDescription;
+
+    private MediaMetadata(Bundle bundle, int bitmapDimensionLimit) {
+        mBundle = new Bundle(bundle);
+        mBitmapDimensionLimit = bitmapDimensionLimit;
+    }
+
+    private MediaMetadata(Parcel in) {
+        mBundle = in.readBundle();
+        mBitmapDimensionLimit = Math.max(in.readInt(), 1);
+    }
+
+    /**
+     * Returns true if the given key is contained in the metadata
+     *
+     * @param key a String key
+     * @return true if the key exists in this metadata, false otherwise
+     */
+    public boolean containsKey(String key) {
+        return mBundle.containsKey(key);
+    }
+
+    /**
+     * Returns the value associated with the given key, or null if no mapping of
+     * the desired type exists for the given key or a null value is explicitly
+     * associated with the key.
+     *
+     * @param key The key the value is stored under
+     * @return a CharSequence value, or null
+     */
+    public CharSequence getText(@TextKey String key) {
+        return mBundle.getCharSequence(key);
+    }
+
+    /**
+     * Returns the text value associated with the given key as a String, or null
+     * if no mapping of the desired type exists for the given key or a null
+     * value is explicitly associated with the key. This is equivalent to
+     * calling {@link #getText getText().toString()} if the value is not null.
+     *
+     * @param key The key the value is stored under
+     * @return a String value, or null
+     */
+    public String getString(@TextKey String key) {
+        CharSequence text = getText(key);
+        if (text != null) {
+            return text.toString();
+        }
+        return null;
+    }
+
+    /**
+     * Returns the value associated with the given key, or 0L if no long exists
+     * for the given key.
+     *
+     * @param key The key the value is stored under
+     * @return a long value
+     */
+    public long getLong(@LongKey String key) {
+        return mBundle.getLong(key, 0);
+    }
+
+    /**
+     * Returns a {@link Rating} for the given key or null if no rating exists
+     * for the given key.
+     *
+     * @param key The key the value is stored under
+     * @return A {@link Rating} or null
+     */
+    public Rating getRating(@RatingKey String key) {
+        Rating rating = null;
+        try {
+            rating = mBundle.getParcelable(key);
+        } catch (Exception e) {
+            // ignore, value was not a bitmap
+            Log.w(TAG, "Failed to retrieve a key as Rating.", e);
+        }
+        return rating;
+    }
+
+    /**
+     * Returns a {@link Bitmap} for the given key or null if no bitmap exists
+     * for the given key.
+     *
+     * @param key The key the value is stored under
+     * @return A {@link Bitmap} or null
+     */
+    public Bitmap getBitmap(@BitmapKey String key) {
+        Bitmap bmp = null;
+        try {
+            bmp = mBundle.getParcelable(key);
+        } catch (Exception e) {
+            // ignore, value was not a bitmap
+            Log.w(TAG, "Failed to retrieve a key as Bitmap.", e);
+        }
+        return bmp;
+    }
+
+    /**
+     * Gets the width/height limit (in pixels) for the bitmaps when this metadata was created.
+     * This method always returns a positive value.
+     * <p>
+     * If it returns {@link Integer#MAX_VALUE}, then no scaling down was applied to the bitmaps
+     * when this metadata was created.
+     * <p>
+     * If it returns another positive value, then all the bitmaps in this metadata has width/height
+     * not greater than this limit. Bitmaps may have been scaled down according to the limit.
+     * <p>
+     *
+     * @see Builder#setBitmapDimensionLimit(int)
+     */
+    public @IntRange(from = 1) int getBitmapDimensionLimit() {
+        return mBitmapDimensionLimit;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeBundle(mBundle);
+        dest.writeInt(mBitmapDimensionLimit);
+    }
+
+    /**
+     * Returns the number of fields in this metadata.
+     *
+     * @return The number of fields in the metadata.
+     */
+    public int size() {
+        return mBundle.size();
+    }
+
+    /**
+     * Returns a Set containing the Strings used as keys in this metadata.
+     *
+     * @return a Set of String keys
+     */
+    public Set<String> keySet() {
+        return mBundle.keySet();
+    }
+
+    /**
+     * Returns a simple description of this metadata for display purposes.
+     *
+     * @return A simple description of this metadata.
+     */
+    public @NonNull MediaDescription getDescription() {
+        if (mDescription != null) {
+            return mDescription;
+        }
+
+        String mediaId = getString(METADATA_KEY_MEDIA_ID);
+
+        CharSequence[] text = new CharSequence[3];
+        Bitmap icon = null;
+        Uri iconUri = null;
+
+        // First handle the case where display data is set already
+        CharSequence displayText = getText(METADATA_KEY_DISPLAY_TITLE);
+        if (!TextUtils.isEmpty(displayText)) {
+            // If they have a display title use only display data, otherwise use
+            // our best bets
+            text[0] = displayText;
+            text[1] = getText(METADATA_KEY_DISPLAY_SUBTITLE);
+            text[2] = getText(METADATA_KEY_DISPLAY_DESCRIPTION);
+        } else {
+            // Use whatever fields we can
+            int textIndex = 0;
+            int keyIndex = 0;
+            while (textIndex < text.length && keyIndex < PREFERRED_DESCRIPTION_ORDER.length) {
+                CharSequence next = getText(PREFERRED_DESCRIPTION_ORDER[keyIndex++]);
+                if (!TextUtils.isEmpty(next)) {
+                    // Fill in the next empty bit of text
+                    text[textIndex++] = next;
+                }
+            }
+        }
+
+        // Get the best art bitmap we can find
+        for (int i = 0; i < PREFERRED_BITMAP_ORDER.length; i++) {
+            Bitmap next = getBitmap(PREFERRED_BITMAP_ORDER[i]);
+            if (next != null) {
+                icon = next;
+                break;
+            }
+        }
+
+        // Get the best Uri we can find
+        for (int i = 0; i < PREFERRED_URI_ORDER.length; i++) {
+            String next = getString(PREFERRED_URI_ORDER[i]);
+            if (!TextUtils.isEmpty(next)) {
+                iconUri = Uri.parse(next);
+                break;
+            }
+        }
+
+        Uri mediaUri = null;
+        String mediaUriStr = getString(METADATA_KEY_MEDIA_URI);
+        if (!TextUtils.isEmpty(mediaUriStr)) {
+            mediaUri = Uri.parse(mediaUriStr);
+        }
+
+        MediaDescription.Builder bob = new MediaDescription.Builder();
+        bob.setMediaId(mediaId);
+        bob.setTitle(text[0]);
+        bob.setSubtitle(text[1]);
+        bob.setDescription(text[2]);
+        bob.setIconBitmap(icon);
+        bob.setIconUri(iconUri);
+        bob.setMediaUri(mediaUri);
+        if (mBundle.containsKey(METADATA_KEY_BT_FOLDER_TYPE)) {
+            Bundle bundle = new Bundle();
+            bundle.putLong(MediaDescription.EXTRA_BT_FOLDER_TYPE,
+                    getLong(METADATA_KEY_BT_FOLDER_TYPE));
+            bob.setExtras(bundle);
+        }
+        mDescription = bob.build();
+
+        return mDescription;
+    }
+
+    /**
+     * Helper for getting the String key used by {@link MediaMetadata} from the
+     * integer key that {@link MediaMetadataEditor} uses.
+     *
+     * @param editorKey The key used by the editor
+     * @return The key used by this class or null if no mapping exists
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public static String getKeyFromMetadataEditorKey(int editorKey) {
+        return EDITOR_KEY_MAPPING.get(editorKey, null);
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<MediaMetadata> CREATOR =
+            new Parcelable.Creator<MediaMetadata>() {
+                @Override
+                public MediaMetadata createFromParcel(Parcel in) {
+                    return new MediaMetadata(in);
+                }
+
+                @Override
+                public MediaMetadata[] newArray(int size) {
+                    return new MediaMetadata[size];
+                }
+            };
+
+    /**
+     * Compares the contents of this object to another MediaMetadata object. It
+     * does not compare Bitmaps and Ratings as the media player can choose to
+     * forgo these fields depending on how you retrieve the MediaMetadata.
+     *
+     * @param o The Metadata object to compare this object against
+     * @return Whether or not the two objects have matching fields (excluding
+     * Bitmaps and Ratings)
+     */
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        if (!(o instanceof MediaMetadata)) {
+            return false;
+        }
+
+        final MediaMetadata m = (MediaMetadata) o;
+
+        for (int i = 0; i < METADATA_KEYS_TYPE.size(); i++) {
+            String key = METADATA_KEYS_TYPE.keyAt(i);
+            switch (METADATA_KEYS_TYPE.valueAt(i)) {
+                case METADATA_TYPE_TEXT:
+                    if (!Objects.equals(getString(key), m.getString(key))) {
+                        return false;
+                    }
+                    break;
+                case METADATA_TYPE_LONG:
+                    if (getLong(key) != m.getLong(key)) {
+                        return false;
+                    }
+                    break;
+                default:
+                    // Ignore ratings and bitmaps when comparing
+                    break;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int hashCode = 17;
+
+        for (int i = 0; i < METADATA_KEYS_TYPE.size(); i++) {
+            String key = METADATA_KEYS_TYPE.keyAt(i);
+            switch (METADATA_KEYS_TYPE.valueAt(i)) {
+                case METADATA_TYPE_TEXT:
+                    hashCode = 31 * hashCode + Objects.hash(getString(key));
+                    break;
+                case METADATA_TYPE_LONG:
+                    hashCode = 31 * hashCode + Long.hashCode(getLong(key));
+                    break;
+                default:
+                    // Ignore ratings and bitmaps when comparing
+                    break;
+            }
+        }
+
+        return hashCode;
+    }
+
+    /**
+     * Use to build MediaMetadata objects. The system defined metadata keys must
+     * use the appropriate data type.
+     */
+    public static final class Builder {
+        private final Bundle mBundle;
+        private int mBitmapDimensionLimit = Integer.MAX_VALUE;
+
+        /**
+         * Create an empty Builder. Any field that should be included in the
+         * {@link MediaMetadata} must be added.
+         */
+        public Builder() {
+            mBundle = new Bundle();
+        }
+
+        /**
+         * Create a Builder using a {@link MediaMetadata} instance to set the
+         * initial values. All fields in the source metadata will be included in
+         * the new metadata. Fields can be overwritten by adding the same key.
+         *
+         * @param source
+         */
+        public Builder(MediaMetadata source) {
+            mBundle = new Bundle(source.mBundle);
+            mBitmapDimensionLimit = source.mBitmapDimensionLimit;
+        }
+
+        /**
+         * Put a CharSequence value into the metadata. Custom keys may be used,
+         * but if the METADATA_KEYs defined in this class are used they may only
+         * be one of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_TITLE}</li>
+         * <li>{@link #METADATA_KEY_ARTIST}</li>
+         * <li>{@link #METADATA_KEY_ALBUM}</li>
+         * <li>{@link #METADATA_KEY_AUTHOR}</li>
+         * <li>{@link #METADATA_KEY_WRITER}</li>
+         * <li>{@link #METADATA_KEY_COMPOSER}</li>
+         * <li>{@link #METADATA_KEY_DATE}</li>
+         * <li>{@link #METADATA_KEY_GENRE}</li>
+         * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li>
+         * <li>{@link #METADATA_KEY_ART_URI}</li>
+         * <li>{@link #METADATA_KEY_ALBUM_ART_URI}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_TITLE}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_SUBTITLE}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_DESCRIPTION}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_ICON_URI}</li>
+         * </ul>
+         *
+         * @param key The key for referencing this value
+         * @param value The CharSequence value to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putText(@TextKey String key, CharSequence value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a CharSequence");
+                }
+            }
+            mBundle.putCharSequence(key, value);
+            return this;
+        }
+
+        /**
+         * Put a String value into the metadata. Custom keys may be used, but if
+         * the METADATA_KEYs defined in this class are used they may only be one
+         * of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_TITLE}</li>
+         * <li>{@link #METADATA_KEY_ARTIST}</li>
+         * <li>{@link #METADATA_KEY_ALBUM}</li>
+         * <li>{@link #METADATA_KEY_AUTHOR}</li>
+         * <li>{@link #METADATA_KEY_WRITER}</li>
+         * <li>{@link #METADATA_KEY_COMPOSER}</li>
+         * <li>{@link #METADATA_KEY_DATE}</li>
+         * <li>{@link #METADATA_KEY_GENRE}</li>
+         * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li>
+         * <li>{@link #METADATA_KEY_ART_URI}</li>
+         * <li>{@link #METADATA_KEY_ALBUM_ART_URI}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_TITLE}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_SUBTITLE}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_DESCRIPTION}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_ICON_URI}</li>
+         * </ul>
+         * <p>
+         * Uris for artwork should use the content:// style and support
+         * {@link ContentResolver#EXTRA_SIZE} for retrieving scaled artwork
+         * through {@link ContentResolver#openTypedAssetFileDescriptor(Uri,
+         * String, Bundle)}.
+         *
+         * @param key The key for referencing this value
+         * @param value The String value to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putString(@TextKey String key, String value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_TEXT) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a String");
+                }
+            }
+            mBundle.putCharSequence(key, value);
+            return this;
+        }
+
+        /**
+         * Put a long value into the metadata. Custom keys may be used, but if
+         * the METADATA_KEYs defined in this class are used they may only be one
+         * of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_DURATION}</li>
+         * <li>{@link #METADATA_KEY_TRACK_NUMBER}</li>
+         * <li>{@link #METADATA_KEY_NUM_TRACKS}</li>
+         * <li>{@link #METADATA_KEY_DISC_NUMBER}</li>
+         * <li>{@link #METADATA_KEY_YEAR}</li>
+         * </ul>
+         *
+         * @param key The key for referencing this value
+         * @param value The long value to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putLong(@LongKey String key, long value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_LONG) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a long");
+                }
+            }
+            mBundle.putLong(key, value);
+            return this;
+        }
+
+        /**
+         * Put a {@link Rating} into the metadata. Custom keys may be used, but
+         * if the METADATA_KEYs defined in this class are used they may only be
+         * one of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_RATING}</li>
+         * <li>{@link #METADATA_KEY_USER_RATING}</li>
+         * </ul>
+         *
+         * @param key The key for referencing this value
+         * @param value The Rating value to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putRating(@RatingKey String key, Rating value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_RATING) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a Rating");
+                }
+            }
+            mBundle.putParcelable(key, value);
+            return this;
+        }
+
+        /**
+         * Put a {@link Bitmap} into the metadata. Custom keys may be used, but
+         * if the METADATA_KEYs defined in this class are used they may only be
+         * one of the following:
+         * <ul>
+         * <li>{@link #METADATA_KEY_ART}</li>
+         * <li>{@link #METADATA_KEY_ALBUM_ART}</li>
+         * <li>{@link #METADATA_KEY_DISPLAY_ICON}</li>
+         * </ul>
+         * <p>
+         * Large bitmaps may be scaled down by the system with
+         * {@link Builder#setBitmapDimensionLimit(int)} when {@link MediaSession#setMetadata}
+         * is called. To pass full resolution images {@link Uri Uris} should be used with
+         * {@link #putString}.
+         *
+         * @param key The key for referencing this value
+         * @param value The Bitmap to store
+         * @return The Builder to allow chaining
+         */
+        public Builder putBitmap(@BitmapKey String key, Bitmap value) {
+            if (METADATA_KEYS_TYPE.containsKey(key)) {
+                if (METADATA_KEYS_TYPE.get(key) != METADATA_TYPE_BITMAP) {
+                    throw new IllegalArgumentException("The " + key
+                            + " key cannot be used to put a Bitmap");
+                }
+            }
+            mBundle.putParcelable(key, value);
+            return this;
+        }
+
+        /**
+         * Sets the maximum width/height (in pixels) for the bitmaps in the metadata.
+         * Bitmaps will be replaced with scaled down copies if their width (or height) is
+         * larger than {@code bitmapDimensionLimit}.
+         * <p>
+         * In order to unset the limit, pass {@link Integer#MAX_VALUE} as
+         * {@code bitmapDimensionLimit}.
+         *
+         * @param bitmapDimensionLimit The maximum width/height (in pixels) for bitmaps
+         *                             contained in the metadata. Non-positive values are ignored.
+         *                             Pass {@link Integer#MAX_VALUE} to unset the limit.
+         */
+        @NonNull
+        public Builder setBitmapDimensionLimit(@IntRange(from = 1) int bitmapDimensionLimit) {
+            if (bitmapDimensionLimit > 0) {
+                mBitmapDimensionLimit = bitmapDimensionLimit;
+            } else {
+                Log.w(TAG, "setBitmapDimensionLimit(): Ignoring non-positive bitmapDimensionLimit: "
+                        + bitmapDimensionLimit);
+            }
+            return this;
+        }
+
+        /**
+         * Creates a {@link MediaMetadata} instance with the specified fields.
+         *
+         * @return The new MediaMetadata instance
+         */
+        public MediaMetadata build() {
+            if (mBitmapDimensionLimit != Integer.MAX_VALUE) {
+                for (String key : mBundle.keySet()) {
+                    Object value = mBundle.get(key);
+                    if (value instanceof Bitmap) {
+                        Bitmap bmp = (Bitmap) value;
+                        if (bmp.getHeight() > mBitmapDimensionLimit
+                                || bmp.getWidth() > mBitmapDimensionLimit) {
+                            putBitmap(key, scaleBitmap(bmp, mBitmapDimensionLimit));
+                        }
+                    }
+                }
+            }
+            return new MediaMetadata(mBundle, mBitmapDimensionLimit);
+        }
+
+        private Bitmap scaleBitmap(Bitmap bmp, int maxDimension) {
+            float maxDimensionF = maxDimension;
+            float widthScale = maxDimensionF / bmp.getWidth();
+            float heightScale = maxDimensionF / bmp.getHeight();
+            float scale = Math.min(widthScale, heightScale);
+            int height = (int) (bmp.getHeight() * scale);
+            int width = (int) (bmp.getWidth() * scale);
+            return Bitmap.createScaledBitmap(bmp, width, height, true);
+        }
+    }
+}
diff --git a/android/media/MediaMetadataEditor.java b/android/media/MediaMetadataEditor.java
new file mode 100644
index 0000000..877c872
--- /dev/null
+++ b/android/media/MediaMetadataEditor.java
@@ -0,0 +1,470 @@
+/*
+ * Copyright (C) 2013 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.graphics.Bitmap;
+import android.media.session.MediaSession;
+import android.os.Bundle;
+import android.os.Parcelable;
+import android.util.Log;
+import android.util.SparseIntArray;
+
+/**
+ * An abstract class for editing and storing metadata that can be published by
+ * {@link RemoteControlClient}. See the {@link RemoteControlClient#editMetadata(boolean)}
+ * method to instantiate a {@link RemoteControlClient.MetadataEditor} object.
+ *
+ * @deprecated Use {@link MediaMetadata} instead together with {@link MediaSession}.
+ */
+@Deprecated public abstract class MediaMetadataEditor {
+
+    private final static String TAG = "MediaMetadataEditor";
+    /**
+     * @hide
+     */
+    protected MediaMetadataEditor() {
+    }
+
+    // Public keys for metadata used by RemoteControlClient and RemoteController.
+    // Note that these keys are defined here, and not in MediaMetadataRetriever
+    // because they are not supported by the MediaMetadataRetriever features.
+    /**
+     * The metadata key for the content artwork / album art.
+     */
+    public final static int BITMAP_KEY_ARTWORK =
+            RemoteControlClient.MetadataEditor.BITMAP_KEY_ARTWORK;
+
+    /**
+     * The metadata key for the content's average rating, not the user's rating.
+     * The value associated with this key is a {@link Rating} instance.
+     * @see #RATING_KEY_BY_USER
+     */
+    public final static int RATING_KEY_BY_OTHERS = 101;
+
+    /**
+     * The metadata key for the content's user rating.
+     * The value associated with this key is a {@link Rating} instance.
+     * This key can be flagged as "editable" (with {@link #addEditableKey(int)}) to enable
+     * receiving user rating values through the
+     * {@link android.media.RemoteControlClient.OnMetadataUpdateListener} interface.
+     */
+    public final static int RATING_KEY_BY_USER = 0x10000001;
+
+    /**
+     * @hide
+     * Editable key mask
+     */
+    public final static int KEY_EDITABLE_MASK = 0x1FFFFFFF;
+
+
+    /**
+     * Applies all of the metadata changes that have been set since the MediaMetadataEditor instance
+     * was created or since {@link #clear()} was called. Subclasses should synchronize on
+     * {@code this} for thread safety.
+     */
+    public abstract void apply();
+
+
+    /**
+     * @hide
+     * Mask of editable keys.
+     */
+    protected long mEditableKeys;
+
+    /**
+     * @hide
+     */
+    protected boolean mMetadataChanged = false;
+
+    /**
+     * @hide
+     */
+    protected boolean mApplied = false;
+
+    /**
+     * @hide
+     */
+    protected boolean mArtworkChanged = false;
+
+    /**
+     * @hide
+     */
+    protected Bitmap mEditorArtwork;
+
+    /**
+     * @hide
+     */
+    protected Bundle mEditorMetadata;
+
+    /**
+     * @hide
+     */
+    protected MediaMetadata.Builder mMetadataBuilder;
+
+    /**
+     * Clears all the pending metadata changes set since the MediaMetadataEditor instance was
+     * created or since this method was last called.
+     * Note that clearing the metadata doesn't reset the editable keys
+     * (use {@link #removeEditableKeys()} instead).
+     */
+    public synchronized void clear() {
+        if (mApplied) {
+            Log.e(TAG, "Can't clear a previously applied MediaMetadataEditor");
+            return;
+        }
+        mEditorMetadata.clear();
+        mEditorArtwork = null;
+        mMetadataBuilder = new MediaMetadata.Builder();
+    }
+
+    /**
+     * Flags the given key as being editable.
+     * This should only be used by metadata publishers, such as {@link RemoteControlClient},
+     * which will declare the metadata field as eligible to be updated, with new values
+     * received through the {@link RemoteControlClient.OnMetadataUpdateListener} interface.
+     * @param key the type of metadata that can be edited. The supported key is
+     *     {@link #RATING_KEY_BY_USER}.
+     */
+    public synchronized void addEditableKey(int key) {
+        if (mApplied) {
+            Log.e(TAG, "Can't change editable keys of a previously applied MetadataEditor");
+            return;
+        }
+        // only one editable key at the moment, so we're not wasting memory on an array
+        // of editable keys to check the validity of the key, just hardcode the supported key.
+        if (key == RATING_KEY_BY_USER) {
+            mEditableKeys |= (KEY_EDITABLE_MASK & key);
+            mMetadataChanged = true;
+        } else {
+            Log.e(TAG, "Metadata key " + key + " cannot be edited");
+        }
+    }
+
+    /**
+     * Causes all metadata fields to be read-only.
+     */
+    public synchronized void removeEditableKeys() {
+        if (mApplied) {
+            Log.e(TAG, "Can't remove all editable keys of a previously applied MetadataEditor");
+            return;
+        }
+        if (mEditableKeys != 0) {
+            mEditableKeys = 0;
+            mMetadataChanged = true;
+        }
+    }
+
+    /**
+     * Retrieves the keys flagged as editable.
+     * @return null if there are no editable keys, or an array containing the keys.
+     */
+    public synchronized int[] getEditableKeys() {
+        // only one editable key supported here
+        if (mEditableKeys == RATING_KEY_BY_USER) {
+            int[] keys = { RATING_KEY_BY_USER };
+            return keys;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Adds textual information.
+     * Note that none of the information added after {@link #apply()} has been called,
+     * will be available to consumers of metadata stored by the MediaMetadataEditor.
+     * @param key The identifier of a the metadata field to set. Valid values are
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM},
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST},
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ARTIST},
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_AUTHOR},
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPILATION},
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPOSER},
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE},
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE},
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER}.
+     * @param value The text for the given key, or {@code null} to signify there is no valid
+     *      information for the field.
+     * @return Returns a reference to the same MediaMetadataEditor object, so you can chain put
+     *      calls together.
+     */
+    public synchronized MediaMetadataEditor putString(int key, String value)
+            throws IllegalArgumentException {
+        if (mApplied) {
+            Log.e(TAG, "Can't edit a previously applied MediaMetadataEditor");
+            return this;
+        }
+        if (METADATA_KEYS_TYPE.get(key, METADATA_TYPE_INVALID) != METADATA_TYPE_STRING) {
+            throw(new IllegalArgumentException("Invalid type 'String' for key "+ key));
+        }
+        mEditorMetadata.putString(String.valueOf(key), value);
+        mMetadataChanged = true;
+        return this;
+    }
+
+    /**
+     * Adds numerical information.
+     * Note that none of the information added after {@link #apply()} has been called
+     * will be available to consumers of metadata stored by the MediaMetadataEditor.
+     * @param key the identifier of a the metadata field to set. Valid values are
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER},
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER},
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} (with a value
+     *      expressed in milliseconds),
+     *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}.
+     * @param value The long value for the given key
+     * @return Returns a reference to the same MediaMetadataEditor object, so you can chain put
+     *      calls together.
+     * @throws IllegalArgumentException
+     */
+    public synchronized MediaMetadataEditor putLong(int key, long value)
+            throws IllegalArgumentException {
+        if (mApplied) {
+            Log.e(TAG, "Can't edit a previously applied MediaMetadataEditor");
+            return this;
+        }
+        if (METADATA_KEYS_TYPE.get(key, METADATA_TYPE_INVALID) != METADATA_TYPE_LONG) {
+            throw(new IllegalArgumentException("Invalid type 'long' for key "+ key));
+        }
+        mEditorMetadata.putLong(String.valueOf(key), value);
+        mMetadataChanged = true;
+        return this;
+    }
+
+    /**
+     * Adds image.
+     * @param key the identifier of the bitmap to set. The only valid value is
+     *      {@link #BITMAP_KEY_ARTWORK}
+     * @param bitmap The bitmap for the artwork, or null if there isn't any.
+     * @return Returns a reference to the same MediaMetadataEditor object, so you can chain put
+     *      calls together.
+     * @throws IllegalArgumentException
+     * @see android.graphics.Bitmap
+     */
+    public synchronized MediaMetadataEditor putBitmap(int key, Bitmap bitmap)
+            throws IllegalArgumentException {
+        if (mApplied) {
+            Log.e(TAG, "Can't edit a previously applied MediaMetadataEditor");
+            return this;
+        }
+        if (key != BITMAP_KEY_ARTWORK) {
+            throw(new IllegalArgumentException("Invalid type 'Bitmap' for key "+ key));
+        }
+        mEditorArtwork = bitmap;
+        mArtworkChanged = true;
+        return this;
+    }
+
+    /**
+     * Adds information stored as an instance.
+     * Note that none of the information added after {@link #apply()} has been called
+     * will be available to consumers of metadata stored by the MediaMetadataEditor.
+     * @param key the identifier of a the metadata field to set. Valid keys for a:
+     *     <ul>
+     *     <li>{@link Bitmap} object are {@link #BITMAP_KEY_ARTWORK},</li>
+     *     <li>{@link String} object are the same as for {@link #putString(int, String)}</li>
+     *     <li>{@link Long} object are the same as for {@link #putLong(int, long)}</li>
+     *     <li>{@link Rating} object are {@link #RATING_KEY_BY_OTHERS}
+     *         and {@link #RATING_KEY_BY_USER}.</li>
+     *     </ul>
+     * @param value the metadata to add.
+     * @return Returns a reference to the same MediaMetadataEditor object, so you can chain put
+     *      calls together.
+     * @throws IllegalArgumentException
+     */
+    public synchronized MediaMetadataEditor putObject(int key, Object value)
+            throws IllegalArgumentException {
+        if (mApplied) {
+            Log.e(TAG, "Can't edit a previously applied MediaMetadataEditor");
+            return this;
+        }
+        switch(METADATA_KEYS_TYPE.get(key, METADATA_TYPE_INVALID)) {
+            case METADATA_TYPE_LONG:
+                if (value instanceof Long) {
+                    return putLong(key, ((Long)value).longValue());
+                } else {
+                    throw(new IllegalArgumentException("Not a non-null Long for key "+ key));
+                }
+            case METADATA_TYPE_STRING:
+                if ((value == null) || (value instanceof String)) {
+                    return putString(key, (String) value);
+                } else {
+                    throw(new IllegalArgumentException("Not a String for key "+ key));
+                }
+            case METADATA_TYPE_RATING:
+                mEditorMetadata.putParcelable(String.valueOf(key), (Parcelable)value);
+                mMetadataChanged = true;
+                break;
+            case METADATA_TYPE_BITMAP:
+                if ((value == null) || (value instanceof Bitmap))  {
+                    return putBitmap(key, (Bitmap) value);
+                } else {
+                    throw(new IllegalArgumentException("Not a Bitmap for key "+ key));
+                }
+            default:
+                throw(new IllegalArgumentException("Invalid key "+ key));
+        }
+        return this;
+    }
+
+
+    /**
+     * Returns the long value for the key.
+     * @param key one of the keys supported in {@link #putLong(int, long)}
+     * @param defaultValue the value returned if the key is not present
+     * @return the long value for the key, or the supplied default value if the key is not present
+     * @throws IllegalArgumentException
+     */
+    public synchronized long getLong(int key, long defaultValue)
+            throws IllegalArgumentException {
+        if (METADATA_KEYS_TYPE.get(key, METADATA_TYPE_INVALID) != METADATA_TYPE_LONG) {
+            throw(new IllegalArgumentException("Invalid type 'long' for key "+ key));
+        }
+        return mEditorMetadata.getLong(String.valueOf(key), defaultValue);
+    }
+
+    /**
+     * Returns the {@link String} value for the key.
+     * @param key one of the keys supported in {@link #putString(int, String)}
+     * @param defaultValue the value returned if the key is not present
+     * @return the {@link String} value for the key, or the supplied default value if the key is
+     *     not present
+     * @throws IllegalArgumentException
+     */
+    public synchronized String getString(int key, String defaultValue)
+            throws IllegalArgumentException {
+        if (METADATA_KEYS_TYPE.get(key, METADATA_TYPE_INVALID) != METADATA_TYPE_STRING) {
+            throw(new IllegalArgumentException("Invalid type 'String' for key "+ key));
+        }
+        return mEditorMetadata.getString(String.valueOf(key), defaultValue);
+    }
+
+    /**
+     * Returns the {@link Bitmap} value for the key.
+     * @param key the {@link #BITMAP_KEY_ARTWORK} key
+     * @param defaultValue the value returned if the key is not present
+     * @return the {@link Bitmap} value for the key, or the supplied default value if the key is
+     *     not present
+     * @throws IllegalArgumentException
+     */
+    public synchronized Bitmap getBitmap(int key, Bitmap defaultValue)
+            throws IllegalArgumentException {
+        if (key != BITMAP_KEY_ARTWORK) {
+            throw(new IllegalArgumentException("Invalid type 'Bitmap' for key "+ key));
+        }
+        return (mEditorArtwork != null ? mEditorArtwork : defaultValue);
+    }
+
+    /**
+     * Returns an object representation of the value for the key
+     * @param key one of the keys supported in {@link #putObject(int, Object)}
+     * @param defaultValue the value returned if the key is not present
+     * @return the object for the key, as a {@link Long}, {@link Bitmap}, {@link String}, or
+     *     {@link Rating} depending on the key value, or the supplied default value if the key is
+     *     not present
+     * @throws IllegalArgumentException
+     */
+    public synchronized Object getObject(int key, Object defaultValue)
+            throws IllegalArgumentException {
+        switch (METADATA_KEYS_TYPE.get(key, METADATA_TYPE_INVALID)) {
+            case METADATA_TYPE_LONG:
+                if (mEditorMetadata.containsKey(String.valueOf(key))) {
+                    return mEditorMetadata.getLong(String.valueOf(key));
+                } else {
+                    return defaultValue;
+                }
+            case METADATA_TYPE_STRING:
+                if (mEditorMetadata.containsKey(String.valueOf(key))) {
+                    return mEditorMetadata.getString(String.valueOf(key));
+                } else {
+                    return defaultValue;
+                }
+            case METADATA_TYPE_RATING:
+                if (mEditorMetadata.containsKey(String.valueOf(key))) {
+                    return mEditorMetadata.getParcelable(String.valueOf(key));
+                } else {
+                    return defaultValue;
+                }
+            case METADATA_TYPE_BITMAP:
+                // only one key for Bitmap supported, value is not stored in mEditorMetadata Bundle
+                if (key == BITMAP_KEY_ARTWORK) {
+                    return (mEditorArtwork != null ? mEditorArtwork : defaultValue);
+                } // else: fall through to invalid key handling
+            default:
+                throw(new IllegalArgumentException("Invalid key "+ key));
+        }
+    }
+
+
+    /**
+     * @hide
+     */
+    protected static final int METADATA_TYPE_INVALID = -1;
+    /**
+     * @hide
+     */
+    protected static final int METADATA_TYPE_LONG = 0;
+
+    /**
+     * @hide
+     */
+    protected static final int METADATA_TYPE_STRING = 1;
+
+    /**
+     * @hide
+     */
+    protected static final int METADATA_TYPE_BITMAP = 2;
+
+    /**
+     * @hide
+     */
+    protected static final int METADATA_TYPE_RATING = 3;
+
+    /**
+     * @hide
+     */
+    protected static final SparseIntArray METADATA_KEYS_TYPE;
+
+    static {
+        METADATA_KEYS_TYPE = new SparseIntArray(17);
+        // NOTE: if adding to the list below, make sure you increment the array initialization size
+        // keys with long values
+        METADATA_KEYS_TYPE.put(
+                MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(MediaMetadataRetriever.METADATA_KEY_DURATION, METADATA_TYPE_LONG);
+        METADATA_KEYS_TYPE.put(MediaMetadataRetriever.METADATA_KEY_YEAR, METADATA_TYPE_LONG);
+        // keys with String values
+        METADATA_KEYS_TYPE.put(MediaMetadataRetriever.METADATA_KEY_ALBUM, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(
+                MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(MediaMetadataRetriever.METADATA_KEY_TITLE, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(MediaMetadataRetriever.METADATA_KEY_ARTIST, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(MediaMetadataRetriever.METADATA_KEY_AUTHOR, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(
+                MediaMetadataRetriever.METADATA_KEY_COMPILATION, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(MediaMetadataRetriever.METADATA_KEY_COMPOSER, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(MediaMetadataRetriever.METADATA_KEY_DATE, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(MediaMetadataRetriever.METADATA_KEY_GENRE, METADATA_TYPE_STRING);
+        METADATA_KEYS_TYPE.put(MediaMetadataRetriever.METADATA_KEY_WRITER, METADATA_TYPE_STRING);
+        // keys with Bitmap values
+        METADATA_KEYS_TYPE.put(BITMAP_KEY_ARTWORK, METADATA_TYPE_BITMAP);
+        // keys with Rating values
+        METADATA_KEYS_TYPE.put(RATING_KEY_BY_OTHERS, METADATA_TYPE_RATING);
+        METADATA_KEYS_TYPE.put(RATING_KEY_BY_USER, METADATA_TYPE_RATING);
+    }
+}
diff --git a/android/media/MediaMetadataRetriever.java b/android/media/MediaMetadataRetriever.java
new file mode 100644
index 0000000..a15529e
--- /dev/null
+++ b/android/media/MediaMetadataRetriever.java
@@ -0,0 +1,1395 @@
+/*
+ * Copyright (C) 2008 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.annotation.SystemApi.Client.MODULE_LIBRARIES;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.FileUtils;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.SystemProperties;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * MediaMetadataRetriever class provides a unified interface for retrieving
+ * frame and meta data from an input media file.
+ */
+public class MediaMetadataRetriever implements AutoCloseable {
+    private static final String TAG = "MediaMetadataRetriever";
+
+    // borrowed from ExoPlayer
+    private static final String[] STANDARD_GENRES = new String[] {
+            // These are the official ID3v1 genres.
+            "Blues",
+            "Classic Rock",
+            "Country",
+            "Dance",
+            "Disco",
+            "Funk",
+            "Grunge",
+            "Hip-Hop",
+            "Jazz",
+            "Metal",
+            "New Age",
+            "Oldies",
+            "Other",
+            "Pop",
+            "R&B",
+            "Rap",
+            "Reggae",
+            "Rock",
+            "Techno",
+            "Industrial",
+            "Alternative",
+            "Ska",
+            "Death Metal",
+            "Pranks",
+            "Soundtrack",
+            "Euro-Techno",
+            "Ambient",
+            "Trip-Hop",
+            "Vocal",
+            "Jazz+Funk",
+            "Fusion",
+            "Trance",
+            "Classical",
+            "Instrumental",
+            "Acid",
+            "House",
+            "Game",
+            "Sound Clip",
+            "Gospel",
+            "Noise",
+            "AlternRock",
+            "Bass",
+            "Soul",
+            "Punk",
+            "Space",
+            "Meditative",
+            "Instrumental Pop",
+            "Instrumental Rock",
+            "Ethnic",
+            "Gothic",
+            "Darkwave",
+            "Techno-Industrial",
+            "Electronic",
+            "Pop-Folk",
+            "Eurodance",
+            "Dream",
+            "Southern Rock",
+            "Comedy",
+            "Cult",
+            "Gangsta",
+            "Top 40",
+            "Christian Rap",
+            "Pop/Funk",
+            "Jungle",
+            "Native American",
+            "Cabaret",
+            "New Wave",
+            "Psychadelic",
+            "Rave",
+            "Showtunes",
+            "Trailer",
+            "Lo-Fi",
+            "Tribal",
+            "Acid Punk",
+            "Acid Jazz",
+            "Polka",
+            "Retro",
+            "Musical",
+            "Rock & Roll",
+            "Hard Rock",
+            // These were made up by the authors of Winamp and later added to the ID3 spec.
+            "Folk",
+            "Folk-Rock",
+            "National Folk",
+            "Swing",
+            "Fast Fusion",
+            "Bebob",
+            "Latin",
+            "Revival",
+            "Celtic",
+            "Bluegrass",
+            "Avantgarde",
+            "Gothic Rock",
+            "Progressive Rock",
+            "Psychedelic Rock",
+            "Symphonic Rock",
+            "Slow Rock",
+            "Big Band",
+            "Chorus",
+            "Easy Listening",
+            "Acoustic",
+            "Humour",
+            "Speech",
+            "Chanson",
+            "Opera",
+            "Chamber Music",
+            "Sonata",
+            "Symphony",
+            "Booty Bass",
+            "Primus",
+            "Porn Groove",
+            "Satire",
+            "Slow Jam",
+            "Club",
+            "Tango",
+            "Samba",
+            "Folklore",
+            "Ballad",
+            "Power Ballad",
+            "Rhythmic Soul",
+            "Freestyle",
+            "Duet",
+            "Punk Rock",
+            "Drum Solo",
+            "A capella",
+            "Euro-House",
+            "Dance Hall",
+            // These were made up by the authors of Winamp but have not been added to the ID3 spec.
+            "Goa",
+            "Drum & Bass",
+            "Club-House",
+            "Hardcore",
+            "Terror",
+            "Indie",
+            "BritPop",
+            "Afro-Punk",
+            "Polsk Punk",
+            "Beat",
+            "Christian Gangsta Rap",
+            "Heavy Metal",
+            "Black Metal",
+            "Crossover",
+            "Contemporary Christian",
+            "Christian Rock",
+            "Merengue",
+            "Salsa",
+            "Thrash Metal",
+            "Anime",
+            "Jpop",
+            "Synthpop"
+    };
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    // The field below is accessed by native methods
+    @SuppressWarnings("unused")
+    private long mNativeContext;
+
+    private static final int EMBEDDED_PICTURE_TYPE_ANY = 0xFFFF;
+
+    public MediaMetadataRetriever() {
+        native_setup();
+    }
+
+    /**
+     * Sets the data source (file pathname) to use. Call this
+     * method before the rest of the methods in this class. This method may be
+     * time-consuming.
+     *
+     * @param path The path, or the URI (doesn't support streaming source currently)
+     * of the input media file.
+     * @throws IllegalArgumentException If the path is invalid.
+     */
+    public void setDataSource(String path) throws IllegalArgumentException {
+        if (path == null) {
+            throw new IllegalArgumentException("null path");
+        }
+
+        final Uri uri = Uri.parse(path);
+        final String scheme = uri.getScheme();
+        if ("file".equals(scheme)) {
+            path = uri.getPath();
+        } else if (scheme != null) {
+            setDataSource(path, new HashMap<String, String>());
+            return;
+        }
+
+        try (FileInputStream is = new FileInputStream(path)) {
+            FileDescriptor fd = is.getFD();
+            setDataSource(fd, 0, 0x7ffffffffffffffL);
+        } catch (FileNotFoundException fileEx) {
+            throw new IllegalArgumentException(path + " does not exist");
+        } catch (IOException ioEx) {
+            throw new IllegalArgumentException("couldn't open " + path);
+        }
+    }
+
+    /**
+     * Sets the data source (URI) to use. Call this
+     * method before the rest of the methods in this class. This method may be
+     * time-consuming.
+     *
+     * @param uri The URI of the input media.
+     * @param headers the headers to be sent together with the request for the data
+     * @throws IllegalArgumentException If the URI is invalid.
+     */
+    public void setDataSource(String uri,  Map<String, String> headers)
+            throws IllegalArgumentException {
+        int i = 0;
+        String[] keys = new String[headers.size()];
+        String[] values = new String[headers.size()];
+        for (Map.Entry<String, String> entry: headers.entrySet()) {
+            keys[i] = entry.getKey();
+            values[i] = entry.getValue();
+            ++i;
+        }
+
+        _setDataSource(
+                MediaHTTPService.createHttpServiceBinderIfNecessary(uri),
+                uri,
+                keys,
+                values);
+    }
+
+    private native void _setDataSource(
+        IBinder httpServiceBinder, String uri, String[] keys, String[] values)
+        throws IllegalArgumentException;
+
+    /**
+     * Sets the data source (FileDescriptor) to use.  It is the caller's
+     * responsibility to close the file descriptor. It is safe to do so as soon
+     * as this call returns. Call this method before the rest of the methods in
+     * this class. This method may be time-consuming.
+     *
+     * @param fd the FileDescriptor for the file you want to play
+     * @param offset the offset into the file where the data to be played starts,
+     * in bytes. It must be non-negative
+     * @param length the length in bytes of the data to be played. It must be
+     * non-negative.
+     * @throws IllegalArgumentException if the arguments are invalid
+     */
+    public void setDataSource(FileDescriptor fd, long offset, long length)
+            throws IllegalArgumentException  {
+
+        try (ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd)) {
+            if (modernFd == null) {
+                _setDataSource(fd, offset, length);
+            } else {
+                _setDataSource(modernFd.getFileDescriptor(), offset, length);
+            }
+        } catch (IOException e) {
+            Log.w(TAG, "Ignoring IO error while setting data source", e);
+        }
+    }
+
+    private native void _setDataSource(FileDescriptor fd, long offset, long length)
+            throws IllegalArgumentException;
+
+    /**
+     * Sets the data source (FileDescriptor) to use. It is the caller's
+     * responsibility to close the file descriptor. It is safe to do so as soon
+     * as this call returns. Call this method before the rest of the methods in
+     * this class. This method may be time-consuming.
+     *
+     * @param fd the FileDescriptor for the file you want to play
+     * @throws IllegalArgumentException if the FileDescriptor is invalid
+     */
+    public void setDataSource(FileDescriptor fd)
+            throws IllegalArgumentException {
+        // intentionally less than LONG_MAX
+        setDataSource(fd, 0, 0x7ffffffffffffffL);
+    }
+
+    /**
+     * Sets the data source as a content Uri. Call this method before
+     * the rest of the methods in this class. This method may be time-consuming.
+     *
+     * @param context the Context to use when resolving the Uri
+     * @param uri the Content URI of the data you want to play
+     * @throws IllegalArgumentException if the Uri is invalid
+     * @throws SecurityException if the Uri cannot be used due to lack of
+     * permission.
+     */
+    public void setDataSource(Context context, Uri uri)
+        throws IllegalArgumentException, SecurityException {
+        if (uri == null) {
+            throw new IllegalArgumentException("null uri");
+        }
+
+        String scheme = uri.getScheme();
+        if(scheme == null || scheme.equals("file")) {
+            setDataSource(uri.getPath());
+            return;
+        }
+
+        AssetFileDescriptor fd = null;
+        try {
+            ContentResolver resolver = context.getContentResolver();
+            try {
+                boolean optimize =
+                        SystemProperties.getBoolean("fuse.sys.transcode_retriever_optimize", false);
+                Bundle opts = new Bundle();
+                opts.putBoolean("android.provider.extra.ACCEPT_ORIGINAL_MEDIA_FORMAT", true);
+                fd = optimize ? resolver.openTypedAssetFileDescriptor(uri, "*/*", opts)
+                        : resolver.openAssetFileDescriptor(uri, "r");
+            } catch(FileNotFoundException e) {
+                throw new IllegalArgumentException("could not access " + uri);
+            }
+            if (fd == null) {
+                throw new IllegalArgumentException("got null FileDescriptor for " + uri);
+            }
+            FileDescriptor descriptor = fd.getFileDescriptor();
+            if (!descriptor.valid()) {
+                throw new IllegalArgumentException("got invalid FileDescriptor for " + uri);
+            }
+            // Note: using getDeclaredLength so that our behavior is the same
+            // as previous versions when the content provider is returning
+            // a full file.
+            if (fd.getDeclaredLength() < 0) {
+                setDataSource(descriptor);
+            } else {
+                setDataSource(descriptor, fd.getStartOffset(), fd.getDeclaredLength());
+            }
+            return;
+        } catch (SecurityException ex) {
+        } finally {
+            try {
+                if (fd != null) {
+                    fd.close();
+                }
+            } catch(IOException ioEx) {
+            }
+        }
+        setDataSource(uri.toString());
+    }
+
+    /**
+     * Sets the data source (MediaDataSource) to use.
+     *
+     * @param dataSource the MediaDataSource for the media you want to play
+     */
+    public void setDataSource(MediaDataSource dataSource)
+            throws IllegalArgumentException {
+        _setDataSource(dataSource);
+    }
+
+    private native void _setDataSource(MediaDataSource dataSource)
+          throws IllegalArgumentException;
+
+    private native @Nullable String nativeExtractMetadata(int keyCode);
+
+    /**
+     * Call this method after setDataSource(). This method retrieves the
+     * meta data value associated with the keyCode.
+     *
+     * The keyCode currently supported is listed below as METADATA_XXX
+     * constants. With any other value, it returns a null pointer.
+     *
+     * @param keyCode One of the constants listed below at the end of the class.
+     * @return The meta data value associate with the given keyCode on success;
+     * null on failure.
+     */
+    public @Nullable String extractMetadata(int keyCode) {
+        String meta = nativeExtractMetadata(keyCode);
+        if (keyCode == METADATA_KEY_GENRE) {
+            // translate numeric genre code(s) to human readable
+            meta = convertGenreTag(meta);
+        }
+        return meta;
+    }
+
+    /*
+     * The id3v2 spec doesn't specify the syntax of the genre tag very precisely, so
+     * some assumptions are made. Using one possible interpretation of the id3v2
+     * spec, this method converts an id3 genre tag string to a human readable string,
+     * as follows:
+     * - if the first character of the tag is a digit, the entire tag is assumed to
+     *   be an id3v1 numeric genre code. If the tag does not parse to a number, or
+     *   the number is outside the range of defined standard genres, it is ignored.
+     * - if the tag does not start with a digit, it is assumed to be an id3v2 style
+     *   tag consisting of one or more genres, with each genre being either a parenthesized
+     *   integer referring to an id3v1 numeric genre code, the special indicators "(CR)" or
+     *   "(RX)" (for "Cover" or "Remix", respectively), or a custom genre string. When
+     *   a custom genre string is encountered, it is assumed to continue until the end
+     *   of the tag, unless it starts with "((" in which case it is assumed to continue
+     *   until the next close-parenthesis or the end of the tag. Any parse error in the tag
+     *   causes it to be ignored.
+     * The human-readable genre string is not localized, and uses the English genre names
+     * from the spec.
+     */
+    private String convertGenreTag(String meta) {
+        if (TextUtils.isEmpty(meta)) {
+            return null;
+        }
+
+        if (Character.isDigit(meta.charAt(0))) {
+            // assume a single id3v1-style bare number without any extra characters
+            try {
+                int genreIndex = Integer.parseInt(meta);
+                if (genreIndex >= 0 && genreIndex < STANDARD_GENRES.length) {
+                    return STANDARD_GENRES[genreIndex];
+                }
+            } catch (NumberFormatException e) {
+                // ignore and fall through
+            }
+            return null;
+        } else {
+            // assume id3v2-style genre tag, with parenthesized numeric genres
+            // and/or literal genre strings, possibly more than one per tag.
+            StringBuilder genres = null;
+            String nextGenre = null;
+            while (true) {
+                if (!TextUtils.isEmpty(nextGenre)) {
+                    if (genres == null) {
+                        genres = new StringBuilder();
+                    }
+                    if (genres.length() != 0) {
+                        genres.append(", ");
+                    }
+                    genres.append(nextGenre);
+                    nextGenre = null;
+                }
+                if (TextUtils.isEmpty(meta)) {
+                    // entire tag has been processed.
+                    break;
+                }
+                if (meta.startsWith("(RX)")) {
+                    nextGenre = "Remix";
+                    meta = meta.substring(4);
+                } else if (meta.startsWith("(CR)")) {
+                    nextGenre = "Cover";
+                    meta = meta.substring(4);
+                } else if (meta.startsWith("((")) {
+                    // the id3v2 spec says that custom genres that start with a parenthesis
+                    // should be "escaped" with another parenthesis, however the spec doesn't
+                    // specify escaping parentheses inside the custom string. We'll parse any
+                    // such strings until a closing parenthesis is found, or the end of
+                    // the tag is reached.
+                    int closeParenOffset = meta.indexOf(')');
+                    if (closeParenOffset == -1) {
+                        // string continues to end of tag
+                        nextGenre = meta.substring(1);
+                        meta = "";
+                    } else {
+                        nextGenre = meta.substring(1, closeParenOffset + 1);
+                        meta = meta.substring(closeParenOffset + 1);
+                    }
+                } else if (meta.startsWith("(")) {
+                    // should be a parenthesized numeric genre
+                    int closeParenOffset = meta.indexOf(')');
+                    if (closeParenOffset == -1) {
+                        return null;
+                    }
+                    String genreNumString = meta.substring(1, closeParenOffset);
+                    try {
+                        int genreIndex = Integer.parseInt(genreNumString.toString());
+                        if (genreIndex >= 0 && genreIndex < STANDARD_GENRES.length) {
+                            nextGenre = STANDARD_GENRES[genreIndex];
+                        } else {
+                            return null;
+                        }
+                    } catch (NumberFormatException e) {
+                        return null;
+                    }
+                    meta = meta.substring(closeParenOffset + 1);
+                } else {
+                    // custom genre
+                    nextGenre = meta;
+                    meta = "";
+                }
+            }
+            return genres == null || genres.length() == 0 ? null : genres.toString();
+        }
+    }
+
+    /**
+     * This method is similar to {@link #getFrameAtTime(long, int, BitmapParams)}
+     * except that the device will choose the actual {@link Bitmap.Config} to use.
+     *
+     * @param timeUs The time position where the frame will be retrieved.
+     * When retrieving the frame at the given time position, there is no
+     * guarantee that the data source has a frame located at the position.
+     * When this happens, a frame nearby will be returned. If timeUs is
+     * negative, time position and option will ignored, and any frame
+     * that the implementation considers as representative may be returned.
+     *
+     * @param option a hint on how the frame is found. Use
+     * {@link #OPTION_PREVIOUS_SYNC} if one wants to retrieve a sync frame
+     * that has a timestamp earlier than or the same as timeUs. Use
+     * {@link #OPTION_NEXT_SYNC} if one wants to retrieve a sync frame
+     * that has a timestamp later than or the same as timeUs. Use
+     * {@link #OPTION_CLOSEST_SYNC} if one wants to retrieve a sync frame
+     * that has a timestamp closest to or the same as timeUs. Use
+     * {@link #OPTION_CLOSEST} if one wants to retrieve a frame that may
+     * or may not be a sync frame but is closest to or the same as timeUs.
+     * {@link #OPTION_CLOSEST} often has larger performance overhead compared
+     * to the other options if there is no sync frame located at timeUs.
+     *
+     * @return A Bitmap containing a representative video frame, which can be null,
+     *         if such a frame cannot be retrieved. {@link Bitmap#getConfig()} can
+     *         be used to query the actual {@link Bitmap.Config}.
+     *
+     * @see #getFrameAtTime(long, int, BitmapParams)
+     */
+    public @Nullable Bitmap getFrameAtTime(long timeUs, @Option int option) {
+        if (option < OPTION_PREVIOUS_SYNC ||
+            option > OPTION_CLOSEST) {
+            throw new IllegalArgumentException("Unsupported option: " + option);
+        }
+
+        return _getFrameAtTime(timeUs, option, -1 /*dst_width*/, -1 /*dst_height*/, null);
+    }
+
+    /**
+     * Call this method after setDataSource(). This method finds a
+     * representative frame close to the given time position by considering
+     * the given option if possible, and returns it as a bitmap.
+     *
+     * <p>If you don't need a full-resolution
+     * frame (for example, because you need a thumbnail image), use
+     * {@link #getScaledFrameAtTime getScaledFrameAtTime()} instead of this
+     * method.</p>
+     *
+     * @param timeUs The time position where the frame will be retrieved.
+     * When retrieving the frame at the given time position, there is no
+     * guarantee that the data source has a frame located at the position.
+     * When this happens, a frame nearby will be returned. If timeUs is
+     * negative, time position and option will ignored, and any frame
+     * that the implementation considers as representative may be returned.
+     *
+     * @param option a hint on how the frame is found. Use
+     * {@link #OPTION_PREVIOUS_SYNC} if one wants to retrieve a sync frame
+     * that has a timestamp earlier than or the same as timeUs. Use
+     * {@link #OPTION_NEXT_SYNC} if one wants to retrieve a sync frame
+     * that has a timestamp later than or the same as timeUs. Use
+     * {@link #OPTION_CLOSEST_SYNC} if one wants to retrieve a sync frame
+     * that has a timestamp closest to or the same as timeUs. Use
+     * {@link #OPTION_CLOSEST} if one wants to retrieve a frame that may
+     * or may not be a sync frame but is closest to or the same as timeUs.
+     * {@link #OPTION_CLOSEST} often has larger performance overhead compared
+     * to the other options if there is no sync frame located at timeUs.
+     *
+     * @param params BitmapParams that controls the returned bitmap config
+     *        (such as pixel formats).
+     *
+     * @return A Bitmap containing a representative video frame, which
+     *         can be null, if such a frame cannot be retrieved.
+     *
+     * @see #getFrameAtTime(long, int)
+     */
+    public @Nullable Bitmap getFrameAtTime(
+            long timeUs, @Option int option, @NonNull BitmapParams params) {
+        if (option < OPTION_PREVIOUS_SYNC ||
+            option > OPTION_CLOSEST) {
+            throw new IllegalArgumentException("Unsupported option: " + option);
+        }
+
+        return _getFrameAtTime(timeUs, option, -1 /*dst_width*/, -1 /*dst_height*/, params);
+    }
+
+    /**
+     * This method is similar to {@link #getScaledFrameAtTime(long, int, int, int, BitmapParams)}
+     * except that the device will choose the actual {@link Bitmap.Config} to use.
+     *
+     * @param timeUs The time position in microseconds where the frame will be retrieved.
+     * When retrieving the frame at the given time position, there is no
+     * guarantee that the data source has a frame located at the position.
+     * When this happens, a frame nearby will be returned. If timeUs is
+     * negative, time position and option will ignored, and any frame
+     * that the implementation considers as representative may be returned.
+     *
+     * @param option a hint on how the frame is found. Use
+     * {@link #OPTION_PREVIOUS_SYNC} if one wants to retrieve a sync frame
+     * that has a timestamp earlier than or the same as timeUs. Use
+     * {@link #OPTION_NEXT_SYNC} if one wants to retrieve a sync frame
+     * that has a timestamp later than or the same as timeUs. Use
+     * {@link #OPTION_CLOSEST_SYNC} if one wants to retrieve a sync frame
+     * that has a timestamp closest to or the same as timeUs. Use
+     * {@link #OPTION_CLOSEST} if one wants to retrieve a frame that may
+     * or may not be a sync frame but is closest to or the same as timeUs.
+     * {@link #OPTION_CLOSEST} often has larger performance overhead compared
+     * to the other options if there is no sync frame located at timeUs.
+     *
+     * @param dstWidth expected output bitmap width
+     * @param dstHeight expected output bitmap height
+     * @return A Bitmap containing a representative video frame, which can be null,
+     *         if such a frame cannot be retrieved. {@link Bitmap#getConfig()} can
+     *         be used to query the actual {@link Bitmap.Config}.
+     * @throws IllegalArgumentException if passed in invalid option or width by height
+     *         is less than or equal to 0.
+     * @see #getScaledFrameAtTime(long, int, int, int, BitmapParams)
+     */
+    public @Nullable Bitmap getScaledFrameAtTime(long timeUs, @Option int option,
+            @IntRange(from=1) int dstWidth, @IntRange(from=1) int dstHeight) {
+        validate(option, dstWidth, dstHeight);
+        return _getFrameAtTime(timeUs, option, dstWidth, dstHeight, null);
+    }
+
+    /**
+     * Retrieve a video frame near a given timestamp scaled to a desired size.
+     * Call this method after setDataSource(). This method finds a representative
+     * frame close to the given time position by considering the given option
+     * if possible, and returns it as a bitmap with same aspect ratio as the source
+     * while scaling it so that it fits into the desired size of dst_width by dst_height.
+     * This is useful for generating a thumbnail for an input data source or just to
+     * obtain a scaled frame at the given time position.
+     *
+     * @param timeUs The time position in microseconds where the frame will be retrieved.
+     * When retrieving the frame at the given time position, there is no
+     * guarantee that the data source has a frame located at the position.
+     * When this happens, a frame nearby will be returned. If timeUs is
+     * negative, time position and option will ignored, and any frame
+     * that the implementation considers as representative may be returned.
+     *
+     * @param option a hint on how the frame is found. Use
+     * {@link #OPTION_PREVIOUS_SYNC} if one wants to retrieve a sync frame
+     * that has a timestamp earlier than or the same as timeUs. Use
+     * {@link #OPTION_NEXT_SYNC} if one wants to retrieve a sync frame
+     * that has a timestamp later than or the same as timeUs. Use
+     * {@link #OPTION_CLOSEST_SYNC} if one wants to retrieve a sync frame
+     * that has a timestamp closest to or the same as timeUs. Use
+     * {@link #OPTION_CLOSEST} if one wants to retrieve a frame that may
+     * or may not be a sync frame but is closest to or the same as timeUs.
+     * {@link #OPTION_CLOSEST} often has larger performance overhead compared
+     * to the other options if there is no sync frame located at timeUs.
+     *
+     * @param dstWidth expected output bitmap width
+     * @param dstHeight expected output bitmap height
+     * @param params BitmapParams that controls the returned bitmap config
+     *        (such as pixel formats).
+     *
+     * @return A Bitmap of size not larger than dstWidth by dstHeight containing a
+     *         scaled video frame, which can be null, if such a frame cannot be retrieved.
+     * @throws IllegalArgumentException if passed in invalid option or width by height
+     *         is less than or equal to 0.
+     * @see #getScaledFrameAtTime(long, int, int, int)
+     */
+    public @Nullable Bitmap getScaledFrameAtTime(long timeUs, @Option int option,
+            @IntRange(from=1) int dstWidth, @IntRange(from=1) int dstHeight,
+            @NonNull BitmapParams params) {
+        validate(option, dstWidth, dstHeight);
+        return _getFrameAtTime(timeUs, option, dstWidth, dstHeight, params);
+    }
+
+    private void validate(@Option int option, int dstWidth, int dstHeight) {
+        if (option < OPTION_PREVIOUS_SYNC || option > OPTION_CLOSEST) {
+            throw new IllegalArgumentException("Unsupported option: " + option);
+        }
+        if (dstWidth <= 0) {
+            throw new IllegalArgumentException("Invalid width: " + dstWidth);
+        }
+        if (dstHeight <= 0) {
+            throw new IllegalArgumentException("Invalid height: " + dstHeight);
+        }
+    }
+
+    /**
+     * Call this method after setDataSource(). This method finds a
+     * representative frame close to the given time position if possible,
+     * and returns it as a bitmap. Call this method if one does not care
+     * how the frame is found as long as it is close to the given time;
+     * otherwise, please call {@link #getFrameAtTime(long, int)}.
+     *
+     * <p>If you don't need a full-resolution
+     * frame (for example, because you need a thumbnail image), use
+     * {@link #getScaledFrameAtTime getScaledFrameAtTime()} instead of this
+     * method.</p>
+     *
+     * @param timeUs The time position where the frame will be retrieved.
+     * When retrieving the frame at the given time position, there is no
+     * guarentee that the data source has a frame located at the position.
+     * When this happens, a frame nearby will be returned. If timeUs is
+     * negative, time position and option will ignored, and any frame
+     * that the implementation considers as representative may be returned.
+     *
+     * @return A Bitmap of size dst_widthxdst_height containing a representative
+     *         video frame, which can be null, if such a frame cannot be retrieved.
+     *
+     * @see #getFrameAtTime(long, int)
+     */
+    public @Nullable Bitmap getFrameAtTime(long timeUs) {
+        return getFrameAtTime(timeUs, OPTION_CLOSEST_SYNC);
+    }
+
+    /**
+     * Call this method after setDataSource(). This method finds a
+     * representative frame at any time position if possible,
+     * and returns it as a bitmap. Call this method if one does not
+     * care about where the frame is located; otherwise, please call
+     * {@link #getFrameAtTime(long)} or {@link #getFrameAtTime(long, int)}
+     *
+     * <p>If you don't need a full-resolution
+     * frame (for example, because you need a thumbnail image), use
+     * {@link #getScaledFrameAtTime getScaledFrameAtTime()} instead of this
+     * method.</p>
+     *
+     * @return A Bitmap containing a representative video frame, which
+     *         can be null, if such a frame cannot be retrieved.
+     *
+     * @see #getFrameAtTime(long)
+     * @see #getFrameAtTime(long, int)
+     */
+    public @Nullable Bitmap getFrameAtTime() {
+        return _getFrameAtTime(
+                -1, OPTION_CLOSEST_SYNC, -1 /*dst_width*/, -1 /*dst_height*/, null);
+    }
+
+    private native Bitmap _getFrameAtTime(
+            long timeUs, int option, int width, int height, @Nullable BitmapParams params);
+
+    public static final class BitmapParams {
+        private Bitmap.Config inPreferredConfig = Bitmap.Config.ARGB_8888;
+        private Bitmap.Config outActualConfig = Bitmap.Config.ARGB_8888;
+
+        /**
+         * Create a default BitmapParams object. By default, it uses {@link Bitmap.Config#ARGB_8888}
+         * as the preferred bitmap config.
+         */
+        public BitmapParams() {}
+
+        /**
+         * Set the preferred bitmap config for the decoder to decode into.
+         *
+         * If not set, or the request cannot be met, the decoder will output
+         * in {@link Bitmap.Config#ARGB_8888} config by default.
+         *
+         * After decode, the actual config used can be retrieved by {@link #getActualConfig()}.
+         *
+         * @param config the preferred bitmap config to use.
+         */
+        public void setPreferredConfig(@NonNull Bitmap.Config config) {
+            if (config == null) {
+                throw new IllegalArgumentException("preferred config can't be null");
+            }
+            inPreferredConfig = config;
+        }
+
+        /**
+         * Retrieve the preferred bitmap config in the params.
+         *
+         * @return the preferred bitmap config.
+         */
+        public @NonNull Bitmap.Config getPreferredConfig() {
+            return inPreferredConfig;
+        }
+
+        /**
+         * Get the actual bitmap config used to decode the bitmap after the decoding.
+         *
+         * @return the actual bitmap config used.
+         */
+        public @NonNull Bitmap.Config getActualConfig() {
+            return outActualConfig;
+        }
+    }
+
+    /**
+     * This method retrieves a video frame by its index. It should only be called
+     * after {@link #setDataSource}.
+     *
+     * After the bitmap is returned, you can query the actual parameters that were
+     * used to create the bitmap from the {@code BitmapParams} argument, for instance
+     * to query the bitmap config used for the bitmap with {@link BitmapParams#getActualConfig}.
+     *
+     * @param frameIndex 0-based index of the video frame. The frame index must be that of
+     *        a valid frame. The total number of frames available for retrieval can be queried
+     *        via the {@link #METADATA_KEY_VIDEO_FRAME_COUNT} key.
+     * @param params BitmapParams that controls the returned bitmap config (such as pixel formats).
+     *
+     * @throws IllegalStateException if the container doesn't contain video or image sequences.
+     * @throws IllegalArgumentException if the requested frame index does not exist.
+     *
+     * @return A Bitmap containing the requested video frame, or null if the retrieval fails.
+     *
+     * @see #getFrameAtIndex(int)
+     * @see #getFramesAtIndex(int, int, BitmapParams)
+     * @see #getFramesAtIndex(int, int)
+     */
+    public @Nullable Bitmap getFrameAtIndex(int frameIndex, @NonNull BitmapParams params) {
+        List<Bitmap> bitmaps = getFramesAtIndex(frameIndex, 1, params);
+        return bitmaps.get(0);
+    }
+
+    /**
+     * This method is similar to {@link #getFrameAtIndex(int, BitmapParams)} except that
+     * the default for {@link BitmapParams} will be used.
+     *
+     * @param frameIndex 0-based index of the video frame. The frame index must be that of
+     *        a valid frame. The total number of frames available for retrieval can be queried
+     *        via the {@link #METADATA_KEY_VIDEO_FRAME_COUNT} key.
+     *
+     * @throws IllegalStateException if the container doesn't contain video or image sequences.
+     * @throws IllegalArgumentException if the requested frame index does not exist.
+     *
+     * @return A Bitmap containing the requested video frame, or null if the retrieval fails.
+     *
+     * @see #getFrameAtIndex(int, BitmapParams)
+     * @see #getFramesAtIndex(int, int, BitmapParams)
+     * @see #getFramesAtIndex(int, int)
+     */
+    public @Nullable Bitmap getFrameAtIndex(int frameIndex) {
+        List<Bitmap> bitmaps = getFramesAtIndex(frameIndex, 1);
+        return bitmaps.get(0);
+    }
+
+    /**
+     * This method retrieves a consecutive set of video frames starting at the
+     * specified index. It should only be called after {@link #setDataSource}.
+     *
+     * If the caller intends to retrieve more than one consecutive video frames,
+     * this method is preferred over {@link #getFrameAtIndex(int, BitmapParams)} for efficiency.
+     *
+     * After the bitmaps are returned, you can query the actual parameters that were
+     * used to create the bitmaps from the {@code BitmapParams} argument, for instance
+     * to query the bitmap config used for the bitmaps with {@link BitmapParams#getActualConfig}.
+     *
+     * @param frameIndex 0-based index of the first video frame to retrieve. The frame index
+     *        must be that of a valid frame. The total number of frames available for retrieval
+     *        can be queried via the {@link #METADATA_KEY_VIDEO_FRAME_COUNT} key.
+     * @param numFrames number of consecutive video frames to retrieve. Must be a positive
+     *        value. The stream must contain at least numFrames frames starting at frameIndex.
+     * @param params BitmapParams that controls the returned bitmap config (such as pixel formats).
+     *
+     * @throws IllegalStateException if the container doesn't contain video or image sequences.
+     * @throws IllegalArgumentException if the frameIndex or numFrames is invalid, or the
+     *         stream doesn't contain at least numFrames starting at frameIndex.
+
+     * @return An list of Bitmaps containing the requested video frames. The returned
+     *         array could contain less frames than requested if the retrieval fails.
+     *
+     * @see #getFrameAtIndex(int, BitmapParams)
+     * @see #getFrameAtIndex(int)
+     * @see #getFramesAtIndex(int, int)
+     */
+    public @NonNull List<Bitmap> getFramesAtIndex(
+            int frameIndex, int numFrames, @NonNull BitmapParams params) {
+        return getFramesAtIndexInternal(frameIndex, numFrames, params);
+    }
+
+    /**
+     * This method is similar to {@link #getFramesAtIndex(int, int, BitmapParams)} except that
+     * the default for {@link BitmapParams} will be used.
+     *
+     * @param frameIndex 0-based index of the first video frame to retrieve. The frame index
+     *        must be that of a valid frame. The total number of frames available for retrieval
+     *        can be queried via the {@link #METADATA_KEY_VIDEO_FRAME_COUNT} key.
+     * @param numFrames number of consecutive video frames to retrieve. Must be a positive
+     *        value. The stream must contain at least numFrames frames starting at frameIndex.
+     *
+     * @throws IllegalStateException if the container doesn't contain video or image sequences.
+     * @throws IllegalArgumentException if the frameIndex or numFrames is invalid, or the
+     *         stream doesn't contain at least numFrames starting at frameIndex.
+
+     * @return An list of Bitmaps containing the requested video frames. The returned
+     *         array could contain less frames than requested if the retrieval fails.
+     *
+     * @see #getFrameAtIndex(int, BitmapParams)
+     * @see #getFrameAtIndex(int)
+     * @see #getFramesAtIndex(int, int, BitmapParams)
+     */
+    public @NonNull List<Bitmap> getFramesAtIndex(int frameIndex, int numFrames) {
+        return getFramesAtIndexInternal(frameIndex, numFrames, null);
+    }
+
+    private @NonNull List<Bitmap> getFramesAtIndexInternal(
+            int frameIndex, int numFrames, @Nullable BitmapParams params) {
+        if (!"yes".equals(extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO))) {
+            throw new IllegalStateException("Does not contail video or image sequences");
+        }
+        int frameCount = Integer.parseInt(
+                extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_FRAME_COUNT));
+        if (frameIndex < 0 || numFrames < 1
+                || frameIndex >= frameCount
+                || frameIndex > frameCount - numFrames) {
+            throw new IllegalArgumentException("Invalid frameIndex or numFrames: "
+                + frameIndex + ", " + numFrames);
+        }
+        return _getFrameAtIndex(frameIndex, numFrames, params);
+    }
+
+    private native @NonNull List<Bitmap> _getFrameAtIndex(
+            int frameIndex, int numFrames, @Nullable BitmapParams params);
+
+    /**
+     * This method retrieves a still image by its index. It should only be called
+     * after {@link #setDataSource}.
+     *
+     * After the bitmap is returned, you can query the actual parameters that were
+     * used to create the bitmap from the {@code BitmapParams} argument, for instance
+     * to query the bitmap config used for the bitmap with {@link BitmapParams#getActualConfig}.
+     *
+     * @param imageIndex 0-based index of the image.
+     * @param params BitmapParams that controls the returned bitmap config (such as pixel formats).
+     *
+     * @throws IllegalStateException if the container doesn't contain still images.
+     * @throws IllegalArgumentException if the requested image does not exist.
+     *
+     * @return the requested still image, or null if the image cannot be retrieved.
+     *
+     * @see #getImageAtIndex(int)
+     * @see #getPrimaryImage(BitmapParams)
+     * @see #getPrimaryImage()
+     */
+    public @Nullable Bitmap getImageAtIndex(int imageIndex, @NonNull BitmapParams params) {
+        return getImageAtIndexInternal(imageIndex, params);
+    }
+
+    /**
+     * @hide
+     *
+     * This method retrieves the thumbnail image for a still image if it's available.
+     * It should only be called after {@link #setDataSource}.
+     *
+     * @param imageIndex 0-based index of the image, negative value indicates primary image.
+     * @param params BitmapParams that controls the returned bitmap config (such as pixel formats).
+     * @param targetSize intended size of one edge (wdith or height) of the thumbnail,
+     *                   this is a heuristic for the framework to decide whether the embedded
+     *                   thumbnail should be used.
+     * @param maxPixels maximum pixels of thumbnail, this is a heuristic for the frameowrk to
+     *                  decide whehther the embedded thumnbail (or a downscaled version of it)
+     *                  should be used.
+     * @return the retrieved thumbnail, or null if no suitable thumbnail is available.
+     */
+    public native @Nullable Bitmap getThumbnailImageAtIndex(
+            int imageIndex, @NonNull BitmapParams params, int targetSize, int maxPixels);
+
+    /**
+     * This method is similar to {@link #getImageAtIndex(int, BitmapParams)} except that
+     * the default for {@link BitmapParams} will be used.
+     *
+     * @param imageIndex 0-based index of the image.
+     *
+     * @throws IllegalStateException if the container doesn't contain still images.
+     * @throws IllegalArgumentException if the requested image does not exist.
+     *
+     * @return the requested still image, or null if the image cannot be retrieved.
+     *
+     * @see #getImageAtIndex(int, BitmapParams)
+     * @see #getPrimaryImage(BitmapParams)
+     * @see #getPrimaryImage()
+     */
+    public @Nullable Bitmap getImageAtIndex(int imageIndex) {
+        return getImageAtIndexInternal(imageIndex, null);
+    }
+
+    /**
+     * This method retrieves the primary image of the media content. It should only
+     * be called after {@link #setDataSource}.
+     *
+     * After the bitmap is returned, you can query the actual parameters that were
+     * used to create the bitmap from the {@code BitmapParams} argument, for instance
+     * to query the bitmap config used for the bitmap with {@link BitmapParams#getActualConfig}.
+     *
+     * @param params BitmapParams that controls the returned bitmap config (such as pixel formats).
+     *
+     * @return the primary image, or null if it cannot be retrieved.
+     *
+     * @throws IllegalStateException if the container doesn't contain still images.
+     *
+     * @see #getImageAtIndex(int, BitmapParams)
+     * @see #getImageAtIndex(int)
+     * @see #getPrimaryImage()
+     */
+    public @Nullable Bitmap getPrimaryImage(@NonNull BitmapParams params) {
+        return getImageAtIndexInternal(-1, params);
+    }
+
+    /**
+     * This method is similar to {@link #getPrimaryImage(BitmapParams)} except that
+     * the default for {@link BitmapParams} will be used.
+     *
+     * @return the primary image, or null if it cannot be retrieved.
+     *
+     * @throws IllegalStateException if the container doesn't contain still images.
+     *
+     * @see #getImageAtIndex(int, BitmapParams)
+     * @see #getImageAtIndex(int)
+     * @see #getPrimaryImage(BitmapParams)
+     */
+    public @Nullable Bitmap getPrimaryImage() {
+        return getImageAtIndexInternal(-1, null);
+    }
+
+    private Bitmap getImageAtIndexInternal(int imageIndex, @Nullable BitmapParams params) {
+        if (!"yes".equals(extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_IMAGE))) {
+            throw new IllegalStateException("Does not contail still images");
+        }
+
+        String imageCount = extractMetadata(MediaMetadataRetriever.METADATA_KEY_IMAGE_COUNT);
+        if (imageIndex >= Integer.parseInt(imageCount)) {
+            throw new IllegalArgumentException("Invalid image index: " + imageCount);
+        }
+
+        return _getImageAtIndex(imageIndex, params);
+    }
+
+    private native Bitmap _getImageAtIndex(int imageIndex, @Nullable BitmapParams params);
+
+    /**
+     * Call this method after setDataSource(). This method finds the optional
+     * graphic or album/cover art associated associated with the data source. If
+     * there are more than one pictures, (any) one of them is returned.
+     *
+     * @return null if no such graphic is found.
+     */
+    public @Nullable byte[] getEmbeddedPicture() {
+        return getEmbeddedPicture(EMBEDDED_PICTURE_TYPE_ANY);
+    }
+
+    @UnsupportedAppUsage
+    private native byte[] getEmbeddedPicture(int pictureType);
+
+    @Override
+    public void close() {
+        release();
+    }
+
+    /**
+     * Call it when one is done with the object. This method releases the memory
+     * allocated internally.
+     */
+    public native void release();
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private native void native_setup();
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private static native void native_init();
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private native final void native_finalize();
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            native_finalize();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Option used in method {@link #getFrameAtTime(long, int)} to get a
+     * frame at a specified location.
+     *
+     * @see #getFrameAtTime(long, int)
+     */
+    /* Do not change these option values without updating their counterparts
+     * in include/media/MediaSource.h!
+     */
+    /**
+     * This option is used with {@link #getFrameAtTime(long, int)} to retrieve
+     * a sync (or key) frame associated with a data source that is located
+     * right before or at the given time.
+     *
+     * @see #getFrameAtTime(long, int)
+     */
+    public static final int OPTION_PREVIOUS_SYNC    = 0x00;
+    /**
+     * This option is used with {@link #getFrameAtTime(long, int)} to retrieve
+     * a sync (or key) frame associated with a data source that is located
+     * right after or at the given time.
+     *
+     * @see #getFrameAtTime(long, int)
+     */
+    public static final int OPTION_NEXT_SYNC        = 0x01;
+    /**
+     * This option is used with {@link #getFrameAtTime(long, int)} to retrieve
+     * a sync (or key) frame associated with a data source that is located
+     * closest to (in time) or at the given time.
+     *
+     * @see #getFrameAtTime(long, int)
+     */
+    public static final int OPTION_CLOSEST_SYNC     = 0x02;
+    /**
+     * This option is used with {@link #getFrameAtTime(long, int)} to retrieve
+     * a frame (not necessarily a key frame) associated with a data source that
+     * is located closest to or at the given time.
+     *
+     * @see #getFrameAtTime(long, int)
+     */
+    public static final int OPTION_CLOSEST          = 0x03;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "OPTION_" }, value = {
+            OPTION_PREVIOUS_SYNC,
+            OPTION_NEXT_SYNC,
+            OPTION_CLOSEST_SYNC,
+            OPTION_CLOSEST,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Option {}
+
+    /*
+     * Do not change these metadata key values without updating their
+     * counterparts in include/media/mediametadataretriever.h!
+     */
+    /**
+     * The metadata key to retrieve the numeric string describing the
+     * order of the audio data source on its original recording.
+     */
+    public static final int METADATA_KEY_CD_TRACK_NUMBER = 0;
+    /**
+     * The metadata key to retrieve the information about the album title
+     * of the data source.
+     */
+    public static final int METADATA_KEY_ALBUM           = 1;
+    /**
+     * The metadata key to retrieve the information about the artist of
+     * the data source.
+     */
+    public static final int METADATA_KEY_ARTIST          = 2;
+    /**
+     * The metadata key to retrieve the information about the author of
+     * the data source.
+     */
+    public static final int METADATA_KEY_AUTHOR          = 3;
+    /**
+     * The metadata key to retrieve the information about the composer of
+     * the data source.
+     */
+    public static final int METADATA_KEY_COMPOSER        = 4;
+    /**
+     * The metadata key to retrieve the date when the data source was created
+     * or modified.
+     */
+    public static final int METADATA_KEY_DATE            = 5;
+    /**
+     * The metadata key to retrieve the content type or genre of the data
+     * source.
+     */
+    public static final int METADATA_KEY_GENRE           = 6;
+    /**
+     * The metadata key to retrieve the data source title.
+     */
+    public static final int METADATA_KEY_TITLE           = 7;
+    /**
+     * The metadata key to retrieve the year when the data source was created
+     * or modified.
+     */
+    public static final int METADATA_KEY_YEAR            = 8;
+    /**
+     * The metadata key to retrieve the playback duration (in ms) of the data source.
+     */
+    public static final int METADATA_KEY_DURATION        = 9;
+    /**
+     * The metadata key to retrieve the number of tracks, such as audio, video,
+     * text, in the data source, such as a mp4 or 3gpp file.
+     */
+    public static final int METADATA_KEY_NUM_TRACKS      = 10;
+    /**
+     * The metadata key to retrieve the information of the writer (such as
+     * lyricist) of the data source.
+     */
+    public static final int METADATA_KEY_WRITER          = 11;
+    /**
+     * The metadata key to retrieve the mime type of the data source. Some
+     * example mime types include: "video/mp4", "audio/mp4", "audio/amr-wb",
+     * etc.
+     */
+    public static final int METADATA_KEY_MIMETYPE        = 12;
+    /**
+     * The metadata key to retrieve the information about the performers or
+     * artist associated with the data source.
+     */
+    public static final int METADATA_KEY_ALBUMARTIST     = 13;
+    /**
+     * The metadata key to retrieve the numberic string that describes which
+     * part of a set the audio data source comes from.
+     */
+    public static final int METADATA_KEY_DISC_NUMBER     = 14;
+    /**
+     * The metadata key to retrieve the music album compilation status.
+     */
+    public static final int METADATA_KEY_COMPILATION     = 15;
+    /**
+     * If this key exists the media contains audio content.
+     */
+    public static final int METADATA_KEY_HAS_AUDIO       = 16;
+    /**
+     * If this key exists the media contains video content.
+     */
+    public static final int METADATA_KEY_HAS_VIDEO       = 17;
+    /**
+     * If the media contains video, this key retrieves its width.
+     */
+    public static final int METADATA_KEY_VIDEO_WIDTH     = 18;
+    /**
+     * If the media contains video, this key retrieves its height.
+     */
+    public static final int METADATA_KEY_VIDEO_HEIGHT    = 19;
+    /**
+     * This key retrieves the average bitrate (in bits/sec), if available.
+     */
+    public static final int METADATA_KEY_BITRATE         = 20;
+    /**
+     * This key retrieves the language code of text tracks, if available.
+     * If multiple text tracks present, the return value will look like:
+     * "eng:chi"
+     * @hide
+     */
+    public static final int METADATA_KEY_TIMED_TEXT_LANGUAGES      = 21;
+    /**
+     * If this key exists the media is drm-protected.
+     * @hide
+     */
+    public static final int METADATA_KEY_IS_DRM          = 22;
+    /**
+     * This key retrieves the location information, if available.
+     * The location should be specified according to ISO-6709 standard, under
+     * a mp4/3gp box "@xyz". Location with longitude of -90 degrees and latitude
+     * of 180 degrees will be retrieved as "+180.0000-90.0000/", for instance.
+     */
+    public static final int METADATA_KEY_LOCATION        = 23;
+    /**
+     * This key retrieves the video rotation angle in degrees, if available.
+     * The video rotation angle may be 0, 90, 180, or 270 degrees.
+     */
+    public static final int METADATA_KEY_VIDEO_ROTATION = 24;
+    /**
+     * This key retrieves the original capture framerate, if it's
+     * available. The capture framerate will be a floating point
+     * number.
+     */
+    public static final int METADATA_KEY_CAPTURE_FRAMERATE = 25;
+    /**
+     * If this key exists the media contains still image content.
+     */
+    public static final int METADATA_KEY_HAS_IMAGE       = 26;
+    /**
+     * If the media contains still images, this key retrieves the number
+     * of still images.
+     */
+    public static final int METADATA_KEY_IMAGE_COUNT     = 27;
+    /**
+     * If the media contains still images, this key retrieves the image
+     * index of the primary image.
+     */
+    public static final int METADATA_KEY_IMAGE_PRIMARY   = 28;
+    /**
+     * If the media contains still images, this key retrieves the width
+     * of the primary image.
+     */
+    public static final int METADATA_KEY_IMAGE_WIDTH     = 29;
+    /**
+     * If the media contains still images, this key retrieves the height
+     * of the primary image.
+     */
+    public static final int METADATA_KEY_IMAGE_HEIGHT    = 30;
+    /**
+     * If the media contains still images, this key retrieves the rotation
+     * angle (in degrees clockwise) of the primary image. The image rotation
+     * angle must be one of 0, 90, 180, or 270 degrees.
+     */
+    public static final int METADATA_KEY_IMAGE_ROTATION  = 31;
+    /**
+     * If the media contains video and this key exists, it retrieves the
+     * total number of frames in the video sequence.
+     */
+    public static final int METADATA_KEY_VIDEO_FRAME_COUNT = 32;
+
+    /**
+     * If the media contains EXIF data, this key retrieves the offset (in bytes)
+     * of the data.
+     */
+    public static final int METADATA_KEY_EXIF_OFFSET = 33;
+
+    /**
+     * If the media contains EXIF data, this key retrieves the length (in bytes)
+     * of the data.
+     */
+    public static final int METADATA_KEY_EXIF_LENGTH = 34;
+
+    /**
+     * This key retrieves the color standard, if available.
+     *
+     * @see MediaFormat#COLOR_STANDARD_BT709
+     * @see MediaFormat#COLOR_STANDARD_BT601_PAL
+     * @see MediaFormat#COLOR_STANDARD_BT601_NTSC
+     * @see MediaFormat#COLOR_STANDARD_BT2020
+     */
+    public static final int METADATA_KEY_COLOR_STANDARD = 35;
+
+    /**
+     * This key retrieves the color transfer, if available.
+     *
+     * @see MediaFormat#COLOR_TRANSFER_LINEAR
+     * @see MediaFormat#COLOR_TRANSFER_SDR_VIDEO
+     * @see MediaFormat#COLOR_TRANSFER_ST2084
+     * @see MediaFormat#COLOR_TRANSFER_HLG
+     */
+    public static final int METADATA_KEY_COLOR_TRANSFER = 36;
+
+    /**
+     * This key retrieves the color range, if available.
+     *
+     * @see MediaFormat#COLOR_RANGE_LIMITED
+     * @see MediaFormat#COLOR_RANGE_FULL
+     */
+    public static final int METADATA_KEY_COLOR_RANGE    = 37;
+
+    /**
+     * This key retrieves the sample rate in Hz, if available.
+     * This is a signed 32-bit integer formatted as a string in base 10.
+     */
+    public static final int METADATA_KEY_SAMPLERATE      = 38;
+
+    /**
+     * This key retrieves the bits per sample in numbers of bits, if available.
+     * This is a signed 32-bit integer formatted as a string in base 10.
+     */
+    public static final int METADATA_KEY_BITS_PER_SAMPLE = 39;
+
+    /**
+     * This key retrieves the video codec mimetype if available.
+     * @hide
+     */
+    @SystemApi(client = MODULE_LIBRARIES)
+    public static final int METADATA_KEY_VIDEO_CODEC_MIME_TYPE = 40;
+
+    /**
+     * If the media contains XMP data, this key retrieves the offset (in bytes)
+     * of the data.
+     */
+    public static final int METADATA_KEY_XMP_OFFSET = 41;
+
+    /**
+     * If the media contains XMP data, this key retrieves the length (in bytes)
+     * of the data.
+     */
+    public static final int METADATA_KEY_XMP_LENGTH = 42;
+
+    // Add more here...
+}
diff --git a/android/media/MediaMetrics.java b/android/media/MediaMetrics.java
new file mode 100644
index 0000000..3a5216e
--- /dev/null
+++ b/android/media/MediaMetrics.java
@@ -0,0 +1,833 @@
+/*
+ * Copyright 2019 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.util.Objects;
+
+/**
+ * MediaMetrics is the Java interface to the MediaMetrics service.
+ *
+ * This is used to collect media statistics by the framework.
+ * It is not intended for direct application use.
+ *
+ * @hide
+ */
+public class MediaMetrics {
+    public static final String TAG = "MediaMetrics";
+
+    public static final String SEPARATOR = ".";
+
+    /**
+     * A list of established MediaMetrics names that can be used for Items.
+     */
+    public static class Name {
+        public static final String AUDIO = "audio";
+        public static final String AUDIO_BLUETOOTH = AUDIO + SEPARATOR + "bluetooth";
+        public static final String AUDIO_DEVICE = AUDIO + SEPARATOR + "device";
+        public static final String AUDIO_FOCUS = AUDIO + SEPARATOR + "focus";
+        public static final String AUDIO_FORCE_USE = AUDIO + SEPARATOR + "forceUse";
+        public static final String AUDIO_MIC = AUDIO + SEPARATOR + "mic";
+        public static final String AUDIO_SERVICE = AUDIO + SEPARATOR + "service";
+        public static final String AUDIO_VOLUME = AUDIO + SEPARATOR + "volume";
+        public static final String AUDIO_VOLUME_EVENT = AUDIO_VOLUME + SEPARATOR + "event";
+        public static final String AUDIO_MODE = AUDIO + SEPARATOR + "mode";
+    }
+
+    /**
+     * A list of established string values.
+     */
+    public static class Value {
+        public static final String CONNECT = "connect";
+        public static final String CONNECTED = "connected";
+        public static final String DISCONNECT = "disconnect";
+        public static final String DISCONNECTED = "disconnected";
+        public static final String DOWN = "down";
+        public static final String MUTE = "mute";
+        public static final String NO = "no";
+        public static final String OFF = "off";
+        public static final String ON = "on";
+        public static final String UNMUTE = "unmute";
+        public static final String UP = "up";
+        public static final String YES = "yes";
+    }
+
+    /**
+     * A list of standard property keys for consistent use and type.
+     */
+    public static class Property {
+        // A use for Bluetooth or USB device addresses
+        public static final Key<String> ADDRESS = createKey("address", String.class);
+        // A string representing the Audio Attributes
+        public static final Key<String> ATTRIBUTES = createKey("attributes", String.class);
+
+        // The calling package responsible for the state change
+        public static final Key<String> CALLING_PACKAGE =
+                createKey("callingPackage", String.class);
+
+        // The client name
+        public static final Key<String> CLIENT_NAME = createKey("clientName", String.class);
+
+        // The device type
+        public static final Key<Integer> DELAY_MS = createKey("delayMs", Integer.class);
+
+        // The device type
+        public static final Key<String> DEVICE = createKey("device", String.class);
+
+        // For volume changes, up or down
+        public static final Key<String> DIRECTION = createKey("direction", String.class);
+
+        // A reason for early return or error
+        public static final Key<String> EARLY_RETURN =
+                createKey("earlyReturn", String.class);
+        // ENCODING_ ... string to match AudioFormat encoding
+        public static final Key<String> ENCODING = createKey("encoding", String.class);
+
+        public static final Key<String> EVENT = createKey("event#", String.class);
+
+        // event generated is external (yes, no)
+        public static final Key<String> EXTERNAL = createKey("external", String.class);
+
+        public static final Key<Integer> FLAGS = createKey("flags", Integer.class);
+        public static final Key<String> FOCUS_CHANGE_HINT =
+                createKey("focusChangeHint", String.class);
+        public static final Key<String> FORCE_USE_DUE_TO =
+                createKey("forceUseDueTo", String.class);
+        public static final Key<String> FORCE_USE_MODE =
+                createKey("forceUseMode", String.class);
+        public static final Key<Double> GAIN_DB =
+                createKey("gainDb", Double.class);
+        public static final Key<String> GROUP =
+                createKey("group", String.class);
+        // For volume
+        public static final Key<Integer> INDEX = createKey("index", Integer.class);
+        public static final Key<Integer> MAX_INDEX = createKey("maxIndex", Integer.class);
+        public static final Key<Integer> MIN_INDEX = createKey("minIndex", Integer.class);
+        public static final Key<String> MODE =
+                createKey("mode", String.class); // audio_mode
+        public static final Key<String> MUTE =
+                createKey("mute", String.class); // microphone, on or off.
+
+        // Bluetooth or Usb device name
+        public static final Key<String> NAME =
+                createKey("name", String.class);
+
+        // Number of observers
+        public static final Key<Integer> OBSERVERS =
+                createKey("observers", Integer.class);
+
+        public static final Key<String> REQUEST =
+                createKey("request", String.class);
+
+        // For audio mode
+        public static final Key<String> REQUESTED_MODE =
+                createKey("requestedMode", String.class); // audio_mode
+
+        // For Bluetooth
+        public static final Key<String> SCO_AUDIO_MODE =
+                createKey("scoAudioMode", String.class);
+        public static final Key<Integer> SDK = createKey("sdk", Integer.class);
+        public static final Key<String> STATE = createKey("state", String.class);
+        public static final Key<Integer> STATUS = createKey("status", Integer.class);
+        public static final Key<String> STREAM_TYPE = createKey("streamType", String.class);
+    }
+
+    /**
+     * The TYPE constants below should match those in native MediaMetricsItem.h
+     */
+    private static final int TYPE_NONE = 0;
+    private static final int TYPE_INT32 = 1;     // Java integer
+    private static final int TYPE_INT64 = 2;     // Java long
+    private static final int TYPE_DOUBLE = 3;    // Java double
+    private static final int TYPE_CSTRING = 4;   // Java string
+    private static final int TYPE_RATE = 5;      // Two longs, ignored in Java
+
+    // The charset used for encoding Strings to bytes.
+    private static final Charset MEDIAMETRICS_CHARSET = StandardCharsets.UTF_8;
+
+    /**
+     * Key interface.
+     *
+     * The presence of this {@code Key} interface on an object allows
+     * it to be used to set metrics.
+     *
+     * @param <T> type of value associated with {@code Key}.
+     */
+    public interface Key<T> {
+        /**
+         * Returns the internal name of the key.
+         */
+        @NonNull
+        String getName();
+
+        /**
+         * Returns the class type of the associated value.
+         */
+        @NonNull
+        Class<T> getValueClass();
+    }
+
+    /**
+     * Returns a Key object with the correct interface for MediaMetrics.
+     *
+     * @param name The name of the key.
+     * @param type The class type of the value represented by the key.
+     * @param <T> The type of value.
+     * @return a new key interface.
+     */
+    @NonNull
+    public static <T> Key<T> createKey(@NonNull String name, @NonNull Class<T> type) {
+        // Implementation specific.
+        return new Key<T>() {
+            private final String mName = name;
+            private final Class<T> mType = type;
+
+            @Override
+            @NonNull
+            public String getName() {
+                return mName;
+            }
+
+            @Override
+            @NonNull
+            public Class<T> getValueClass() {
+                return mType;
+            }
+
+            /**
+             * Return true if the name and the type of two objects are the same.
+             */
+            @Override
+            public boolean equals(Object obj) {
+                if (obj == this) {
+                    return true;
+                }
+                if (!(obj instanceof Key)) {
+                    return false;
+                }
+                Key<?> other = (Key<?>) obj;
+                return mName.equals(other.getName()) && mType.equals(other.getValueClass());
+            }
+
+            @Override
+            public int hashCode() {
+                return Objects.hash(mName, mType);
+            }
+        };
+    }
+
+    /**
+     * Item records properties and delivers to the MediaMetrics service
+     *
+     */
+    public static class Item {
+
+        /*
+         * MediaMetrics Item
+         *
+         * Creates a Byte String and sends to the MediaMetrics service.
+         * The Byte String serves as a compact form for logging data
+         * with low overhead for storage.
+         *
+         * The Byte String format is as follows:
+         *
+         * For Java
+         *  int64 corresponds to long
+         *  int32, uint32 corresponds to int
+         *  uint16 corresponds to char
+         *  uint8, int8 corresponds to byte
+         *
+         * For items transmitted from Java, uint8 and uint32 values are limited
+         * to INT8_MAX and INT32_MAX.  This constrains the size of large items
+         * to 2GB, which is consistent with ByteBuffer max size. A native item
+         * can conceivably have size of 4GB.
+         *
+         * Physical layout of integers and doubles within the MediaMetrics byte string
+         * is in Native / host order, which is usually little endian.
+         *
+         * Note that primitive data (ints, doubles) within a Byte String has
+         * no extra padding or alignment requirements, like ByteBuffer.
+         *
+         * -- begin of item
+         * -- begin of header
+         * (uint32) item size: including the item size field
+         * (uint32) header size, including the item size and header size fields.
+         * (uint16) version: exactly 0
+         * (uint16) key size, that is key strlen + 1 for zero termination.
+         * (int8)+ key, a string which is 0 terminated (UTF-8).
+         * (int32) pid
+         * (int32) uid
+         * (int64) timestamp
+         * -- end of header
+         * -- begin body
+         * (uint32) number of properties
+         * -- repeat for number of properties
+         *     (uint16) property size, including property size field itself
+         *     (uint8) type of property
+         *     (int8)+ key string, including 0 termination
+         *      based on type of property (given above), one of:
+         *       (int32)
+         *       (int64)
+         *       (double)
+         *       (int8)+ for TYPE_CSTRING, including 0 termination
+         *       (int64, int64) for rate
+         * -- end body
+         * -- end of item
+         *
+         * To record a MediaMetrics event, one creates a new item with an id,
+         * then use a series of puts to add properties
+         * and then a record() to send to the MediaMetrics service.
+         *
+         * The properties may not be unique, and putting a later property with
+         * the same name as an earlier property will overwrite the value and type
+         * of the prior property.
+         *
+         * The timestamp can only be recorded by a system service (and is ignored otherwise;
+         * the MediaMetrics service will fill in the timestamp as needed).
+         *
+         * The units of time are in SystemClock.elapsedRealtimeNanos().
+         *
+         * A clear() may be called to reset the properties to empty, the time to 0, but keep
+         * the other entries the same. This may be called after record().
+         * Additional properties may be added after calling record().  Changing the same property
+         * repeatedly is discouraged as - for this particular implementation - extra data
+         * is stored per change.
+         *
+         * new MediaMetrics.Item(mSomeId)
+         *     .putString("event", "javaCreate")
+         *     .putInt("value", intValue)
+         *     .record();
+         */
+
+        /**
+         * Creates an Item with server added uid, time.
+         *
+         * This is the typical way to record a MediaMetrics item.
+         *
+         * @param key the Metrics ID associated with the item.
+         */
+        public Item(String key) {
+            this(key, -1 /* pid */, -1 /* uid */, 0 /* SystemClock.elapsedRealtimeNanos() */,
+                    2048 /* capacity */);
+        }
+
+        /**
+         * Creates an Item specifying pid, uid, time, and initial Item capacity.
+         *
+         * This might be used by a service to specify a different PID or UID for a client.
+         *
+         * @param key the Metrics ID associated with the item.
+         *        An app may only set properties on an item which has already been
+         *        logged previously by a service.
+         * @param pid the process ID corresponding to the item.
+         *        A value of -1 (or a record() from an app instead of a service) causes
+         *        the MediaMetrics service to fill this in.
+         * @param uid the user ID corresponding to the item.
+         *        A value of -1 (or a record() from an app instead of a service) causes
+         *        the MediaMetrics service to fill this in.
+         * @param timeNs the time when the item occurred (may be in the past).
+         *        A value of 0 (or a record() from an app instead of a service) causes
+         *        the MediaMetrics service to fill it in.
+         *        Should be obtained from SystemClock.elapsedRealtimeNanos().
+         * @param capacity the anticipated size to use for the buffer.
+         *        If the capacity is too small, the buffer will be resized to accommodate.
+         *        This is amortized to copy data no more than twice.
+         */
+        public Item(String key, int pid, int uid, long timeNs, int capacity) {
+            final byte[] keyBytes = key.getBytes(MEDIAMETRICS_CHARSET);
+            final int keyLength = keyBytes.length;
+            if (keyLength > Character.MAX_VALUE - 1) {
+                throw new IllegalArgumentException("Key length too large");
+            }
+
+            // Version 0 - compute the header offsets here.
+            mHeaderSize = 4 + 4 + 2 + 2 + keyLength + 1 + 4 + 4 + 8; // see format above.
+            mPidOffset = mHeaderSize - 16;
+            mUidOffset = mHeaderSize - 12;
+            mTimeNsOffset = mHeaderSize - 8;
+            mPropertyCountOffset = mHeaderSize;
+            mPropertyStartOffset = mHeaderSize + 4;
+
+            mKey = key;
+            mBuffer = ByteBuffer.allocateDirect(
+                    Math.max(capacity, mHeaderSize + MINIMUM_PAYLOAD_SIZE));
+
+            // Version 0 - fill the ByteBuffer with the header (some details updated later).
+            mBuffer.order(ByteOrder.nativeOrder())
+                .putInt((int) 0)                      // total size in bytes (filled in later)
+                .putInt((int) mHeaderSize)            // size of header
+                .putChar((char) FORMAT_VERSION)       // version
+                .putChar((char) (keyLength + 1))      // length, with zero termination
+                .put(keyBytes).put((byte) 0)
+                .putInt(pid)
+                .putInt(uid)
+                .putLong(timeNs);
+            if (mHeaderSize != mBuffer.position()) {
+                throw new IllegalStateException("Mismatched sizing");
+            }
+            mBuffer.putInt(0);     // number of properties (to be later filled in by record()).
+        }
+
+        /**
+         * Sets a metrics typed key
+         * @param key
+         * @param value
+         * @param <T>
+         * @return
+         */
+        @NonNull
+        public <T> Item set(@NonNull Key<T> key, @Nullable T value) {
+            if (value instanceof Integer) {
+                putInt(key.getName(), (int) value);
+            } else if (value instanceof Long) {
+                putLong(key.getName(), (long) value);
+            } else if (value instanceof Double) {
+                putDouble(key.getName(), (double) value);
+            } else if (value instanceof String) {
+                putString(key.getName(), (String) value);
+            }
+            // if value is null, etc. no error is raised.
+            return this;
+        }
+
+        /**
+         * Sets the property with key to an integer (32 bit) value.
+         *
+         * @param key
+         * @param value
+         * @return itself
+         */
+        public Item putInt(String key, int value) {
+            final byte[] keyBytes = key.getBytes(MEDIAMETRICS_CHARSET);
+            final char propSize = (char) reserveProperty(keyBytes, 4 /* payloadSize */);
+            final int estimatedFinalPosition = mBuffer.position() + propSize;
+            mBuffer.putChar(propSize)
+                .put((byte) TYPE_INT32)
+                .put(keyBytes).put((byte) 0) // key, zero terminated
+                .putInt(value);
+            ++mPropertyCount;
+            if (mBuffer.position() != estimatedFinalPosition) {
+                throw new IllegalStateException("Final position " + mBuffer.position()
+                        + " != estimatedFinalPosition " + estimatedFinalPosition);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the property with key to a long (64 bit) value.
+         *
+         * @param key
+         * @param value
+         * @return itself
+         */
+        public Item putLong(String key, long value) {
+            final byte[] keyBytes = key.getBytes(MEDIAMETRICS_CHARSET);
+            final char propSize = (char) reserveProperty(keyBytes, 8 /* payloadSize */);
+            final int estimatedFinalPosition = mBuffer.position() + propSize;
+            mBuffer.putChar(propSize)
+                .put((byte) TYPE_INT64)
+                .put(keyBytes).put((byte) 0) // key, zero terminated
+                .putLong(value);
+            ++mPropertyCount;
+            if (mBuffer.position() != estimatedFinalPosition) {
+                throw new IllegalStateException("Final position " + mBuffer.position()
+                    + " != estimatedFinalPosition " + estimatedFinalPosition);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the property with key to a double value.
+         *
+         * @param key
+         * @param value
+         * @return itself
+         */
+        public Item putDouble(String key, double value) {
+            final byte[] keyBytes = key.getBytes(MEDIAMETRICS_CHARSET);
+            final char propSize = (char) reserveProperty(keyBytes, 8 /* payloadSize */);
+            final int estimatedFinalPosition = mBuffer.position() + propSize;
+            mBuffer.putChar(propSize)
+                .put((byte) TYPE_DOUBLE)
+                .put(keyBytes).put((byte) 0) // key, zero terminated
+                .putDouble(value);
+            ++mPropertyCount;
+            if (mBuffer.position() != estimatedFinalPosition) {
+                throw new IllegalStateException("Final position " + mBuffer.position()
+                    + " != estimatedFinalPosition " + estimatedFinalPosition);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the property with key to a String value.
+         *
+         * @param key
+         * @param value
+         * @return itself
+         */
+        public Item putString(String key, String value) {
+            final byte[] keyBytes = key.getBytes(MEDIAMETRICS_CHARSET);
+            final byte[] valueBytes = value.getBytes(MEDIAMETRICS_CHARSET);
+            final char propSize = (char) reserveProperty(keyBytes, valueBytes.length + 1);
+            final int estimatedFinalPosition = mBuffer.position() + propSize;
+            mBuffer.putChar(propSize)
+                .put((byte) TYPE_CSTRING)
+                .put(keyBytes).put((byte) 0) // key, zero terminated
+                .put(valueBytes).put((byte) 0); // value, zero term.
+            ++mPropertyCount;
+            if (mBuffer.position() != estimatedFinalPosition) {
+                throw new IllegalStateException("Final position " + mBuffer.position()
+                    + " != estimatedFinalPosition " + estimatedFinalPosition);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the pid to the provided value.
+         *
+         * @param pid which can be -1 if the service is to fill it in from the calling info.
+         * @return itself
+         */
+        public Item setPid(int pid) {
+            mBuffer.putInt(mPidOffset, pid); // pid location in byte string.
+            return this;
+        }
+
+        /**
+         * Sets the uid to the provided value.
+         *
+         * The UID represents the client associated with the property. This must be the UID
+         * of the application if it comes from the application client.
+         *
+         * Trusted services are allowed to set the uid for a client-related item.
+         *
+         * @param uid which can be -1 if the service is to fill it in from calling info.
+         * @return itself
+         */
+        public Item setUid(int uid) {
+            mBuffer.putInt(mUidOffset, uid); // uid location in byte string.
+            return this;
+        }
+
+        /**
+         * Sets the timestamp to the provided value.
+         *
+         * The time is referenced by the Boottime obtained by SystemClock.elapsedRealtimeNanos().
+         * This should be associated with the occurrence of the event.  It is recommended that
+         * the event be registered immediately when it occurs, and no later than 500ms
+         * (and certainly not in the future).
+         *
+         * @param timeNs which can be 0 if the service is to fill it in at the time of call.
+         * @return itself
+         */
+        public Item setTimestamp(long timeNs) {
+            mBuffer.putLong(mTimeNsOffset, timeNs); // time location in byte string.
+            return this;
+        }
+
+        /**
+         * Clears the properties and resets the time to 0.
+         *
+         * No other values are changed.
+         *
+         * @return itself
+         */
+        public Item clear() {
+            mBuffer.position(mPropertyStartOffset);
+            mBuffer.limit(mBuffer.capacity());
+            mBuffer.putLong(mTimeNsOffset, 0); // reset time.
+            mPropertyCount = 0;
+            return this;
+        }
+
+        /**
+         * Sends the item to the MediaMetrics service.
+         *
+         * The item properties are unchanged, hence record() may be called more than once
+         * to send the same item twice. Also, record() may be called without any properties.
+         *
+         * @return true if successful.
+         */
+        public boolean record() {
+            updateHeader();
+            return native_submit_bytebuffer(mBuffer, mBuffer.limit()) >= 0;
+        }
+
+        /**
+         * Converts the Item to a Bundle.
+         *
+         * This is primarily used as a test API for CTS.
+         *
+         * @return a Bundle with the keys set according to data in the Item's buffer.
+         */
+        public Bundle toBundle() {
+            updateHeader();
+
+            final ByteBuffer buffer = mBuffer.duplicate();
+            buffer.order(ByteOrder.nativeOrder()) // restore order property
+                .flip();                          // convert from write buffer to read buffer
+
+            return toBundle(buffer);
+        }
+
+        // The following constants are used for tests to extract
+        // the content of the Bundle for CTS testing.
+        public static final String BUNDLE_TOTAL_SIZE = "_totalSize";
+        public static final String BUNDLE_HEADER_SIZE = "_headerSize";
+        public static final String BUNDLE_VERSION = "_version";
+        public static final String BUNDLE_KEY_SIZE = "_keySize";
+        public static final String BUNDLE_KEY = "_key";
+        public static final String BUNDLE_PID = "_pid";
+        public static final String BUNDLE_UID = "_uid";
+        public static final String BUNDLE_TIMESTAMP = "_timestamp";
+        public static final String BUNDLE_PROPERTY_COUNT = "_propertyCount";
+
+        /**
+         * Converts a buffer contents to a bundle
+         *
+         * This is primarily used as a test API for CTS.
+         *
+         * @param buffer contains the byte data serialized according to the byte string version.
+         * @return a Bundle with the keys set according to data in the buffer.
+         */
+        public static Bundle toBundle(ByteBuffer buffer) {
+            final Bundle bundle = new Bundle();
+
+            final int totalSize = buffer.getInt();
+            final int headerSize = buffer.getInt();
+            final char version = buffer.getChar();
+            final char keySize = buffer.getChar(); // includes zero termination, i.e. keyLength + 1
+
+            if (totalSize < 0 || headerSize < 0) {
+                throw new IllegalArgumentException("Item size cannot be > " + Integer.MAX_VALUE);
+            }
+            final String key;
+            if (keySize > 0) {
+                key = getStringFromBuffer(buffer, keySize);
+            } else {
+                throw new IllegalArgumentException("Illegal null key");
+            }
+
+            final int pid = buffer.getInt();
+            final int uid = buffer.getInt();
+            final long timestamp = buffer.getLong();
+
+            // Verify header size (depending on version).
+            final int headerRead = buffer.position();
+            if (version == 0) {
+                if (headerRead != headerSize) {
+                    throw new IllegalArgumentException(
+                            "Item key:" + key
+                            + " headerRead:" + headerRead + " != headerSize:" + headerSize);
+                }
+            } else {
+                // future versions should only increase header size
+                // by adding to the end.
+                if (headerRead > headerSize) {
+                    throw new IllegalArgumentException(
+                            "Item key:" + key
+                            + " headerRead:" + headerRead + " > headerSize:" + headerSize);
+                } else if (headerRead < headerSize) {
+                    buffer.position(headerSize);
+                }
+            }
+
+            // Body always starts with properties.
+            final int propertyCount = buffer.getInt();
+            if (propertyCount < 0) {
+                throw new IllegalArgumentException(
+                        "Cannot have more than " + Integer.MAX_VALUE + " properties");
+            }
+            bundle.putInt(BUNDLE_TOTAL_SIZE, totalSize);
+            bundle.putInt(BUNDLE_HEADER_SIZE, headerSize);
+            bundle.putChar(BUNDLE_VERSION, version);
+            bundle.putChar(BUNDLE_KEY_SIZE, keySize);
+            bundle.putString(BUNDLE_KEY, key);
+            bundle.putInt(BUNDLE_PID, pid);
+            bundle.putInt(BUNDLE_UID, uid);
+            bundle.putLong(BUNDLE_TIMESTAMP, timestamp);
+            bundle.putInt(BUNDLE_PROPERTY_COUNT, propertyCount);
+
+            for (int i = 0; i < propertyCount; ++i) {
+                final int initialBufferPosition = buffer.position();
+                final char propSize = buffer.getChar();
+                final byte type = buffer.get();
+
+                // Log.d(TAG, "(" + i + ") propSize:" + ((int)propSize) + " type:" + type);
+                final String propKey = getStringFromBuffer(buffer);
+                switch (type) {
+                    case TYPE_INT32:
+                        bundle.putInt(propKey, buffer.getInt());
+                        break;
+                    case TYPE_INT64:
+                        bundle.putLong(propKey, buffer.getLong());
+                        break;
+                    case TYPE_DOUBLE:
+                        bundle.putDouble(propKey, buffer.getDouble());
+                        break;
+                    case TYPE_CSTRING:
+                        bundle.putString(propKey, getStringFromBuffer(buffer));
+                        break;
+                    case TYPE_NONE:
+                        break; // ignore on Java side
+                    case TYPE_RATE:
+                        buffer.getLong();  // consume the first int64_t of rate
+                        buffer.getLong();  // consume the second int64_t of rate
+                        break; // ignore on Java side
+                    default:
+                        // These are unsupported types for version 0
+                        // We ignore them if the version is greater than 0.
+                        if (version == 0) {
+                            throw new IllegalArgumentException(
+                                    "Property " + propKey + " has unsupported type " + type);
+                        }
+                        buffer.position(initialBufferPosition + propSize); // advance and skip
+                        break;
+                }
+                final int deltaPosition = buffer.position() - initialBufferPosition;
+                if (deltaPosition != propSize) {
+                    throw new IllegalArgumentException("propSize:" + propSize
+                        + " != deltaPosition:" + deltaPosition);
+                }
+            }
+
+            final int finalPosition = buffer.position();
+            if (finalPosition != totalSize) {
+                throw new IllegalArgumentException("totalSize:" + totalSize
+                    + " != finalPosition:" + finalPosition);
+            }
+            return bundle;
+        }
+
+        // Version 0 byte offsets for the header.
+        private static final int FORMAT_VERSION = 0;
+        private static final int TOTAL_SIZE_OFFSET = 0;
+        private static final int HEADER_SIZE_OFFSET = 4;
+        private static final int MINIMUM_PAYLOAD_SIZE = 4;
+        private final int mPidOffset;            // computed in constructor
+        private final int mUidOffset;            // computed in constructor
+        private final int mTimeNsOffset;         // computed in constructor
+        private final int mPropertyCountOffset;  // computed in constructor
+        private final int mPropertyStartOffset;  // computed in constructor
+        private final int mHeaderSize;           // computed in constructor
+
+        private final String mKey;
+
+        private ByteBuffer mBuffer;     // may be reallocated if capacity is insufficient.
+        private int mPropertyCount = 0; // overflow not checked (mBuffer would overflow first).
+
+        private int reserveProperty(byte[] keyBytes, int payloadSize) {
+            final int keyLength = keyBytes.length;
+            if (keyLength > Character.MAX_VALUE) {
+                throw new IllegalStateException("property key too long "
+                        + new String(keyBytes, MEDIAMETRICS_CHARSET));
+            }
+            if (payloadSize > Character.MAX_VALUE) {
+                throw new IllegalStateException("payload too large " + payloadSize);
+            }
+
+            // See the byte string property format above.
+            final int size = 2      /* length */
+                    + 1             /* type */
+                    + keyLength + 1 /* key length with zero termination */
+                    + payloadSize;  /* payload size */
+
+            if (size > Character.MAX_VALUE) {
+                throw new IllegalStateException("Item property "
+                        + new String(keyBytes, MEDIAMETRICS_CHARSET) + " is too large to send");
+            }
+
+            if (mBuffer.remaining() < size) {
+                int newCapacity = mBuffer.position() + size;
+                if (newCapacity > Integer.MAX_VALUE >> 1) {
+                    throw new IllegalStateException(
+                        "Item memory requirements too large: " + newCapacity);
+                }
+                newCapacity <<= 1;
+                ByteBuffer buffer = ByteBuffer.allocateDirect(newCapacity);
+                buffer.order(ByteOrder.nativeOrder());
+
+                // Copy data from old buffer to new buffer.
+                mBuffer.flip();
+                buffer.put(mBuffer);
+
+                // set buffer to new buffer
+                mBuffer = buffer;
+            }
+            return size;
+        }
+
+        // Used for test
+        private static String getStringFromBuffer(ByteBuffer buffer) {
+            return getStringFromBuffer(buffer, Integer.MAX_VALUE);
+        }
+
+        // Used for test
+        private static String getStringFromBuffer(ByteBuffer buffer, int size) {
+            int i = buffer.position();
+            int limit = buffer.limit();
+            if (size < Integer.MAX_VALUE - i && i + size < limit) {
+                limit = i + size;
+            }
+            for (; i < limit; ++i) {
+                if (buffer.get(i) == 0) {
+                    final int newPosition = i + 1;
+                    if (size != Integer.MAX_VALUE && newPosition - buffer.position() != size) {
+                        throw new IllegalArgumentException("chars consumed at " + i + ": "
+                            + (newPosition - buffer.position()) + " != size: " + size);
+                    }
+                    final String found;
+                    if (buffer.hasArray()) {
+                        found = new String(
+                            buffer.array(), buffer.position() + buffer.arrayOffset(),
+                            i - buffer.position(), MEDIAMETRICS_CHARSET);
+                        buffer.position(newPosition);
+                    } else {
+                        final byte[] array = new byte[i - buffer.position()];
+                        buffer.get(array);
+                        found = new String(array, MEDIAMETRICS_CHARSET);
+                        buffer.get(); // remove 0.
+                    }
+                    return found;
+                }
+            }
+            throw new IllegalArgumentException(
+                    "No zero termination found in string position: "
+                    + buffer.position() + " end: " + i);
+        }
+
+        /**
+         * May be called multiple times - just makes the header consistent with the current
+         * properties written.
+         */
+        private void updateHeader() {
+            // Buffer sized properly in constructor.
+            mBuffer.putInt(TOTAL_SIZE_OFFSET, mBuffer.position())      // set total length
+                .putInt(mPropertyCountOffset, (char) mPropertyCount); // set number of properties
+        }
+    }
+
+    private static native int native_submit_bytebuffer(@NonNull ByteBuffer buffer, int length);
+}
diff --git a/android/media/MediaMuxer.java b/android/media/MediaMuxer.java
new file mode 100644
index 0000000..ac19c21
--- /dev/null
+++ b/android/media/MediaMuxer.java
@@ -0,0 +1,744 @@
+/*
+ * Copyright (C) 2013 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.media.MediaCodec.BufferInfo;
+import android.os.Build;
+
+import dalvik.system.CloseGuard;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.util.Map;
+
+/**
+ * MediaMuxer facilitates muxing elementary streams. Currently MediaMuxer supports MP4, Webm
+ * and 3GP file as the output. It also supports muxing B-frames in MP4 since Android Nougat.
+ * <p>
+ * It is generally used like this:
+ *
+ * <pre>
+ * MediaMuxer muxer = new MediaMuxer("temp.mp4", OutputFormat.MUXER_OUTPUT_MPEG_4);
+ * // More often, the MediaFormat will be retrieved from MediaCodec.getOutputFormat()
+ * // or MediaExtractor.getTrackFormat().
+ * MediaFormat audioFormat = new MediaFormat(...);
+ * MediaFormat videoFormat = new MediaFormat(...);
+ * int audioTrackIndex = muxer.addTrack(audioFormat);
+ * int videoTrackIndex = muxer.addTrack(videoFormat);
+ * ByteBuffer inputBuffer = ByteBuffer.allocate(bufferSize);
+ * boolean finished = false;
+ * BufferInfo bufferInfo = new BufferInfo();
+ *
+ * muxer.start();
+ * while(!finished) {
+ *   // getInputBuffer() will fill the inputBuffer with one frame of encoded
+ *   // sample from either MediaCodec or MediaExtractor, set isAudioSample to
+ *   // true when the sample is audio data, set up all the fields of bufferInfo,
+ *   // and return true if there are no more samples.
+ *   finished = getInputBuffer(inputBuffer, isAudioSample, bufferInfo);
+ *   if (!finished) {
+ *     int currentTrackIndex = isAudioSample ? audioTrackIndex : videoTrackIndex;
+ *     muxer.writeSampleData(currentTrackIndex, inputBuffer, bufferInfo);
+ *   }
+ * };
+ * muxer.stop();
+ * muxer.release();
+ * </pre>
+ *
+
+ <h4>Metadata Track</h4>
+ <p>
+  Per-frame metadata is useful in carrying extra information that correlated with video or audio to
+  facilitate offline processing, e.g. gyro signals from the sensor could help video stabilization when
+  doing offline processing. Metadata track is only supported in MP4 container. When adding a new
+  metadata track, track's mime format must start with prefix "application/", e.g. "applicaton/gyro".
+  Metadata's format/layout will be defined by the application. Writing metadata is nearly the same as
+  writing video/audio data except that the data will not be from mediacodec. Application just needs
+  to pass the bytebuffer that contains the metadata and also the associated timestamp to the
+  {@link #writeSampleData} api. The timestamp must be in the same time base as video and audio. The
+  generated MP4 file uses TextMetaDataSampleEntry defined in section 12.3.3.2 of the ISOBMFF to signal
+  the metadata's mime format. When using{@link android.media.MediaExtractor} to extract the file with
+  metadata track, the mime format of the metadata will be extracted into {@link android.media.MediaFormat}.
+
+ <pre class=prettyprint>
+   MediaMuxer muxer = new MediaMuxer("temp.mp4", OutputFormat.MUXER_OUTPUT_MPEG_4);
+   // SetUp Video/Audio Tracks.
+   MediaFormat audioFormat = new MediaFormat(...);
+   MediaFormat videoFormat = new MediaFormat(...);
+   int audioTrackIndex = muxer.addTrack(audioFormat);
+   int videoTrackIndex = muxer.addTrack(videoFormat);
+
+   // Setup Metadata Track
+   MediaFormat metadataFormat = new MediaFormat(...);
+   metadataFormat.setString(KEY_MIME, "application/gyro");
+   int metadataTrackIndex = muxer.addTrack(metadataFormat);
+
+   muxer.start();
+   while(..) {
+       // Allocate bytebuffer and write gyro data(x,y,z) into it.
+       ByteBuffer metaData = ByteBuffer.allocate(bufferSize);
+       metaData.putFloat(x);
+       metaData.putFloat(y);
+       metaData.putFloat(z);
+       BufferInfo metaInfo = new BufferInfo();
+       // Associate this metadata with the video frame by setting
+       // the same timestamp as the video frame.
+       metaInfo.presentationTimeUs = currentVideoTrackTimeUs;
+       metaInfo.offset = 0;
+       metaInfo.flags = 0;
+       metaInfo.size = bufferSize;
+       muxer.writeSampleData(metadataTrackIndex, metaData, metaInfo);
+   };
+   muxer.stop();
+   muxer.release();
+ }</pre>
+
+ <h2 id=History><a name="History"></a>Features and API History</h2>
+ <p>
+ The following table summarizes the feature support in different API version and containers.
+ For API version numbers, see {@link android.os.Build.VERSION_CODES}.
+
+ <style>
+ .api > tr > th, .api > tr > td { text-align: center; padding: 4px 4px; }
+ .api > tr > th     { vertical-align: bottom; }
+ .api > tr > td     { vertical-align: middle; }
+ .sml > tr > th, .sml > tr > td { text-align: center; padding: 2px 4px; }
+ .fn { text-align: center; }
+ </style>
+
+ <table align="right" style="width: 0%">
+  <thead>
+   <tbody class=api>
+    <tr><th>Symbol</th>
+    <th>Meaning</th></tr>
+   </tbody>
+  </thead>
+  <tbody class=sml>
+   <tr><td>&#9679;</td><td>Supported</td></tr>
+   <tr><td>&#9675;</td><td>Not supported</td></tr>
+   <tr><td>&#9639;</td><td>Supported in MP4/WebM/3GP</td></tr>
+   <tr><td>&#8277;</td><td>Only Supported in MP4</td></tr>
+  </tbody>
+ </table>
+<table align="center" style="width: 100%;">
+  <thead class=api>
+   <tr>
+    <th rowspan=2>Feature</th>
+    <th colspan="24">SDK Version</th>
+   </tr>
+   <tr>
+    <th>18</th>
+    <th>19</th>
+    <th>20</th>
+    <th>21</th>
+    <th>22</th>
+    <th>23</th>
+    <th>24</th>
+    <th>25</th>
+    <th>26+</th>
+   </tr>
+  </thead>
+ <tbody class=api>
+   <tr>
+    <td align="center">MP4 container</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+    <td align="center">WebM container</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+    <td>&#9679;</td>
+   </tr>
+    <td align="center">3GP container</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9679;</td>
+   </tr>
+    <td align="center">Muxing B-Frames(bi-directional predicted frames)</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#8277;</td>
+    <td>&#8277;</td>
+    <td>&#8277;</td>
+   </tr>
+   </tr>
+    <td align="center">Muxing Single Video/Audio Track</td>
+    <td>&#9639;</td>
+    <td>&#9639;</td>
+    <td>&#9639;</td>
+    <td>&#9639;</td>
+    <td>&#9639;</td>
+    <td>&#9639;</td>
+    <td>&#9639;</td>
+    <td>&#9639;</td>
+    <td>&#9639;</td>
+   </tr>
+   </tr>
+    <td align="center">Muxing Multiple Video/Audio Tracks</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#8277;</td>
+   </tr>
+   </tr>
+    <td align="center">Muxing Metadata Tracks</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#9675;</td>
+    <td>&#8277;</td>
+   </tr>
+   </tbody>
+ </table>
+ */
+
+final public class MediaMuxer {
+
+    static {
+        System.loadLibrary("media_jni");
+    }
+
+    /**
+     * Defines the output format. These constants are used with constructor.
+     */
+    public static final class OutputFormat {
+        /* Do not change these values without updating their counterparts
+         * in include/media/stagefright/MediaMuxer.h!
+         */
+        private OutputFormat() {}
+        /** @hide */
+        public static final int MUXER_OUTPUT_FIRST   = 0;
+        /** MPEG4 media file format*/
+        public static final int MUXER_OUTPUT_MPEG_4 = MUXER_OUTPUT_FIRST;
+        /** WEBM media file format*/
+        public static final int MUXER_OUTPUT_WEBM   = MUXER_OUTPUT_FIRST + 1;
+        /** 3GPP media file format*/
+        public static final int MUXER_OUTPUT_3GPP   = MUXER_OUTPUT_FIRST + 2;
+        /** HEIF media file format*/
+        public static final int MUXER_OUTPUT_HEIF   = MUXER_OUTPUT_FIRST + 3;
+        /** Ogg media file format*/
+        public static final int MUXER_OUTPUT_OGG   = MUXER_OUTPUT_FIRST + 4;
+        /** @hide */
+        public static final int MUXER_OUTPUT_LAST   = MUXER_OUTPUT_OGG;
+    };
+
+    /** @hide */
+    @IntDef({
+        OutputFormat.MUXER_OUTPUT_MPEG_4,
+        OutputFormat.MUXER_OUTPUT_WEBM,
+        OutputFormat.MUXER_OUTPUT_3GPP,
+        OutputFormat.MUXER_OUTPUT_HEIF,
+        OutputFormat.MUXER_OUTPUT_OGG,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Format {}
+
+    // All the native functions are listed here.
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static native long nativeSetup(@NonNull FileDescriptor fd, int format)
+            throws IllegalArgumentException, IOException;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static native void nativeRelease(long nativeObject);
+    private static native void nativeStart(long nativeObject);
+    private static native void nativeStop(long nativeObject);
+    private static native int nativeAddTrack(
+            long nativeObject, @NonNull String[] keys, @NonNull Object[] values);
+    private static native void nativeSetOrientationHint(
+            long nativeObject, int degrees);
+    private static native void nativeSetLocation(long nativeObject, int latitude, int longitude);
+    private static native void nativeWriteSampleData(
+            long nativeObject, int trackIndex, @NonNull ByteBuffer byteBuf,
+            int offset, int size, long presentationTimeUs, @MediaCodec.BufferFlag int flags);
+
+    // Muxer internal states.
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static final int MUXER_STATE_UNINITIALIZED  = -1;
+    private static final int MUXER_STATE_INITIALIZED    = 0;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static final int MUXER_STATE_STARTED        = 1;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static final int MUXER_STATE_STOPPED        = 2;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private int mState = MUXER_STATE_UNINITIALIZED;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+    private int mLastTrackIndex = -1;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private long mNativeObject;
+
+    private String convertMuxerStateCodeToString(int aState) {
+        switch (aState) {
+            case MUXER_STATE_UNINITIALIZED:
+                return "UNINITIALIZED";
+            case MUXER_STATE_INITIALIZED:
+                return "INITIALIZED";
+            case MUXER_STATE_STARTED:
+                return "STARTED";
+            case MUXER_STATE_STOPPED:
+                return "STOPPED";
+            default:
+                return "UNKNOWN";
+        }
+    }
+
+    /**
+     * Constructor.
+     * Creates a media muxer that writes to the specified path.
+     * @param path The path of the output media file.
+     * @param format The format of the output media file.
+     * @see android.media.MediaMuxer.OutputFormat
+     * @throws IllegalArgumentException if path is invalid or format is not supported.
+     * @throws IOException if failed to open the file for write.
+     */
+    public MediaMuxer(@NonNull String path, @Format int format) throws IOException {
+        if (path == null) {
+            throw new IllegalArgumentException("path must not be null");
+        }
+        // Use RandomAccessFile so we can open the file with RW access;
+        // RW access allows the native writer to memory map the output file.
+        RandomAccessFile file = null;
+        try {
+            file = new RandomAccessFile(path, "rws");
+            file.setLength(0);
+            FileDescriptor fd = file.getFD();
+            setUpMediaMuxer(fd, format);
+        } finally {
+            if (file != null) {
+                file.close();
+            }
+        }
+    }
+
+    /**
+     * Constructor.
+     * Creates a media muxer that writes to the specified FileDescriptor. File descriptor
+     * must be seekable and writable. Application should not use the file referenced
+     * by this file descriptor until {@link #stop}. It is the application's responsibility
+     * to close the file descriptor. It is safe to do so as soon as this call returns.
+     * @param fd The FileDescriptor of the output media file.
+     * @param format The format of the output media file.
+     * @see android.media.MediaMuxer.OutputFormat
+     * @throws IllegalArgumentException if fd is invalid or format is not supported.
+     * @throws IOException if failed to open the file for write.
+     */
+    public MediaMuxer(@NonNull FileDescriptor fd, @Format int format) throws IOException {
+        setUpMediaMuxer(fd, format);
+    }
+
+    private void setUpMediaMuxer(@NonNull FileDescriptor fd, @Format int format) throws IOException {
+        if (format < OutputFormat.MUXER_OUTPUT_FIRST || format > OutputFormat.MUXER_OUTPUT_LAST) {
+            throw new IllegalArgumentException("format: " + format + " is invalid");
+        }
+        mNativeObject = nativeSetup(fd, format);
+        mState = MUXER_STATE_INITIALIZED;
+        mCloseGuard.open("release");
+    }
+
+    /**
+     * Sets the orientation hint for output video playback.
+     * <p>This method should be called before {@link #start}. Calling this
+     * method will not rotate the video frame when muxer is generating the file,
+     * but add a composition matrix containing the rotation angle in the output
+     * video if the output format is
+     * {@link OutputFormat#MUXER_OUTPUT_MPEG_4} so that a video player can
+     * choose the proper orientation for playback. Note that some video players
+     * may choose to ignore the composition matrix in a video during playback.
+     * By default, the rotation degree is 0.</p>
+     * @param degrees the angle to be rotated clockwise in degrees.
+     * The supported angles are 0, 90, 180, and 270 degrees.
+     * @throws IllegalArgumentException if degree is not supported.
+     * @throws IllegalStateException If this method is called after {@link #start}.
+     */
+    public void setOrientationHint(int degrees) {
+        if (degrees != 0 && degrees != 90  && degrees != 180 && degrees != 270) {
+            throw new IllegalArgumentException("Unsupported angle: " + degrees);
+        }
+        if (mState == MUXER_STATE_INITIALIZED) {
+            nativeSetOrientationHint(mNativeObject, degrees);
+        } else {
+            throw new IllegalStateException("Can't set rotation degrees due" +
+                    " to wrong state(" + convertMuxerStateCodeToString(mState) + ")");
+        }
+    }
+
+    /**
+     * Set and store the geodata (latitude and longitude) in the output file.
+     * This method should be called before {@link #start}. The geodata is stored
+     * in udta box if the output format is
+     * {@link OutputFormat#MUXER_OUTPUT_MPEG_4}, and is ignored for other output
+     * formats. The geodata is stored according to ISO-6709 standard.
+     *
+     * @param latitude Latitude in degrees. Its value must be in the range [-90,
+     * 90].
+     * @param longitude Longitude in degrees. Its value must be in the range
+     * [-180, 180].
+     * @throws IllegalArgumentException If the given latitude or longitude is out
+     * of range.
+     * @throws IllegalStateException If this method is called after {@link #start}.
+     */
+    public void setLocation(float latitude, float longitude) {
+        int latitudex10000  = (int) (latitude * 10000 + 0.5);
+        int longitudex10000 = (int) (longitude * 10000 + 0.5);
+
+        if (latitudex10000 > 900000 || latitudex10000 < -900000) {
+            String msg = "Latitude: " + latitude + " out of range.";
+            throw new IllegalArgumentException(msg);
+        }
+        if (longitudex10000 > 1800000 || longitudex10000 < -1800000) {
+            String msg = "Longitude: " + longitude + " out of range";
+            throw new IllegalArgumentException(msg);
+        }
+
+        if (mState == MUXER_STATE_INITIALIZED && mNativeObject != 0) {
+            nativeSetLocation(mNativeObject, latitudex10000, longitudex10000);
+        } else {
+            throw new IllegalStateException("Can't set location due to wrong state("
+                                             + convertMuxerStateCodeToString(mState) + ")");
+        }
+    }
+
+    /**
+     * Starts the muxer.
+     * <p>Make sure this is called after {@link #addTrack} and before
+     * {@link #writeSampleData}.</p>
+     * @throws IllegalStateException If this method is called after {@link #start}
+     * or Muxer is released
+     */
+    public void start() {
+        if (mNativeObject == 0) {
+            throw new IllegalStateException("Muxer has been released!");
+        }
+        if (mState == MUXER_STATE_INITIALIZED) {
+            nativeStart(mNativeObject);
+            mState = MUXER_STATE_STARTED;
+        } else {
+            throw new IllegalStateException("Can't start due to wrong state("
+                                             + convertMuxerStateCodeToString(mState) + ")");
+        }
+    }
+
+    /**
+     * Stops the muxer.
+     * <p>Once the muxer stops, it can not be restarted.</p>
+     * @throws IllegalStateException if muxer is in the wrong state.
+     */
+    public void stop() {
+        if (mState == MUXER_STATE_STARTED) {
+            try {
+                nativeStop(mNativeObject);
+            } catch (Exception e) {
+                throw e;
+            } finally {
+                mState = MUXER_STATE_STOPPED;
+            }
+        } else {
+            throw new IllegalStateException("Can't stop due to wrong state("
+                                             + convertMuxerStateCodeToString(mState) + ")");
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mCloseGuard != null) {
+                mCloseGuard.warnIfOpen();
+            }
+            if (mNativeObject != 0) {
+                nativeRelease(mNativeObject);
+                mNativeObject = 0;
+            }
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Adds a track with the specified format.
+     * <p>
+     * The following table summarizes support for specific format keys across android releases.
+     * Keys marked with '+:' are required.
+     *
+     * <table style="width: 0%">
+     *  <thead>
+     *   <tr>
+     *    <th rowspan=2>OS Version(s)</th>
+     *    <td colspan=3>{@code MediaFormat} keys used for</th>
+     *   </tr><tr>
+     *    <th>All Tracks</th>
+     *    <th>Audio Tracks</th>
+     *    <th>Video Tracks</th>
+     *   </tr>
+     *  </thead>
+     *  <tbody>
+     *   <tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}</td>
+     *    <td rowspan=7>+: {@link MediaFormat#KEY_MIME}</td>
+     *    <td rowspan=3>+: {@link MediaFormat#KEY_SAMPLE_RATE},<br>
+     *        +: {@link MediaFormat#KEY_CHANNEL_COUNT},<br>
+     *        +: <strong>codec-specific data<sup>AAC</sup></strong></td>
+     *    <td rowspan=5>+: {@link MediaFormat#KEY_WIDTH},<br>
+     *        +: {@link MediaFormat#KEY_HEIGHT},<br>
+     *        no {@code KEY_ROTATION},
+     *        use {@link #setOrientationHint setOrientationHint()}<sup>.mp4</sup>,<br>
+     *        +: <strong>codec-specific data<sup>AVC, MPEG4</sup></strong></td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#KITKAT}</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#KITKAT_WATCH}</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP}</td>
+     *    <td rowspan=4>as above, plus<br>
+     *        +: <strong>codec-specific data<sup>Vorbis & .webm</sup></strong></td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#M}</td>
+     *    <td>as above, plus<br>
+     *        {@link MediaFormat#KEY_BIT_RATE}<sup>AAC</sup></td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#N}</td>
+     *    <td>as above, plus<br>
+     *        <!-- {link MediaFormat#KEY_MAX_BIT_RATE}<sup>AAC, MPEG4</sup>,<br> -->
+     *        {@link MediaFormat#KEY_BIT_RATE}<sup>MPEG4</sup>,<br>
+     *        {@link MediaFormat#KEY_HDR_STATIC_INFO}<sup>#, .webm</sup>,<br>
+     *        {@link MediaFormat#KEY_COLOR_STANDARD}<sup>#</sup>,<br>
+     *        {@link MediaFormat#KEY_COLOR_TRANSFER}<sup>#</sup>,<br>
+     *        {@link MediaFormat#KEY_COLOR_RANGE}<sup>#</sup>,<br>
+     *        +: <strong>codec-specific data<sup>HEVC</sup></strong>,<br>
+     *        codec-specific data<sup>VP9</sup></td>
+     *   </tr>
+     *   <tr>
+     *    <td colspan=4>
+     *     <p class=note><strong>Notes:</strong><br>
+     *      #: storing into container metadata.<br>
+     *      .mp4, .webm&hellip;: for listed containers<br>
+     *      MPEG4, AAC&hellip;: for listed codecs
+     *    </td>
+     *   </tr><tr>
+     *    <td colspan=4>
+     *     <p class=note>Note that the codec-specific data for the track must be specified using
+     *     this method. Furthermore, codec-specific data must not be passed/specified via the
+     *     {@link #writeSampleData writeSampleData()} call.
+     *    </td>
+     *   </tr>
+     *  </tbody>
+     * </table>
+     *
+     * <p>
+     * The following table summarizes codec support for containers across android releases:
+     *
+     * <table style="width: 0%">
+     *  <thead>
+     *   <tr>
+     *    <th rowspan=2>OS Version(s)</th>
+     *    <td colspan=3>Codec support</th>
+     *   </tr><tr>
+     *    <th>{@linkplain OutputFormat#MUXER_OUTPUT_MPEG_4 MP4}</th>
+     *    <th>{@linkplain OutputFormat#MUXER_OUTPUT_WEBM WEBM}</th>
+     *   </tr>
+     *  </thead>
+     *  <tbody>
+     *   <tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#JELLY_BEAN_MR2}</td>
+     *    <td rowspan=6>{@link MediaFormat#MIMETYPE_AUDIO_AAC AAC},<br>
+     *        {@link MediaFormat#MIMETYPE_AUDIO_AMR_NB NB-AMR},<br>
+     *        {@link MediaFormat#MIMETYPE_AUDIO_AMR_WB WB-AMR},<br>
+     *        {@link MediaFormat#MIMETYPE_VIDEO_H263 H.263},<br>
+     *        {@link MediaFormat#MIMETYPE_VIDEO_MPEG4 MPEG-4},<br>
+     *        {@link MediaFormat#MIMETYPE_VIDEO_AVC AVC} (H.264)</td>
+     *    <td rowspan=3>Not supported</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#KITKAT}</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#KITKAT_WATCH}</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP}</td>
+     *    <td rowspan=3>{@link MediaFormat#MIMETYPE_AUDIO_VORBIS Vorbis},<br>
+     *        {@link MediaFormat#MIMETYPE_VIDEO_VP8 VP8}</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#M}</td>
+     *   </tr><tr>
+     *    <td>{@link android.os.Build.VERSION_CODES#N}</td>
+     *    <td>as above, plus<br>
+     *        {@link MediaFormat#MIMETYPE_VIDEO_HEVC HEVC} (H.265)</td>
+     *    <td>as above, plus<br>
+     *        {@link MediaFormat#MIMETYPE_VIDEO_VP9 VP9}</td>
+     *   </tr>
+     *  </tbody>
+     * </table>
+     *
+     * @param format The media format for the track.  This must not be an empty
+     *               MediaFormat.
+     * @return The track index for this newly added track, and it should be used
+     * in the {@link #writeSampleData}.
+     * @throws IllegalArgumentException if format is invalid.
+     * @throws IllegalStateException if muxer is in the wrong state.
+     */
+    public int addTrack(@NonNull MediaFormat format) {
+        if (format == null) {
+            throw new IllegalArgumentException("format must not be null.");
+        }
+        if (mState != MUXER_STATE_INITIALIZED) {
+            throw new IllegalStateException("Muxer is not initialized.");
+        }
+        if (mNativeObject == 0) {
+            throw new IllegalStateException("Muxer has been released!");
+        }
+        int trackIndex = -1;
+        // Convert the MediaFormat into key-value pairs and send to the native.
+        Map<String, Object> formatMap = format.getMap();
+
+        String[] keys = null;
+        Object[] values = null;
+        int mapSize = formatMap.size();
+        if (mapSize > 0) {
+            keys = new String[mapSize];
+            values = new Object[mapSize];
+            int i = 0;
+            for (Map.Entry<String, Object> entry : formatMap.entrySet()) {
+                keys[i] = entry.getKey();
+                values[i] = entry.getValue();
+                ++i;
+            }
+            trackIndex = nativeAddTrack(mNativeObject, keys, values);
+        } else {
+            throw new IllegalArgumentException("format must not be empty.");
+        }
+
+        // Track index number is expected to incremented as addTrack succeed.
+        // However, if format is invalid, it will get a negative trackIndex.
+        if (mLastTrackIndex >= trackIndex) {
+            throw new IllegalArgumentException("Invalid format.");
+        }
+        mLastTrackIndex = trackIndex;
+        return trackIndex;
+    }
+
+    /**
+     * Writes an encoded sample into the muxer.
+     * <p>The application needs to make sure that the samples are written into
+     * the right tracks. Also, it needs to make sure the samples for each track
+     * are written in chronological order (e.g. in the order they are provided
+     * by the encoder.)</p>
+     * <p> For MPEG4 media format, the duration of the last sample in a track can be set by passing
+     * an additional empty buffer(bufferInfo.size = 0) with MediaCodec.BUFFER_FLAG_END_OF_STREAM
+     * flag and a suitable presentation timestamp set in bufferInfo parameter as the last sample of
+     * that track.  This last sample's presentation timestamp shall be a sum of the presentation
+     * timestamp and the duration preferred for the original last sample.  If no explicit
+     * END_OF_STREAM sample was passed, then the duration of the last sample would be the same as
+     * that of the sample before that.</p>
+     * @param byteBuf The encoded sample.
+     * @param trackIndex The track index for this sample.
+     * @param bufferInfo The buffer information related to this sample.
+     * @throws IllegalArgumentException if trackIndex, byteBuf or bufferInfo is  invalid.
+     * @throws IllegalStateException if muxer is in wrong state.
+     * MediaMuxer uses the flags provided in {@link MediaCodec.BufferInfo},
+     * to signal sync frames.
+     */
+    public void writeSampleData(int trackIndex, @NonNull ByteBuffer byteBuf,
+            @NonNull BufferInfo bufferInfo) {
+        if (trackIndex < 0 || trackIndex > mLastTrackIndex) {
+            throw new IllegalArgumentException("trackIndex is invalid");
+        }
+
+        if (byteBuf == null) {
+            throw new IllegalArgumentException("byteBuffer must not be null");
+        }
+
+        if (bufferInfo == null) {
+            throw new IllegalArgumentException("bufferInfo must not be null");
+        }
+        if (bufferInfo.size < 0 || bufferInfo.offset < 0
+                || (bufferInfo.offset + bufferInfo.size) > byteBuf.capacity()) {
+            throw new IllegalArgumentException("bufferInfo must specify a" +
+                    " valid buffer offset and size");
+        }
+
+        if (mNativeObject == 0) {
+            throw new IllegalStateException("Muxer has been released!");
+        }
+
+        if (mState != MUXER_STATE_STARTED) {
+            throw new IllegalStateException("Can't write, muxer is not started");
+        }
+
+        nativeWriteSampleData(mNativeObject, trackIndex, byteBuf,
+                bufferInfo.offset, bufferInfo.size,
+                bufferInfo.presentationTimeUs, bufferInfo.flags);
+    }
+
+    /**
+     * Make sure you call this when you're done to free up any resources
+     * instead of relying on the garbage collector to do this for you at
+     * some point in the future.
+     */
+    public void release() {
+        if (mState == MUXER_STATE_STARTED) {
+            stop();
+        }
+        if (mNativeObject != 0) {
+            nativeRelease(mNativeObject);
+            mNativeObject = 0;
+            mCloseGuard.close();
+        }
+        mState = MUXER_STATE_UNINITIALIZED;
+    }
+}
diff --git a/android/media/MediaParceledListSlice.java b/android/media/MediaParceledListSlice.java
new file mode 100644
index 0000000..47ac193
--- /dev/null
+++ b/android/media/MediaParceledListSlice.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2020 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.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * This is a copied version of MediaParceledListSlice in framework with hidden API usages removed,
+ * and also with some lint error fixed.
+ *
+ * Transfer a large list of Parcelable objects across an IPC.  Splits into
+ * multiple transactions if needed.
+ *
+ * TODO: Remove this from @SystemApi once all the MediaSession related classes are moved
+ *       to apex (or ParceledListSlice moved to apex). This class is temporaily added to system API
+ *       for moving classes step by step.
+ *
+ * @param <T> The type of the elements in the list.
+ * @see BaseMediaParceledListSlice
+ * @deprecated This is temporary marked as @SystemApi. Should be removed from the API surface.
+ * @hide
+ */
+@Deprecated
+@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+public final class MediaParceledListSlice<T extends Parcelable>
+        extends BaseMediaParceledListSlice<T> {
+    public MediaParceledListSlice(@NonNull List<T> list) {
+        super(list);
+    }
+
+    private MediaParceledListSlice(Parcel in, ClassLoader loader) {
+        super(in, loader);
+    }
+
+    @NonNull
+    public static <T extends Parcelable> MediaParceledListSlice<T> emptyList() {
+        return new MediaParceledListSlice<T>(Collections.<T> emptyList());
+    }
+
+    @Override
+    public int describeContents() {
+        int contents = 0;
+        final List<T> list = getList();
+        for (int i=0; i<list.size(); i++) {
+            contents |= list.get(i).describeContents();
+        }
+        return contents;
+    }
+
+    @Override
+    void writeElement(T parcelable, Parcel dest, int callFlags) {
+        parcelable.writeToParcel(dest, callFlags);
+    }
+
+    @Override
+    void writeParcelableCreator(T parcelable, Parcel dest) {
+        dest.writeParcelableCreator((Parcelable) parcelable);
+    }
+
+    @Override
+    Parcelable.Creator<?> readParcelableCreator(Parcel from, ClassLoader loader) {
+        return from.readParcelableCreator(loader);
+    }
+
+    @NonNull
+    @SuppressWarnings("unchecked")
+    public static final Parcelable.ClassLoaderCreator<MediaParceledListSlice> CREATOR =
+            new Parcelable.ClassLoaderCreator<MediaParceledListSlice>() {
+        public MediaParceledListSlice createFromParcel(Parcel in) {
+            return new MediaParceledListSlice(in, null);
+        }
+
+        @Override
+        public MediaParceledListSlice createFromParcel(Parcel in, ClassLoader loader) {
+            return new MediaParceledListSlice(in, loader);
+        }
+
+        @Override
+        public MediaParceledListSlice[] newArray(int size) {
+            return new MediaParceledListSlice[size];
+        }
+    };
+}
diff --git a/android/media/MediaParser.java b/android/media/MediaParser.java
new file mode 100644
index 0000000..8cc3bc0
--- /dev/null
+++ b/android/media/MediaParser.java
@@ -0,0 +1,2292 @@
+/*
+ * Copyright (C) 2019 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.annotation.CheckResult;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.StringDef;
+import android.media.MediaCodec.CryptoInfo;
+import android.media.metrics.LogSessionId;
+import android.os.Build;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
+import android.util.SparseArray;
+
+import androidx.annotation.RequiresApi;
+
+import com.android.modules.utils.build.SdkLevel;
+
+import com.google.android.exoplayer2.C;
+import com.google.android.exoplayer2.Format;
+import com.google.android.exoplayer2.ParserException;
+import com.google.android.exoplayer2.drm.DrmInitData.SchemeData;
+import com.google.android.exoplayer2.extractor.ChunkIndex;
+import com.google.android.exoplayer2.extractor.DefaultExtractorInput;
+import com.google.android.exoplayer2.extractor.Extractor;
+import com.google.android.exoplayer2.extractor.ExtractorInput;
+import com.google.android.exoplayer2.extractor.ExtractorOutput;
+import com.google.android.exoplayer2.extractor.PositionHolder;
+import com.google.android.exoplayer2.extractor.SeekMap.SeekPoints;
+import com.google.android.exoplayer2.extractor.TrackOutput;
+import com.google.android.exoplayer2.extractor.amr.AmrExtractor;
+import com.google.android.exoplayer2.extractor.flac.FlacExtractor;
+import com.google.android.exoplayer2.extractor.flv.FlvExtractor;
+import com.google.android.exoplayer2.extractor.mkv.MatroskaExtractor;
+import com.google.android.exoplayer2.extractor.mp3.Mp3Extractor;
+import com.google.android.exoplayer2.extractor.mp4.FragmentedMp4Extractor;
+import com.google.android.exoplayer2.extractor.mp4.Mp4Extractor;
+import com.google.android.exoplayer2.extractor.ogg.OggExtractor;
+import com.google.android.exoplayer2.extractor.ts.Ac3Extractor;
+import com.google.android.exoplayer2.extractor.ts.Ac4Extractor;
+import com.google.android.exoplayer2.extractor.ts.AdtsExtractor;
+import com.google.android.exoplayer2.extractor.ts.DefaultTsPayloadReaderFactory;
+import com.google.android.exoplayer2.extractor.ts.PsExtractor;
+import com.google.android.exoplayer2.extractor.ts.TsExtractor;
+import com.google.android.exoplayer2.extractor.wav.WavExtractor;
+import com.google.android.exoplayer2.upstream.DataReader;
+import com.google.android.exoplayer2.util.ParsableByteArray;
+import com.google.android.exoplayer2.util.TimestampAdjuster;
+import com.google.android.exoplayer2.util.Util;
+import com.google.android.exoplayer2.video.ColorInfo;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.UUID;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.function.Function;
+
+/**
+ * Parses media container formats and extracts contained media samples and metadata.
+ *
+ * <p>This class provides access to a battery of low-level media container parsers. Each instance of
+ * this class is associated to a specific media parser implementation which is suitable for
+ * extraction from a specific media container format. The media parser implementation assignment
+ * depends on the factory method (see {@link #create} and {@link #createByName}) used to create the
+ * instance.
+ *
+ * <p>Users must implement the following to use this class.
+ *
+ * <ul>
+ *   <li>{@link InputReader}: Provides the media container's bytes to parse.
+ *   <li>{@link OutputConsumer}: Provides a sink for all extracted data and metadata.
+ * </ul>
+ *
+ * <p>The following code snippet includes a usage example:
+ *
+ * <pre>
+ * MyOutputConsumer myOutputConsumer = new MyOutputConsumer();
+ * MyInputReader myInputReader = new MyInputReader("www.example.com");
+ * MediaParser mediaParser = MediaParser.create(myOutputConsumer);
+ *
+ * while (mediaParser.advance(myInputReader)) {}
+ *
+ * mediaParser.release();
+ * mediaParser = null;
+ * </pre>
+ *
+ * <p>The following code snippet provides a rudimentary {@link OutputConsumer} sample implementation
+ * which extracts and publishes all video samples:
+ *
+ * <pre>
+ * class VideoOutputConsumer implements MediaParser.OutputConsumer {
+ *
+ *     private byte[] sampleDataBuffer = new byte[4096];
+ *     private byte[] discardedDataBuffer = new byte[4096];
+ *     private int videoTrackIndex = -1;
+ *     private int bytesWrittenCount = 0;
+ *
+ *     &#64;Override
+ *     public void onSeekMapFound(int i, &#64;NonNull MediaFormat mediaFormat) {
+ *       // Do nothing.
+ *     }
+ *
+ *     &#64;Override
+ *     public void onTrackDataFound(int i, &#64;NonNull TrackData trackData) {
+ *       MediaFormat mediaFormat = trackData.mediaFormat;
+ *       if (videoTrackIndex == -1 &amp;&amp;
+ *           mediaFormat
+ *               .getString(MediaFormat.KEY_MIME, &#47;* defaultValue= *&#47; "")
+ *               .startsWith("video/")) {
+ *         videoTrackIndex = i;
+ *       }
+ *     }
+ *
+ *     &#64;Override
+ *     public void onSampleDataFound(int trackIndex, &#64;NonNull InputReader inputReader)
+ *         throws IOException {
+ *       int numberOfBytesToRead = (int) inputReader.getLength();
+ *       if (videoTrackIndex != trackIndex) {
+ *         // Discard contents.
+ *         inputReader.read(
+ *             discardedDataBuffer,
+ *             &#47;* offset= *&#47; 0,
+ *             Math.min(discardDataBuffer.length, numberOfBytesToRead));
+ *       } else {
+ *         ensureSpaceInBuffer(numberOfBytesToRead);
+ *         int bytesRead = inputReader.read(
+ *             sampleDataBuffer, bytesWrittenCount, numberOfBytesToRead);
+ *         bytesWrittenCount += bytesRead;
+ *       }
+ *     }
+ *
+ *     &#64;Override
+ *     public void onSampleCompleted(
+ *         int trackIndex,
+ *         long timeMicros,
+ *         int flags,
+ *         int size,
+ *         int offset,
+ *         &#64;Nullable CryptoInfo cryptoData) {
+ *       if (videoTrackIndex != trackIndex) {
+ *         return; // It's not the video track. Ignore.
+ *       }
+ *       byte[] sampleData = new byte[size];
+ *       int sampleStartOffset = bytesWrittenCount - size - offset;
+ *       System.arraycopy(
+ *           sampleDataBuffer,
+ *           sampleStartOffset,
+ *           sampleData,
+ *           &#47;* destPos= *&#47; 0,
+ *           size);
+ *       // Place trailing bytes at the start of the buffer.
+ *       System.arraycopy(
+ *           sampleDataBuffer,
+ *           bytesWrittenCount - offset,
+ *           sampleDataBuffer,
+ *           &#47;* destPos= *&#47; 0,
+ *           &#47;* size= *&#47; offset);
+ *       bytesWrittenCount = bytesWrittenCount - offset;
+ *       publishSample(sampleData, timeMicros, flags);
+ *     }
+ *
+ *    private void ensureSpaceInBuffer(int numberOfBytesToRead) {
+ *      int requiredLength = bytesWrittenCount + numberOfBytesToRead;
+ *      if (requiredLength &gt; sampleDataBuffer.length) {
+ *        sampleDataBuffer = Arrays.copyOf(sampleDataBuffer, requiredLength);
+ *      }
+ *    }
+ *
+ *   }
+ *
+ * </pre>
+ */
+public final class MediaParser {
+
+    /**
+     * Maps seek positions to {@link SeekPoint SeekPoints} in the stream.
+     *
+     * <p>A {@link SeekPoint} is a position in the stream from which a player may successfully start
+     * playing media samples.
+     */
+    public static final class SeekMap {
+
+        /** Returned by {@link #getDurationMicros()} when the duration is unknown. */
+        public static final int UNKNOWN_DURATION = Integer.MIN_VALUE;
+
+        /**
+         * For each {@link #getSeekPoints} call, returns a single {@link SeekPoint} whose {@link
+         * SeekPoint#timeMicros} matches the requested timestamp, and whose {@link
+         * SeekPoint#position} is 0.
+         *
+         * @hide
+         */
+        public static final SeekMap DUMMY = new SeekMap(new DummyExoPlayerSeekMap());
+
+        private final com.google.android.exoplayer2.extractor.SeekMap mExoPlayerSeekMap;
+
+        private SeekMap(com.google.android.exoplayer2.extractor.SeekMap exoplayerSeekMap) {
+            mExoPlayerSeekMap = exoplayerSeekMap;
+        }
+
+        /** Returns whether seeking is supported. */
+        public boolean isSeekable() {
+            return mExoPlayerSeekMap.isSeekable();
+        }
+
+        /**
+         * Returns the duration of the stream in microseconds or {@link #UNKNOWN_DURATION} if the
+         * duration is unknown.
+         */
+        public long getDurationMicros() {
+            long durationUs = mExoPlayerSeekMap.getDurationUs();
+            return durationUs != C.TIME_UNSET ? durationUs : UNKNOWN_DURATION;
+        }
+
+        /**
+         * Obtains {@link SeekPoint SeekPoints} for the specified seek time in microseconds.
+         *
+         * <p>{@code getSeekPoints(timeMicros).first} contains the latest seek point for samples
+         * with timestamp equal to or smaller than {@code timeMicros}.
+         *
+         * <p>{@code getSeekPoints(timeMicros).second} contains the earliest seek point for samples
+         * with timestamp equal to or greater than {@code timeMicros}. If a seek point exists for
+         * {@code timeMicros}, the returned pair will contain the same {@link SeekPoint} twice.
+         *
+         * @param timeMicros A seek time in microseconds.
+         * @return The corresponding {@link SeekPoint SeekPoints}.
+         */
+        @NonNull
+        public Pair<SeekPoint, SeekPoint> getSeekPoints(long timeMicros) {
+            SeekPoints seekPoints = mExoPlayerSeekMap.getSeekPoints(timeMicros);
+            return new Pair<>(toSeekPoint(seekPoints.first), toSeekPoint(seekPoints.second));
+        }
+    }
+
+    /** Holds information associated with a track. */
+    public static final class TrackData {
+
+        /** Holds {@link MediaFormat} information for the track. */
+        @NonNull public final MediaFormat mediaFormat;
+
+        /**
+         * Holds {@link DrmInitData} necessary to acquire keys associated with the track, or null if
+         * the track has no encryption data.
+         */
+        @Nullable public final DrmInitData drmInitData;
+
+        private TrackData(MediaFormat mediaFormat, DrmInitData drmInitData) {
+            this.mediaFormat = mediaFormat;
+            this.drmInitData = drmInitData;
+        }
+    }
+
+    /** Defines a seek point in a media stream. */
+    public static final class SeekPoint {
+
+        /** A {@link SeekPoint} whose time and byte offset are both set to 0. */
+        @NonNull public static final SeekPoint START = new SeekPoint(0, 0);
+
+        /** The time of the seek point, in microseconds. */
+        public final long timeMicros;
+
+        /** The byte offset of the seek point. */
+        public final long position;
+
+        /**
+         * @param timeMicros The time of the seek point, in microseconds.
+         * @param position The byte offset of the seek point.
+         */
+        private SeekPoint(long timeMicros, long position) {
+            this.timeMicros = timeMicros;
+            this.position = position;
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "[timeMicros=" + timeMicros + ", position=" + position + "]";
+        }
+
+        @Override
+        public boolean equals(@Nullable Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (obj == null || getClass() != obj.getClass()) {
+                return false;
+            }
+            SeekPoint other = (SeekPoint) obj;
+            return timeMicros == other.timeMicros && position == other.position;
+        }
+
+        @Override
+        public int hashCode() {
+            int result = (int) timeMicros;
+            result = 31 * result + (int) position;
+            return result;
+        }
+    }
+
+    /** Provides input data to {@link MediaParser}. */
+    public interface InputReader {
+
+        /**
+         * Reads up to {@code readLength} bytes of data and stores them into {@code buffer},
+         * starting at index {@code offset}.
+         *
+         * <p>This method blocks until at least one byte is read, the end of input is detected, or
+         * an exception is thrown. The read position advances to the first unread byte.
+         *
+         * @param buffer The buffer into which the read data should be stored.
+         * @param offset The start offset into {@code buffer} at which data should be written.
+         * @param readLength The maximum number of bytes to read.
+         * @return The non-zero number of bytes read, or -1 if no data is available because the end
+         *     of the input has been reached.
+         * @throws java.io.IOException If an error occurs reading from the source.
+         */
+        int read(@NonNull byte[] buffer, int offset, int readLength) throws IOException;
+
+        /** Returns the current read position (byte offset) in the stream. */
+        long getPosition();
+
+        /** Returns the length of the input in bytes, or -1 if the length is unknown. */
+        long getLength();
+    }
+
+    /** {@link InputReader} that allows setting the read position. */
+    public interface SeekableInputReader extends InputReader {
+
+        /**
+         * Sets the read position at the given {@code position}.
+         *
+         * <p>{@link #advance} will immediately return after calling this method.
+         *
+         * @param position The position to seek to, in bytes.
+         */
+        void seekToPosition(long position);
+    }
+
+    /** Receives extracted media sample data and metadata from {@link MediaParser}. */
+    public interface OutputConsumer {
+
+        /**
+         * Called when a {@link SeekMap} has been extracted from the stream.
+         *
+         * <p>This method is called at least once before any samples are {@link #onSampleCompleted
+         * complete}. May be called multiple times after that in order to add {@link SeekPoint
+         * SeekPoints}.
+         *
+         * @param seekMap The extracted {@link SeekMap}.
+         */
+        void onSeekMapFound(@NonNull SeekMap seekMap);
+
+        /**
+         * Called when the number of tracks is found.
+         *
+         * @param numberOfTracks The number of tracks in the stream.
+         */
+        void onTrackCountFound(int numberOfTracks);
+
+        /**
+         * Called when new {@link TrackData} is found in the stream.
+         *
+         * @param trackIndex The index of the track for which the {@link TrackData} was extracted.
+         * @param trackData The extracted {@link TrackData}.
+         */
+        void onTrackDataFound(int trackIndex, @NonNull TrackData trackData);
+
+        /**
+         * Called when sample data is found in the stream.
+         *
+         * <p>If the invocation of this method returns before the entire {@code inputReader} {@link
+         * InputReader#getLength() length} is consumed, the method will be called again for the
+         * implementer to read the remaining data. Implementers should surface any thrown {@link
+         * IOException} caused by reading from {@code input}.
+         *
+         * @param trackIndex The index of the track to which the sample data corresponds.
+         * @param inputReader The {@link InputReader} from which to read the data.
+         * @throws IOException If an exception occurs while reading from {@code inputReader}.
+         */
+        void onSampleDataFound(int trackIndex, @NonNull InputReader inputReader) throws IOException;
+
+        /**
+         * Called once all the data of a sample has been passed to {@link #onSampleDataFound}.
+         *
+         * <p>Includes sample metadata, like presentation timestamp and flags.
+         *
+         * @param trackIndex The index of the track to which the sample corresponds.
+         * @param timeMicros The media timestamp associated with the sample, in microseconds.
+         * @param flags Flags associated with the sample. See the {@code SAMPLE_FLAG_*} constants.
+         * @param size The size of the sample data, in bytes.
+         * @param offset The number of bytes that have been consumed by {@code
+         *     onSampleDataFound(int, MediaParser.InputReader)} for the specified track, since the
+         *     last byte belonging to the sample whose metadata is being passed.
+         * @param cryptoInfo Encryption data required to decrypt the sample. May be null for
+         *     unencrypted samples. Implementors should treat any output {@link CryptoInfo}
+         *     instances as immutable. MediaParser will not modify any output {@code cryptoInfos}
+         *     and implementors should not modify them either.
+         */
+        void onSampleCompleted(
+                int trackIndex,
+                long timeMicros,
+                @SampleFlags int flags,
+                int size,
+                int offset,
+                @Nullable CryptoInfo cryptoInfo);
+    }
+
+    /**
+     * Thrown if all parser implementations provided to {@link #create} failed to sniff the input
+     * content.
+     */
+    public static final class UnrecognizedInputFormatException extends IOException {
+
+        /**
+         * Creates a new instance which signals that the parsers with the given names failed to
+         * parse the input.
+         */
+        @NonNull
+        @CheckResult
+        private static UnrecognizedInputFormatException createForExtractors(
+                @NonNull String... extractorNames) {
+            StringBuilder builder = new StringBuilder();
+            builder.append("None of the available parsers ( ");
+            builder.append(extractorNames[0]);
+            for (int i = 1; i < extractorNames.length; i++) {
+                builder.append(", ");
+                builder.append(extractorNames[i]);
+            }
+            builder.append(") could read the stream.");
+            return new UnrecognizedInputFormatException(builder.toString());
+        }
+
+        private UnrecognizedInputFormatException(String extractorNames) {
+            super(extractorNames);
+        }
+    }
+
+    /** Thrown when an error occurs while parsing a media stream. */
+    public static final class ParsingException extends IOException {
+
+        private ParsingException(ParserException cause) {
+            super(cause);
+        }
+    }
+
+    // Sample flags.
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(
+            flag = true,
+            value = {
+                SAMPLE_FLAG_KEY_FRAME,
+                SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA,
+                SAMPLE_FLAG_LAST_SAMPLE,
+                SAMPLE_FLAG_ENCRYPTED,
+                SAMPLE_FLAG_DECODE_ONLY
+            })
+    public @interface SampleFlags {}
+    /** Indicates that the sample holds a synchronization sample. */
+    public static final int SAMPLE_FLAG_KEY_FRAME = MediaCodec.BUFFER_FLAG_KEY_FRAME;
+    /**
+     * Indicates that the sample has supplemental data.
+     *
+     * <p>Samples will not have this flag set unless the {@code
+     * "android.media.mediaparser.includeSupplementalData"} parameter is set to {@code true} via
+     * {@link #setParameter}.
+     *
+     * <p>Samples with supplemental data have the following sample data format:
+     *
+     * <ul>
+     *   <li>If the {@code "android.media.mediaparser.inBandCryptoInfo"} parameter is set, all
+     *       encryption information.
+     *   <li>(4 bytes) {@code sample_data_size}: The size of the actual sample data, not including
+     *       supplemental data or encryption information.
+     *   <li>({@code sample_data_size} bytes): The media sample data.
+     *   <li>(remaining bytes) The supplemental data.
+     * </ul>
+     */
+    public static final int SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA = 1 << 28;
+    /** Indicates that the sample is known to contain the last media sample of the stream. */
+    public static final int SAMPLE_FLAG_LAST_SAMPLE = 1 << 29;
+    /** Indicates that the sample is (at least partially) encrypted. */
+    public static final int SAMPLE_FLAG_ENCRYPTED = 1 << 30;
+    /** Indicates that the sample should be decoded but not rendered. */
+    public static final int SAMPLE_FLAG_DECODE_ONLY = 1 << 31;
+
+    // Parser implementation names.
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @StringDef(
+            prefix = {"PARSER_NAME_"},
+            value = {
+                PARSER_NAME_UNKNOWN,
+                PARSER_NAME_MATROSKA,
+                PARSER_NAME_FMP4,
+                PARSER_NAME_MP4,
+                PARSER_NAME_MP3,
+                PARSER_NAME_ADTS,
+                PARSER_NAME_AC3,
+                PARSER_NAME_TS,
+                PARSER_NAME_FLV,
+                PARSER_NAME_OGG,
+                PARSER_NAME_PS,
+                PARSER_NAME_WAV,
+                PARSER_NAME_AMR,
+                PARSER_NAME_AC4,
+                PARSER_NAME_FLAC
+            })
+    public @interface ParserName {}
+
+    /** Parser name returned by {@link #getParserName()} when no parser has been selected yet. */
+    public static final String PARSER_NAME_UNKNOWN = "android.media.mediaparser.UNKNOWN";
+    /**
+     * Parser for the Matroska container format, as defined in the <a
+     * href="https://matroska.org/technical/specs/">spec</a>.
+     */
+    public static final String PARSER_NAME_MATROSKA = "android.media.mediaparser.MatroskaParser";
+    /**
+     * Parser for fragmented files using the MP4 container format, as defined in ISO/IEC 14496-12.
+     */
+    public static final String PARSER_NAME_FMP4 = "android.media.mediaparser.FragmentedMp4Parser";
+    /**
+     * Parser for non-fragmented files using the MP4 container format, as defined in ISO/IEC
+     * 14496-12.
+     */
+    public static final String PARSER_NAME_MP4 = "android.media.mediaparser.Mp4Parser";
+    /** Parser for the MP3 container format, as defined in ISO/IEC 11172-3. */
+    public static final String PARSER_NAME_MP3 = "android.media.mediaparser.Mp3Parser";
+    /** Parser for the ADTS container format, as defined in ISO/IEC 13818-7. */
+    public static final String PARSER_NAME_ADTS = "android.media.mediaparser.AdtsParser";
+    /**
+     * Parser for the AC-3 container format, as defined in Digital Audio Compression Standard
+     * (AC-3).
+     */
+    public static final String PARSER_NAME_AC3 = "android.media.mediaparser.Ac3Parser";
+    /** Parser for the TS container format, as defined in ISO/IEC 13818-1. */
+    public static final String PARSER_NAME_TS = "android.media.mediaparser.TsParser";
+    /**
+     * Parser for the FLV container format, as defined in Adobe Flash Video File Format
+     * Specification.
+     */
+    public static final String PARSER_NAME_FLV = "android.media.mediaparser.FlvParser";
+    /** Parser for the OGG container format, as defined in RFC 3533. */
+    public static final String PARSER_NAME_OGG = "android.media.mediaparser.OggParser";
+    /** Parser for the PS container format, as defined in ISO/IEC 11172-1. */
+    public static final String PARSER_NAME_PS = "android.media.mediaparser.PsParser";
+    /**
+     * Parser for the WAV container format, as defined in Multimedia Programming Interface and Data
+     * Specifications.
+     */
+    public static final String PARSER_NAME_WAV = "android.media.mediaparser.WavParser";
+    /** Parser for the AMR container format, as defined in RFC 4867. */
+    public static final String PARSER_NAME_AMR = "android.media.mediaparser.AmrParser";
+    /**
+     * Parser for the AC-4 container format, as defined by Dolby AC-4: Audio delivery for
+     * Next-Generation Entertainment Services.
+     */
+    public static final String PARSER_NAME_AC4 = "android.media.mediaparser.Ac4Parser";
+    /**
+     * Parser for the FLAC container format, as defined in the <a
+     * href="https://xiph.org/flac/">spec</a>.
+     */
+    public static final String PARSER_NAME_FLAC = "android.media.mediaparser.FlacParser";
+
+    // MediaParser parameters.
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @StringDef(
+            prefix = {"PARAMETER_"},
+            value = {
+                PARAMETER_ADTS_ENABLE_CBR_SEEKING,
+                PARAMETER_AMR_ENABLE_CBR_SEEKING,
+                PARAMETER_FLAC_DISABLE_ID3,
+                PARAMETER_MP4_IGNORE_EDIT_LISTS,
+                PARAMETER_MP4_IGNORE_TFDT_BOX,
+                PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES,
+                PARAMETER_MATROSKA_DISABLE_CUES_SEEKING,
+                PARAMETER_MP3_DISABLE_ID3,
+                PARAMETER_MP3_ENABLE_CBR_SEEKING,
+                PARAMETER_MP3_ENABLE_INDEX_SEEKING,
+                PARAMETER_TS_MODE,
+                PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES,
+                PARAMETER_TS_IGNORE_AAC_STREAM,
+                PARAMETER_TS_IGNORE_AVC_STREAM,
+                PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM,
+                PARAMETER_TS_DETECT_ACCESS_UNITS,
+                PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS,
+                PARAMETER_IN_BAND_CRYPTO_INFO,
+                PARAMETER_INCLUDE_SUPPLEMENTAL_DATA
+            })
+    public @interface ParameterName {}
+
+    /**
+     * Sets whether constant bitrate seeking should be enabled for ADTS parsing. {@code boolean}
+     * expected. Default value is {@code false}.
+     */
+    public static final String PARAMETER_ADTS_ENABLE_CBR_SEEKING =
+            "android.media.mediaparser.adts.enableCbrSeeking";
+    /**
+     * Sets whether constant bitrate seeking should be enabled for AMR. {@code boolean} expected.
+     * Default value is {@code false}.
+     */
+    public static final String PARAMETER_AMR_ENABLE_CBR_SEEKING =
+            "android.media.mediaparser.amr.enableCbrSeeking";
+    /**
+     * Sets whether the ID3 track should be disabled for FLAC. {@code boolean} expected. Default
+     * value is {@code false}.
+     */
+    public static final String PARAMETER_FLAC_DISABLE_ID3 =
+            "android.media.mediaparser.flac.disableId3";
+    /**
+     * Sets whether MP4 parsing should ignore edit lists. {@code boolean} expected. Default value is
+     * {@code false}.
+     */
+    public static final String PARAMETER_MP4_IGNORE_EDIT_LISTS =
+            "android.media.mediaparser.mp4.ignoreEditLists";
+    /**
+     * Sets whether MP4 parsing should ignore the tfdt box. {@code boolean} expected. Default value
+     * is {@code false}.
+     */
+    public static final String PARAMETER_MP4_IGNORE_TFDT_BOX =
+            "android.media.mediaparser.mp4.ignoreTfdtBox";
+    /**
+     * Sets whether MP4 parsing should treat all video frames as key frames. {@code boolean}
+     * expected. Default value is {@code false}.
+     */
+    public static final String PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES =
+            "android.media.mediaparser.mp4.treatVideoFramesAsKeyframes";
+    /**
+     * Sets whether Matroska parsing should avoid seeking to the cues element. {@code boolean}
+     * expected. Default value is {@code false}.
+     *
+     * <p>If this flag is enabled and the cues element occurs after the first cluster, then the
+     * media is treated as unseekable.
+     */
+    public static final String PARAMETER_MATROSKA_DISABLE_CUES_SEEKING =
+            "android.media.mediaparser.matroska.disableCuesSeeking";
+    /**
+     * Sets whether the ID3 track should be disabled for MP3. {@code boolean} expected. Default
+     * value is {@code false}.
+     */
+    public static final String PARAMETER_MP3_DISABLE_ID3 =
+            "android.media.mediaparser.mp3.disableId3";
+    /**
+     * Sets whether constant bitrate seeking should be enabled for MP3. {@code boolean} expected.
+     * Default value is {@code false}.
+     */
+    public static final String PARAMETER_MP3_ENABLE_CBR_SEEKING =
+            "android.media.mediaparser.mp3.enableCbrSeeking";
+    /**
+     * Sets whether MP3 parsing should generate a time-to-byte mapping. {@code boolean} expected.
+     * Default value is {@code false}.
+     *
+     * <p>Enabling this flag may require to scan a significant portion of the file to compute a seek
+     * point. Therefore, it should only be used if:
+     *
+     * <ul>
+     *   <li>the file is small, or
+     *   <li>the bitrate is variable (or the type of bitrate is unknown) and the seeking metadata
+     *       provided in the file is not precise enough (or is not present).
+     * </ul>
+     */
+    public static final String PARAMETER_MP3_ENABLE_INDEX_SEEKING =
+            "android.media.mediaparser.mp3.enableIndexSeeking";
+    /**
+     * Sets the operation mode for TS parsing. {@code String} expected. Valid values are {@code
+     * "single_pmt"}, {@code "multi_pmt"}, and {@code "hls"}. Default value is {@code "single_pmt"}.
+     *
+     * <p>The operation modes alter the way TS behaves so that it can handle certain kinds of
+     * commonly-occurring malformed media.
+     *
+     * <ul>
+     *   <li>{@code "single_pmt"}: Only the first found PMT is parsed. Others are ignored, even if
+     *       more PMTs are declared in the PAT.
+     *   <li>{@code "multi_pmt"}: Behave as described in ISO/IEC 13818-1.
+     *   <li>{@code "hls"}: Enable {@code "single_pmt"} mode, and ignore continuity counters.
+     * </ul>
+     */
+    public static final String PARAMETER_TS_MODE = "android.media.mediaparser.ts.mode";
+    /**
+     * Sets whether TS should treat samples consisting of non-IDR I slices as synchronization
+     * samples (key-frames). {@code boolean} expected. Default value is {@code false}.
+     */
+    public static final String PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES =
+            "android.media.mediaparser.ts.allowNonIdrAvcKeyframes";
+    /**
+     * Sets whether TS parsing should ignore AAC elementary streams. {@code boolean} expected.
+     * Default value is {@code false}.
+     */
+    public static final String PARAMETER_TS_IGNORE_AAC_STREAM =
+            "android.media.mediaparser.ts.ignoreAacStream";
+    /**
+     * Sets whether TS parsing should ignore AVC elementary streams. {@code boolean} expected.
+     * Default value is {@code false}.
+     */
+    public static final String PARAMETER_TS_IGNORE_AVC_STREAM =
+            "android.media.mediaparser.ts.ignoreAvcStream";
+    /**
+     * Sets whether TS parsing should ignore splice information streams. {@code boolean} expected.
+     * Default value is {@code false}.
+     */
+    public static final String PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM =
+            "android.media.mediaparser.ts.ignoreSpliceInfoStream";
+    /**
+     * Sets whether TS parsing should split AVC stream into access units based on slice headers.
+     * {@code boolean} expected. Default value is {@code false}.
+     *
+     * <p>This flag should be left disabled if the stream contains access units delimiters in order
+     * to avoid unnecessary computational costs.
+     */
+    public static final String PARAMETER_TS_DETECT_ACCESS_UNITS =
+            "android.media.mediaparser.ts.ignoreDetectAccessUnits";
+    /**
+     * Sets whether TS parsing should handle HDMV DTS audio streams. {@code boolean} expected.
+     * Default value is {@code false}.
+     *
+     * <p>Enabling this flag will disable the detection of SCTE subtitles.
+     */
+    public static final String PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS =
+            "android.media.mediaparser.ts.enableHdmvDtsAudioStreams";
+    /**
+     * Sets whether encryption data should be sent in-band with the sample data, as per {@link
+     * OutputConsumer#onSampleDataFound}. {@code boolean} expected. Default value is {@code false}.
+     *
+     * <p>If this parameter is set, encrypted samples' data will be prefixed with the encryption
+     * information bytes. The format for in-band encryption information is:
+     *
+     * <ul>
+     *   <li>(1 byte) {@code encryption_signal_byte}: Most significant bit signals whether the
+     *       encryption data contains subsample encryption data. The remaining bits contain {@code
+     *       initialization_vector_size}.
+     *   <li>({@code initialization_vector_size} bytes) Initialization vector.
+     *   <li>If subsample encryption data is present, as per {@code encryption_signal_byte}, the
+     *       encryption data also contains:
+     *       <ul>
+     *         <li>(2 bytes) {@code subsample_encryption_data_length}.
+     *         <li>({@code subsample_encryption_data_length * 6} bytes) Subsample encryption data
+     *             (repeated {@code subsample_encryption_data_length} times):
+     *             <ul>
+     *               <li>(2 bytes) Size of a clear section in sample.
+     *               <li>(4 bytes) Size of an encryption section in sample.
+     *             </ul>
+     *       </ul>
+     * </ul>
+     *
+     * @hide
+     */
+    public static final String PARAMETER_IN_BAND_CRYPTO_INFO =
+            "android.media.mediaparser.inBandCryptoInfo";
+    /**
+     * Sets whether supplemental data should be included as part of the sample data. {@code boolean}
+     * expected. Default value is {@code false}. See {@link #SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA} for
+     * information about the sample data format.
+     *
+     * @hide
+     */
+    public static final String PARAMETER_INCLUDE_SUPPLEMENTAL_DATA =
+            "android.media.mediaparser.includeSupplementalData";
+    /**
+     * Sets whether sample timestamps may start from non-zero offsets. {@code boolean} expected.
+     * Default value is {@code false}.
+     *
+     * <p>When set to true, sample timestamps will not be offset to start from zero, and the media
+     * provided timestamps will be used instead. For example, transport stream sample timestamps
+     * will not be converted to a zero-based timebase.
+     *
+     * @hide
+     */
+    public static final String PARAMETER_IGNORE_TIMESTAMP_OFFSET =
+            "android.media.mediaparser.ignoreTimestampOffset";
+    /**
+     * Sets whether each track type should be eagerly exposed. {@code boolean} expected. Default
+     * value is {@code false}.
+     *
+     * <p>When set to true, each track type will be eagerly exposed through a call to {@link
+     * OutputConsumer#onTrackDataFound} containing a single-value {@link MediaFormat}. The key for
+     * the track type is {@code "track-type-string"}, and the possible values are {@code "video"},
+     * {@code "audio"}, {@code "text"}, {@code "metadata"}, and {@code "unknown"}.
+     *
+     * @hide
+     */
+    public static final String PARAMETER_EAGERLY_EXPOSE_TRACKTYPE =
+            "android.media.mediaparser.eagerlyExposeTrackType";
+    /**
+     * Sets whether a dummy {@link SeekMap} should be exposed before starting extraction. {@code
+     * boolean} expected. Default value is {@code false}.
+     *
+     * <p>For each {@link SeekMap#getSeekPoints} call, the dummy {@link SeekMap} returns a single
+     * {@link SeekPoint} whose {@link SeekPoint#timeMicros} matches the requested timestamp, and
+     * whose {@link SeekPoint#position} is 0.
+     *
+     * @hide
+     */
+    public static final String PARAMETER_EXPOSE_DUMMY_SEEKMAP =
+            "android.media.mediaparser.exposeDummySeekMap";
+
+    /**
+     * Sets whether chunk indices available in the extracted media should be exposed as {@link
+     * MediaFormat MediaFormats}. {@code boolean} expected. Default value is {@link false}.
+     *
+     * <p>When set to true, any information about media segmentation will be exposed as a {@link
+     * MediaFormat} (with track index 0) containing four {@link ByteBuffer} elements under the
+     * following keys:
+     *
+     * <ul>
+     *   <li>"chunk-index-int-sizes": Contains {@code ints} representing the sizes in bytes of each
+     *       of the media segments.
+     *   <li>"chunk-index-long-offsets": Contains {@code longs} representing the byte offsets of
+     *       each segment in the stream.
+     *   <li>"chunk-index-long-us-durations": Contains {@code longs} representing the media duration
+     *       of each segment, in microseconds.
+     *   <li>"chunk-index-long-us-times": Contains {@code longs} representing the start time of each
+     *       segment, in microseconds.
+     * </ul>
+     *
+     * @hide
+     */
+    public static final String PARAMETER_EXPOSE_CHUNK_INDEX_AS_MEDIA_FORMAT =
+            "android.media.mediaParser.exposeChunkIndexAsMediaFormat";
+    /**
+     * Sets a list of closed-caption {@link MediaFormat MediaFormats} that should be exposed as part
+     * of the extracted media. {@code List<MediaFormat>} expected. Default value is an empty list.
+     *
+     * <p>Expected keys in the {@link MediaFormat} are:
+     *
+     * <ul>
+     *   <p>{@link MediaFormat#KEY_MIME}: Determine the type of captions (for example,
+     *   application/cea-608). Mandatory.
+     *   <p>{@link MediaFormat#KEY_CAPTION_SERVICE_NUMBER}: Determine the channel on which the
+     *   captions are transmitted. Optional.
+     * </ul>
+     *
+     * @hide
+     */
+    public static final String PARAMETER_EXPOSE_CAPTION_FORMATS =
+            "android.media.mediaParser.exposeCaptionFormats";
+    /**
+     * Sets whether the value associated with {@link #PARAMETER_EXPOSE_CAPTION_FORMATS} should
+     * override any in-band caption service declarations. {@code boolean} expected. Default value is
+     * {@link false}.
+     *
+     * <p>When {@code false}, any present in-band caption services information will override the
+     * values associated with {@link #PARAMETER_EXPOSE_CAPTION_FORMATS}.
+     *
+     * @hide
+     */
+    public static final String PARAMETER_OVERRIDE_IN_BAND_CAPTION_DECLARATIONS =
+            "android.media.mediaParser.overrideInBandCaptionDeclarations";
+    /**
+     * Sets whether a track for EMSG events should be exposed in case of parsing a container that
+     * supports them. {@code boolean} expected. Default value is {@link false}.
+     *
+     * @hide
+     */
+    public static final String PARAMETER_EXPOSE_EMSG_TRACK =
+            "android.media.mediaParser.exposeEmsgTrack";
+
+    // Private constants.
+
+    private static final String TAG = "MediaParser";
+    private static final String JNI_LIBRARY_NAME = "mediaparser-jni";
+    private static final Map<String, ExtractorFactory> EXTRACTOR_FACTORIES_BY_NAME;
+    private static final Map<String, Class> EXPECTED_TYPE_BY_PARAMETER_NAME;
+    private static final String TS_MODE_SINGLE_PMT = "single_pmt";
+    private static final String TS_MODE_MULTI_PMT = "multi_pmt";
+    private static final String TS_MODE_HLS = "hls";
+    private static final int BYTES_PER_SUBSAMPLE_ENCRYPTION_ENTRY = 6;
+    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+    private static final String MEDIAMETRICS_ELEMENT_SEPARATOR = "|";
+    private static final int MEDIAMETRICS_MAX_STRING_SIZE = 200;
+    private static final int MEDIAMETRICS_PARAMETER_LIST_MAX_LENGTH;
+    /**
+     * Intentional error introduced to reported metrics to prevent identification of the parsed
+     * media. Note: Increasing this value may cause older hostside CTS tests to fail.
+     */
+    private static final float MEDIAMETRICS_DITHER = .02f;
+
+    @IntDef(
+            value = {
+                STATE_READING_SIGNAL_BYTE,
+                STATE_READING_INIT_VECTOR,
+                STATE_READING_SUBSAMPLE_ENCRYPTION_SIZE,
+                STATE_READING_SUBSAMPLE_ENCRYPTION_DATA
+            })
+    private @interface EncryptionDataReadState {}
+
+    private static final int STATE_READING_SIGNAL_BYTE = 0;
+    private static final int STATE_READING_INIT_VECTOR = 1;
+    private static final int STATE_READING_SUBSAMPLE_ENCRYPTION_SIZE = 2;
+    private static final int STATE_READING_SUBSAMPLE_ENCRYPTION_DATA = 3;
+
+    // Instance creation methods.
+
+    /**
+     * Creates an instance backed by the parser with the given {@code name}. The returned instance
+     * will attempt parsing without sniffing the content.
+     *
+     * @param name The name of the parser that will be associated with the created instance.
+     * @param outputConsumer The {@link OutputConsumer} to which track data and samples are pushed.
+     * @return A new instance.
+     * @throws IllegalArgumentException If an invalid name is provided.
+     */
+    @NonNull
+    public static MediaParser createByName(
+            @NonNull @ParserName String name, @NonNull OutputConsumer outputConsumer) {
+        String[] nameAsArray = new String[] {name};
+        assertValidNames(nameAsArray);
+        return new MediaParser(outputConsumer, /* createdByName= */ true, name);
+    }
+
+    /**
+     * Creates an instance whose backing parser will be selected by sniffing the content during the
+     * first {@link #advance} call. Parser implementations will sniff the content in order of
+     * appearance in {@code parserNames}.
+     *
+     * @param outputConsumer The {@link OutputConsumer} to which extracted data is output.
+     * @param parserNames The names of the parsers to sniff the content with. If empty, a default
+     *     array of names is used.
+     * @return A new instance.
+     */
+    @NonNull
+    public static MediaParser create(
+            @NonNull OutputConsumer outputConsumer, @NonNull @ParserName String... parserNames) {
+        assertValidNames(parserNames);
+        if (parserNames.length == 0) {
+            parserNames = EXTRACTOR_FACTORIES_BY_NAME.keySet().toArray(new String[0]);
+        }
+        return new MediaParser(outputConsumer, /* createdByName= */ false, parserNames);
+    }
+
+    // Misc static methods.
+
+    /**
+     * Returns an immutable list with the names of the parsers that are suitable for container
+     * formats with the given {@link MediaFormat}.
+     *
+     * <p>A parser supports a {@link MediaFormat} if the mime type associated with {@link
+     * MediaFormat#KEY_MIME} corresponds to the supported container format.
+     *
+     * @param mediaFormat The {@link MediaFormat} to check support for.
+     * @return The parser names that support the given {@code mediaFormat}, or the list of all
+     *     parsers available if no container specific format information is provided.
+     */
+    @NonNull
+    @ParserName
+    public static List<String> getParserNames(@NonNull MediaFormat mediaFormat) {
+        String mimeType = mediaFormat.getString(MediaFormat.KEY_MIME);
+        mimeType = mimeType == null ? null : Util.toLowerInvariant(mimeType.trim());
+        if (TextUtils.isEmpty(mimeType)) {
+            // No MIME type provided. Return all.
+            return Collections.unmodifiableList(
+                    new ArrayList<>(EXTRACTOR_FACTORIES_BY_NAME.keySet()));
+        }
+        ArrayList<String> result = new ArrayList<>();
+        switch (mimeType) {
+            case "video/x-matroska":
+            case "audio/x-matroska":
+            case "video/x-webm":
+            case "audio/x-webm":
+                result.add(PARSER_NAME_MATROSKA);
+                break;
+            case "video/mp4":
+            case "audio/mp4":
+            case "application/mp4":
+                result.add(PARSER_NAME_MP4);
+                result.add(PARSER_NAME_FMP4);
+                break;
+            case "audio/mpeg":
+                result.add(PARSER_NAME_MP3);
+                break;
+            case "audio/aac":
+                result.add(PARSER_NAME_ADTS);
+                break;
+            case "audio/ac3":
+                result.add(PARSER_NAME_AC3);
+                break;
+            case "video/mp2t":
+            case "audio/mp2t":
+                result.add(PARSER_NAME_TS);
+                break;
+            case "video/x-flv":
+                result.add(PARSER_NAME_FLV);
+                break;
+            case "video/ogg":
+            case "audio/ogg":
+            case "application/ogg":
+                result.add(PARSER_NAME_OGG);
+                break;
+            case "video/mp2p":
+            case "video/mp1s":
+                result.add(PARSER_NAME_PS);
+                break;
+            case "audio/vnd.wave":
+            case "audio/wav":
+            case "audio/wave":
+            case "audio/x-wav":
+                result.add(PARSER_NAME_WAV);
+                break;
+            case "audio/amr":
+                result.add(PARSER_NAME_AMR);
+                break;
+            case "audio/ac4":
+                result.add(PARSER_NAME_AC4);
+                break;
+            case "audio/flac":
+            case "audio/x-flac":
+                result.add(PARSER_NAME_FLAC);
+                break;
+            default:
+                // No parsers support the given mime type. Do nothing.
+                break;
+        }
+        return Collections.unmodifiableList(result);
+    }
+
+    // Private fields.
+
+    private final Map<String, Object> mParserParameters;
+    private final OutputConsumer mOutputConsumer;
+    private final String[] mParserNamesPool;
+    private final PositionHolder mPositionHolder;
+    private final InputReadingDataReader mExoDataReader;
+    private final DataReaderAdapter mScratchDataReaderAdapter;
+    private final ParsableByteArrayAdapter mScratchParsableByteArrayAdapter;
+    @Nullable private final Constructor<DrmInitData.SchemeInitData> mSchemeInitDataConstructor;
+    private final ArrayList<Format> mMuxedCaptionFormats;
+    private boolean mInBandCryptoInfo;
+    private boolean mIncludeSupplementalData;
+    private boolean mIgnoreTimestampOffset;
+    private boolean mEagerlyExposeTrackType;
+    private boolean mExposeDummySeekMap;
+    private boolean mExposeChunkIndexAsMediaFormat;
+    private String mParserName;
+    private Extractor mExtractor;
+    private ExtractorInput mExtractorInput;
+    private boolean mPendingExtractorInit;
+    private long mPendingSeekPosition;
+    private long mPendingSeekTimeMicros;
+    private boolean mLoggedSchemeInitDataCreationException;
+    private boolean mReleased;
+
+    // MediaMetrics fields.
+    @Nullable private LogSessionId mLogSessionId;
+    private final boolean mCreatedByName;
+    private final SparseArray<Format> mTrackFormats;
+    private String mLastObservedExceptionName;
+    private long mDurationMillis;
+    private long mResourceByteCount;
+
+    // Public methods.
+
+    /**
+     * Sets parser-specific parameters which allow customizing behavior.
+     *
+     * <p>Must be called before the first call to {@link #advance}.
+     *
+     * @param parameterName The name of the parameter to set. See {@code PARAMETER_*} constants for
+     *     documentation on possible values.
+     * @param value The value to set for the given {@code parameterName}. See {@code PARAMETER_*}
+     *     constants for documentation on the expected types.
+     * @return This instance, for convenience.
+     * @throws IllegalStateException If called after calling {@link #advance} on the same instance.
+     */
+    @NonNull
+    public MediaParser setParameter(
+            @NonNull @ParameterName String parameterName, @NonNull Object value) {
+        if (mExtractor != null) {
+            throw new IllegalStateException(
+                    "setParameters() must be called before the first advance() call.");
+        }
+        Class expectedType = EXPECTED_TYPE_BY_PARAMETER_NAME.get(parameterName);
+        // Ignore parameter names that are not contained in the map, in case the client is passing
+        // a parameter that is being added in a future version of this library.
+        if (expectedType != null && !expectedType.isInstance(value)) {
+            throw new IllegalArgumentException(
+                    parameterName
+                            + " expects a "
+                            + expectedType.getSimpleName()
+                            + " but a "
+                            + value.getClass().getSimpleName()
+                            + " was passed.");
+        }
+        if (PARAMETER_TS_MODE.equals(parameterName)
+                && !TS_MODE_SINGLE_PMT.equals(value)
+                && !TS_MODE_HLS.equals(value)
+                && !TS_MODE_MULTI_PMT.equals(value)) {
+            throw new IllegalArgumentException(PARAMETER_TS_MODE + " does not accept: " + value);
+        }
+        if (PARAMETER_IN_BAND_CRYPTO_INFO.equals(parameterName)) {
+            mInBandCryptoInfo = (boolean) value;
+        }
+        if (PARAMETER_INCLUDE_SUPPLEMENTAL_DATA.equals(parameterName)) {
+            mIncludeSupplementalData = (boolean) value;
+        }
+        if (PARAMETER_IGNORE_TIMESTAMP_OFFSET.equals(parameterName)) {
+            mIgnoreTimestampOffset = (boolean) value;
+        }
+        if (PARAMETER_EAGERLY_EXPOSE_TRACKTYPE.equals(parameterName)) {
+            mEagerlyExposeTrackType = (boolean) value;
+        }
+        if (PARAMETER_EXPOSE_DUMMY_SEEKMAP.equals(parameterName)) {
+            mExposeDummySeekMap = (boolean) value;
+        }
+        if (PARAMETER_EXPOSE_CHUNK_INDEX_AS_MEDIA_FORMAT.equals(parameterName)) {
+            mExposeChunkIndexAsMediaFormat = (boolean) value;
+        }
+        if (PARAMETER_EXPOSE_CAPTION_FORMATS.equals(parameterName)) {
+            setMuxedCaptionFormats((List<MediaFormat>) value);
+        }
+        mParserParameters.put(parameterName, value);
+        return this;
+    }
+
+    /**
+     * Returns whether the given {@code parameterName} is supported by this parser.
+     *
+     * @param parameterName The parameter name to check support for. One of the {@code PARAMETER_*}
+     *     constants.
+     * @return Whether the given {@code parameterName} is supported.
+     */
+    public boolean supportsParameter(@NonNull @ParameterName String parameterName) {
+        return EXPECTED_TYPE_BY_PARAMETER_NAME.containsKey(parameterName);
+    }
+
+    /**
+     * Returns the name of the backing parser implementation.
+     *
+     * <p>If this instance was creating using {@link #createByName}, the provided name is returned.
+     * If this instance was created using {@link #create}, this method will return {@link
+     * #PARSER_NAME_UNKNOWN} until the first call to {@link #advance}, after which the name of the
+     * backing parser implementation is returned.
+     *
+     * @return The name of the backing parser implementation, or null if the backing parser
+     *     implementation has not yet been selected.
+     */
+    @NonNull
+    @ParserName
+    public String getParserName() {
+        return mParserName;
+    }
+
+    /**
+     * Makes progress in the extraction of the input media stream, unless the end of the input has
+     * been reached.
+     *
+     * <p>This method will block until some progress has been made.
+     *
+     * <p>If this instance was created using {@link #create}, the first call to this method will
+     * sniff the content using the selected parser implementations.
+     *
+     * @param seekableInputReader The {@link SeekableInputReader} from which to obtain the media
+     *     container data.
+     * @return Whether there is any data left to extract. Returns false if the end of input has been
+     *     reached.
+     * @throws IOException If an error occurs while reading from the {@link SeekableInputReader}.
+     * @throws UnrecognizedInputFormatException If the format cannot be recognized by any of the
+     *     underlying parser implementations.
+     */
+    public boolean advance(@NonNull SeekableInputReader seekableInputReader) throws IOException {
+        if (mExtractorInput == null) {
+            // TODO: For efficiency, the same implementation should be used, by providing a
+            // clearBuffers() method, or similar.
+            long resourceLength = seekableInputReader.getLength();
+            if (mResourceByteCount == 0) {
+                // For resource byte count metric collection, we only take into account the length
+                // of the first provided input reader.
+                mResourceByteCount = resourceLength;
+            }
+            mExtractorInput =
+                    new DefaultExtractorInput(
+                            mExoDataReader, seekableInputReader.getPosition(), resourceLength);
+        }
+        mExoDataReader.mInputReader = seekableInputReader;
+
+        if (mExtractor == null) {
+            mPendingExtractorInit = true;
+            if (!mParserName.equals(PARSER_NAME_UNKNOWN)) {
+                mExtractor = createExtractor(mParserName);
+            } else {
+                for (String parserName : mParserNamesPool) {
+                    Extractor extractor = createExtractor(parserName);
+                    try {
+                        if (extractor.sniff(mExtractorInput)) {
+                            mParserName = parserName;
+                            mExtractor = extractor;
+                            mPendingExtractorInit = true;
+                            break;
+                        }
+                    } catch (EOFException e) {
+                        // Do nothing.
+                    } finally {
+                        mExtractorInput.resetPeekPosition();
+                    }
+                }
+                if (mExtractor == null) {
+                    UnrecognizedInputFormatException exception =
+                            UnrecognizedInputFormatException.createForExtractors(mParserNamesPool);
+                    mLastObservedExceptionName = exception.getClass().getName();
+                    throw exception;
+                }
+                return true;
+            }
+        }
+
+        if (mPendingExtractorInit) {
+            if (mExposeDummySeekMap) {
+                // We propagate the dummy seek map before initializing the extractor, in case the
+                // extractor initialization outputs a seek map.
+                mOutputConsumer.onSeekMapFound(SeekMap.DUMMY);
+            }
+            mExtractor.init(new ExtractorOutputAdapter());
+            mPendingExtractorInit = false;
+            // We return after initialization to allow clients use any output information before
+            // starting actual extraction.
+            return true;
+        }
+
+        if (isPendingSeek()) {
+            mExtractor.seek(mPendingSeekPosition, mPendingSeekTimeMicros);
+            removePendingSeek();
+        }
+
+        mPositionHolder.position = seekableInputReader.getPosition();
+        int result;
+        try {
+            result = mExtractor.read(mExtractorInput, mPositionHolder);
+        } catch (Exception e) {
+            mLastObservedExceptionName = e.getClass().getName();
+            if (e instanceof ParserException) {
+                throw new ParsingException((ParserException) e);
+            } else {
+                throw e;
+            }
+        }
+        if (result == Extractor.RESULT_END_OF_INPUT) {
+            mExtractorInput = null;
+            return false;
+        }
+        if (result == Extractor.RESULT_SEEK) {
+            mExtractorInput = null;
+            seekableInputReader.seekToPosition(mPositionHolder.position);
+        }
+        return true;
+    }
+
+    /**
+     * Seeks within the media container being extracted.
+     *
+     * <p>{@link SeekPoint SeekPoints} can be obtained from the {@link SeekMap} passed to {@link
+     * OutputConsumer#onSeekMapFound(SeekMap)}.
+     *
+     * <p>Following a call to this method, the {@link InputReader} passed to the next invocation of
+     * {@link #advance} must provide data starting from {@link SeekPoint#position} in the stream.
+     *
+     * @param seekPoint The {@link SeekPoint} to seek to.
+     */
+    public void seek(@NonNull SeekPoint seekPoint) {
+        if (mExtractor == null) {
+            mPendingSeekPosition = seekPoint.position;
+            mPendingSeekTimeMicros = seekPoint.timeMicros;
+        } else {
+            mExtractor.seek(seekPoint.position, seekPoint.timeMicros);
+        }
+    }
+
+    /**
+     * Releases any acquired resources.
+     *
+     * <p>After calling this method, this instance becomes unusable and no other methods should be
+     * invoked.
+     */
+    public void release() {
+        mExtractorInput = null;
+        mExtractor = null;
+        if (mReleased) {
+            // Nothing to do.
+            return;
+        }
+        mReleased = true;
+
+        String trackMimeTypes = buildMediaMetricsString(format -> format.sampleMimeType);
+        String trackCodecs = buildMediaMetricsString(format -> format.codecs);
+        int videoWidth = -1;
+        int videoHeight = -1;
+        for (int i = 0; i < mTrackFormats.size(); i++) {
+            Format format = mTrackFormats.valueAt(i);
+            if (format.width != Format.NO_VALUE && format.height != Format.NO_VALUE) {
+                videoWidth = format.width;
+                videoHeight = format.height;
+                break;
+            }
+        }
+
+        String alteredParameters =
+                String.join(
+                        MEDIAMETRICS_ELEMENT_SEPARATOR,
+                        mParserParameters.keySet().toArray(new String[0]));
+        alteredParameters =
+                alteredParameters.substring(
+                        0,
+                        Math.min(
+                                alteredParameters.length(),
+                                MEDIAMETRICS_PARAMETER_LIST_MAX_LENGTH));
+
+        nativeSubmitMetrics(
+                SdkLevel.isAtLeastS() ? getLogSessionIdStringV31() : "",
+                mParserName,
+                mCreatedByName,
+                String.join(MEDIAMETRICS_ELEMENT_SEPARATOR, mParserNamesPool),
+                mLastObservedExceptionName,
+                addDither(mResourceByteCount),
+                addDither(mDurationMillis),
+                trackMimeTypes,
+                trackCodecs,
+                alteredParameters,
+                videoWidth,
+                videoHeight);
+    }
+
+    @RequiresApi(31)
+    public void setLogSessionId(@NonNull LogSessionId logSessionId) {
+        this.mLogSessionId = Objects.requireNonNull(logSessionId);
+    }
+
+    @RequiresApi(31)
+    @NonNull
+    public LogSessionId getLogSessionId() {
+        return mLogSessionId != null ? mLogSessionId : LogSessionId.LOG_SESSION_ID_NONE;
+    }
+
+    // Private methods.
+
+    private MediaParser(
+            OutputConsumer outputConsumer, boolean createdByName, String... parserNamesPool) {
+        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
+            throw new UnsupportedOperationException("Android version must be R or greater.");
+        }
+        mParserParameters = new HashMap<>();
+        mOutputConsumer = outputConsumer;
+        mParserNamesPool = parserNamesPool;
+        mCreatedByName = createdByName;
+        mParserName = createdByName ? parserNamesPool[0] : PARSER_NAME_UNKNOWN;
+        mPositionHolder = new PositionHolder();
+        mExoDataReader = new InputReadingDataReader();
+        removePendingSeek();
+        mScratchDataReaderAdapter = new DataReaderAdapter();
+        mScratchParsableByteArrayAdapter = new ParsableByteArrayAdapter();
+        mSchemeInitDataConstructor = getSchemeInitDataConstructor();
+        mMuxedCaptionFormats = new ArrayList<>();
+
+        // MediaMetrics.
+        mTrackFormats = new SparseArray<>();
+        mLastObservedExceptionName = "";
+        mDurationMillis = -1;
+    }
+
+    private String buildMediaMetricsString(Function<Format, String> formatFieldGetter) {
+        StringBuilder stringBuilder = new StringBuilder();
+        for (int i = 0; i < mTrackFormats.size(); i++) {
+            if (i > 0) {
+                stringBuilder.append(MEDIAMETRICS_ELEMENT_SEPARATOR);
+            }
+            String fieldValue = formatFieldGetter.apply(mTrackFormats.valueAt(i));
+            stringBuilder.append(fieldValue != null ? fieldValue : "");
+        }
+        return stringBuilder.substring(
+                0, Math.min(stringBuilder.length(), MEDIAMETRICS_MAX_STRING_SIZE));
+    }
+
+    private void setMuxedCaptionFormats(List<MediaFormat> mediaFormats) {
+        mMuxedCaptionFormats.clear();
+        for (MediaFormat mediaFormat : mediaFormats) {
+            mMuxedCaptionFormats.add(toExoPlayerCaptionFormat(mediaFormat));
+        }
+    }
+
+    private boolean isPendingSeek() {
+        return mPendingSeekPosition >= 0;
+    }
+
+    private void removePendingSeek() {
+        mPendingSeekPosition = -1;
+        mPendingSeekTimeMicros = -1;
+    }
+
+    private Extractor createExtractor(String parserName) {
+        int flags = 0;
+        TimestampAdjuster timestampAdjuster = null;
+        if (mIgnoreTimestampOffset) {
+            timestampAdjuster = new TimestampAdjuster(TimestampAdjuster.DO_NOT_OFFSET);
+        }
+        switch (parserName) {
+            case PARSER_NAME_MATROSKA:
+                flags =
+                        getBooleanParameter(PARAMETER_MATROSKA_DISABLE_CUES_SEEKING)
+                                ? MatroskaExtractor.FLAG_DISABLE_SEEK_FOR_CUES
+                                : 0;
+                return new MatroskaExtractor(flags);
+            case PARSER_NAME_FMP4:
+                flags |=
+                        getBooleanParameter(PARAMETER_EXPOSE_EMSG_TRACK)
+                                ? FragmentedMp4Extractor.FLAG_ENABLE_EMSG_TRACK
+                                : 0;
+                flags |=
+                        getBooleanParameter(PARAMETER_MP4_IGNORE_EDIT_LISTS)
+                                ? FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS
+                                : 0;
+                flags |=
+                        getBooleanParameter(PARAMETER_MP4_IGNORE_TFDT_BOX)
+                                ? FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_TFDT_BOX
+                                : 0;
+                flags |=
+                        getBooleanParameter(PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES)
+                                ? FragmentedMp4Extractor
+                                        .FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME
+                                : 0;
+                return new FragmentedMp4Extractor(
+                        flags,
+                        timestampAdjuster,
+                        /* sideloadedTrack= */ null,
+                        mMuxedCaptionFormats);
+            case PARSER_NAME_MP4:
+                flags |=
+                        getBooleanParameter(PARAMETER_MP4_IGNORE_EDIT_LISTS)
+                                ? Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS
+                                : 0;
+                return new Mp4Extractor(flags);
+            case PARSER_NAME_MP3:
+                flags |=
+                        getBooleanParameter(PARAMETER_MP3_DISABLE_ID3)
+                                ? Mp3Extractor.FLAG_DISABLE_ID3_METADATA
+                                : 0;
+                flags |=
+                        getBooleanParameter(PARAMETER_MP3_ENABLE_CBR_SEEKING)
+                                ? Mp3Extractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
+                                : 0;
+                // TODO: Add index seeking once we update the ExoPlayer version.
+                return new Mp3Extractor(flags);
+            case PARSER_NAME_ADTS:
+                flags |=
+                        getBooleanParameter(PARAMETER_ADTS_ENABLE_CBR_SEEKING)
+                                ? AdtsExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
+                                : 0;
+                return new AdtsExtractor(flags);
+            case PARSER_NAME_AC3:
+                return new Ac3Extractor();
+            case PARSER_NAME_TS:
+                flags |=
+                        getBooleanParameter(PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES)
+                                ? DefaultTsPayloadReaderFactory.FLAG_ALLOW_NON_IDR_KEYFRAMES
+                                : 0;
+                flags |=
+                        getBooleanParameter(PARAMETER_TS_DETECT_ACCESS_UNITS)
+                                ? DefaultTsPayloadReaderFactory.FLAG_DETECT_ACCESS_UNITS
+                                : 0;
+                flags |=
+                        getBooleanParameter(PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS)
+                                ? DefaultTsPayloadReaderFactory.FLAG_ENABLE_HDMV_DTS_AUDIO_STREAMS
+                                : 0;
+                flags |=
+                        getBooleanParameter(PARAMETER_TS_IGNORE_AAC_STREAM)
+                                ? DefaultTsPayloadReaderFactory.FLAG_IGNORE_AAC_STREAM
+                                : 0;
+                flags |=
+                        getBooleanParameter(PARAMETER_TS_IGNORE_AVC_STREAM)
+                                ? DefaultTsPayloadReaderFactory.FLAG_IGNORE_H264_STREAM
+                                : 0;
+                flags |=
+                        getBooleanParameter(PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM)
+                                ? DefaultTsPayloadReaderFactory.FLAG_IGNORE_SPLICE_INFO_STREAM
+                                : 0;
+                flags |=
+                        getBooleanParameter(PARAMETER_OVERRIDE_IN_BAND_CAPTION_DECLARATIONS)
+                                ? DefaultTsPayloadReaderFactory.FLAG_OVERRIDE_CAPTION_DESCRIPTORS
+                                : 0;
+                String tsMode = getStringParameter(PARAMETER_TS_MODE, TS_MODE_SINGLE_PMT);
+                int hlsMode =
+                        TS_MODE_SINGLE_PMT.equals(tsMode)
+                                ? TsExtractor.MODE_SINGLE_PMT
+                                : TS_MODE_HLS.equals(tsMode)
+                                        ? TsExtractor.MODE_HLS
+                                        : TsExtractor.MODE_MULTI_PMT;
+                return new TsExtractor(
+                        hlsMode,
+                        timestampAdjuster != null
+                                ? timestampAdjuster
+                                : new TimestampAdjuster(/* firstSampleTimestampUs= */ 0),
+                        new DefaultTsPayloadReaderFactory(flags, mMuxedCaptionFormats));
+            case PARSER_NAME_FLV:
+                return new FlvExtractor();
+            case PARSER_NAME_OGG:
+                return new OggExtractor();
+            case PARSER_NAME_PS:
+                return new PsExtractor();
+            case PARSER_NAME_WAV:
+                return new WavExtractor();
+            case PARSER_NAME_AMR:
+                flags |=
+                        getBooleanParameter(PARAMETER_AMR_ENABLE_CBR_SEEKING)
+                                ? AmrExtractor.FLAG_ENABLE_CONSTANT_BITRATE_SEEKING
+                                : 0;
+                return new AmrExtractor(flags);
+            case PARSER_NAME_AC4:
+                return new Ac4Extractor();
+            case PARSER_NAME_FLAC:
+                flags |=
+                        getBooleanParameter(PARAMETER_FLAC_DISABLE_ID3)
+                                ? FlacExtractor.FLAG_DISABLE_ID3_METADATA
+                                : 0;
+                return new FlacExtractor(flags);
+            default:
+                // Should never happen.
+                throw new IllegalStateException("Unexpected attempt to create: " + parserName);
+        }
+    }
+
+    private boolean getBooleanParameter(String name) {
+        return (boolean) mParserParameters.getOrDefault(name, false);
+    }
+
+    private String getStringParameter(String name, String defaultValue) {
+        return (String) mParserParameters.getOrDefault(name, defaultValue);
+    }
+
+    @RequiresApi(31)
+    private String getLogSessionIdStringV31() {
+        return mLogSessionId != null ? mLogSessionId.getStringId() : "";
+    }
+
+    // Private classes.
+
+    private static final class InputReadingDataReader implements DataReader {
+
+        public InputReader mInputReader;
+
+        @Override
+        public int read(byte[] buffer, int offset, int readLength) throws IOException {
+            return mInputReader.read(buffer, offset, readLength);
+        }
+    }
+
+    private final class MediaParserDrmInitData extends DrmInitData {
+
+        private final SchemeInitData[] mSchemeDatas;
+
+        private MediaParserDrmInitData(com.google.android.exoplayer2.drm.DrmInitData exoDrmInitData)
+                throws IllegalAccessException, InstantiationException, InvocationTargetException {
+            mSchemeDatas = new SchemeInitData[exoDrmInitData.schemeDataCount];
+            for (int i = 0; i < mSchemeDatas.length; i++) {
+                mSchemeDatas[i] = toFrameworkSchemeInitData(exoDrmInitData.get(i));
+            }
+        }
+
+        @Override
+        @Nullable
+        public SchemeInitData get(UUID schemeUuid) {
+            for (SchemeInitData schemeInitData : mSchemeDatas) {
+                if (schemeInitData.uuid.equals(schemeUuid)) {
+                    return schemeInitData;
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public SchemeInitData getSchemeInitDataAt(int index) {
+            return mSchemeDatas[index];
+        }
+
+        @Override
+        public int getSchemeInitDataCount() {
+            return mSchemeDatas.length;
+        }
+
+        private DrmInitData.SchemeInitData toFrameworkSchemeInitData(SchemeData exoSchemeData)
+                throws IllegalAccessException, InvocationTargetException, InstantiationException {
+            return mSchemeInitDataConstructor.newInstance(
+                    exoSchemeData.uuid, exoSchemeData.mimeType, exoSchemeData.data);
+        }
+    }
+
+    private final class ExtractorOutputAdapter implements ExtractorOutput {
+
+        private final SparseArray<TrackOutput> mTrackOutputAdapters;
+        private boolean mTracksEnded;
+
+        private ExtractorOutputAdapter() {
+            mTrackOutputAdapters = new SparseArray<>();
+        }
+
+        @Override
+        public TrackOutput track(int id, int type) {
+            TrackOutput trackOutput = mTrackOutputAdapters.get(id);
+            if (trackOutput == null) {
+                int trackIndex = mTrackOutputAdapters.size();
+                trackOutput = new TrackOutputAdapter(trackIndex);
+                mTrackOutputAdapters.put(id, trackOutput);
+                if (mEagerlyExposeTrackType) {
+                    MediaFormat mediaFormat = new MediaFormat();
+                    mediaFormat.setString("track-type-string", toTypeString(type));
+                    mOutputConsumer.onTrackDataFound(
+                            trackIndex, new TrackData(mediaFormat, /* drmInitData= */ null));
+                }
+            }
+            return trackOutput;
+        }
+
+        @Override
+        public void endTracks() {
+            mOutputConsumer.onTrackCountFound(mTrackOutputAdapters.size());
+        }
+
+        @Override
+        public void seekMap(com.google.android.exoplayer2.extractor.SeekMap exoplayerSeekMap) {
+            long durationUs = exoplayerSeekMap.getDurationUs();
+            if (durationUs != C.TIME_UNSET) {
+                mDurationMillis = C.usToMs(durationUs);
+            }
+            if (mExposeChunkIndexAsMediaFormat && exoplayerSeekMap instanceof ChunkIndex) {
+                ChunkIndex chunkIndex = (ChunkIndex) exoplayerSeekMap;
+                MediaFormat mediaFormat = new MediaFormat();
+                mediaFormat.setByteBuffer("chunk-index-int-sizes", toByteBuffer(chunkIndex.sizes));
+                mediaFormat.setByteBuffer(
+                        "chunk-index-long-offsets", toByteBuffer(chunkIndex.offsets));
+                mediaFormat.setByteBuffer(
+                        "chunk-index-long-us-durations", toByteBuffer(chunkIndex.durationsUs));
+                mediaFormat.setByteBuffer(
+                        "chunk-index-long-us-times", toByteBuffer(chunkIndex.timesUs));
+                mOutputConsumer.onTrackDataFound(
+                        /* trackIndex= */ 0, new TrackData(mediaFormat, /* drmInitData= */ null));
+            }
+            mOutputConsumer.onSeekMapFound(new SeekMap(exoplayerSeekMap));
+        }
+    }
+
+    private class TrackOutputAdapter implements TrackOutput {
+
+        private final int mTrackIndex;
+
+        private CryptoInfo mLastOutputCryptoInfo;
+        private CryptoInfo.Pattern mLastOutputEncryptionPattern;
+        private CryptoData mLastReceivedCryptoData;
+
+        @EncryptionDataReadState private int mEncryptionDataReadState;
+        private int mEncryptionDataSizeToSubtractFromSampleDataSize;
+        private int mEncryptionVectorSize;
+        private byte[] mScratchIvSpace;
+        private int mSubsampleEncryptionDataSize;
+        private int[] mScratchSubsampleEncryptedBytesCount;
+        private int[] mScratchSubsampleClearBytesCount;
+        private boolean mHasSubsampleEncryptionData;
+        private int mSkippedSupplementalDataBytes;
+
+        private TrackOutputAdapter(int trackIndex) {
+            mTrackIndex = trackIndex;
+            mScratchIvSpace = new byte[16]; // Size documented in CryptoInfo.
+            mScratchSubsampleEncryptedBytesCount = new int[32];
+            mScratchSubsampleClearBytesCount = new int[32];
+            mEncryptionDataReadState = STATE_READING_SIGNAL_BYTE;
+            mLastOutputEncryptionPattern =
+                    new CryptoInfo.Pattern(/* blocksToEncrypt= */ 0, /* blocksToSkip= */ 0);
+        }
+
+        @Override
+        public void format(Format format) {
+            mTrackFormats.put(mTrackIndex, format);
+            mOutputConsumer.onTrackDataFound(
+                    mTrackIndex,
+                    new TrackData(
+                            toMediaFormat(format), toFrameworkDrmInitData(format.drmInitData)));
+        }
+
+        @Override
+        public int sampleData(
+                DataReader input,
+                int length,
+                boolean allowEndOfInput,
+                @SampleDataPart int sampleDataPart)
+                throws IOException {
+            mScratchDataReaderAdapter.setDataReader(input, length);
+            long positionBeforeReading = mScratchDataReaderAdapter.getPosition();
+            mOutputConsumer.onSampleDataFound(mTrackIndex, mScratchDataReaderAdapter);
+            return (int) (mScratchDataReaderAdapter.getPosition() - positionBeforeReading);
+        }
+
+        @Override
+        public void sampleData(
+                ParsableByteArray data, int length, @SampleDataPart int sampleDataPart) {
+            if (sampleDataPart == SAMPLE_DATA_PART_ENCRYPTION && !mInBandCryptoInfo) {
+                while (length > 0) {
+                    switch (mEncryptionDataReadState) {
+                        case STATE_READING_SIGNAL_BYTE:
+                            int encryptionSignalByte = data.readUnsignedByte();
+                            length--;
+                            mHasSubsampleEncryptionData = ((encryptionSignalByte >> 7) & 1) != 0;
+                            mEncryptionVectorSize = encryptionSignalByte & 0x7F;
+                            mEncryptionDataSizeToSubtractFromSampleDataSize =
+                                    mEncryptionVectorSize + 1; // Signal byte.
+                            mEncryptionDataReadState = STATE_READING_INIT_VECTOR;
+                            break;
+                        case STATE_READING_INIT_VECTOR:
+                            Arrays.fill(mScratchIvSpace, (byte) 0); // Ensure 0-padding.
+                            data.readBytes(mScratchIvSpace, /* offset= */ 0, mEncryptionVectorSize);
+                            length -= mEncryptionVectorSize;
+                            if (mHasSubsampleEncryptionData) {
+                                mEncryptionDataReadState = STATE_READING_SUBSAMPLE_ENCRYPTION_SIZE;
+                            } else {
+                                mSubsampleEncryptionDataSize = 0;
+                                mEncryptionDataReadState = STATE_READING_SIGNAL_BYTE;
+                            }
+                            break;
+                        case STATE_READING_SUBSAMPLE_ENCRYPTION_SIZE:
+                            mSubsampleEncryptionDataSize = data.readUnsignedShort();
+                            if (mScratchSubsampleClearBytesCount.length
+                                    < mSubsampleEncryptionDataSize) {
+                                mScratchSubsampleClearBytesCount =
+                                        new int[mSubsampleEncryptionDataSize];
+                                mScratchSubsampleEncryptedBytesCount =
+                                        new int[mSubsampleEncryptionDataSize];
+                            }
+                            length -= 2;
+                            mEncryptionDataSizeToSubtractFromSampleDataSize +=
+                                    2
+                                            + mSubsampleEncryptionDataSize
+                                                    * BYTES_PER_SUBSAMPLE_ENCRYPTION_ENTRY;
+                            mEncryptionDataReadState = STATE_READING_SUBSAMPLE_ENCRYPTION_DATA;
+                            break;
+                        case STATE_READING_SUBSAMPLE_ENCRYPTION_DATA:
+                            for (int i = 0; i < mSubsampleEncryptionDataSize; i++) {
+                                mScratchSubsampleClearBytesCount[i] = data.readUnsignedShort();
+                                mScratchSubsampleEncryptedBytesCount[i] = data.readInt();
+                            }
+                            length -=
+                                    mSubsampleEncryptionDataSize
+                                            * BYTES_PER_SUBSAMPLE_ENCRYPTION_ENTRY;
+                            mEncryptionDataReadState = STATE_READING_SIGNAL_BYTE;
+                            if (length != 0) {
+                                throw new IllegalStateException();
+                            }
+                            break;
+                        default:
+                            // Never happens.
+                            throw new IllegalStateException();
+                    }
+                }
+            } else if (sampleDataPart == SAMPLE_DATA_PART_SUPPLEMENTAL
+                    && !mIncludeSupplementalData) {
+                mSkippedSupplementalDataBytes += length;
+                data.skipBytes(length);
+            } else {
+                outputSampleData(data, length);
+            }
+        }
+
+        @Override
+        public void sampleMetadata(
+                long timeUs, int flags, int size, int offset, @Nullable CryptoData cryptoData) {
+            size -= mSkippedSupplementalDataBytes;
+            mSkippedSupplementalDataBytes = 0;
+            mOutputConsumer.onSampleCompleted(
+                    mTrackIndex,
+                    timeUs,
+                    getMediaParserFlags(flags),
+                    size - mEncryptionDataSizeToSubtractFromSampleDataSize,
+                    offset,
+                    getPopulatedCryptoInfo(cryptoData));
+            mEncryptionDataReadState = STATE_READING_SIGNAL_BYTE;
+            mEncryptionDataSizeToSubtractFromSampleDataSize = 0;
+        }
+
+        @Nullable
+        private CryptoInfo getPopulatedCryptoInfo(@Nullable CryptoData cryptoData) {
+            if (cryptoData == null) {
+                // The sample is not encrypted.
+                return null;
+            } else if (mInBandCryptoInfo) {
+                if (cryptoData != mLastReceivedCryptoData) {
+                    mLastOutputCryptoInfo =
+                            createNewCryptoInfoAndPopulateWithCryptoData(cryptoData);
+                    // We are using in-band crypto info, so the IV will be ignored. But we prevent
+                    // it from being null because toString assumes it non-null.
+                    mLastOutputCryptoInfo.iv = EMPTY_BYTE_ARRAY;
+                }
+            } else /* We must populate the full CryptoInfo. */ {
+                // CryptoInfo.pattern is not accessible to the user, so the user needs to feed
+                // this CryptoInfo directly to MediaCodec. We need to create a new CryptoInfo per
+                // sample because of per-sample initialization vector changes.
+                CryptoInfo newCryptoInfo = createNewCryptoInfoAndPopulateWithCryptoData(cryptoData);
+                newCryptoInfo.iv = Arrays.copyOf(mScratchIvSpace, mScratchIvSpace.length);
+                boolean canReuseSubsampleInfo =
+                        mLastOutputCryptoInfo != null
+                                && mLastOutputCryptoInfo.numSubSamples
+                                        == mSubsampleEncryptionDataSize;
+                for (int i = 0; i < mSubsampleEncryptionDataSize && canReuseSubsampleInfo; i++) {
+                    canReuseSubsampleInfo =
+                            mLastOutputCryptoInfo.numBytesOfClearData[i]
+                                            == mScratchSubsampleClearBytesCount[i]
+                                    && mLastOutputCryptoInfo.numBytesOfEncryptedData[i]
+                                            == mScratchSubsampleEncryptedBytesCount[i];
+                }
+                newCryptoInfo.numSubSamples = mSubsampleEncryptionDataSize;
+                if (canReuseSubsampleInfo) {
+                    newCryptoInfo.numBytesOfClearData = mLastOutputCryptoInfo.numBytesOfClearData;
+                    newCryptoInfo.numBytesOfEncryptedData =
+                            mLastOutputCryptoInfo.numBytesOfEncryptedData;
+                } else {
+                    newCryptoInfo.numBytesOfClearData =
+                            Arrays.copyOf(
+                                    mScratchSubsampleClearBytesCount, mSubsampleEncryptionDataSize);
+                    newCryptoInfo.numBytesOfEncryptedData =
+                            Arrays.copyOf(
+                                    mScratchSubsampleEncryptedBytesCount,
+                                    mSubsampleEncryptionDataSize);
+                }
+                mLastOutputCryptoInfo = newCryptoInfo;
+            }
+            mLastReceivedCryptoData = cryptoData;
+            return mLastOutputCryptoInfo;
+        }
+
+        private CryptoInfo createNewCryptoInfoAndPopulateWithCryptoData(CryptoData cryptoData) {
+            CryptoInfo cryptoInfo = new CryptoInfo();
+            cryptoInfo.key = cryptoData.encryptionKey;
+            cryptoInfo.mode = cryptoData.cryptoMode;
+            if (cryptoData.clearBlocks != mLastOutputEncryptionPattern.getSkipBlocks()
+                    || cryptoData.encryptedBlocks
+                            != mLastOutputEncryptionPattern.getEncryptBlocks()) {
+                mLastOutputEncryptionPattern =
+                        new CryptoInfo.Pattern(cryptoData.encryptedBlocks, cryptoData.clearBlocks);
+            }
+            cryptoInfo.setPattern(mLastOutputEncryptionPattern);
+            return cryptoInfo;
+        }
+
+        private void outputSampleData(ParsableByteArray data, int length) {
+            mScratchParsableByteArrayAdapter.resetWithByteArray(data, length);
+            try {
+                // Read all bytes from data. ExoPlayer extractors expect all sample data to be
+                // consumed by TrackOutput implementations when passing a ParsableByteArray.
+                while (mScratchParsableByteArrayAdapter.getLength() > 0) {
+                    mOutputConsumer.onSampleDataFound(
+                            mTrackIndex, mScratchParsableByteArrayAdapter);
+                }
+            } catch (IOException e) {
+                // Unexpected.
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    private static final class DataReaderAdapter implements InputReader {
+
+        private DataReader mDataReader;
+        private int mCurrentPosition;
+        private long mLength;
+
+        public void setDataReader(DataReader dataReader, long length) {
+            mDataReader = dataReader;
+            mCurrentPosition = 0;
+            mLength = length;
+        }
+
+        // Input implementation.
+
+        @Override
+        public int read(byte[] buffer, int offset, int readLength) throws IOException {
+            int readBytes = 0;
+            readBytes = mDataReader.read(buffer, offset, readLength);
+            mCurrentPosition += readBytes;
+            return readBytes;
+        }
+
+        @Override
+        public long getPosition() {
+            return mCurrentPosition;
+        }
+
+        @Override
+        public long getLength() {
+            return mLength - mCurrentPosition;
+        }
+    }
+
+    private static final class ParsableByteArrayAdapter implements InputReader {
+
+        private ParsableByteArray mByteArray;
+        private long mLength;
+        private int mCurrentPosition;
+
+        public void resetWithByteArray(ParsableByteArray byteArray, long length) {
+            mByteArray = byteArray;
+            mCurrentPosition = 0;
+            mLength = length;
+        }
+
+        // Input implementation.
+
+        @Override
+        public int read(byte[] buffer, int offset, int readLength) {
+            mByteArray.readBytes(buffer, offset, readLength);
+            mCurrentPosition += readLength;
+            return readLength;
+        }
+
+        @Override
+        public long getPosition() {
+            return mCurrentPosition;
+        }
+
+        @Override
+        public long getLength() {
+            return mLength - mCurrentPosition;
+        }
+    }
+
+    private static final class DummyExoPlayerSeekMap
+            implements com.google.android.exoplayer2.extractor.SeekMap {
+
+        @Override
+        public boolean isSeekable() {
+            return true;
+        }
+
+        @Override
+        public long getDurationUs() {
+            return C.TIME_UNSET;
+        }
+
+        @Override
+        public SeekPoints getSeekPoints(long timeUs) {
+            com.google.android.exoplayer2.extractor.SeekPoint seekPoint =
+                    new com.google.android.exoplayer2.extractor.SeekPoint(
+                            timeUs, /* position= */ 0);
+            return new SeekPoints(seekPoint, seekPoint);
+        }
+    }
+
+    /** Creates extractor instances. */
+    private interface ExtractorFactory {
+
+        /** Returns a new extractor instance. */
+        Extractor createInstance();
+    }
+
+    // Private static methods.
+
+    private static Format toExoPlayerCaptionFormat(MediaFormat mediaFormat) {
+        Format.Builder formatBuilder =
+                new Format.Builder().setSampleMimeType(mediaFormat.getString(MediaFormat.KEY_MIME));
+        if (mediaFormat.containsKey(MediaFormat.KEY_CAPTION_SERVICE_NUMBER)) {
+            formatBuilder.setAccessibilityChannel(
+                    mediaFormat.getInteger(MediaFormat.KEY_CAPTION_SERVICE_NUMBER));
+        }
+        return formatBuilder.build();
+    }
+
+    private static MediaFormat toMediaFormat(Format format) {
+        MediaFormat result = new MediaFormat();
+        setOptionalMediaFormatInt(result, MediaFormat.KEY_BIT_RATE, format.bitrate);
+        setOptionalMediaFormatInt(result, MediaFormat.KEY_CHANNEL_COUNT, format.channelCount);
+
+        ColorInfo colorInfo = format.colorInfo;
+        if (colorInfo != null) {
+            setOptionalMediaFormatInt(
+                    result, MediaFormat.KEY_COLOR_TRANSFER, colorInfo.colorTransfer);
+            setOptionalMediaFormatInt(result, MediaFormat.KEY_COLOR_RANGE, colorInfo.colorRange);
+            setOptionalMediaFormatInt(result, MediaFormat.KEY_COLOR_STANDARD, colorInfo.colorSpace);
+
+            if (format.colorInfo.hdrStaticInfo != null) {
+                result.setByteBuffer(
+                        MediaFormat.KEY_HDR_STATIC_INFO,
+                        ByteBuffer.wrap(format.colorInfo.hdrStaticInfo));
+            }
+        }
+
+        setOptionalMediaFormatString(result, MediaFormat.KEY_MIME, format.sampleMimeType);
+        setOptionalMediaFormatString(result, MediaFormat.KEY_CODECS_STRING, format.codecs);
+        if (format.frameRate != Format.NO_VALUE) {
+            result.setFloat(MediaFormat.KEY_FRAME_RATE, format.frameRate);
+        }
+        setOptionalMediaFormatInt(result, MediaFormat.KEY_WIDTH, format.width);
+        setOptionalMediaFormatInt(result, MediaFormat.KEY_HEIGHT, format.height);
+
+        List<byte[]> initData = format.initializationData;
+        for (int i = 0; i < initData.size(); i++) {
+            result.setByteBuffer("csd-" + i, ByteBuffer.wrap(initData.get(i)));
+        }
+        setPcmEncoding(format, result);
+        setOptionalMediaFormatString(result, MediaFormat.KEY_LANGUAGE, format.language);
+        setOptionalMediaFormatInt(result, MediaFormat.KEY_MAX_INPUT_SIZE, format.maxInputSize);
+        setOptionalMediaFormatInt(result, MediaFormat.KEY_ROTATION, format.rotationDegrees);
+        setOptionalMediaFormatInt(result, MediaFormat.KEY_SAMPLE_RATE, format.sampleRate);
+        setOptionalMediaFormatInt(
+                result, MediaFormat.KEY_CAPTION_SERVICE_NUMBER, format.accessibilityChannel);
+
+        int selectionFlags = format.selectionFlags;
+        result.setInteger(
+                MediaFormat.KEY_IS_AUTOSELECT, selectionFlags & C.SELECTION_FLAG_AUTOSELECT);
+        result.setInteger(MediaFormat.KEY_IS_DEFAULT, selectionFlags & C.SELECTION_FLAG_DEFAULT);
+        result.setInteger(
+                MediaFormat.KEY_IS_FORCED_SUBTITLE, selectionFlags & C.SELECTION_FLAG_FORCED);
+
+        setOptionalMediaFormatInt(result, MediaFormat.KEY_ENCODER_DELAY, format.encoderDelay);
+        setOptionalMediaFormatInt(result, MediaFormat.KEY_ENCODER_PADDING, format.encoderPadding);
+
+        if (format.pixelWidthHeightRatio != Format.NO_VALUE && format.pixelWidthHeightRatio != 0) {
+            int parWidth = 1;
+            int parHeight = 1;
+            if (format.pixelWidthHeightRatio < 1.0f) {
+                parHeight = 1 << 30;
+                parWidth = (int) (format.pixelWidthHeightRatio * parHeight);
+            } else if (format.pixelWidthHeightRatio > 1.0f) {
+                parWidth = 1 << 30;
+                parHeight = (int) (parWidth / format.pixelWidthHeightRatio);
+            }
+            result.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_WIDTH, parWidth);
+            result.setInteger(MediaFormat.KEY_PIXEL_ASPECT_RATIO_HEIGHT, parHeight);
+            result.setFloat("pixel-width-height-ratio-float", format.pixelWidthHeightRatio);
+        }
+        if (format.drmInitData != null) {
+            // The crypto mode is propagated along with sample metadata. We also include it in the
+            // format for convenient use from ExoPlayer.
+            result.setString("crypto-mode-fourcc", format.drmInitData.schemeType);
+        }
+        if (format.subsampleOffsetUs != Format.OFFSET_SAMPLE_RELATIVE) {
+            result.setLong("subsample-offset-us-long", format.subsampleOffsetUs);
+        }
+        // LACK OF SUPPORT FOR:
+        //    format.id;
+        //    format.metadata;
+        //    format.stereoMode;
+        return result;
+    }
+
+    private static ByteBuffer toByteBuffer(long[] longArray) {
+        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(longArray.length * Long.BYTES);
+        for (long element : longArray) {
+            byteBuffer.putLong(element);
+        }
+        byteBuffer.flip();
+        return byteBuffer;
+    }
+
+    private static ByteBuffer toByteBuffer(int[] intArray) {
+        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(intArray.length * Integer.BYTES);
+        for (int element : intArray) {
+            byteBuffer.putInt(element);
+        }
+        byteBuffer.flip();
+        return byteBuffer;
+    }
+
+    private static String toTypeString(int type) {
+        switch (type) {
+            case C.TRACK_TYPE_VIDEO:
+                return "video";
+            case C.TRACK_TYPE_AUDIO:
+                return "audio";
+            case C.TRACK_TYPE_TEXT:
+                return "text";
+            case C.TRACK_TYPE_METADATA:
+                return "metadata";
+            default:
+                return "unknown";
+        }
+    }
+
+    private static void setPcmEncoding(Format format, MediaFormat result) {
+        int exoPcmEncoding = format.pcmEncoding;
+        setOptionalMediaFormatInt(result, "exo-pcm-encoding", format.pcmEncoding);
+        int mediaFormatPcmEncoding;
+        switch (exoPcmEncoding) {
+            case C.ENCODING_PCM_8BIT:
+                mediaFormatPcmEncoding = AudioFormat.ENCODING_PCM_8BIT;
+                break;
+            case C.ENCODING_PCM_16BIT:
+                mediaFormatPcmEncoding = AudioFormat.ENCODING_PCM_16BIT;
+                break;
+            case C.ENCODING_PCM_FLOAT:
+                mediaFormatPcmEncoding = AudioFormat.ENCODING_PCM_FLOAT;
+                break;
+            default:
+                // No matching value. Do nothing.
+                return;
+        }
+        result.setInteger(MediaFormat.KEY_PCM_ENCODING, mediaFormatPcmEncoding);
+    }
+
+    private static void setOptionalMediaFormatInt(MediaFormat mediaFormat, String key, int value) {
+        if (value != Format.NO_VALUE) {
+            mediaFormat.setInteger(key, value);
+        }
+    }
+
+    private static void setOptionalMediaFormatString(
+            MediaFormat mediaFormat, String key, @Nullable String value) {
+        if (value != null) {
+            mediaFormat.setString(key, value);
+        }
+    }
+
+    private DrmInitData toFrameworkDrmInitData(
+            com.google.android.exoplayer2.drm.DrmInitData exoDrmInitData) {
+        try {
+            return exoDrmInitData != null && mSchemeInitDataConstructor != null
+                    ? new MediaParserDrmInitData(exoDrmInitData)
+                    : null;
+        } catch (Throwable e) {
+            if (!mLoggedSchemeInitDataCreationException) {
+                mLoggedSchemeInitDataCreationException = true;
+                Log.e(TAG, "Unable to create SchemeInitData instance.");
+            }
+            return null;
+        }
+    }
+
+    /** Returns a new {@link SeekPoint} equivalent to the given {@code exoPlayerSeekPoint}. */
+    private static SeekPoint toSeekPoint(
+            com.google.android.exoplayer2.extractor.SeekPoint exoPlayerSeekPoint) {
+        return new SeekPoint(exoPlayerSeekPoint.timeUs, exoPlayerSeekPoint.position);
+    }
+
+    /**
+     * Introduces random error to the given metric value in order to prevent the identification of
+     * the parsed media.
+     */
+    private static long addDither(long value) {
+        // Generate a random in [0, 1].
+        double randomDither = ThreadLocalRandom.current().nextFloat();
+        // Clamp the random number to [0, 2 * MEDIAMETRICS_DITHER].
+        randomDither *= 2 * MEDIAMETRICS_DITHER;
+        // Translate the random number to [1 - MEDIAMETRICS_DITHER, 1 + MEDIAMETRICS_DITHER].
+        randomDither += 1 - MEDIAMETRICS_DITHER;
+        return value != -1 ? (long) (value * randomDither) : -1;
+    }
+
+    private static void assertValidNames(@NonNull String[] names) {
+        for (String name : names) {
+            if (!EXTRACTOR_FACTORIES_BY_NAME.containsKey(name)) {
+                throw new IllegalArgumentException(
+                        "Invalid extractor name: "
+                                + name
+                                + ". Supported parsers are: "
+                                + TextUtils.join(", ", EXTRACTOR_FACTORIES_BY_NAME.keySet())
+                                + ".");
+            }
+        }
+    }
+
+    private int getMediaParserFlags(int flags) {
+        @SampleFlags int result = 0;
+        result |= (flags & C.BUFFER_FLAG_ENCRYPTED) != 0 ? SAMPLE_FLAG_ENCRYPTED : 0;
+        result |= (flags & C.BUFFER_FLAG_KEY_FRAME) != 0 ? SAMPLE_FLAG_KEY_FRAME : 0;
+        result |= (flags & C.BUFFER_FLAG_DECODE_ONLY) != 0 ? SAMPLE_FLAG_DECODE_ONLY : 0;
+        result |=
+                (flags & C.BUFFER_FLAG_HAS_SUPPLEMENTAL_DATA) != 0 && mIncludeSupplementalData
+                        ? SAMPLE_FLAG_HAS_SUPPLEMENTAL_DATA
+                        : 0;
+        result |= (flags & C.BUFFER_FLAG_LAST_SAMPLE) != 0 ? SAMPLE_FLAG_LAST_SAMPLE : 0;
+        return result;
+    }
+
+    @Nullable
+    private static Constructor<DrmInitData.SchemeInitData> getSchemeInitDataConstructor() {
+        // TODO: Use constructor statically when available.
+        Constructor<DrmInitData.SchemeInitData> constructor;
+        try {
+            return DrmInitData.SchemeInitData.class.getConstructor(
+                    UUID.class, String.class, byte[].class);
+        } catch (Throwable e) {
+            Log.e(TAG, "Unable to get SchemeInitData constructor.");
+            return null;
+        }
+    }
+
+    // Native methods.
+
+    private native void nativeSubmitMetrics(
+            String logSessionId,
+            String parserName,
+            boolean createdByName,
+            String parserPool,
+            String lastObservedExceptionName,
+            long resourceByteCount,
+            long durationMillis,
+            String trackMimeTypes,
+            String trackCodecs,
+            String alteredParameters,
+            int videoWidth,
+            int videoHeight);
+
+    // Static initialization.
+
+    static {
+        System.loadLibrary(JNI_LIBRARY_NAME);
+
+        // Using a LinkedHashMap to keep the insertion order when iterating over the keys.
+        LinkedHashMap<String, ExtractorFactory> extractorFactoriesByName = new LinkedHashMap<>();
+        // Parsers are ordered to match ExoPlayer's DefaultExtractorsFactory extractor ordering,
+        // which in turn aims to minimize the chances of incorrect extractor selections.
+        extractorFactoriesByName.put(PARSER_NAME_MATROSKA, MatroskaExtractor::new);
+        extractorFactoriesByName.put(PARSER_NAME_FMP4, FragmentedMp4Extractor::new);
+        extractorFactoriesByName.put(PARSER_NAME_MP4, Mp4Extractor::new);
+        extractorFactoriesByName.put(PARSER_NAME_MP3, Mp3Extractor::new);
+        extractorFactoriesByName.put(PARSER_NAME_ADTS, AdtsExtractor::new);
+        extractorFactoriesByName.put(PARSER_NAME_AC3, Ac3Extractor::new);
+        extractorFactoriesByName.put(PARSER_NAME_TS, TsExtractor::new);
+        extractorFactoriesByName.put(PARSER_NAME_FLV, FlvExtractor::new);
+        extractorFactoriesByName.put(PARSER_NAME_OGG, OggExtractor::new);
+        extractorFactoriesByName.put(PARSER_NAME_PS, PsExtractor::new);
+        extractorFactoriesByName.put(PARSER_NAME_WAV, WavExtractor::new);
+        extractorFactoriesByName.put(PARSER_NAME_AMR, AmrExtractor::new);
+        extractorFactoriesByName.put(PARSER_NAME_AC4, Ac4Extractor::new);
+        extractorFactoriesByName.put(PARSER_NAME_FLAC, FlacExtractor::new);
+        EXTRACTOR_FACTORIES_BY_NAME = Collections.unmodifiableMap(extractorFactoriesByName);
+
+        HashMap<String, Class> expectedTypeByParameterName = new HashMap<>();
+        expectedTypeByParameterName.put(PARAMETER_ADTS_ENABLE_CBR_SEEKING, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_AMR_ENABLE_CBR_SEEKING, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_FLAC_DISABLE_ID3, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_MP4_IGNORE_EDIT_LISTS, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_MP4_IGNORE_TFDT_BOX, Boolean.class);
+        expectedTypeByParameterName.put(
+                PARAMETER_MP4_TREAT_VIDEO_FRAMES_AS_KEYFRAMES, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_MATROSKA_DISABLE_CUES_SEEKING, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_MP3_DISABLE_ID3, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_MP3_ENABLE_CBR_SEEKING, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_MP3_ENABLE_INDEX_SEEKING, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_TS_MODE, String.class);
+        expectedTypeByParameterName.put(PARAMETER_TS_ALLOW_NON_IDR_AVC_KEYFRAMES, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_TS_IGNORE_AAC_STREAM, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_TS_IGNORE_AVC_STREAM, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_TS_IGNORE_SPLICE_INFO_STREAM, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_TS_DETECT_ACCESS_UNITS, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_TS_ENABLE_HDMV_DTS_AUDIO_STREAMS, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_IN_BAND_CRYPTO_INFO, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_INCLUDE_SUPPLEMENTAL_DATA, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_IGNORE_TIMESTAMP_OFFSET, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_EAGERLY_EXPOSE_TRACKTYPE, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_EXPOSE_DUMMY_SEEKMAP, Boolean.class);
+        expectedTypeByParameterName.put(
+                PARAMETER_EXPOSE_CHUNK_INDEX_AS_MEDIA_FORMAT, Boolean.class);
+        expectedTypeByParameterName.put(
+                PARAMETER_OVERRIDE_IN_BAND_CAPTION_DECLARATIONS, Boolean.class);
+        expectedTypeByParameterName.put(PARAMETER_EXPOSE_EMSG_TRACK, Boolean.class);
+        // We do not check PARAMETER_EXPOSE_CAPTION_FORMATS here, and we do it in setParameters
+        // instead. Checking that the value is a List is insufficient to catch wrong parameter
+        // value types.
+        int sumOfParameterNameLengths =
+                expectedTypeByParameterName.keySet().stream()
+                        .map(String::length)
+                        .reduce(0, Integer::sum);
+        sumOfParameterNameLengths += PARAMETER_EXPOSE_CAPTION_FORMATS.length();
+        // Add space for any required separators.
+        MEDIAMETRICS_PARAMETER_LIST_MAX_LENGTH =
+                sumOfParameterNameLengths + expectedTypeByParameterName.size();
+
+        EXPECTED_TYPE_BY_PARAMETER_NAME = Collections.unmodifiableMap(expectedTypeByParameterName);
+    }
+}
diff --git a/android/media/MediaPlayer.java b/android/media/MediaPlayer.java
new file mode 100644
index 0000000..26eb2a9
--- /dev/null
+++ b/android/media/MediaPlayer.java
@@ -0,0 +1,6252 @@
+/*
+ * Copyright (C) 2006 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.Manifest.permission.BIND_IMS_SERVICE;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.app.ActivityThread;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
+import android.content.AttributionSource.ScopedParcelState;
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.graphics.SurfaceTexture;
+import android.media.SubtitleController.Anchor;
+import android.media.SubtitleTrack.RenderingWidget;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.FileUtils;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
+import android.os.Parcelable;
+import android.os.PersistableBundle;
+import android.os.PowerManager;
+import android.os.Process;
+import android.os.SystemProperties;
+import android.provider.Settings;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Pair;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.widget.VideoView;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import libcore.io.IoBridge;
+import libcore.io.Streams;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.net.CookieHandler;
+import java.net.CookieManager;
+import java.net.HttpCookie;
+import java.net.HttpURLConnection;
+import java.net.InetSocketAddress;
+import java.net.URL;
+import java.nio.ByteOrder;
+import java.util.Arrays;
+import java.util.BitSet;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Scanner;
+import java.util.Set;
+import java.util.UUID;
+import java.util.Vector;
+import java.util.concurrent.Executor;
+
+/**
+ * MediaPlayer class can be used to control playback of audio/video files and streams.
+ *
+ * <p>MediaPlayer is not thread-safe. Creation of and all access to player instances
+ * should be on the same thread. If registering <a href="#Callbacks">callbacks</a>,
+ * the thread must have a Looper.
+ *
+ * <p>Topics covered here are:
+ * <ol>
+ * <li><a href="#StateDiagram">State Diagram</a>
+ * <li><a href="#Valid_and_Invalid_States">Valid and Invalid States</a>
+ * <li><a href="#Permissions">Permissions</a>
+ * <li><a href="#Callbacks">Register informational and error callbacks</a>
+ * </ol>
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about how to use MediaPlayer, read the
+ * <a href="{@docRoot}guide/topics/media/mediaplayer.html">Media Playback</a> developer guide.</p>
+ * </div>
+ *
+ * <a name="StateDiagram"></a>
+ * <h3>State Diagram</h3>
+ *
+ * <p>Playback control of audio/video files and streams is managed as a state
+ * machine. The following diagram shows the life cycle and the states of a
+ * MediaPlayer object driven by the supported playback control operations.
+ * The ovals represent the states a MediaPlayer object may reside
+ * in. The arcs represent the playback control operations that drive the object
+ * state transition. There are two types of arcs. The arcs with a single arrow
+ * head represent synchronous method calls, while those with
+ * a double arrow head represent asynchronous method calls.</p>
+ *
+ * <p><img src="../../../images/mediaplayer_state_diagram.gif"
+ *         alt="MediaPlayer State diagram"
+ *         border="0" /></p>
+ *
+ * <p>From this state diagram, one can see that a MediaPlayer object has the
+ *    following states:</p>
+ * <ul>
+ *     <li>When a MediaPlayer object is just created using <code>new</code> or
+ *         after {@link #reset()} is called, it is in the <em>Idle</em> state; and after
+ *         {@link #release()} is called, it is in the <em>End</em> state. Between these
+ *         two states is the life cycle of the MediaPlayer object.
+ *         <ul>
+ *         <li>There is a subtle but important difference between a newly constructed
+ *         MediaPlayer object and the MediaPlayer object after {@link #reset()}
+ *         is called. It is a programming error to invoke methods such
+ *         as {@link #getCurrentPosition()},
+ *         {@link #getDuration()}, {@link #getVideoHeight()},
+ *         {@link #getVideoWidth()}, {@link #setAudioAttributes(AudioAttributes)},
+ *         {@link #setLooping(boolean)},
+ *         {@link #setVolume(float, float)}, {@link #pause()}, {@link #start()},
+ *         {@link #stop()}, {@link #seekTo(long, int)}, {@link #prepare()} or
+ *         {@link #prepareAsync()} in the <em>Idle</em> state for both cases. If any of these
+ *         methods is called right after a MediaPlayer object is constructed,
+ *         the user supplied callback method OnErrorListener.onError() won't be
+ *         called by the internal player engine and the object state remains
+ *         unchanged; but if these methods are called right after {@link #reset()},
+ *         the user supplied callback method OnErrorListener.onError() will be
+ *         invoked by the internal player engine and the object will be
+ *         transfered to the <em>Error</em> state. </li>
+ *         <li>It is also recommended that once
+ *         a MediaPlayer object is no longer being used, call {@link #release()} immediately
+ *         so that resources used by the internal player engine associated with the
+ *         MediaPlayer object can be released immediately. Resource may include
+ *         singleton resources such as hardware acceleration components and
+ *         failure to call {@link #release()} may cause subsequent instances of
+ *         MediaPlayer objects to fallback to software implementations or fail
+ *         altogether. Once the MediaPlayer
+ *         object is in the <em>End</em> state, it can no longer be used and
+ *         there is no way to bring it back to any other state. </li>
+ *         <li>Furthermore,
+ *         the MediaPlayer objects created using <code>new</code> is in the
+ *         <em>Idle</em> state, while those created with one
+ *         of the overloaded convenient <code>create</code> methods are <em>NOT</em>
+ *         in the <em>Idle</em> state. In fact, the objects are in the <em>Prepared</em>
+ *         state if the creation using <code>create</code> method is successful.
+ *         </li>
+ *         </ul>
+ *         </li>
+ *     <li>In general, some playback control operation may fail due to various
+ *         reasons, such as unsupported audio/video format, poorly interleaved
+ *         audio/video, resolution too high, streaming timeout, and the like.
+ *         Thus, error reporting and recovery is an important concern under
+ *         these circumstances. Sometimes, due to programming errors, invoking a playback
+ *         control operation in an invalid state may also occur. Under all these
+ *         error conditions, the internal player engine invokes a user supplied
+ *         OnErrorListener.onError() method if an OnErrorListener has been
+ *         registered beforehand via
+ *         {@link #setOnErrorListener(android.media.MediaPlayer.OnErrorListener)}.
+ *         <ul>
+ *         <li>It is important to note that once an error occurs, the
+ *         MediaPlayer object enters the <em>Error</em> state (except as noted
+ *         above), even if an error listener has not been registered by the application.</li>
+ *         <li>In order to reuse a MediaPlayer object that is in the <em>
+ *         Error</em> state and recover from the error,
+ *         {@link #reset()} can be called to restore the object to its <em>Idle</em>
+ *         state.</li>
+ *         <li>It is good programming practice to have your application
+ *         register a OnErrorListener to look out for error notifications from
+ *         the internal player engine.</li>
+ *         <li>IllegalStateException is
+ *         thrown to prevent programming errors such as calling {@link #prepare()},
+ *         {@link #prepareAsync()}, or one of the overloaded <code>setDataSource
+ *         </code> methods in an invalid state. </li>
+ *         </ul>
+ *         </li>
+ *     <li>Calling
+ *         {@link #setDataSource(FileDescriptor)}, or
+ *         {@link #setDataSource(String)}, or
+ *         {@link #setDataSource(Context, Uri)}, or
+ *         {@link #setDataSource(FileDescriptor, long, long)}, or
+ *         {@link #setDataSource(MediaDataSource)} transfers a
+ *         MediaPlayer object in the <em>Idle</em> state to the
+ *         <em>Initialized</em> state.
+ *         <ul>
+ *         <li>An IllegalStateException is thrown if
+ *         setDataSource() is called in any other state.</li>
+ *         <li>It is good programming
+ *         practice to always look out for <code>IllegalArgumentException</code>
+ *         and <code>IOException</code> that may be thrown from the overloaded
+ *         <code>setDataSource</code> methods.</li>
+ *         </ul>
+ *         </li>
+ *     <li>A MediaPlayer object must first enter the <em>Prepared</em> state
+ *         before playback can be started.
+ *         <ul>
+ *         <li>There are two ways (synchronous vs.
+ *         asynchronous) that the <em>Prepared</em> state can be reached:
+ *         either a call to {@link #prepare()} (synchronous) which
+ *         transfers the object to the <em>Prepared</em> state once the method call
+ *         returns, or a call to {@link #prepareAsync()} (asynchronous) which
+ *         first transfers the object to the <em>Preparing</em> state after the
+ *         call returns (which occurs almost right away) while the internal
+ *         player engine continues working on the rest of preparation work
+ *         until the preparation work completes. When the preparation completes or when {@link #prepare()} call returns,
+ *         the internal player engine then calls a user supplied callback method,
+ *         onPrepared() of the OnPreparedListener interface, if an
+ *         OnPreparedListener is registered beforehand via {@link
+ *         #setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener)}.</li>
+ *         <li>It is important to note that
+ *         the <em>Preparing</em> state is a transient state, and the behavior
+ *         of calling any method with side effect while a MediaPlayer object is
+ *         in the <em>Preparing</em> state is undefined.</li>
+ *         <li>An IllegalStateException is
+ *         thrown if {@link #prepare()} or {@link #prepareAsync()} is called in
+ *         any other state.</li>
+ *         <li>While in the <em>Prepared</em> state, properties
+ *         such as audio/sound volume, screenOnWhilePlaying, looping can be
+ *         adjusted by invoking the corresponding set methods.</li>
+ *         </ul>
+ *         </li>
+ *     <li>To start the playback, {@link #start()} must be called. After
+ *         {@link #start()} returns successfully, the MediaPlayer object is in the
+ *         <em>Started</em> state. {@link #isPlaying()} can be called to test
+ *         whether the MediaPlayer object is in the <em>Started</em> state.
+ *         <ul>
+ *         <li>While in the <em>Started</em> state, the internal player engine calls
+ *         a user supplied OnBufferingUpdateListener.onBufferingUpdate() callback
+ *         method if a OnBufferingUpdateListener has been registered beforehand
+ *         via {@link #setOnBufferingUpdateListener(OnBufferingUpdateListener)}.
+ *         This callback allows applications to keep track of the buffering status
+ *         while streaming audio/video.</li>
+ *         <li>Calling {@link #start()} has no effect
+ *         on a MediaPlayer object that is already in the <em>Started</em> state.</li>
+ *         </ul>
+ *         </li>
+ *     <li>Playback can be paused and stopped, and the current playback position
+ *         can be adjusted. Playback can be paused via {@link #pause()}. When the call to
+ *         {@link #pause()} returns, the MediaPlayer object enters the
+ *         <em>Paused</em> state. Note that the transition from the <em>Started</em>
+ *         state to the <em>Paused</em> state and vice versa happens
+ *         asynchronously in the player engine. It may take some time before
+ *         the state is updated in calls to {@link #isPlaying()}, and it can be
+ *         a number of seconds in the case of streamed content.
+ *         <ul>
+ *         <li>Calling {@link #start()} to resume playback for a paused
+ *         MediaPlayer object, and the resumed playback
+ *         position is the same as where it was paused. When the call to
+ *         {@link #start()} returns, the paused MediaPlayer object goes back to
+ *         the <em>Started</em> state.</li>
+ *         <li>Calling {@link #pause()} has no effect on
+ *         a MediaPlayer object that is already in the <em>Paused</em> state.</li>
+ *         </ul>
+ *         </li>
+ *     <li>Calling  {@link #stop()} stops playback and causes a
+ *         MediaPlayer in the <em>Started</em>, <em>Paused</em>, <em>Prepared
+ *         </em> or <em>PlaybackCompleted</em> state to enter the
+ *         <em>Stopped</em> state.
+ *         <ul>
+ *         <li>Once in the <em>Stopped</em> state, playback cannot be started
+ *         until {@link #prepare()} or {@link #prepareAsync()} are called to set
+ *         the MediaPlayer object to the <em>Prepared</em> state again.</li>
+ *         <li>Calling {@link #stop()} has no effect on a MediaPlayer
+ *         object that is already in the <em>Stopped</em> state.</li>
+ *         </ul>
+ *         </li>
+ *     <li>The playback position can be adjusted with a call to
+ *         {@link #seekTo(long, int)}.
+ *         <ul>
+ *         <li>Although the asynchronuous {@link #seekTo(long, int)}
+ *         call returns right away, the actual seek operation may take a while to
+ *         finish, especially for audio/video being streamed. When the actual
+ *         seek operation completes, the internal player engine calls a user
+ *         supplied OnSeekComplete.onSeekComplete() if an OnSeekCompleteListener
+ *         has been registered beforehand via
+ *         {@link #setOnSeekCompleteListener(OnSeekCompleteListener)}.</li>
+ *         <li>Please
+ *         note that {@link #seekTo(long, int)} can also be called in the other states,
+ *         such as <em>Prepared</em>, <em>Paused</em> and <em>PlaybackCompleted
+ *         </em> state. When {@link #seekTo(long, int)} is called in those states,
+ *         one video frame will be displayed if the stream has video and the requested
+ *         position is valid.
+ *         </li>
+ *         <li>Furthermore, the actual current playback position
+ *         can be retrieved with a call to {@link #getCurrentPosition()}, which
+ *         is helpful for applications such as a Music player that need to keep
+ *         track of the playback progress.</li>
+ *         </ul>
+ *         </li>
+ *     <li>When the playback reaches the end of stream, the playback completes.
+ *         <ul>
+ *         <li>If the looping mode was being set to <var>true</var> with
+ *         {@link #setLooping(boolean)}, the MediaPlayer object shall remain in
+ *         the <em>Started</em> state.</li>
+ *         <li>If the looping mode was set to <var>false
+ *         </var>, the player engine calls a user supplied callback method,
+ *         OnCompletion.onCompletion(), if a OnCompletionListener is registered
+ *         beforehand via {@link #setOnCompletionListener(OnCompletionListener)}.
+ *         The invoke of the callback signals that the object is now in the <em>
+ *         PlaybackCompleted</em> state.</li>
+ *         <li>While in the <em>PlaybackCompleted</em>
+ *         state, calling {@link #start()} can restart the playback from the
+ *         beginning of the audio/video source.</li>
+ * </ul>
+ *
+ *
+ * <a name="Valid_and_Invalid_States"></a>
+ * <h3>Valid and invalid states</h3>
+ *
+ * <table border="0" cellspacing="0" cellpadding="0">
+ * <tr><td>Method Name </p></td>
+ *     <td>Valid States </p></td>
+ *     <td>Invalid States </p></td>
+ *     <td>Comments </p></td></tr>
+ * <tr><td>attachAuxEffect </p></td>
+ *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
+ *     <td>{Idle, Error} </p></td>
+ *     <td>This method must be called after setDataSource.
+ *     Calling it does not change the object state. </p></td></tr>
+ * <tr><td>getAudioSessionId </p></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>This method can be called in any state and calling it does not change
+ *         the object state. </p></td></tr>
+ * <tr><td>getCurrentPosition </p></td>
+ *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ *         PlaybackCompleted} </p></td>
+ *     <td>{Error}</p></td>
+ *     <td>Successful invoke of this method in a valid state does not change the
+ *         state. Calling this method in an invalid state transfers the object
+ *         to the <em>Error</em> state. </p></td></tr>
+ * <tr><td>getDuration </p></td>
+ *     <td>{Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
+ *     <td>{Idle, Initialized, Error} </p></td>
+ *     <td>Successful invoke of this method in a valid state does not change the
+ *         state. Calling this method in an invalid state transfers the object
+ *         to the <em>Error</em> state. </p></td></tr>
+ * <tr><td>getVideoHeight </p></td>
+ *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ *         PlaybackCompleted}</p></td>
+ *     <td>{Error}</p></td>
+ *     <td>Successful invoke of this method in a valid state does not change the
+ *         state. Calling this method in an invalid state transfers the object
+ *         to the <em>Error</em> state.  </p></td></tr>
+ * <tr><td>getVideoWidth </p></td>
+ *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ *         PlaybackCompleted}</p></td>
+ *     <td>{Error}</p></td>
+ *     <td>Successful invoke of this method in a valid state does not change
+ *         the state. Calling this method in an invalid state transfers the
+ *         object to the <em>Error</em> state. </p></td></tr>
+ * <tr><td>isPlaying </p></td>
+ *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ *          PlaybackCompleted}</p></td>
+ *     <td>{Error}</p></td>
+ *     <td>Successful invoke of this method in a valid state does not change
+ *         the state. Calling this method in an invalid state transfers the
+ *         object to the <em>Error</em> state. </p></td></tr>
+ * <tr><td>pause </p></td>
+ *     <td>{Started, Paused, PlaybackCompleted}</p></td>
+ *     <td>{Idle, Initialized, Prepared, Stopped, Error}</p></td>
+ *     <td>Successful invoke of this method in a valid state transfers the
+ *         object to the <em>Paused</em> state. Calling this method in an
+ *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
+ * <tr><td>prepare </p></td>
+ *     <td>{Initialized, Stopped} </p></td>
+ *     <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
+ *     <td>Successful invoke of this method in a valid state transfers the
+ *         object to the <em>Prepared</em> state. Calling this method in an
+ *         invalid state throws an IllegalStateException.</p></td></tr>
+ * <tr><td>prepareAsync </p></td>
+ *     <td>{Initialized, Stopped} </p></td>
+ *     <td>{Idle, Prepared, Started, Paused, PlaybackCompleted, Error} </p></td>
+ *     <td>Successful invoke of this method in a valid state transfers the
+ *         object to the <em>Preparing</em> state. Calling this method in an
+ *         invalid state throws an IllegalStateException.</p></td></tr>
+ * <tr><td>release </p></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>After {@link #release()}, the object is no longer available. </p></td></tr>
+ * <tr><td>reset </p></td>
+ *     <td>{Idle, Initialized, Prepared, Started, Paused, Stopped,
+ *         PlaybackCompleted, Error}</p></td>
+ *     <td>{}</p></td>
+ *     <td>After {@link #reset()}, the object is like being just created.</p></td></tr>
+ * <tr><td>seekTo </p></td>
+ *     <td>{Prepared, Started, Paused, PlaybackCompleted} </p></td>
+ *     <td>{Idle, Initialized, Stopped, Error}</p></td>
+ *     <td>Successful invoke of this method in a valid state does not change
+ *         the state. Calling this method in an invalid state transfers the
+ *         object to the <em>Error</em> state. </p></td></tr>
+ * <tr><td>setAudioAttributes </p></td>
+ *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ *          PlaybackCompleted}</p></td>
+ *     <td>{Error}</p></td>
+ *     <td>Successful invoke of this method does not change the state. In order for the
+ *         target audio attributes type to become effective, this method must be called before
+ *         prepare() or prepareAsync().</p></td></tr>
+ * <tr><td>setAudioSessionId </p></td>
+ *     <td>{Idle} </p></td>
+ *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
+ *          Error} </p></td>
+ *     <td>This method must be called in idle state as the audio session ID must be known before
+ *         calling setDataSource. Calling it does not change the object state. </p></td></tr>
+ * <tr><td>setAudioStreamType (deprecated)</p></td>
+ *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ *          PlaybackCompleted}</p></td>
+ *     <td>{Error}</p></td>
+ *     <td>Successful invoke of this method does not change the state. In order for the
+ *         target audio stream type to become effective, this method must be called before
+ *         prepare() or prepareAsync().</p></td></tr>
+ * <tr><td>setAuxEffectSendLevel </p></td>
+ *     <td>any</p></td>
+ *     <td>{} </p></td>
+ *     <td>Calling this method does not change the object state. </p></td></tr>
+ * <tr><td>setDataSource </p></td>
+ *     <td>{Idle} </p></td>
+ *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted,
+ *          Error} </p></td>
+ *     <td>Successful invoke of this method in a valid state transfers the
+ *         object to the <em>Initialized</em> state. Calling this method in an
+ *         invalid state throws an IllegalStateException.</p></td></tr>
+ * <tr><td>setDisplay </p></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>This method can be called in any state and calling it does not change
+ *         the object state. </p></td></tr>
+ * <tr><td>setSurface </p></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>This method can be called in any state and calling it does not change
+ *         the object state. </p></td></tr>
+ * <tr><td>setVideoScalingMode </p></td>
+ *     <td>{Initialized, Prepared, Started, Paused, Stopped, PlaybackCompleted} </p></td>
+ *     <td>{Idle, Error}</p></td>
+ *     <td>Successful invoke of this method does not change the state.</p></td></tr>
+ * <tr><td>setLooping </p></td>
+ *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ *         PlaybackCompleted}</p></td>
+ *     <td>{Error}</p></td>
+ *     <td>Successful invoke of this method in a valid state does not change
+ *         the state. Calling this method in an
+ *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
+ * <tr><td>isLooping </p></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>This method can be called in any state and calling it does not change
+ *         the object state. </p></td></tr>
+ * <tr><td>setOnBufferingUpdateListener </p></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>This method can be called in any state and calling it does not change
+ *         the object state. </p></td></tr>
+ * <tr><td>setOnCompletionListener </p></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>This method can be called in any state and calling it does not change
+ *         the object state. </p></td></tr>
+ * <tr><td>setOnErrorListener </p></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>This method can be called in any state and calling it does not change
+ *         the object state. </p></td></tr>
+ * <tr><td>setOnPreparedListener </p></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>This method can be called in any state and calling it does not change
+ *         the object state. </p></td></tr>
+ * <tr><td>setOnSeekCompleteListener </p></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>This method can be called in any state and calling it does not change
+ *         the object state. </p></td></tr>
+ * <tr><td>setPlaybackParams</p></td>
+ *     <td>{Initialized, Prepared, Started, Paused, PlaybackCompleted, Error}</p></td>
+ *     <td>{Idle, Stopped} </p></td>
+ *     <td>This method will change state in some cases, depending on when it's called.
+ *         </p></td></tr>
+ * <tr><td>setScreenOnWhilePlaying</></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>This method can be called in any state and calling it does not change
+ *         the object state.  </p></td></tr>
+ * <tr><td>setVolume </p></td>
+ *     <td>{Idle, Initialized, Stopped, Prepared, Started, Paused,
+ *          PlaybackCompleted}</p></td>
+ *     <td>{Error}</p></td>
+ *     <td>Successful invoke of this method does not change the state.
+ * <tr><td>setWakeMode </p></td>
+ *     <td>any </p></td>
+ *     <td>{} </p></td>
+ *     <td>This method can be called in any state and calling it does not change
+ *         the object state.</p></td></tr>
+ * <tr><td>start </p></td>
+ *     <td>{Prepared, Started, Paused, PlaybackCompleted}</p></td>
+ *     <td>{Idle, Initialized, Stopped, Error}</p></td>
+ *     <td>Successful invoke of this method in a valid state transfers the
+ *         object to the <em>Started</em> state. Calling this method in an
+ *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
+ * <tr><td>stop </p></td>
+ *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ *     <td>{Idle, Initialized, Error}</p></td>
+ *     <td>Successful invoke of this method in a valid state transfers the
+ *         object to the <em>Stopped</em> state. Calling this method in an
+ *         invalid state transfers the object to the <em>Error</em> state.</p></td></tr>
+ * <tr><td>getTrackInfo </p></td>
+ *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ *     <td>{Idle, Initialized, Error}</p></td>
+ *     <td>Successful invoke of this method does not change the state.</p></td></tr>
+ * <tr><td>addTimedTextSource </p></td>
+ *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ *     <td>{Idle, Initialized, Error}</p></td>
+ *     <td>Successful invoke of this method does not change the state.</p></td></tr>
+ * <tr><td>selectTrack </p></td>
+ *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ *     <td>{Idle, Initialized, Error}</p></td>
+ *     <td>Successful invoke of this method does not change the state.</p></td></tr>
+ * <tr><td>deselectTrack </p></td>
+ *     <td>{Prepared, Started, Stopped, Paused, PlaybackCompleted}</p></td>
+ *     <td>{Idle, Initialized, Error}</p></td>
+ *     <td>Successful invoke of this method does not change the state.</p></td></tr>
+ *
+ * </table>
+ *
+ * <a name="Permissions"></a>
+ * <h3>Permissions</h3>
+ * <p>One may need to declare a corresponding WAKE_LOCK permission {@link
+ * android.R.styleable#AndroidManifestUsesPermission &lt;uses-permission&gt;}
+ * element.
+ *
+ * <p>This class requires the {@link android.Manifest.permission#INTERNET} permission
+ * when used with network-based content.
+ *
+ * <a name="Callbacks"></a>
+ * <h3>Callbacks</h3>
+ * <p>Applications may want to register for informational and error
+ * events in order to be informed of some internal state update and
+ * possible runtime errors during playback or streaming. Registration for
+ * these events is done by properly setting the appropriate listeners (via calls
+ * to
+ * {@link #setOnPreparedListener(OnPreparedListener) setOnPreparedListener},
+ * {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener) setOnVideoSizeChangedListener},
+ * {@link #setOnSeekCompleteListener(OnSeekCompleteListener) setOnSeekCompleteListener},
+ * {@link #setOnCompletionListener(OnCompletionListener) setOnCompletionListener},
+ * {@link #setOnBufferingUpdateListener(OnBufferingUpdateListener) setOnBufferingUpdateListener},
+ * {@link #setOnInfoListener(OnInfoListener) setOnInfoListener},
+ * {@link #setOnErrorListener(OnErrorListener) setOnErrorListener}, etc).
+ * In order to receive the respective callback
+ * associated with these listeners, applications are required to create
+ * MediaPlayer objects on a thread with its own Looper running (main UI
+ * thread by default has a Looper running).
+ *
+ */
+public class MediaPlayer extends PlayerBase
+                         implements SubtitleController.Listener
+                                  , VolumeAutomation
+                                  , AudioRouting
+{
+    /**
+       Constant to retrieve only the new metadata since the last
+       call.
+       // FIXME: unhide.
+       // FIXME: add link to getMetadata(boolean, boolean)
+       {@hide}
+     */
+    public static final boolean METADATA_UPDATE_ONLY = true;
+
+    /**
+       Constant to retrieve all the metadata.
+       // FIXME: unhide.
+       // FIXME: add link to getMetadata(boolean, boolean)
+       {@hide}
+     */
+    @UnsupportedAppUsage
+    public static final boolean METADATA_ALL = false;
+
+    /**
+       Constant to enable the metadata filter during retrieval.
+       // FIXME: unhide.
+       // FIXME: add link to getMetadata(boolean, boolean)
+       {@hide}
+     */
+    public static final boolean APPLY_METADATA_FILTER = true;
+
+    /**
+       Constant to disable the metadata filter during retrieval.
+       // FIXME: unhide.
+       // FIXME: add link to getMetadata(boolean, boolean)
+       {@hide}
+     */
+    @UnsupportedAppUsage
+    public static final boolean BYPASS_METADATA_FILTER = false;
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    private final static String TAG = "MediaPlayer";
+    // Name of the remote interface for the media player. Must be kept
+    // in sync with the 2nd parameter of the IMPLEMENT_META_INTERFACE
+    // macro invocation in IMediaPlayer.cpp
+    private final static String IMEDIA_PLAYER = "android.media.IMediaPlayer";
+
+    private long mNativeContext; // accessed by native methods
+    private long mNativeSurfaceTexture;  // accessed by native methods
+    private int mListenerContext; // accessed by native methods
+    private SurfaceHolder mSurfaceHolder;
+    @UnsupportedAppUsage
+    private EventHandler mEventHandler;
+    private PowerManager.WakeLock mWakeLock = null;
+    private boolean mScreenOnWhilePlaying;
+    private boolean mStayAwake;
+    private int mStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE;
+
+    // Modular DRM
+    private UUID mDrmUUID;
+    private final Object mDrmLock = new Object();
+    private DrmInfo mDrmInfo;
+    private MediaDrm mDrmObj;
+    private byte[] mDrmSessionId;
+    private boolean mDrmInfoResolved;
+    private boolean mActiveDrmScheme;
+    private boolean mDrmConfigAllowed;
+    private boolean mDrmProvisioningInProgress;
+    private boolean mPrepareDrmInProgress;
+    private ProvisioningThread mDrmProvisioningThread;
+
+    /**
+     * Default constructor. Consider using one of the create() methods for
+     * synchronously instantiating a MediaPlayer from a Uri or resource.
+     * <p>When done with the MediaPlayer, you should call  {@link #release()},
+     * to free the resources. If not released, too many MediaPlayer instances may
+     * result in an exception.</p>
+     */
+    public MediaPlayer() {
+        this(AudioSystem.AUDIO_SESSION_ALLOCATE);
+    }
+
+    private MediaPlayer(int sessionId) {
+        super(new AudioAttributes.Builder().build(),
+                AudioPlaybackConfiguration.PLAYER_TYPE_JAM_MEDIAPLAYER);
+
+        Looper looper;
+        if ((looper = Looper.myLooper()) != null) {
+            mEventHandler = new EventHandler(this, looper);
+        } else if ((looper = Looper.getMainLooper()) != null) {
+            mEventHandler = new EventHandler(this, looper);
+        } else {
+            mEventHandler = null;
+        }
+
+        mTimeProvider = new TimeProvider(this);
+        mOpenSubtitleSources = new Vector<InputStream>();
+
+        AttributionSource attributionSource = AttributionSource.myAttributionSource();
+        // set the package name to empty if it was null
+        if (attributionSource.getPackageName() == null) {
+            attributionSource = attributionSource.withPackageName("");
+        }
+
+        /* Native setup requires a weak reference to our object.
+         * It's easier to create it here than in C++.
+         */
+        try (ScopedParcelState attributionSourceState = attributionSource.asScopedParcelState()) {
+            native_setup(new WeakReference<MediaPlayer>(this), attributionSourceState.getParcel());
+        }
+
+        baseRegisterPlayer(sessionId);
+    }
+
+    /*
+     * Update the MediaPlayer SurfaceTexture.
+     * Call after setting a new display surface.
+     */
+    private native void _setVideoSurface(Surface surface);
+
+    /* Do not change these values (starting with INVOKE_ID) without updating
+     * their counterparts in include/media/mediaplayer.h!
+     */
+    private static final int INVOKE_ID_GET_TRACK_INFO = 1;
+    private static final int INVOKE_ID_ADD_EXTERNAL_SOURCE = 2;
+    private static final int INVOKE_ID_ADD_EXTERNAL_SOURCE_FD = 3;
+    private static final int INVOKE_ID_SELECT_TRACK = 4;
+    private static final int INVOKE_ID_DESELECT_TRACK = 5;
+    private static final int INVOKE_ID_SET_VIDEO_SCALE_MODE = 6;
+    private static final int INVOKE_ID_GET_SELECTED_TRACK = 7;
+
+    /**
+     * Create a request parcel which can be routed to the native media
+     * player using {@link #invoke(Parcel, Parcel)}. The Parcel
+     * returned has the proper InterfaceToken set. The caller should
+     * not overwrite that token, i.e it can only append data to the
+     * Parcel.
+     *
+     * @return A parcel suitable to hold a request for the native
+     * player.
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    public Parcel newRequest() {
+        Parcel parcel = Parcel.obtain();
+        parcel.writeInterfaceToken(IMEDIA_PLAYER);
+        return parcel;
+    }
+
+    /**
+     * Invoke a generic method on the native player using opaque
+     * parcels for the request and reply. Both payloads' format is a
+     * convention between the java caller and the native player.
+     * Must be called after setDataSource to make sure a native player
+     * exists. On failure, a RuntimeException is thrown.
+     *
+     * @param request Parcel with the data for the extension. The
+     * caller must use {@link #newRequest()} to get one.
+     *
+     * @param reply Output parcel with the data returned by the
+     * native player.
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    public void invoke(Parcel request, Parcel reply) {
+        int retcode = native_invoke(request, reply);
+        reply.setDataPosition(0);
+        if (retcode != 0) {
+            throw new RuntimeException("failure code: " + retcode);
+        }
+    }
+
+    /**
+     * Sets the {@link SurfaceHolder} to use for displaying the video
+     * portion of the media.
+     *
+     * Either a surface holder or surface must be set if a display or video sink
+     * is needed.  Not calling this method or {@link #setSurface(Surface)}
+     * when playing back a video will result in only the audio track being played.
+     * A null surface holder or surface will result in only the audio track being
+     * played.
+     *
+     * @param sh the SurfaceHolder to use for video display
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized or has been released.
+     */
+    public void setDisplay(SurfaceHolder sh) {
+        mSurfaceHolder = sh;
+        Surface surface;
+        if (sh != null) {
+            surface = sh.getSurface();
+        } else {
+            surface = null;
+        }
+        _setVideoSurface(surface);
+        updateSurfaceScreenOn();
+    }
+
+    /**
+     * Sets the {@link Surface} to be used as the sink for the video portion of
+     * the media. This is similar to {@link #setDisplay(SurfaceHolder)}, but
+     * does not support {@link #setScreenOnWhilePlaying(boolean)}.  Setting a
+     * Surface will un-set any Surface or SurfaceHolder that was previously set.
+     * A null surface will result in only the audio track being played.
+     *
+     * If the Surface sends frames to a {@link SurfaceTexture}, the timestamps
+     * returned from {@link SurfaceTexture#getTimestamp()} will have an
+     * unspecified zero point.  These timestamps cannot be directly compared
+     * between different media sources, different instances of the same media
+     * source, or multiple runs of the same program.  The timestamp is normally
+     * monotonically increasing and is unaffected by time-of-day adjustments,
+     * but it is reset when the position is set.
+     *
+     * @param surface The {@link Surface} to be used for the video portion of
+     * the media.
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized or has been released.
+     */
+    public void setSurface(Surface surface) {
+        if (mScreenOnWhilePlaying && surface != null) {
+            Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective for Surface");
+        }
+        mSurfaceHolder = null;
+        _setVideoSurface(surface);
+        updateSurfaceScreenOn();
+    }
+
+    /* Do not change these video scaling mode values below without updating
+     * their counterparts in system/window.h! Please do not forget to update
+     * {@link #isVideoScalingModeSupported} when new video scaling modes
+     * are added.
+     */
+    /**
+     * Specifies a video scaling mode. The content is stretched to the
+     * surface rendering area. When the surface has the same aspect ratio
+     * as the content, the aspect ratio of the content is maintained;
+     * otherwise, the aspect ratio of the content is not maintained when video
+     * is being rendered. Unlike {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING},
+     * there is no content cropping with this video scaling mode.
+     */
+    public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT = 1;
+
+    /**
+     * Specifies a video scaling mode. The content is scaled, maintaining
+     * its aspect ratio. The whole surface area is always used. When the
+     * aspect ratio of the content is the same as the surface, no content
+     * is cropped; otherwise, content is cropped to fit the surface.
+     */
+    public static final int VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING = 2;
+    /**
+     * Sets video scaling mode. To make the target video scaling mode
+     * effective during playback, this method must be called after
+     * data source is set. If not called, the default video
+     * scaling mode is {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT}.
+     *
+     * <p> The supported video scaling modes are:
+     * <ul>
+     * <li> {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT}
+     * <li> {@link #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING}
+     * </ul>
+     *
+     * @param mode target video scaling mode. Must be one of the supported
+     * video scaling modes; otherwise, IllegalArgumentException will be thrown.
+     *
+     * @see MediaPlayer#VIDEO_SCALING_MODE_SCALE_TO_FIT
+     * @see MediaPlayer#VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING
+     */
+    public void setVideoScalingMode(int mode) {
+        if (!isVideoScalingModeSupported(mode)) {
+            final String msg = "Scaling mode " + mode + " is not supported";
+            throw new IllegalArgumentException(msg);
+        }
+        Parcel request = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            request.writeInterfaceToken(IMEDIA_PLAYER);
+            request.writeInt(INVOKE_ID_SET_VIDEO_SCALE_MODE);
+            request.writeInt(mode);
+            invoke(request, reply);
+        } finally {
+            request.recycle();
+            reply.recycle();
+        }
+    }
+
+    /**
+     * Convenience method to create a MediaPlayer for a given Uri.
+     * On success, {@link #prepare()} will already have been called and must not be called again.
+     * <p>When done with the MediaPlayer, you should call  {@link #release()},
+     * to free the resources. If not released, too many MediaPlayer instances will
+     * result in an exception.</p>
+     * <p>Note that since {@link #prepare()} is called automatically in this method,
+     * you cannot change the audio
+     * session ID (see {@link #setAudioSessionId(int)}) or audio attributes
+     * (see {@link #setAudioAttributes(AudioAttributes)} of the new MediaPlayer.</p>
+     *
+     * @param context the Context to use
+     * @param uri the Uri from which to get the datasource
+     * @return a MediaPlayer object, or null if creation failed
+     */
+    public static MediaPlayer create(Context context, Uri uri) {
+        return create (context, uri, null);
+    }
+
+    /**
+     * Convenience method to create a MediaPlayer for a given Uri.
+     * On success, {@link #prepare()} will already have been called and must not be called again.
+     * <p>When done with the MediaPlayer, you should call  {@link #release()},
+     * to free the resources. If not released, too many MediaPlayer instances will
+     * result in an exception.</p>
+     * <p>Note that since {@link #prepare()} is called automatically in this method,
+     * you cannot change the audio
+     * session ID (see {@link #setAudioSessionId(int)}) or audio attributes
+     * (see {@link #setAudioAttributes(AudioAttributes)} of the new MediaPlayer.</p>
+     *
+     * @param context the Context to use
+     * @param uri the Uri from which to get the datasource
+     * @param holder the SurfaceHolder to use for displaying the video
+     * @return a MediaPlayer object, or null if creation failed
+     */
+    public static MediaPlayer create(Context context, Uri uri, SurfaceHolder holder) {
+        int s = AudioSystem.newAudioSessionId();
+        return create(context, uri, holder, null, s > 0 ? s : 0);
+    }
+
+    /**
+     * Same factory method as {@link #create(Context, Uri, SurfaceHolder)} but that lets you specify
+     * the audio attributes and session ID to be used by the new MediaPlayer instance.
+     * @param context the Context to use
+     * @param uri the Uri from which to get the datasource
+     * @param holder the SurfaceHolder to use for displaying the video, may be null.
+     * @param audioAttributes the {@link AudioAttributes} to be used by the media player.
+     * @param audioSessionId the audio session ID to be used by the media player,
+     *     see {@link AudioManager#generateAudioSessionId()} to obtain a new session.
+     * @return a MediaPlayer object, or null if creation failed
+     */
+    public static MediaPlayer create(Context context, Uri uri, SurfaceHolder holder,
+            AudioAttributes audioAttributes, int audioSessionId) {
+
+        try {
+            MediaPlayer mp = new MediaPlayer(audioSessionId);
+            final AudioAttributes aa = audioAttributes != null ? audioAttributes :
+                new AudioAttributes.Builder().build();
+            mp.setAudioAttributes(aa);
+            mp.native_setAudioSessionId(audioSessionId);
+            mp.setDataSource(context, uri);
+            if (holder != null) {
+                mp.setDisplay(holder);
+            }
+            mp.prepare();
+            return mp;
+        } catch (IOException ex) {
+            Log.d(TAG, "create failed:", ex);
+            // fall through
+        } catch (IllegalArgumentException ex) {
+            Log.d(TAG, "create failed:", ex);
+            // fall through
+        } catch (SecurityException ex) {
+            Log.d(TAG, "create failed:", ex);
+            // fall through
+        }
+
+        return null;
+    }
+
+    // Note no convenience method to create a MediaPlayer with SurfaceTexture sink.
+
+    /**
+     * Convenience method to create a MediaPlayer for a given resource id.
+     * On success, {@link #prepare()} will already have been called and must not be called again.
+     * <p>When done with the MediaPlayer, you should call  {@link #release()},
+     * to free the resources. If not released, too many MediaPlayer instances will
+     * result in an exception.</p>
+     * <p>Note that since {@link #prepare()} is called automatically in this method,
+     * you cannot change the audio
+     * session ID (see {@link #setAudioSessionId(int)}) or audio attributes
+     * (see {@link #setAudioAttributes(AudioAttributes)} of the new MediaPlayer.</p>
+     *
+     * @param context the Context to use
+     * @param resid the raw resource id (<var>R.raw.&lt;something></var>) for
+     *              the resource to use as the datasource
+     * @return a MediaPlayer object, or null if creation failed
+     */
+    public static MediaPlayer create(Context context, int resid) {
+        int s = AudioSystem.newAudioSessionId();
+        return create(context, resid, null, s > 0 ? s : 0);
+    }
+
+    /**
+     * Same factory method as {@link #create(Context, int)} but that lets you specify the audio
+     * attributes and session ID to be used by the new MediaPlayer instance.
+     * @param context the Context to use
+     * @param resid the raw resource id (<var>R.raw.&lt;something></var>) for
+     *              the resource to use as the datasource
+     * @param audioAttributes the {@link AudioAttributes} to be used by the media player.
+     * @param audioSessionId the audio session ID to be used by the media player,
+     *     see {@link AudioManager#generateAudioSessionId()} to obtain a new session.
+     * @return a MediaPlayer object, or null if creation failed
+     */
+    public static MediaPlayer create(Context context, int resid,
+            AudioAttributes audioAttributes, int audioSessionId) {
+        try {
+            AssetFileDescriptor afd = context.getResources().openRawResourceFd(resid);
+            if (afd == null) return null;
+
+            MediaPlayer mp = new MediaPlayer(audioSessionId);
+
+            final AudioAttributes aa = audioAttributes != null ? audioAttributes :
+                new AudioAttributes.Builder().build();
+            mp.setAudioAttributes(aa);
+            mp.native_setAudioSessionId(audioSessionId);
+
+            mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
+            afd.close();
+            mp.prepare();
+            return mp;
+        } catch (IOException ex) {
+            Log.d(TAG, "create failed:", ex);
+            // fall through
+        } catch (IllegalArgumentException ex) {
+            Log.d(TAG, "create failed:", ex);
+           // fall through
+        } catch (SecurityException ex) {
+            Log.d(TAG, "create failed:", ex);
+            // fall through
+        }
+        return null;
+    }
+
+    /**
+     * Sets the data source as a content Uri.
+     *
+     * @param context the Context to use when resolving the Uri
+     * @param uri the Content URI of the data you want to play
+     * @throws IllegalStateException if it is called in an invalid state
+     */
+    public void setDataSource(@NonNull Context context, @NonNull Uri uri)
+            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+        setDataSource(context, uri, null, null);
+    }
+
+    /**
+     * Sets the data source as a content Uri.
+     *
+     * To provide cookies for the subsequent HTTP requests, you can install your own default cookie
+     * handler and use other variants of setDataSource APIs instead. Alternatively, you can use
+     * this API to pass the cookies as a list of HttpCookie. If the app has not installed
+     * a CookieHandler already, this API creates a CookieManager and populates its CookieStore with
+     * the provided cookies. If the app has installed its own handler already, this API requires the
+     * handler to be of CookieManager type such that the API can update the manager’s CookieStore.
+     *
+     * <p><strong>Note</strong> that the cross domain redirection is allowed by default,
+     * but that can be changed with key/value pairs through the headers parameter with
+     * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to
+     * disallow or allow cross domain redirection.
+     *
+     * @param context the Context to use when resolving the Uri
+     * @param uri the Content URI of the data you want to play
+     * @param headers the headers to be sent together with the request for the data
+     *                The headers must not include cookies. Instead, use the cookies param.
+     * @param cookies the cookies to be sent together with the request
+     * @throws IllegalArgumentException if cookies are provided and the installed handler is not
+     *                                  a CookieManager
+     * @throws IllegalStateException    if it is called in an invalid state
+     * @throws NullPointerException     if context or uri is null
+     * @throws IOException              if uri has a file scheme and an I/O error occurs
+     */
+    public void setDataSource(@NonNull Context context, @NonNull Uri uri,
+            @Nullable Map<String, String> headers, @Nullable List<HttpCookie> cookies)
+            throws IOException {
+        if (context == null) {
+            throw new NullPointerException("context param can not be null.");
+        }
+
+        if (uri == null) {
+            throw new NullPointerException("uri param can not be null.");
+        }
+
+        if (cookies != null) {
+            CookieHandler cookieHandler = CookieHandler.getDefault();
+            if (cookieHandler != null && !(cookieHandler instanceof CookieManager)) {
+                throw new IllegalArgumentException("The cookie handler has to be of CookieManager "
+                        + "type when cookies are provided.");
+            }
+        }
+
+        // The context and URI usually belong to the calling user. Get a resolver for that user
+        // and strip out the userId from the URI if present.
+        final ContentResolver resolver = context.getContentResolver();
+        final String scheme = uri.getScheme();
+        final String authority = ContentProvider.getAuthorityWithoutUserId(uri.getAuthority());
+        if (ContentResolver.SCHEME_FILE.equals(scheme)) {
+            setDataSource(uri.getPath());
+            return;
+        } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)
+                && Settings.AUTHORITY.equals(authority)) {
+            // Try cached ringtone first since the actual provider may not be
+            // encryption aware, or it may be stored on CE media storage
+            final int type = RingtoneManager.getDefaultType(uri);
+            final Uri cacheUri = RingtoneManager.getCacheForType(type, context.getUserId());
+            final Uri actualUri = RingtoneManager.getActualDefaultRingtoneUri(context, type);
+            if (attemptDataSource(resolver, cacheUri)) {
+                return;
+            } else if (attemptDataSource(resolver, actualUri)) {
+                return;
+            } else {
+                setDataSource(uri.toString(), headers, cookies);
+            }
+        } else {
+            // Try requested Uri locally first, or fallback to media server
+            if (attemptDataSource(resolver, uri)) {
+                return;
+            } else {
+                setDataSource(uri.toString(), headers, cookies);
+            }
+        }
+    }
+
+    /**
+     * Sets the data source as a content Uri.
+     *
+     * <p><strong>Note</strong> that the cross domain redirection is allowed by default,
+     * but that can be changed with key/value pairs through the headers parameter with
+     * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value to
+     * disallow or allow cross domain redirection.
+     *
+     * @param context the Context to use when resolving the Uri
+     * @param uri the Content URI of the data you want to play
+     * @param headers the headers to be sent together with the request for the data
+     * @throws IllegalStateException if it is called in an invalid state
+     */
+    public void setDataSource(@NonNull Context context, @NonNull Uri uri,
+            @Nullable Map<String, String> headers)
+            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+        setDataSource(context, uri, headers, null);
+    }
+
+    private boolean attemptDataSource(ContentResolver resolver, Uri uri) {
+        boolean optimize = SystemProperties.getBoolean("fuse.sys.transcode_player_optimize",
+                false);
+        Bundle opts = new Bundle();
+        opts.putBoolean("android.provider.extra.ACCEPT_ORIGINAL_MEDIA_FORMAT", true);
+        try (AssetFileDescriptor afd = optimize
+                ? resolver.openTypedAssetFileDescriptor(uri, "*/*", opts)
+                : resolver.openAssetFileDescriptor(uri, "r")) {
+            setDataSource(afd);
+            return true;
+        } catch (NullPointerException | SecurityException | IOException ex) {
+            return false;
+        }
+    }
+
+    /**
+     * Sets the data source (file-path or http/rtsp URL) to use.
+     *
+     * <p>When <code>path</code> refers to a local file, the file may actually be opened by a
+     * process other than the calling application.  This implies that the pathname
+     * should be an absolute path (as any other process runs with unspecified current working
+     * directory), and that the pathname should reference a world-readable file.
+     * As an alternative, the application could first open the file for reading,
+     * and then use the file descriptor form {@link #setDataSource(FileDescriptor)}.
+     *
+     * @param path the path of the file, or the http/rtsp URL of the stream you want to play
+     * @throws IllegalStateException if it is called in an invalid state
+     */
+    public void setDataSource(String path)
+            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+        setDataSource(path, null, null);
+    }
+
+    /**
+     * Sets the data source (file-path or http/rtsp URL) to use.
+     *
+     * @param path the path of the file, or the http/rtsp URL of the stream you want to play
+     * @param headers the headers associated with the http request for the stream you want to play
+     * @throws IllegalStateException if it is called in an invalid state
+     * @hide pending API council
+     */
+    @UnsupportedAppUsage
+    public void setDataSource(String path, Map<String, String> headers)
+            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+        setDataSource(path, headers, null);
+    }
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private void setDataSource(String path, Map<String, String> headers, List<HttpCookie> cookies)
+            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException
+    {
+        String[] keys = null;
+        String[] values = null;
+
+        if (headers != null) {
+            keys = new String[headers.size()];
+            values = new String[headers.size()];
+
+            int i = 0;
+            for (Map.Entry<String, String> entry: headers.entrySet()) {
+                keys[i] = entry.getKey();
+                values[i] = entry.getValue();
+                ++i;
+            }
+        }
+        setDataSource(path, keys, values, cookies);
+    }
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private void setDataSource(String path, String[] keys, String[] values,
+            List<HttpCookie> cookies)
+            throws IOException, IllegalArgumentException, SecurityException, IllegalStateException {
+        final Uri uri = Uri.parse(path);
+        final String scheme = uri.getScheme();
+        if ("file".equals(scheme)) {
+            path = uri.getPath();
+        } else if (scheme != null) {
+            // handle non-file sources
+            nativeSetDataSource(
+                MediaHTTPService.createHttpServiceBinderIfNecessary(path, cookies),
+                path,
+                keys,
+                values);
+            return;
+        }
+
+        final File file = new File(path);
+        try (FileInputStream is = new FileInputStream(file)) {
+            setDataSource(is.getFD());
+        }
+    }
+
+    private native void nativeSetDataSource(
+        IBinder httpServiceBinder, String path, String[] keys, String[] values)
+        throws IOException, IllegalArgumentException, SecurityException, IllegalStateException;
+
+    /**
+     * Sets the data source (AssetFileDescriptor) to use. It is the caller's
+     * responsibility to close the file descriptor. It is safe to do so as soon
+     * as this call returns.
+     *
+     * @param afd the AssetFileDescriptor for the file you want to play
+     * @throws IllegalStateException if it is called in an invalid state
+     * @throws IllegalArgumentException if afd is not a valid AssetFileDescriptor
+     * @throws IOException if afd can not be read
+     */
+    public void setDataSource(@NonNull AssetFileDescriptor afd)
+            throws IOException, IllegalArgumentException, IllegalStateException {
+        Preconditions.checkNotNull(afd);
+        // Note: using getDeclaredLength so that our behavior is the same
+        // as previous versions when the content provider is returning
+        // a full file.
+        if (afd.getDeclaredLength() < 0) {
+            setDataSource(afd.getFileDescriptor());
+        } else {
+            setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getDeclaredLength());
+        }
+    }
+
+    /**
+     * Sets the data source (FileDescriptor) to use. It is the caller's responsibility
+     * to close the file descriptor. It is safe to do so as soon as this call returns.
+     *
+     * @param fd the FileDescriptor for the file you want to play
+     * @throws IllegalStateException if it is called in an invalid state
+     * @throws IllegalArgumentException if fd is not a valid FileDescriptor
+     * @throws IOException if fd can not be read
+     */
+    public void setDataSource(FileDescriptor fd)
+            throws IOException, IllegalArgumentException, IllegalStateException {
+        // intentionally less than LONG_MAX
+        setDataSource(fd, 0, 0x7ffffffffffffffL);
+    }
+
+    /**
+     * Sets the data source (FileDescriptor) to use.  The FileDescriptor must be
+     * seekable (N.B. a LocalSocket is not seekable). It is the caller's responsibility
+     * to close the file descriptor. It is safe to do so as soon as this call returns.
+     *
+     * @param fd the FileDescriptor for the file you want to play
+     * @param offset the offset into the file where the data to be played starts, in bytes
+     * @param length the length in bytes of the data to be played
+     * @throws IllegalStateException if it is called in an invalid state
+     * @throws IllegalArgumentException if fd is not a valid FileDescriptor
+     * @throws IOException if fd can not be read
+     */
+    public void setDataSource(FileDescriptor fd, long offset, long length)
+            throws IOException, IllegalArgumentException, IllegalStateException {
+        try (ParcelFileDescriptor modernFd = FileUtils.convertToModernFd(fd)) {
+            if (modernFd == null) {
+                _setDataSource(fd, offset, length);
+            } else {
+                _setDataSource(modernFd.getFileDescriptor(), offset, length);
+            }
+        } catch (IOException e) {
+            Log.w(TAG, "Ignoring IO error while setting data source", e);
+        }
+    }
+
+    private native void _setDataSource(FileDescriptor fd, long offset, long length)
+            throws IOException, IllegalArgumentException, IllegalStateException;
+
+    /**
+     * Sets the data source (MediaDataSource) to use.
+     *
+     * @param dataSource the MediaDataSource for the media you want to play
+     * @throws IllegalStateException if it is called in an invalid state
+     * @throws IllegalArgumentException if dataSource is not a valid MediaDataSource
+     */
+    public void setDataSource(MediaDataSource dataSource)
+            throws IllegalArgumentException, IllegalStateException {
+        _setDataSource(dataSource);
+    }
+
+    private native void _setDataSource(MediaDataSource dataSource)
+          throws IllegalArgumentException, IllegalStateException;
+
+    /**
+     * Prepares the player for playback, synchronously.
+     *
+     * After setting the datasource and the display surface, you need to either
+     * call prepare() or prepareAsync(). For files, it is OK to call prepare(),
+     * which blocks until MediaPlayer is ready for playback.
+     *
+     * @throws IllegalStateException if it is called in an invalid state
+     */
+    public void prepare() throws IOException, IllegalStateException {
+        _prepare();
+        scanInternalSubtitleTracks();
+
+        // DrmInfo, if any, has been resolved by now.
+        synchronized (mDrmLock) {
+            mDrmInfoResolved = true;
+        }
+    }
+
+    private native void _prepare() throws IOException, IllegalStateException;
+
+    /**
+     * Prepares the player for playback, asynchronously.
+     *
+     * After setting the datasource and the display surface, you need to either
+     * call prepare() or prepareAsync(). For streams, you should call prepareAsync(),
+     * which returns immediately, rather than blocking until enough data has been
+     * buffered.
+     *
+     * @throws IllegalStateException if it is called in an invalid state
+     */
+    public native void prepareAsync() throws IllegalStateException;
+
+    /**
+     * Starts or resumes playback. If playback had previously been paused,
+     * playback will continue from where it was paused. If playback had
+     * been stopped, or never started before, playback will start at the
+     * beginning.
+     *
+     * @throws IllegalStateException if it is called in an invalid state
+     */
+    public void start() throws IllegalStateException {
+        //FIXME use lambda to pass startImpl to superclass
+        final int delay = getStartDelayMs();
+        if (delay == 0) {
+            startImpl();
+        } else {
+            new Thread() {
+                public void run() {
+                    try {
+                        Thread.sleep(delay);
+                    } catch (InterruptedException e) {
+                        e.printStackTrace();
+                    }
+                    baseSetStartDelayMs(0);
+                    try {
+                        startImpl();
+                    } catch (IllegalStateException e) {
+                        // fail silently for a state exception when it is happening after
+                        // a delayed start, as the player state could have changed between the
+                        // call to start() and the execution of startImpl()
+                    }
+                }
+            }.start();
+        }
+    }
+
+    private void startImpl() {
+        baseStart(0); // unknown device at this point
+        stayAwake(true);
+        tryToEnableNativeRoutingCallback();
+        _start();
+    }
+
+    private native void _start() throws IllegalStateException;
+
+
+    private int getAudioStreamType() {
+        if (mStreamType == AudioManager.USE_DEFAULT_STREAM_TYPE) {
+            mStreamType = _getAudioStreamType();
+        }
+        return mStreamType;
+    }
+
+    private native int _getAudioStreamType() throws IllegalStateException;
+
+    /**
+     * Stops playback after playback has been started or paused.
+     *
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized.
+     */
+    public void stop() throws IllegalStateException {
+        stayAwake(false);
+        _stop();
+        baseStop();
+        tryToDisableNativeRoutingCallback();
+    }
+
+    private native void _stop() throws IllegalStateException;
+
+    /**
+     * Pauses playback. Call start() to resume.
+     *
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized.
+     */
+    public void pause() throws IllegalStateException {
+        stayAwake(false);
+        _pause();
+        basePause();
+    }
+
+    private native void _pause() throws IllegalStateException;
+
+    @Override
+    void playerStart() {
+        start();
+    }
+
+    @Override
+    void playerPause() {
+        pause();
+    }
+
+    @Override
+    void playerStop() {
+        stop();
+    }
+
+    @Override
+    /* package */ int playerApplyVolumeShaper(
+            @NonNull VolumeShaper.Configuration configuration,
+            @NonNull VolumeShaper.Operation operation) {
+        return native_applyVolumeShaper(configuration, operation);
+    }
+
+    @Override
+    /* package */ @Nullable VolumeShaper.State playerGetVolumeShaperState(int id) {
+        return native_getVolumeShaperState(id);
+    }
+
+    @Override
+    public @NonNull VolumeShaper createVolumeShaper(
+            @NonNull VolumeShaper.Configuration configuration) {
+        return new VolumeShaper(configuration, this);
+    }
+
+    private native int native_applyVolumeShaper(
+            @NonNull VolumeShaper.Configuration configuration,
+            @NonNull VolumeShaper.Operation operation);
+
+    private native @Nullable VolumeShaper.State native_getVolumeShaperState(int id);
+
+    //--------------------------------------------------------------------------
+    // Explicit Routing
+    //--------------------
+    private AudioDeviceInfo mPreferredDevice = null;
+
+    /**
+     * Specifies an audio device (via an {@link AudioDeviceInfo} object) to route
+     * the output from this MediaPlayer.
+     * @param deviceInfo The {@link AudioDeviceInfo} specifying the audio sink or source.
+     *  If deviceInfo is null, default routing is restored.
+     * @return true if succesful, false if the specified {@link AudioDeviceInfo} is non-null and
+     * does not correspond to a valid audio device.
+     */
+    @Override
+    public boolean setPreferredDevice(AudioDeviceInfo deviceInfo) {
+        if (deviceInfo != null && !deviceInfo.isSink()) {
+            return false;
+        }
+        int preferredDeviceId = deviceInfo != null ? deviceInfo.getId() : 0;
+        boolean status = native_setOutputDevice(preferredDeviceId);
+        if (status == true) {
+            synchronized (this) {
+                mPreferredDevice = deviceInfo;
+            }
+        }
+        return status;
+    }
+
+    /**
+     * Returns the selected output specified by {@link #setPreferredDevice}. Note that this
+     * is not guaranteed to correspond to the actual device being used for playback.
+     */
+    @Override
+    public AudioDeviceInfo getPreferredDevice() {
+        synchronized (this) {
+            return mPreferredDevice;
+        }
+    }
+
+    /**
+     * Returns an {@link AudioDeviceInfo} identifying the current routing of this MediaPlayer
+     * Note: The query is only valid if the MediaPlayer is currently playing.
+     * If the player is not playing, the returned device can be null or correspond to previously
+     * selected device when the player was last active.
+     */
+    @Override
+    public AudioDeviceInfo getRoutedDevice() {
+        int deviceId = native_getRoutedDeviceId();
+        if (deviceId == 0) {
+            return null;
+        }
+        return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_OUTPUTS);
+    }
+
+
+    /**
+     * Sends device list change notification to all listeners.
+     */
+    private void broadcastRoutingChange() {
+        AudioManager.resetAudioPortGeneration();
+        synchronized (mRoutingChangeListeners) {
+            // Prevent the case where an event is triggered by registering a routing change
+            // listener via the media player.
+            if (mEnableSelfRoutingMonitor) {
+                baseUpdateDeviceId(getRoutedDevice());
+            }
+            for (NativeRoutingEventHandlerDelegate delegate
+                    : mRoutingChangeListeners.values()) {
+                delegate.notifyClient();
+            }
+        }
+    }
+
+    /**
+     * Call BEFORE adding a routing callback handler and when enabling self routing listener
+     * @return returns true for success, false otherwise.
+     */
+    @GuardedBy("mRoutingChangeListeners")
+    private boolean testEnableNativeRoutingCallbacksLocked() {
+        if (mRoutingChangeListeners.size() == 0 && !mEnableSelfRoutingMonitor) {
+            try {
+                native_enableDeviceCallback(true);
+                return true;
+            } catch (IllegalStateException e) {
+                if (Log.isLoggable(TAG, Log.DEBUG)) {
+                    Log.d(TAG, "testEnableNativeRoutingCallbacks failed", e);
+                }
+            }
+        }
+        return false;
+    }
+
+    private void  tryToEnableNativeRoutingCallback() {
+        synchronized (mRoutingChangeListeners) {
+            if (!mEnableSelfRoutingMonitor) {
+                mEnableSelfRoutingMonitor = testEnableNativeRoutingCallbacksLocked();
+            }
+        }
+    }
+
+    private void tryToDisableNativeRoutingCallback() {
+        synchronized (mRoutingChangeListeners) {
+            if (mEnableSelfRoutingMonitor) {
+                mEnableSelfRoutingMonitor = false;
+                testDisableNativeRoutingCallbacksLocked();
+            }
+        }
+    }
+
+    /*
+     * Call AFTER removing a routing callback handler and when disabling self routing listener
+     */
+    @GuardedBy("mRoutingChangeListeners")
+    private void testDisableNativeRoutingCallbacksLocked() {
+        if (mRoutingChangeListeners.size() == 0 && !mEnableSelfRoutingMonitor) {
+            try {
+                native_enableDeviceCallback(false);
+            } catch (IllegalStateException e) {
+                // Fail silently as media player state could have changed in between stop
+                // and disabling routing callback
+            }
+        }
+    }
+
+    /**
+     * The list of AudioRouting.OnRoutingChangedListener interfaces added (with
+     * {@link #addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, Handler)}
+     * by an app to receive (re)routing notifications.
+     */
+    @GuardedBy("mRoutingChangeListeners")
+    private ArrayMap<AudioRouting.OnRoutingChangedListener,
+            NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<>();
+
+    @GuardedBy("mRoutingChangeListeners")
+    private boolean mEnableSelfRoutingMonitor;
+
+    /**
+     * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
+     * changes on this MediaPlayer.
+     * @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive
+     * notifications of rerouting events.
+     * @param handler  Specifies the {@link Handler} object for the thread on which to execute
+     * the callback. If <code>null</code>, the handler on the main looper will be used.
+     */
+    @Override
+    public void addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener,
+            Handler handler) {
+        synchronized (mRoutingChangeListeners) {
+            if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
+                mEnableSelfRoutingMonitor = testEnableNativeRoutingCallbacksLocked();
+                mRoutingChangeListeners.put(
+                        listener, new NativeRoutingEventHandlerDelegate(this, listener,
+                                handler != null ? handler : mEventHandler));
+            }
+        }
+    }
+
+    /**
+     * Removes an {@link AudioRouting.OnRoutingChangedListener} which has been previously added
+     * to receive rerouting notifications.
+     * @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
+     * to remove.
+     */
+    @Override
+    public void removeOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener) {
+        synchronized (mRoutingChangeListeners) {
+            if (mRoutingChangeListeners.containsKey(listener)) {
+                mRoutingChangeListeners.remove(listener);
+            }
+            testDisableNativeRoutingCallbacksLocked();
+        }
+    }
+
+    private native final boolean native_setOutputDevice(int deviceId);
+    private native final int native_getRoutedDeviceId();
+    private native final void native_enableDeviceCallback(boolean enabled);
+
+    /**
+     * Set the low-level power management behavior for this MediaPlayer.  This
+     * can be used when the MediaPlayer is not playing through a SurfaceHolder
+     * set with {@link #setDisplay(SurfaceHolder)} and thus can use the
+     * high-level {@link #setScreenOnWhilePlaying(boolean)} feature.
+     *
+     * <p>This function has the MediaPlayer access the low-level power manager
+     * service to control the device's power usage while playing is occurring.
+     * The parameter is a combination of {@link android.os.PowerManager} wake flags.
+     * Use of this method requires {@link android.Manifest.permission#WAKE_LOCK}
+     * permission.
+     * By default, no attempt is made to keep the device awake during playback.
+     *
+     * @param context the Context to use
+     * @param mode    the power/wake mode to set
+     * @see android.os.PowerManager
+     */
+    public void setWakeMode(Context context, int mode) {
+        boolean washeld = false;
+
+        /* Disable persistant wakelocks in media player based on property */
+        if (SystemProperties.getBoolean("audio.offload.ignore_setawake", false) == true) {
+            Log.w(TAG, "IGNORING setWakeMode " + mode);
+            return;
+        }
+
+        if (mWakeLock != null) {
+            if (mWakeLock.isHeld()) {
+                washeld = true;
+                mWakeLock.release();
+            }
+            mWakeLock = null;
+        }
+
+        PowerManager pm = (PowerManager)context.getSystemService(Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(mode|PowerManager.ON_AFTER_RELEASE, MediaPlayer.class.getName());
+        mWakeLock.setReferenceCounted(false);
+        if (washeld) {
+            mWakeLock.acquire();
+        }
+    }
+
+    /**
+     * Control whether we should use the attached SurfaceHolder to keep the
+     * screen on while video playback is occurring.  This is the preferred
+     * method over {@link #setWakeMode} where possible, since it doesn't
+     * require that the application have permission for low-level wake lock
+     * access.
+     *
+     * @param screenOn Supply true to keep the screen on, false to allow it
+     * to turn off.
+     */
+    public void setScreenOnWhilePlaying(boolean screenOn) {
+        if (mScreenOnWhilePlaying != screenOn) {
+            if (screenOn && mSurfaceHolder == null) {
+                Log.w(TAG, "setScreenOnWhilePlaying(true) is ineffective without a SurfaceHolder");
+            }
+            mScreenOnWhilePlaying = screenOn;
+            updateSurfaceScreenOn();
+        }
+    }
+
+    private void stayAwake(boolean awake) {
+        if (mWakeLock != null) {
+            if (awake && !mWakeLock.isHeld()) {
+                mWakeLock.acquire();
+            } else if (!awake && mWakeLock.isHeld()) {
+                mWakeLock.release();
+            }
+        }
+        mStayAwake = awake;
+        updateSurfaceScreenOn();
+    }
+
+    private void updateSurfaceScreenOn() {
+        if (mSurfaceHolder != null) {
+            mSurfaceHolder.setKeepScreenOn(mScreenOnWhilePlaying && mStayAwake);
+        }
+    }
+
+    /**
+     * Returns the width of the video.
+     *
+     * @return the width of the video, or 0 if there is no video,
+     * no display surface was set, or the width has not been determined
+     * yet. The OnVideoSizeChangedListener can be registered via
+     * {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener)}
+     * to provide a notification when the width is available.
+     */
+    public native int getVideoWidth();
+
+    /**
+     * Returns the height of the video.
+     *
+     * @return the height of the video, or 0 if there is no video,
+     * no display surface was set, or the height has not been determined
+     * yet. The OnVideoSizeChangedListener can be registered via
+     * {@link #setOnVideoSizeChangedListener(OnVideoSizeChangedListener)}
+     * to provide a notification when the height is available.
+     */
+    public native int getVideoHeight();
+
+    /**
+     * Return Metrics data about the current player.
+     *
+     * @return a {@link PersistableBundle} containing the set of attributes and values
+     * available for the media being handled by this instance of MediaPlayer
+     * The attributes are descibed in {@link MetricsConstants}.
+     *
+     *  Additional vendor-specific fields may also be present in
+     *  the return value.
+     */
+    public PersistableBundle getMetrics() {
+        PersistableBundle bundle = native_getMetrics();
+        return bundle;
+    }
+
+    private native PersistableBundle native_getMetrics();
+
+    /**
+     * Checks whether the MediaPlayer is playing.
+     *
+     * @return true if currently playing, false otherwise
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized or has been released.
+     */
+    public native boolean isPlaying();
+
+    /**
+     * Change playback speed of audio by resampling the audio.
+     * <p>
+     * Specifies resampling as audio mode for variable rate playback, i.e.,
+     * resample the waveform based on the requested playback rate to get
+     * a new waveform, and play back the new waveform at the original sampling
+     * frequency.
+     * When rate is larger than 1.0, pitch becomes higher.
+     * When rate is smaller than 1.0, pitch becomes lower.
+     *
+     * @hide
+     */
+    public static final int PLAYBACK_RATE_AUDIO_MODE_RESAMPLE = 2;
+
+    /**
+     * Change playback speed of audio without changing its pitch.
+     * <p>
+     * Specifies time stretching as audio mode for variable rate playback.
+     * Time stretching changes the duration of the audio samples without
+     * affecting its pitch.
+     * <p>
+     * This mode is only supported for a limited range of playback speed factors,
+     * e.g. between 1/2x and 2x.
+     *
+     * @hide
+     */
+    public static final int PLAYBACK_RATE_AUDIO_MODE_STRETCH = 1;
+
+    /**
+     * Change playback speed of audio without changing its pitch, and
+     * possibly mute audio if time stretching is not supported for the playback
+     * speed.
+     * <p>
+     * Try to keep audio pitch when changing the playback rate, but allow the
+     * system to determine how to change audio playback if the rate is out
+     * of range.
+     *
+     * @hide
+     */
+    public static final int PLAYBACK_RATE_AUDIO_MODE_DEFAULT = 0;
+
+    /** @hide */
+    @IntDef(
+        value = {
+            PLAYBACK_RATE_AUDIO_MODE_DEFAULT,
+            PLAYBACK_RATE_AUDIO_MODE_STRETCH,
+            PLAYBACK_RATE_AUDIO_MODE_RESAMPLE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PlaybackRateAudioMode {}
+
+    /**
+     * Sets playback rate and audio mode.
+     *
+     * @param rate the ratio between desired playback rate and normal one.
+     * @param audioMode audio playback mode. Must be one of the supported
+     * audio modes.
+     *
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized.
+     * @throws IllegalArgumentException if audioMode is not supported.
+     *
+     * @hide
+     */
+    @NonNull
+    public PlaybackParams easyPlaybackParams(float rate, @PlaybackRateAudioMode int audioMode) {
+        PlaybackParams params = new PlaybackParams();
+        params.allowDefaults();
+        switch (audioMode) {
+        case PLAYBACK_RATE_AUDIO_MODE_DEFAULT:
+            params.setSpeed(rate).setPitch(1.0f);
+            break;
+        case PLAYBACK_RATE_AUDIO_MODE_STRETCH:
+            params.setSpeed(rate).setPitch(1.0f)
+                    .setAudioFallbackMode(params.AUDIO_FALLBACK_MODE_FAIL);
+            break;
+        case PLAYBACK_RATE_AUDIO_MODE_RESAMPLE:
+            params.setSpeed(rate).setPitch(rate);
+            break;
+        default:
+            final String msg = "Audio playback mode " + audioMode + " is not supported";
+            throw new IllegalArgumentException(msg);
+        }
+        return params;
+    }
+
+    /**
+     * Sets playback rate using {@link PlaybackParams}. The object sets its internal
+     * PlaybackParams to the input, except that the object remembers previous speed
+     * when input speed is zero. This allows the object to resume at previous speed
+     * when start() is called. Calling it before the object is prepared does not change
+     * the object state. After the object is prepared, calling it with zero speed is
+     * equivalent to calling pause(). After the object is prepared, calling it with
+     * non-zero speed is equivalent to calling start().
+     *
+     * @param params the playback params.
+     *
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized or has been released.
+     * @throws IllegalArgumentException if params is not supported.
+     */
+    public native void setPlaybackParams(@NonNull PlaybackParams params);
+
+    /**
+     * Gets the playback params, containing the current playback rate.
+     *
+     * @return the playback params.
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized.
+     */
+    @NonNull
+    public native PlaybackParams getPlaybackParams();
+
+    /**
+     * Sets A/V sync mode.
+     *
+     * @param params the A/V sync params to apply
+     *
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized.
+     * @throws IllegalArgumentException if params are not supported.
+     */
+    public native void setSyncParams(@NonNull SyncParams params);
+
+    /**
+     * Gets the A/V sync mode.
+     *
+     * @return the A/V sync params
+     *
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized.
+     */
+    @NonNull
+    public native SyncParams getSyncParams();
+
+    /**
+     * Seek modes used in method seekTo(long, int) to move media position
+     * to a specified location.
+     *
+     * Do not change these mode values without updating their counterparts
+     * in include/media/IMediaSource.h!
+     */
+    /**
+     * This mode is used with {@link #seekTo(long, int)} to move media position to
+     * a sync (or key) frame associated with a data source that is located
+     * right before or at the given time.
+     *
+     * @see #seekTo(long, int)
+     */
+    public static final int SEEK_PREVIOUS_SYNC    = 0x00;
+    /**
+     * This mode is used with {@link #seekTo(long, int)} to move media position to
+     * a sync (or key) frame associated with a data source that is located
+     * right after or at the given time.
+     *
+     * @see #seekTo(long, int)
+     */
+    public static final int SEEK_NEXT_SYNC        = 0x01;
+    /**
+     * This mode is used with {@link #seekTo(long, int)} to move media position to
+     * a sync (or key) frame associated with a data source that is located
+     * closest to (in time) or at the given time.
+     *
+     * @see #seekTo(long, int)
+     */
+    public static final int SEEK_CLOSEST_SYNC     = 0x02;
+    /**
+     * This mode is used with {@link #seekTo(long, int)} to move media position to
+     * a frame (not necessarily a key frame) associated with a data source that
+     * is located closest to or at the given time.
+     *
+     * @see #seekTo(long, int)
+     */
+    public static final int SEEK_CLOSEST          = 0x03;
+
+    /** @hide */
+    @IntDef(
+        value = {
+            SEEK_PREVIOUS_SYNC,
+            SEEK_NEXT_SYNC,
+            SEEK_CLOSEST_SYNC,
+            SEEK_CLOSEST,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SeekMode {}
+
+    private native final void _seekTo(long msec, int mode);
+
+    /**
+     * Moves the media to specified time position by considering the given mode.
+     * <p>
+     * When seekTo is finished, the user will be notified via OnSeekComplete supplied by the user.
+     * There is at most one active seekTo processed at any time. If there is a to-be-completed
+     * seekTo, new seekTo requests will be queued in such a way that only the last request
+     * is kept. When current seekTo is completed, the queued request will be processed if
+     * that request is different from just-finished seekTo operation, i.e., the requested
+     * position or mode is different.
+     *
+     * @param msec the offset in milliseconds from the start to seek to.
+     * When seeking to the given time position, there is no guarantee that the data source
+     * has a frame located at the position. When this happens, a frame nearby will be rendered.
+     * If msec is negative, time position zero will be used.
+     * If msec is larger than duration, duration will be used.
+     * @param mode the mode indicating where exactly to seek to.
+     * Use {@link #SEEK_PREVIOUS_SYNC} if one wants to seek to a sync frame
+     * that has a timestamp earlier than or the same as msec. Use
+     * {@link #SEEK_NEXT_SYNC} if one wants to seek to a sync frame
+     * that has a timestamp later than or the same as msec. Use
+     * {@link #SEEK_CLOSEST_SYNC} if one wants to seek to a sync frame
+     * that has a timestamp closest to or the same as msec. Use
+     * {@link #SEEK_CLOSEST} if one wants to seek to a frame that may
+     * or may not be a sync frame but is closest to or the same as msec.
+     * {@link #SEEK_CLOSEST} often has larger performance overhead compared
+     * to the other options if there is no sync frame located at msec.
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized
+     * @throws IllegalArgumentException if the mode is invalid.
+     */
+    public void seekTo(long msec, @SeekMode int mode) {
+        if (mode < SEEK_PREVIOUS_SYNC || mode > SEEK_CLOSEST) {
+            final String msg = "Illegal seek mode: " + mode;
+            throw new IllegalArgumentException(msg);
+        }
+        // TODO: pass long to native, instead of truncating here.
+        if (msec > Integer.MAX_VALUE) {
+            Log.w(TAG, "seekTo offset " + msec + " is too large, cap to " + Integer.MAX_VALUE);
+            msec = Integer.MAX_VALUE;
+        } else if (msec < Integer.MIN_VALUE) {
+            Log.w(TAG, "seekTo offset " + msec + " is too small, cap to " + Integer.MIN_VALUE);
+            msec = Integer.MIN_VALUE;
+        }
+        _seekTo(msec, mode);
+    }
+
+    /**
+     * Seeks to specified time position.
+     * Same as {@link #seekTo(long, int)} with {@code mode = SEEK_PREVIOUS_SYNC}.
+     *
+     * @param msec the offset in milliseconds from the start to seek to
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized
+     */
+    public void seekTo(int msec) throws IllegalStateException {
+        seekTo(msec, SEEK_PREVIOUS_SYNC /* mode */);
+    }
+
+    /**
+     * Get current playback position as a {@link MediaTimestamp}.
+     * <p>
+     * The MediaTimestamp represents how the media time correlates to the system time in
+     * a linear fashion using an anchor and a clock rate. During regular playback, the media
+     * time moves fairly constantly (though the anchor frame may be rebased to a current
+     * system time, the linear correlation stays steady). Therefore, this method does not
+     * need to be called often.
+     * <p>
+     * To help users get current playback position, this method always anchors the timestamp
+     * to the current {@link System#nanoTime system time}, so
+     * {@link MediaTimestamp#getAnchorMediaTimeUs} can be used as current playback position.
+     *
+     * @return a MediaTimestamp object if a timestamp is available, or {@code null} if no timestamp
+     *         is available, e.g. because the media player has not been initialized.
+     *
+     * @see MediaTimestamp
+     */
+    @Nullable
+    public MediaTimestamp getTimestamp()
+    {
+        try {
+            // TODO: get the timestamp from native side
+            return new MediaTimestamp(
+                    getCurrentPosition() * 1000L,
+                    System.nanoTime(),
+                    isPlaying() ? getPlaybackParams().getSpeed() : 0.f);
+        } catch (IllegalStateException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Gets the current playback position.
+     *
+     * @return the current position in milliseconds
+     */
+    public native int getCurrentPosition();
+
+    /**
+     * Gets the duration of the file.
+     *
+     * @return the duration in milliseconds, if no duration is available
+     *         (for example, if streaming live content), -1 is returned.
+     */
+    public native int getDuration();
+
+    /**
+     * Gets the media metadata.
+     *
+     * @param update_only controls whether the full set of available
+     * metadata is returned or just the set that changed since the
+     * last call. See {@see #METADATA_UPDATE_ONLY} and {@see
+     * #METADATA_ALL}.
+     *
+     * @param apply_filter if true only metadata that matches the
+     * filter is returned. See {@see #APPLY_METADATA_FILTER} and {@see
+     * #BYPASS_METADATA_FILTER}.
+     *
+     * @return The metadata, possibly empty. null if an error occured.
+     // FIXME: unhide.
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    public Metadata getMetadata(final boolean update_only,
+                                final boolean apply_filter) {
+        Parcel reply = Parcel.obtain();
+        Metadata data = new Metadata();
+
+        if (!native_getMetadata(update_only, apply_filter, reply)) {
+            reply.recycle();
+            return null;
+        }
+
+        // Metadata takes over the parcel, don't recycle it unless
+        // there is an error.
+        if (!data.parse(reply)) {
+            reply.recycle();
+            return null;
+        }
+        return data;
+    }
+
+    /**
+     * Set a filter for the metadata update notification and update
+     * retrieval. The caller provides 2 set of metadata keys, allowed
+     * and blocked. The blocked set always takes precedence over the
+     * allowed one.
+     * Metadata.MATCH_ALL and Metadata.MATCH_NONE are 2 sets available as
+     * shorthands to allow/block all or no metadata.
+     *
+     * By default, there is no filter set.
+     *
+     * @param allow Is the set of metadata the client is interested
+     *              in receiving new notifications for.
+     * @param block Is the set of metadata the client is not interested
+     *              in receiving new notifications for.
+     * @return The call status code.
+     *
+     // FIXME: unhide.
+     * {@hide}
+     */
+    public int setMetadataFilter(Set<Integer> allow, Set<Integer> block) {
+        // Do our serialization manually instead of calling
+        // Parcel.writeArray since the sets are made of the same type
+        // we avoid paying the price of calling writeValue (used by
+        // writeArray) which burns an extra int per element to encode
+        // the type.
+        Parcel request =  newRequest();
+
+        // The parcel starts already with an interface token. There
+        // are 2 filters. Each one starts with a 4bytes number to
+        // store the len followed by a number of int (4 bytes as well)
+        // representing the metadata type.
+        int capacity = request.dataSize() + 4 * (1 + allow.size() + 1 + block.size());
+
+        if (request.dataCapacity() < capacity) {
+            request.setDataCapacity(capacity);
+        }
+
+        request.writeInt(allow.size());
+        for(Integer t: allow) {
+            request.writeInt(t);
+        }
+        request.writeInt(block.size());
+        for(Integer t: block) {
+            request.writeInt(t);
+        }
+        return native_setMetadataFilter(request);
+    }
+
+    /**
+     * Set the MediaPlayer to start when this MediaPlayer finishes playback
+     * (i.e. reaches the end of the stream).
+     * The media framework will attempt to transition from this player to
+     * the next as seamlessly as possible. The next player can be set at
+     * any time before completion, but shall be after setDataSource has been
+     * called successfully. The next player must be prepared by the
+     * app, and the application should not call start() on it.
+     * The next MediaPlayer must be different from 'this'. An exception
+     * will be thrown if next == this.
+     * The application may call setNextMediaPlayer(null) to indicate no
+     * next player should be started at the end of playback.
+     * If the current player is looping, it will keep looping and the next
+     * player will not be started.
+     *
+     * @param next the player to start after this one completes playback.
+     *
+     */
+    public native void setNextMediaPlayer(MediaPlayer next);
+
+    /**
+     * Releases resources associated with this MediaPlayer object.
+     * It is considered good practice to call this method when you're
+     * done using the MediaPlayer. In particular, whenever an Activity
+     * of an application is paused (its onPause() method is called),
+     * or stopped (its onStop() method is called), this method should be
+     * invoked to release the MediaPlayer object, unless the application
+     * has a special need to keep the object around. In addition to
+     * unnecessary resources (such as memory and instances of codecs)
+     * being held, failure to call this method immediately if a
+     * MediaPlayer object is no longer needed may also lead to
+     * continuous battery consumption for mobile devices, and playback
+     * failure for other applications if no multiple instances of the
+     * same codec are supported on a device. Even if multiple instances
+     * of the same codec are supported, some performance degradation
+     * may be expected when unnecessary multiple instances are used
+     * at the same time.
+     */
+    public void release() {
+        baseRelease();
+        stayAwake(false);
+        updateSurfaceScreenOn();
+        mOnPreparedListener = null;
+        mOnBufferingUpdateListener = null;
+        mOnCompletionListener = null;
+        mOnSeekCompleteListener = null;
+        mOnErrorListener = null;
+        mOnInfoListener = null;
+        mOnVideoSizeChangedListener = null;
+        mOnTimedTextListener = null;
+        mOnRtpRxNoticeListener = null;
+        mOnRtpRxNoticeExecutor = null;
+        synchronized (mTimeProviderLock) {
+            if (mTimeProvider != null) {
+                mTimeProvider.close();
+                mTimeProvider = null;
+            }
+        }
+        synchronized(this) {
+            mSubtitleDataListenerDisabled = false;
+            mExtSubtitleDataListener = null;
+            mExtSubtitleDataHandler = null;
+            mOnMediaTimeDiscontinuityListener = null;
+            mOnMediaTimeDiscontinuityHandler = null;
+        }
+
+        // Modular DRM clean up
+        mOnDrmConfigHelper = null;
+        mOnDrmInfoHandlerDelegate = null;
+        mOnDrmPreparedHandlerDelegate = null;
+        resetDrmState();
+
+        _release();
+    }
+
+    private native void _release();
+
+    /**
+     * Resets the MediaPlayer to its uninitialized state. After calling
+     * this method, you will have to initialize it again by setting the
+     * data source and calling prepare().
+     */
+    public void reset() {
+        mSelectedSubtitleTrackIndex = -1;
+        synchronized(mOpenSubtitleSources) {
+            for (final InputStream is: mOpenSubtitleSources) {
+                try {
+                    is.close();
+                } catch (IOException e) {
+                }
+            }
+            mOpenSubtitleSources.clear();
+        }
+        if (mSubtitleController != null) {
+            mSubtitleController.reset();
+        }
+        synchronized (mTimeProviderLock) {
+            if (mTimeProvider != null) {
+                mTimeProvider.close();
+                mTimeProvider = null;
+            }
+        }
+
+        stayAwake(false);
+        _reset();
+        // make sure none of the listeners get called anymore
+        if (mEventHandler != null) {
+            mEventHandler.removeCallbacksAndMessages(null);
+        }
+
+        synchronized (mIndexTrackPairs) {
+            mIndexTrackPairs.clear();
+            mInbandTrackIndices.clear();
+        };
+
+        resetDrmState();
+    }
+
+    private native void _reset();
+
+    /**
+     * Set up a timer for {@link #TimeProvider}. {@link #TimeProvider} will be
+     * notified when the presentation time reaches (becomes greater than or equal to)
+     * the value specified.
+     *
+     * @param mediaTimeUs presentation time to get timed event callback at
+     * @hide
+     */
+    public void notifyAt(long mediaTimeUs) {
+        _notifyAt(mediaTimeUs);
+    }
+
+    private native void _notifyAt(long mediaTimeUs);
+
+    /**
+     * Sets the audio stream type for this MediaPlayer. See {@link AudioManager}
+     * for a list of stream types. Must call this method before prepare() or
+     * prepareAsync() in order for the target stream type to become effective
+     * thereafter.
+     *
+     * @param streamtype the audio stream type
+     * @deprecated use {@link #setAudioAttributes(AudioAttributes)}
+     * @see android.media.AudioManager
+     */
+    public void setAudioStreamType(int streamtype) {
+        deprecateStreamTypeForPlayback(streamtype, "MediaPlayer", "setAudioStreamType()");
+        baseUpdateAudioAttributes(
+                new AudioAttributes.Builder().setInternalLegacyStreamType(streamtype).build());
+        _setAudioStreamType(streamtype);
+        mStreamType = streamtype;
+    }
+
+    private native void _setAudioStreamType(int streamtype);
+
+    // Keep KEY_PARAMETER_* in sync with include/media/mediaplayer.h
+    private final static int KEY_PARAMETER_AUDIO_ATTRIBUTES = 1400;
+    /**
+     * Sets the parameter indicated by key.
+     * @param key key indicates the parameter to be set.
+     * @param value value of the parameter to be set.
+     * @return true if the parameter is set successfully, false otherwise
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    private native boolean setParameter(int key, Parcel value);
+
+    /**
+     * Sets the audio attributes for this MediaPlayer.
+     * See {@link AudioAttributes} for how to build and configure an instance of this class.
+     * You must call this method before {@link #prepare()} or {@link #prepareAsync()} in order
+     * for the audio attributes to become effective thereafter.
+     * @param attributes a non-null set of audio attributes
+     */
+    public void setAudioAttributes(AudioAttributes attributes) throws IllegalArgumentException {
+        if (attributes == null) {
+            final String msg = "Cannot set AudioAttributes to null";
+            throw new IllegalArgumentException(msg);
+        }
+        baseUpdateAudioAttributes(attributes);
+        Parcel pattributes = Parcel.obtain();
+        attributes.writeToParcel(pattributes, AudioAttributes.FLATTEN_TAGS);
+        setParameter(KEY_PARAMETER_AUDIO_ATTRIBUTES, pattributes);
+        pattributes.recycle();
+    }
+
+    /**
+     * Sets the player to be looping or non-looping.
+     *
+     * @param looping whether to loop or not
+     */
+    public native void setLooping(boolean looping);
+
+    /**
+     * Checks whether the MediaPlayer is looping or non-looping.
+     *
+     * @return true if the MediaPlayer is currently looping, false otherwise
+     */
+    public native boolean isLooping();
+
+    /**
+     * Sets the volume on this player.
+     * This API is recommended for balancing the output of audio streams
+     * within an application. Unless you are writing an application to
+     * control user settings, this API should be used in preference to
+     * {@link AudioManager#setStreamVolume(int, int, int)} which sets the volume of ALL streams of
+     * a particular type. Note that the passed volume values are raw scalars in range 0.0 to 1.0.
+     * UI controls should be scaled logarithmically.
+     *
+     * @param leftVolume left volume scalar
+     * @param rightVolume right volume scalar
+     */
+    /*
+     * FIXME: Merge this into javadoc comment above when setVolume(float) is not @hide.
+     * The single parameter form below is preferred if the channel volumes don't need
+     * to be set independently.
+     */
+    public void setVolume(float leftVolume, float rightVolume) {
+        baseSetVolume(leftVolume, rightVolume);
+    }
+
+    @Override
+    void playerSetVolume(boolean muting, float leftVolume, float rightVolume) {
+        _setVolume(muting ? 0.0f : leftVolume, muting ? 0.0f : rightVolume);
+    }
+
+    private native void _setVolume(float leftVolume, float rightVolume);
+
+    /**
+     * Similar, excepts sets volume of all channels to same value.
+     * @hide
+     */
+    public void setVolume(float volume) {
+        setVolume(volume, volume);
+    }
+
+    /**
+     * Sets the audio session ID.
+     *
+     * @param sessionId the audio session ID.
+     * The audio session ID is a system wide unique identifier for the audio stream played by
+     * this MediaPlayer instance.
+     * The primary use of the audio session ID  is to associate audio effects to a particular
+     * instance of MediaPlayer: if an audio session ID is provided when creating an audio effect,
+     * this effect will be applied only to the audio content of media players within the same
+     * audio session and not to the output mix.
+     * When created, a MediaPlayer instance automatically generates its own audio session ID.
+     * However, it is possible to force this player to be part of an already existing audio session
+     * by calling this method.
+     * This method must be called before one of the overloaded <code> setDataSource </code> methods.
+     * @throws IllegalStateException if it is called in an invalid state
+     */
+    public void setAudioSessionId(int sessionId)
+            throws IllegalArgumentException, IllegalStateException {
+        native_setAudioSessionId(sessionId);
+        baseUpdateSessionId(sessionId);
+    }
+
+    private native void native_setAudioSessionId(int sessionId);
+
+    /**
+     * Returns the audio session ID.
+     *
+     * @return the audio session ID. {@see #setAudioSessionId(int)}
+     * Note that the audio session ID is 0 only if a problem occured when the MediaPlayer was contructed.
+     */
+    public native int getAudioSessionId();
+
+    /**
+     * Attaches an auxiliary effect to the player. A typical auxiliary effect is a reverberation
+     * effect which can be applied on any sound source that directs a certain amount of its
+     * energy to this effect. This amount is defined by setAuxEffectSendLevel().
+     * See {@link #setAuxEffectSendLevel(float)}.
+     * <p>After creating an auxiliary effect (e.g.
+     * {@link android.media.audiofx.EnvironmentalReverb}), retrieve its ID with
+     * {@link android.media.audiofx.AudioEffect#getId()} and use it when calling this method
+     * to attach the player to the effect.
+     * <p>To detach the effect from the player, call this method with a null effect id.
+     * <p>This method must be called after one of the overloaded <code> setDataSource </code>
+     * methods.
+     * @param effectId system wide unique id of the effect to attach
+     */
+    public native void attachAuxEffect(int effectId);
+
+
+    /**
+     * Sets the send level of the player to the attached auxiliary effect.
+     * See {@link #attachAuxEffect(int)}. The level value range is 0 to 1.0.
+     * <p>By default the send level is 0, so even if an effect is attached to the player
+     * this method must be called for the effect to be applied.
+     * <p>Note that the passed level value is a raw scalar. UI controls should be scaled
+     * logarithmically: the gain applied by audio framework ranges from -72dB to 0dB,
+     * so an appropriate conversion from linear UI input x to level is:
+     * x == 0 -> level = 0
+     * 0 < x <= R -> level = 10^(72*(x-R)/20/R)
+     * @param level send level scalar
+     */
+    public void setAuxEffectSendLevel(float level) {
+        baseSetAuxEffectSendLevel(level);
+    }
+
+    @Override
+    int playerSetAuxEffectSendLevel(boolean muting, float level) {
+        _setAuxEffectSendLevel(muting ? 0.0f : level);
+        return AudioSystem.SUCCESS;
+    }
+
+    private native void _setAuxEffectSendLevel(float level);
+
+    /*
+     * @param request Parcel destinated to the media player. The
+     *                Interface token must be set to the IMediaPlayer
+     *                one to be routed correctly through the system.
+     * @param reply[out] Parcel that will contain the reply.
+     * @return The status code.
+     */
+    private native final int native_invoke(Parcel request, Parcel reply);
+
+
+    /*
+     * @param update_only If true fetch only the set of metadata that have
+     *                    changed since the last invocation of getMetadata.
+     *                    The set is built using the unfiltered
+     *                    notifications the native player sent to the
+     *                    MediaPlayerService during that period of
+     *                    time. If false, all the metadatas are considered.
+     * @param apply_filter  If true, once the metadata set has been built based on
+     *                     the value update_only, the current filter is applied.
+     * @param reply[out] On return contains the serialized
+     *                   metadata. Valid only if the call was successful.
+     * @return The status code.
+     */
+    private native final boolean native_getMetadata(boolean update_only,
+                                                    boolean apply_filter,
+                                                    Parcel reply);
+
+    /*
+     * @param request Parcel with the 2 serialized lists of allowed
+     *                metadata types followed by the one to be
+     *                dropped. Each list starts with an integer
+     *                indicating the number of metadata type elements.
+     * @return The status code.
+     */
+    private native final int native_setMetadataFilter(Parcel request);
+
+    private static native final void native_init();
+    private native void native_setup(Object mediaplayerThis,
+            @NonNull Parcel attributionSource);
+    private native final void native_finalize();
+
+    /**
+     * Class for MediaPlayer to return each audio/video/subtitle track's metadata.
+     *
+     * @see android.media.MediaPlayer#getTrackInfo
+     */
+    static public class TrackInfo implements Parcelable {
+        /**
+         * Gets the track type.
+         * @return TrackType which indicates if the track is video, audio, timed text.
+         */
+        public @TrackType int getTrackType() {
+            return mTrackType;
+        }
+
+        /**
+         * Gets the language code of the track.
+         * @return a language code in either way of ISO-639-1 or ISO-639-2.
+         * When the language is unknown or could not be determined,
+         * ISO-639-2 language code, "und", is returned.
+         */
+        public String getLanguage() {
+            String language = mFormat.getString(MediaFormat.KEY_LANGUAGE);
+            return language == null ? "und" : language;
+        }
+
+        /**
+         * Gets the {@link MediaFormat} of the track.  If the format is
+         * unknown or could not be determined, null is returned.
+         */
+        public MediaFormat getFormat() {
+            if (mTrackType == MEDIA_TRACK_TYPE_TIMEDTEXT
+                    || mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) {
+                return mFormat;
+            }
+            return null;
+        }
+
+        public static final int MEDIA_TRACK_TYPE_UNKNOWN = 0;
+        public static final int MEDIA_TRACK_TYPE_VIDEO = 1;
+        public static final int MEDIA_TRACK_TYPE_AUDIO = 2;
+        public static final int MEDIA_TRACK_TYPE_TIMEDTEXT = 3;
+        public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4;
+        public static final int MEDIA_TRACK_TYPE_METADATA = 5;
+
+        /** @hide */
+        @IntDef(flag = false, prefix = "MEDIA_TRACK_TYPE", value = {
+                MEDIA_TRACK_TYPE_UNKNOWN,
+                MEDIA_TRACK_TYPE_VIDEO,
+                MEDIA_TRACK_TYPE_AUDIO,
+                MEDIA_TRACK_TYPE_TIMEDTEXT,
+                MEDIA_TRACK_TYPE_SUBTITLE,
+                MEDIA_TRACK_TYPE_METADATA }
+        )
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface TrackType {}
+
+
+        final int mTrackType;
+        final MediaFormat mFormat;
+
+        TrackInfo(Parcel in) {
+            mTrackType = in.readInt();
+            // TODO: parcel in the full MediaFormat; currently we are using createSubtitleFormat
+            // even for audio/video tracks, meaning we only set the mime and language.
+            String mime = in.readString();
+            String language = in.readString();
+            mFormat = MediaFormat.createSubtitleFormat(mime, language);
+
+            if (mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) {
+                mFormat.setInteger(MediaFormat.KEY_IS_AUTOSELECT, in.readInt());
+                mFormat.setInteger(MediaFormat.KEY_IS_DEFAULT, in.readInt());
+                mFormat.setInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE, in.readInt());
+            }
+        }
+
+        /** @hide */
+        TrackInfo(int type, MediaFormat format) {
+            mTrackType = type;
+            mFormat = format;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        /**
+         * {@inheritDoc}
+         */
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(mTrackType);
+            dest.writeString(mFormat.getString(MediaFormat.KEY_MIME));
+            dest.writeString(getLanguage());
+
+            if (mTrackType == MEDIA_TRACK_TYPE_SUBTITLE) {
+                dest.writeInt(mFormat.getInteger(MediaFormat.KEY_IS_AUTOSELECT));
+                dest.writeInt(mFormat.getInteger(MediaFormat.KEY_IS_DEFAULT));
+                dest.writeInt(mFormat.getInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE));
+            }
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder out = new StringBuilder(128);
+            out.append(getClass().getName());
+            out.append('{');
+            switch (mTrackType) {
+            case MEDIA_TRACK_TYPE_VIDEO:
+                out.append("VIDEO");
+                break;
+            case MEDIA_TRACK_TYPE_AUDIO:
+                out.append("AUDIO");
+                break;
+            case MEDIA_TRACK_TYPE_TIMEDTEXT:
+                out.append("TIMEDTEXT");
+                break;
+            case MEDIA_TRACK_TYPE_SUBTITLE:
+                out.append("SUBTITLE");
+                break;
+            default:
+                out.append("UNKNOWN");
+                break;
+            }
+            out.append(", " + mFormat.toString());
+            out.append("}");
+            return out.toString();
+        }
+
+        /**
+         * Used to read a TrackInfo from a Parcel.
+         */
+        @UnsupportedAppUsage
+        static final @android.annotation.NonNull Parcelable.Creator<TrackInfo> CREATOR
+                = new Parcelable.Creator<TrackInfo>() {
+                    @Override
+                    public TrackInfo createFromParcel(Parcel in) {
+                        return new TrackInfo(in);
+                    }
+
+                    @Override
+                    public TrackInfo[] newArray(int size) {
+                        return new TrackInfo[size];
+                    }
+                };
+
+    };
+
+    // We would like domain specific classes with more informative names than the `first` and `second`
+    // in generic Pair, but we would also like to avoid creating new/trivial classes. As a compromise
+    // we document the meanings of `first` and `second` here:
+    //
+    // Pair.first - inband track index; non-null iff representing an inband track.
+    // Pair.second - a SubtitleTrack registered with mSubtitleController; non-null iff representing
+    //               an inband subtitle track or any out-of-band track (subtitle or timedtext).
+    private Vector<Pair<Integer, SubtitleTrack>> mIndexTrackPairs = new Vector<>();
+    private BitSet mInbandTrackIndices = new BitSet();
+
+    /**
+     * Returns an array of track information.
+     *
+     * @return Array of track info. The total number of tracks is the array length.
+     * Must be called again if an external timed text source has been added after any of the
+     * addTimedTextSource methods are called.
+     * @throws IllegalStateException if it is called in an invalid state.
+     */
+    public TrackInfo[] getTrackInfo() throws IllegalStateException {
+        TrackInfo trackInfo[] = getInbandTrackInfo();
+        // add out-of-band tracks
+        synchronized (mIndexTrackPairs) {
+            TrackInfo allTrackInfo[] = new TrackInfo[mIndexTrackPairs.size()];
+            for (int i = 0; i < allTrackInfo.length; i++) {
+                Pair<Integer, SubtitleTrack> p = mIndexTrackPairs.get(i);
+                if (p.first != null) {
+                    // inband track
+                    allTrackInfo[i] = trackInfo[p.first];
+                } else {
+                    SubtitleTrack track = p.second;
+                    allTrackInfo[i] = new TrackInfo(track.getTrackType(), track.getFormat());
+                }
+            }
+            return allTrackInfo;
+        }
+    }
+
+    private TrackInfo[] getInbandTrackInfo() throws IllegalStateException {
+        Parcel request = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            request.writeInterfaceToken(IMEDIA_PLAYER);
+            request.writeInt(INVOKE_ID_GET_TRACK_INFO);
+            invoke(request, reply);
+            TrackInfo trackInfo[] = reply.createTypedArray(TrackInfo.CREATOR);
+            return trackInfo;
+        } finally {
+            request.recycle();
+            reply.recycle();
+        }
+    }
+
+    /* Do not change these values without updating their counterparts
+     * in include/media/stagefright/MediaDefs.h and media/libstagefright/MediaDefs.cpp!
+     */
+    /**
+     * MIME type for SubRip (SRT) container. Used in addTimedTextSource APIs.
+     * @deprecated use {@link MediaFormat#MIMETYPE_TEXT_SUBRIP}
+     */
+    public static final String MEDIA_MIMETYPE_TEXT_SUBRIP = MediaFormat.MIMETYPE_TEXT_SUBRIP;
+
+    /**
+     * MIME type for WebVTT subtitle data.
+     * @hide
+     * @deprecated
+     */
+    public static final String MEDIA_MIMETYPE_TEXT_VTT = MediaFormat.MIMETYPE_TEXT_VTT;
+
+    /**
+     * MIME type for CEA-608 closed caption data.
+     * @hide
+     * @deprecated
+     */
+    public static final String MEDIA_MIMETYPE_TEXT_CEA_608 = MediaFormat.MIMETYPE_TEXT_CEA_608;
+
+    /**
+     * MIME type for CEA-708 closed caption data.
+     * @hide
+     * @deprecated
+     */
+    public static final String MEDIA_MIMETYPE_TEXT_CEA_708 = MediaFormat.MIMETYPE_TEXT_CEA_708;
+
+    /*
+     * A helper function to check if the mime type is supported by media framework.
+     */
+    private static boolean availableMimeTypeForExternalSource(String mimeType) {
+        if (MEDIA_MIMETYPE_TEXT_SUBRIP.equals(mimeType)) {
+            return true;
+        }
+        return false;
+    }
+
+    private SubtitleController mSubtitleController;
+
+    /** @hide */
+    @UnsupportedAppUsage
+    public void setSubtitleAnchor(
+            SubtitleController controller,
+            SubtitleController.Anchor anchor) {
+        // TODO: create SubtitleController in MediaPlayer
+        mSubtitleController = controller;
+        mSubtitleController.setAnchor(anchor);
+    }
+
+    /**
+     * The private version of setSubtitleAnchor is used internally to set mSubtitleController if
+     * necessary when clients don't provide their own SubtitleControllers using the public version
+     * {@link #setSubtitleAnchor(SubtitleController, Anchor)} (e.g. {@link VideoView} provides one).
+     */
+    private synchronized void setSubtitleAnchor() {
+        if ((mSubtitleController == null) && (ActivityThread.currentApplication() != null)) {
+            final TimeProvider timeProvider = (TimeProvider) getMediaTimeProvider();
+            final HandlerThread thread = new HandlerThread("SetSubtitleAnchorThread");
+            thread.start();
+            Handler handler = new Handler(thread.getLooper());
+            handler.post(new Runnable() {
+                @Override
+                public void run() {
+                    Context context = ActivityThread.currentApplication();
+                    mSubtitleController =
+                            new SubtitleController(context, timeProvider, MediaPlayer.this);
+                    mSubtitleController.setAnchor(new Anchor() {
+                        @Override
+                        public void setSubtitleWidget(RenderingWidget subtitleWidget) {
+                        }
+
+                        @Override
+                        public Looper getSubtitleLooper() {
+                            return timeProvider.mEventHandler.getLooper();
+                        }
+                    });
+                    thread.getLooper().quitSafely();
+                }
+            });
+            try {
+                thread.join();
+            } catch (InterruptedException e) {
+                Thread.currentThread().interrupt();
+                Log.w(TAG, "failed to join SetSubtitleAnchorThread");
+            }
+        }
+    }
+
+    private int mSelectedSubtitleTrackIndex = -1;
+    private Vector<InputStream> mOpenSubtitleSources;
+
+    private final OnSubtitleDataListener mIntSubtitleDataListener = new OnSubtitleDataListener() {
+        @Override
+        public void onSubtitleData(MediaPlayer mp, SubtitleData data) {
+            int index = data.getTrackIndex();
+            synchronized (mIndexTrackPairs) {
+                for (Pair<Integer, SubtitleTrack> p : mIndexTrackPairs) {
+                    if (p.first != null && p.first == index && p.second != null) {
+                        // inband subtitle track that owns data
+                        SubtitleTrack track = p.second;
+                        track.onData(data);
+                    }
+                }
+            }
+        }
+    };
+
+    /** @hide */
+    @Override
+    public void onSubtitleTrackSelected(SubtitleTrack track) {
+        if (mSelectedSubtitleTrackIndex >= 0) {
+            try {
+                selectOrDeselectInbandTrack(mSelectedSubtitleTrackIndex, false);
+            } catch (IllegalStateException e) {
+            }
+            mSelectedSubtitleTrackIndex = -1;
+        }
+        synchronized (this) {
+            mSubtitleDataListenerDisabled = true;
+        }
+        if (track == null) {
+            return;
+        }
+
+        synchronized (mIndexTrackPairs) {
+            for (Pair<Integer, SubtitleTrack> p : mIndexTrackPairs) {
+                if (p.first != null && p.second == track) {
+                    // inband subtitle track that is selected
+                    mSelectedSubtitleTrackIndex = p.first;
+                    break;
+                }
+            }
+        }
+
+        if (mSelectedSubtitleTrackIndex >= 0) {
+            try {
+                selectOrDeselectInbandTrack(mSelectedSubtitleTrackIndex, true);
+            } catch (IllegalStateException e) {
+            }
+            synchronized (this) {
+                mSubtitleDataListenerDisabled = false;
+            }
+        }
+        // no need to select out-of-band tracks
+    }
+
+    /** @hide */
+    @UnsupportedAppUsage
+    public void addSubtitleSource(InputStream is, MediaFormat format)
+            throws IllegalStateException
+    {
+        final InputStream fIs = is;
+        final MediaFormat fFormat = format;
+
+        if (is != null) {
+            // Ensure all input streams are closed.  It is also a handy
+            // way to implement timeouts in the future.
+            synchronized(mOpenSubtitleSources) {
+                mOpenSubtitleSources.add(is);
+            }
+        } else {
+            Log.w(TAG, "addSubtitleSource called with null InputStream");
+        }
+
+        getMediaTimeProvider();
+
+        // process each subtitle in its own thread
+        final HandlerThread thread = new HandlerThread("SubtitleReadThread",
+              Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
+        thread.start();
+        Handler handler = new Handler(thread.getLooper());
+        handler.post(new Runnable() {
+            private int addTrack() {
+                if (fIs == null || mSubtitleController == null) {
+                    return MEDIA_INFO_UNSUPPORTED_SUBTITLE;
+                }
+
+                SubtitleTrack track = mSubtitleController.addTrack(fFormat);
+                if (track == null) {
+                    return MEDIA_INFO_UNSUPPORTED_SUBTITLE;
+                }
+
+                // TODO: do the conversion in the subtitle track
+                Scanner scanner = new Scanner(fIs, "UTF-8");
+                String contents = scanner.useDelimiter("\\A").next();
+                synchronized(mOpenSubtitleSources) {
+                    mOpenSubtitleSources.remove(fIs);
+                }
+                scanner.close();
+                synchronized (mIndexTrackPairs) {
+                    mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
+                }
+                synchronized (mTimeProviderLock) {
+                    if (mTimeProvider != null) {
+                        Handler h = mTimeProvider.mEventHandler;
+                        int what = TimeProvider.NOTIFY;
+                        int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
+                        Pair<SubtitleTrack, byte[]> trackData =
+                                Pair.create(track, contents.getBytes());
+                        Message m = h.obtainMessage(what, arg1, 0, trackData);
+                        h.sendMessage(m);
+                    }
+                }
+                return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
+            }
+
+            public void run() {
+                int res = addTrack();
+                if (mEventHandler != null) {
+                    Message m = mEventHandler.obtainMessage(MEDIA_INFO, res, 0, null);
+                    mEventHandler.sendMessage(m);
+                }
+                thread.getLooper().quitSafely();
+            }
+        });
+    }
+
+    private void scanInternalSubtitleTracks() {
+        setSubtitleAnchor();
+
+        populateInbandTracks();
+
+        if (mSubtitleController != null) {
+            mSubtitleController.selectDefaultTrack();
+        }
+    }
+
+    private void populateInbandTracks() {
+        TrackInfo[] tracks = getInbandTrackInfo();
+        synchronized (mIndexTrackPairs) {
+            for (int i = 0; i < tracks.length; i++) {
+                if (mInbandTrackIndices.get(i)) {
+                    continue;
+                } else {
+                    mInbandTrackIndices.set(i);
+                }
+
+                if (tracks[i] == null) {
+                    Log.w(TAG, "unexpected NULL track at index " + i);
+                }
+                // newly appeared inband track
+                if (tracks[i] != null
+                        && tracks[i].getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
+                    SubtitleTrack track = mSubtitleController.addTrack(
+                            tracks[i].getFormat());
+                    mIndexTrackPairs.add(Pair.create(i, track));
+                } else {
+                    mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(i, null));
+                }
+            }
+        }
+    }
+
+    /* TODO: Limit the total number of external timed text source to a reasonable number.
+     */
+    /**
+     * Adds an external timed text source file.
+     *
+     * Currently supported format is SubRip with the file extension .srt, case insensitive.
+     * Note that a single external timed text source may contain multiple tracks in it.
+     * One can find the total number of available tracks using {@link #getTrackInfo()} to see what
+     * additional tracks become available after this method call.
+     *
+     * @param path The file path of external timed text source file.
+     * @param mimeType The mime type of the file. Must be one of the mime types listed above.
+     * @throws IOException if the file cannot be accessed or is corrupted.
+     * @throws IllegalArgumentException if the mimeType is not supported.
+     * @throws IllegalStateException if called in an invalid state.
+     */
+    public void addTimedTextSource(String path, String mimeType)
+            throws IOException, IllegalArgumentException, IllegalStateException {
+        if (!availableMimeTypeForExternalSource(mimeType)) {
+            final String msg = "Illegal mimeType for timed text source: " + mimeType;
+            throw new IllegalArgumentException(msg);
+        }
+
+        final File file = new File(path);
+        try (FileInputStream is = new FileInputStream(file)) {
+            addTimedTextSource(is.getFD(), mimeType);
+        }
+    }
+
+    /**
+     * Adds an external timed text source file (Uri).
+     *
+     * Currently supported format is SubRip with the file extension .srt, case insensitive.
+     * Note that a single external timed text source may contain multiple tracks in it.
+     * One can find the total number of available tracks using {@link #getTrackInfo()} to see what
+     * additional tracks become available after this method call.
+     *
+     * @param context the Context to use when resolving the Uri
+     * @param uri the Content URI of the data you want to play
+     * @param mimeType The mime type of the file. Must be one of the mime types listed above.
+     * @throws IOException if the file cannot be accessed or is corrupted.
+     * @throws IllegalArgumentException if the mimeType is not supported.
+     * @throws IllegalStateException if called in an invalid state.
+     */
+    public void addTimedTextSource(Context context, Uri uri, String mimeType)
+            throws IOException, IllegalArgumentException, IllegalStateException {
+        String scheme = uri.getScheme();
+        if(scheme == null || scheme.equals("file")) {
+            addTimedTextSource(uri.getPath(), mimeType);
+            return;
+        }
+
+        AssetFileDescriptor fd = null;
+        try {
+            boolean optimize = SystemProperties.getBoolean("fuse.sys.transcode_player_optimize",
+                    false);
+            ContentResolver resolver = context.getContentResolver();
+            Bundle opts = new Bundle();
+            opts.putBoolean("android.provider.extra.ACCEPT_ORIGINAL_MEDIA_FORMAT", true);
+            fd = optimize ? resolver.openTypedAssetFileDescriptor(uri, "*/*", opts)
+                    : resolver.openAssetFileDescriptor(uri, "r");
+            if (fd == null) {
+                return;
+            }
+            addTimedTextSource(fd.getFileDescriptor(), mimeType);
+            return;
+        } catch (SecurityException ex) {
+        } catch (IOException ex) {
+        } finally {
+            if (fd != null) {
+                fd.close();
+            }
+        }
+    }
+
+    /**
+     * Adds an external timed text source file (FileDescriptor).
+     *
+     * It is the caller's responsibility to close the file descriptor.
+     * It is safe to do so as soon as this call returns.
+     *
+     * Currently supported format is SubRip. Note that a single external timed text source may
+     * contain multiple tracks in it. One can find the total number of available tracks
+     * using {@link #getTrackInfo()} to see what additional tracks become available
+     * after this method call.
+     *
+     * @param fd the FileDescriptor for the file you want to play
+     * @param mimeType The mime type of the file. Must be one of the mime types listed above.
+     * @throws IllegalArgumentException if the mimeType is not supported.
+     * @throws IllegalStateException if called in an invalid state.
+     */
+    public void addTimedTextSource(FileDescriptor fd, String mimeType)
+            throws IllegalArgumentException, IllegalStateException {
+        // intentionally less than LONG_MAX
+        addTimedTextSource(fd, 0, 0x7ffffffffffffffL, mimeType);
+    }
+
+    /**
+     * Adds an external timed text file (FileDescriptor).
+     *
+     * It is the caller's responsibility to close the file descriptor.
+     * It is safe to do so as soon as this call returns.
+     *
+     * Currently supported format is SubRip. Note that a single external timed text source may
+     * contain multiple tracks in it. One can find the total number of available tracks
+     * using {@link #getTrackInfo()} to see what additional tracks become available
+     * after this method call.
+     *
+     * @param fd the FileDescriptor for the file you want to play
+     * @param offset the offset into the file where the data to be played starts, in bytes
+     * @param length the length in bytes of the data to be played
+     * @param mime The mime type of the file. Must be one of the mime types listed above.
+     * @throws IllegalArgumentException if the mimeType is not supported.
+     * @throws IllegalStateException if called in an invalid state.
+     */
+    public void addTimedTextSource(FileDescriptor fd, long offset, long length, String mime)
+            throws IllegalArgumentException, IllegalStateException {
+        if (!availableMimeTypeForExternalSource(mime)) {
+            throw new IllegalArgumentException("Illegal mimeType for timed text source: " + mime);
+        }
+
+        final FileDescriptor dupedFd;
+        try {
+            dupedFd = Os.dup(fd);
+        } catch (ErrnoException ex) {
+            Log.e(TAG, ex.getMessage(), ex);
+            throw new RuntimeException(ex);
+        }
+
+        final MediaFormat fFormat = new MediaFormat();
+        fFormat.setString(MediaFormat.KEY_MIME, mime);
+        fFormat.setInteger(MediaFormat.KEY_IS_TIMED_TEXT, 1);
+
+        // A MediaPlayer created by a VideoView should already have its mSubtitleController set.
+        if (mSubtitleController == null) {
+            setSubtitleAnchor();
+        }
+
+        if (!mSubtitleController.hasRendererFor(fFormat)) {
+            // test and add not atomic
+            Context context = ActivityThread.currentApplication();
+            mSubtitleController.registerRenderer(new SRTRenderer(context, mEventHandler));
+        }
+        final SubtitleTrack track = mSubtitleController.addTrack(fFormat);
+        synchronized (mIndexTrackPairs) {
+            mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
+        }
+
+        getMediaTimeProvider();
+
+        final long offset2 = offset;
+        final long length2 = length;
+        final HandlerThread thread = new HandlerThread(
+                "TimedTextReadThread",
+                Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
+        thread.start();
+        Handler handler = new Handler(thread.getLooper());
+        handler.post(new Runnable() {
+            private int addTrack() {
+                final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+                try {
+                    Os.lseek(dupedFd, offset2, OsConstants.SEEK_SET);
+                    byte[] buffer = new byte[4096];
+                    for (long total = 0; total < length2;) {
+                        int bytesToRead = (int) Math.min(buffer.length, length2 - total);
+                        int bytes = IoBridge.read(dupedFd, buffer, 0, bytesToRead);
+                        if (bytes < 0) {
+                            break;
+                        } else {
+                            bos.write(buffer, 0, bytes);
+                            total += bytes;
+                        }
+                    }
+                    synchronized (mTimeProviderLock) {
+                        if (mTimeProvider != null) {
+                            Handler h = mTimeProvider.mEventHandler;
+                            int what = TimeProvider.NOTIFY;
+                            int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
+                            Pair<SubtitleTrack, byte[]> trackData =
+                                    Pair.create(track, bos.toByteArray());
+                            Message m = h.obtainMessage(what, arg1, 0, trackData);
+                            h.sendMessage(m);
+                        }
+                    }
+                    return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
+                } catch (Exception e) {
+                    Log.e(TAG, e.getMessage(), e);
+                    return MEDIA_INFO_TIMED_TEXT_ERROR;
+                } finally {
+                    try {
+                        Os.close(dupedFd);
+                    } catch (ErrnoException e) {
+                        Log.e(TAG, e.getMessage(), e);
+                    }
+                }
+            }
+
+            public void run() {
+                int res = addTrack();
+                if (mEventHandler != null) {
+                    Message m = mEventHandler.obtainMessage(MEDIA_INFO, res, 0, null);
+                    mEventHandler.sendMessage(m);
+                }
+                thread.getLooper().quitSafely();
+            }
+        });
+    }
+
+    /**
+     * Returns the index of the audio, video, or subtitle track currently selected for playback,
+     * The return value is an index into the array returned by {@link #getTrackInfo()}, and can
+     * be used in calls to {@link #selectTrack(int)} or {@link #deselectTrack(int)}.
+     *
+     * @param trackType should be one of {@link TrackInfo#MEDIA_TRACK_TYPE_VIDEO},
+     * {@link TrackInfo#MEDIA_TRACK_TYPE_AUDIO}, or
+     * {@link TrackInfo#MEDIA_TRACK_TYPE_SUBTITLE}
+     * @return index of the audio, video, or subtitle track currently selected for playback;
+     * a negative integer is returned when there is no selected track for {@code trackType} or
+     * when {@code trackType} is not one of audio, video, or subtitle.
+     * @throws IllegalStateException if called after {@link #release()}
+     *
+     * @see #getTrackInfo()
+     * @see #selectTrack(int)
+     * @see #deselectTrack(int)
+     */
+    public int getSelectedTrack(int trackType) throws IllegalStateException {
+        if (mSubtitleController != null
+                && (trackType == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE
+                || trackType == TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT)) {
+            SubtitleTrack subtitleTrack = mSubtitleController.getSelectedTrack();
+            if (subtitleTrack != null) {
+                synchronized (mIndexTrackPairs) {
+                    for (int i = 0; i < mIndexTrackPairs.size(); i++) {
+                        Pair<Integer, SubtitleTrack> p = mIndexTrackPairs.get(i);
+                        if (p.second == subtitleTrack && subtitleTrack.getTrackType() == trackType) {
+                            return i;
+                        }
+                    }
+                }
+            }
+        }
+
+        Parcel request = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            request.writeInterfaceToken(IMEDIA_PLAYER);
+            request.writeInt(INVOKE_ID_GET_SELECTED_TRACK);
+            request.writeInt(trackType);
+            invoke(request, reply);
+            int inbandTrackIndex = reply.readInt();
+            synchronized (mIndexTrackPairs) {
+                for (int i = 0; i < mIndexTrackPairs.size(); i++) {
+                    Pair<Integer, SubtitleTrack> p = mIndexTrackPairs.get(i);
+                    if (p.first != null && p.first == inbandTrackIndex) {
+                        return i;
+                    }
+                }
+            }
+            return -1;
+        } finally {
+            request.recycle();
+            reply.recycle();
+        }
+    }
+
+    /**
+     * Selects a track.
+     * <p>
+     * If a MediaPlayer is in invalid state, it throws an IllegalStateException exception.
+     * If a MediaPlayer is in <em>Started</em> state, the selected track is presented immediately.
+     * If a MediaPlayer is not in Started state, it just marks the track to be played.
+     * </p>
+     * <p>
+     * In any valid state, if it is called multiple times on the same type of track (ie. Video,
+     * Audio, Timed Text), the most recent one will be chosen.
+     * </p>
+     * <p>
+     * The first audio and video tracks are selected by default if available, even though
+     * this method is not called. However, no timed text track will be selected until
+     * this function is called.
+     * </p>
+     * <p>
+     * Currently, only timed text, subtitle or audio tracks can be selected via this method.
+     * In addition, the support for selecting an audio track at runtime is pretty limited
+     * in that an audio track can only be selected in the <em>Prepared</em> state.
+     * </p>
+     * @param index the index of the track to be selected. The valid range of the index
+     * is 0..total number of track - 1. The total number of tracks as well as the type of
+     * each individual track can be found by calling {@link #getTrackInfo()} method.
+     * @throws IllegalStateException if called in an invalid state.
+     *
+     * @see android.media.MediaPlayer#getTrackInfo
+     */
+    public void selectTrack(int index) throws IllegalStateException {
+        selectOrDeselectTrack(index, true /* select */);
+    }
+
+    /**
+     * Deselect a track.
+     * <p>
+     * Currently, the track must be a timed text track and no audio or video tracks can be
+     * deselected. If the timed text track identified by index has not been
+     * selected before, it throws an exception.
+     * </p>
+     * @param index the index of the track to be deselected. The valid range of the index
+     * is 0..total number of tracks - 1. The total number of tracks as well as the type of
+     * each individual track can be found by calling {@link #getTrackInfo()} method.
+     * @throws IllegalStateException if called in an invalid state.
+     *
+     * @see android.media.MediaPlayer#getTrackInfo
+     */
+    public void deselectTrack(int index) throws IllegalStateException {
+        selectOrDeselectTrack(index, false /* select */);
+    }
+
+    private void selectOrDeselectTrack(int index, boolean select)
+            throws IllegalStateException {
+        // handle subtitle track through subtitle controller
+        populateInbandTracks();
+
+        Pair<Integer,SubtitleTrack> p = null;
+        try {
+            p = mIndexTrackPairs.get(index);
+        } catch (ArrayIndexOutOfBoundsException e) {
+            // ignore bad index
+            return;
+        }
+
+        SubtitleTrack track = p.second;
+        if (track == null) {
+            // inband (de)select
+            selectOrDeselectInbandTrack(p.first, select);
+            return;
+        }
+
+        if (mSubtitleController == null) {
+            return;
+        }
+
+        if (!select) {
+            // out-of-band deselect
+            if (mSubtitleController.getSelectedTrack() == track) {
+                mSubtitleController.selectTrack(null);
+            } else {
+                Log.w(TAG, "trying to deselect track that was not selected");
+            }
+            return;
+        }
+
+        // out-of-band select
+        if (track.getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT) {
+            int ttIndex = getSelectedTrack(TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT);
+            synchronized (mIndexTrackPairs) {
+                if (ttIndex >= 0 && ttIndex < mIndexTrackPairs.size()) {
+                    Pair<Integer,SubtitleTrack> p2 = mIndexTrackPairs.get(ttIndex);
+                    if (p2.first != null && p2.second == null) {
+                        // deselect inband counterpart
+                        selectOrDeselectInbandTrack(p2.first, false);
+                    }
+                }
+            }
+        }
+        mSubtitleController.selectTrack(track);
+    }
+
+    private void selectOrDeselectInbandTrack(int index, boolean select)
+            throws IllegalStateException {
+        Parcel request = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        try {
+            request.writeInterfaceToken(IMEDIA_PLAYER);
+            request.writeInt(select? INVOKE_ID_SELECT_TRACK: INVOKE_ID_DESELECT_TRACK);
+            request.writeInt(index);
+            invoke(request, reply);
+        } finally {
+            request.recycle();
+            reply.recycle();
+        }
+    }
+
+
+    /**
+     * @param reply Parcel with audio/video duration info for battery
+                    tracking usage
+     * @return The status code.
+     * {@hide}
+     */
+    public native static int native_pullBatteryData(Parcel reply);
+
+    /**
+     * Sets the target UDP re-transmit endpoint for the low level player.
+     * Generally, the address portion of the endpoint is an IP multicast
+     * address, although a unicast address would be equally valid.  When a valid
+     * retransmit endpoint has been set, the media player will not decode and
+     * render the media presentation locally.  Instead, the player will attempt
+     * to re-multiplex its media data using the Android@Home RTP profile and
+     * re-transmit to the target endpoint.  Receiver devices (which may be
+     * either the same as the transmitting device or different devices) may
+     * instantiate, prepare, and start a receiver player using a setDataSource
+     * URL of the form...
+     *
+     * aahRX://&lt;multicastIP&gt;:&lt;port&gt;
+     *
+     * to receive, decode and render the re-transmitted content.
+     *
+     * setRetransmitEndpoint may only be called before setDataSource has been
+     * called; while the player is in the Idle state.
+     *
+     * @param endpoint the address and UDP port of the re-transmission target or
+     * null if no re-transmission is to be performed.
+     * @throws IllegalStateException if it is called in an invalid state
+     * @throws IllegalArgumentException if the retransmit endpoint is supplied,
+     * but invalid.
+     *
+     * {@hide} pending API council
+     */
+    @UnsupportedAppUsage
+    public void setRetransmitEndpoint(InetSocketAddress endpoint)
+            throws IllegalStateException, IllegalArgumentException
+    {
+        String addrString = null;
+        int port = 0;
+
+        if (null != endpoint) {
+            addrString = endpoint.getAddress().getHostAddress();
+            port = endpoint.getPort();
+        }
+
+        int ret = native_setRetransmitEndpoint(addrString, port);
+        if (ret != 0) {
+            throw new IllegalArgumentException("Illegal re-transmit endpoint; native ret " + ret);
+        }
+    }
+
+    private native final int native_setRetransmitEndpoint(String addrString, int port);
+
+    @Override
+    protected void finalize() {
+        tryToDisableNativeRoutingCallback();
+        baseRelease();
+        native_finalize();
+    }
+
+    /* Do not change these values without updating their counterparts
+     * in include/media/mediaplayer.h!
+     */
+    private static final int MEDIA_NOP = 0; // interface test message
+    private static final int MEDIA_PREPARED = 1;
+    private static final int MEDIA_PLAYBACK_COMPLETE = 2;
+    private static final int MEDIA_BUFFERING_UPDATE = 3;
+    private static final int MEDIA_SEEK_COMPLETE = 4;
+    private static final int MEDIA_SET_VIDEO_SIZE = 5;
+    private static final int MEDIA_STARTED = 6;
+    private static final int MEDIA_PAUSED = 7;
+    private static final int MEDIA_STOPPED = 8;
+    private static final int MEDIA_SKIPPED = 9;
+    private static final int MEDIA_NOTIFY_TIME = 98;
+    private static final int MEDIA_TIMED_TEXT = 99;
+    private static final int MEDIA_ERROR = 100;
+    private static final int MEDIA_INFO = 200;
+    private static final int MEDIA_SUBTITLE_DATA = 201;
+    private static final int MEDIA_META_DATA = 202;
+    private static final int MEDIA_DRM_INFO = 210;
+    private static final int MEDIA_TIME_DISCONTINUITY = 211;
+    private static final int MEDIA_RTP_RX_NOTICE = 300;
+    private static final int MEDIA_AUDIO_ROUTING_CHANGED = 10000;
+
+    private TimeProvider mTimeProvider;
+    private final Object mTimeProviderLock = new Object();
+
+    /** @hide */
+    @UnsupportedAppUsage
+    public MediaTimeProvider getMediaTimeProvider() {
+        synchronized (mTimeProviderLock) {
+            if (mTimeProvider == null) {
+                mTimeProvider = new TimeProvider(this);
+            }
+            return mTimeProvider;
+        }
+    }
+
+    private class EventHandler extends Handler
+    {
+        private MediaPlayer mMediaPlayer;
+
+        public EventHandler(MediaPlayer mp, Looper looper) {
+            super(looper);
+            mMediaPlayer = mp;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (mMediaPlayer.mNativeContext == 0) {
+                Log.w(TAG, "mediaplayer went away with unhandled events");
+                return;
+            }
+            switch(msg.what) {
+            case MEDIA_PREPARED:
+                try {
+                    scanInternalSubtitleTracks();
+                } catch (RuntimeException e) {
+                    // send error message instead of crashing;
+                    // send error message instead of inlining a call to onError
+                    // to avoid code duplication.
+                    Message msg2 = obtainMessage(
+                            MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null);
+                    sendMessage(msg2);
+                }
+
+                OnPreparedListener onPreparedListener = mOnPreparedListener;
+                if (onPreparedListener != null)
+                    onPreparedListener.onPrepared(mMediaPlayer);
+                return;
+
+            case MEDIA_DRM_INFO:
+                Log.v(TAG, "MEDIA_DRM_INFO " + mOnDrmInfoHandlerDelegate);
+
+                if (msg.obj == null) {
+                    Log.w(TAG, "MEDIA_DRM_INFO msg.obj=NULL");
+                } else if (msg.obj instanceof Parcel) {
+                    // The parcel was parsed already in postEventFromNative
+                    DrmInfo drmInfo = null;
+
+                    OnDrmInfoHandlerDelegate onDrmInfoHandlerDelegate;
+                    synchronized (mDrmLock) {
+                        if (mOnDrmInfoHandlerDelegate != null && mDrmInfo != null) {
+                            drmInfo = mDrmInfo.makeCopy();
+                        }
+                        // local copy while keeping the lock
+                        onDrmInfoHandlerDelegate = mOnDrmInfoHandlerDelegate;
+                    }
+
+                    // notifying the client outside the lock
+                    if (onDrmInfoHandlerDelegate != null) {
+                        onDrmInfoHandlerDelegate.notifyClient(drmInfo);
+                    }
+                } else {
+                    Log.w(TAG, "MEDIA_DRM_INFO msg.obj of unexpected type " + msg.obj);
+                }
+                return;
+
+            case MEDIA_PLAYBACK_COMPLETE:
+                {
+                    mOnCompletionInternalListener.onCompletion(mMediaPlayer);
+                    OnCompletionListener onCompletionListener = mOnCompletionListener;
+                    if (onCompletionListener != null)
+                        onCompletionListener.onCompletion(mMediaPlayer);
+                }
+                stayAwake(false);
+                return;
+
+            case MEDIA_STOPPED:
+                {
+                    TimeProvider timeProvider = mTimeProvider;
+                    if (timeProvider != null) {
+                        timeProvider.onStopped();
+                    }
+                }
+                break;
+
+            case MEDIA_STARTED:
+                // fall through
+            case MEDIA_PAUSED:
+                {
+                    TimeProvider timeProvider = mTimeProvider;
+                    if (timeProvider != null) {
+                        timeProvider.onPaused(msg.what == MEDIA_PAUSED);
+                    }
+                }
+                break;
+
+            case MEDIA_BUFFERING_UPDATE:
+                OnBufferingUpdateListener onBufferingUpdateListener = mOnBufferingUpdateListener;
+                if (onBufferingUpdateListener != null)
+                    onBufferingUpdateListener.onBufferingUpdate(mMediaPlayer, msg.arg1);
+                return;
+
+            case MEDIA_SEEK_COMPLETE:
+                OnSeekCompleteListener onSeekCompleteListener = mOnSeekCompleteListener;
+                if (onSeekCompleteListener != null) {
+                    onSeekCompleteListener.onSeekComplete(mMediaPlayer);
+                }
+                // fall through
+
+            case MEDIA_SKIPPED:
+                {
+                    TimeProvider timeProvider = mTimeProvider;
+                    if (timeProvider != null) {
+                        timeProvider.onSeekComplete(mMediaPlayer);
+                    }
+                }
+                return;
+
+            case MEDIA_SET_VIDEO_SIZE:
+                OnVideoSizeChangedListener onVideoSizeChangedListener = mOnVideoSizeChangedListener;
+                if (onVideoSizeChangedListener != null) {
+                    onVideoSizeChangedListener.onVideoSizeChanged(
+                        mMediaPlayer, msg.arg1, msg.arg2);
+                }
+                return;
+
+            case MEDIA_ERROR:
+                Log.e(TAG, "Error (" + msg.arg1 + "," + msg.arg2 + ")");
+                boolean error_was_handled = false;
+                OnErrorListener onErrorListener = mOnErrorListener;
+                if (onErrorListener != null) {
+                    error_was_handled = onErrorListener.onError(mMediaPlayer, msg.arg1, msg.arg2);
+                }
+                {
+                    mOnCompletionInternalListener.onCompletion(mMediaPlayer);
+                    OnCompletionListener onCompletionListener = mOnCompletionListener;
+                    if (onCompletionListener != null && ! error_was_handled) {
+                        onCompletionListener.onCompletion(mMediaPlayer);
+                    }
+                }
+                stayAwake(false);
+                return;
+
+            case MEDIA_INFO:
+                switch (msg.arg1) {
+                case MEDIA_INFO_VIDEO_TRACK_LAGGING:
+                    Log.i(TAG, "Info (" + msg.arg1 + "," + msg.arg2 + ")");
+                    break;
+                case MEDIA_INFO_METADATA_UPDATE:
+                    try {
+                        scanInternalSubtitleTracks();
+                    } catch (RuntimeException e) {
+                        Message msg2 = obtainMessage(
+                                MEDIA_ERROR, MEDIA_ERROR_UNKNOWN, MEDIA_ERROR_UNSUPPORTED, null);
+                        sendMessage(msg2);
+                    }
+                    // fall through
+
+                case MEDIA_INFO_EXTERNAL_METADATA_UPDATE:
+                    msg.arg1 = MEDIA_INFO_METADATA_UPDATE;
+                    // update default track selection
+                    if (mSubtitleController != null) {
+                        mSubtitleController.selectDefaultTrack();
+                    }
+                    break;
+                case MEDIA_INFO_BUFFERING_START:
+                case MEDIA_INFO_BUFFERING_END:
+                    TimeProvider timeProvider = mTimeProvider;
+                    if (timeProvider != null) {
+                        timeProvider.onBuffering(msg.arg1 == MEDIA_INFO_BUFFERING_START);
+                    }
+                    break;
+                }
+
+                OnInfoListener onInfoListener = mOnInfoListener;
+                if (onInfoListener != null) {
+                    onInfoListener.onInfo(mMediaPlayer, msg.arg1, msg.arg2);
+                }
+                // No real default action so far.
+                return;
+
+            case MEDIA_NOTIFY_TIME:
+                    TimeProvider timeProvider = mTimeProvider;
+                    if (timeProvider != null) {
+                        timeProvider.onNotifyTime();
+                    }
+                return;
+
+            case MEDIA_TIMED_TEXT:
+                OnTimedTextListener onTimedTextListener = mOnTimedTextListener;
+                if (onTimedTextListener == null)
+                    return;
+                if (msg.obj == null) {
+                    onTimedTextListener.onTimedText(mMediaPlayer, null);
+                } else {
+                    if (msg.obj instanceof Parcel) {
+                        Parcel parcel = (Parcel)msg.obj;
+                        TimedText text = new TimedText(parcel);
+                        parcel.recycle();
+                        onTimedTextListener.onTimedText(mMediaPlayer, text);
+                    }
+                }
+                return;
+
+            case MEDIA_SUBTITLE_DATA:
+                final OnSubtitleDataListener extSubtitleListener;
+                final Handler extSubtitleHandler;
+                synchronized(this) {
+                    if (mSubtitleDataListenerDisabled) {
+                        return;
+                    }
+                    extSubtitleListener = mExtSubtitleDataListener;
+                    extSubtitleHandler = mExtSubtitleDataHandler;
+                }
+                if (msg.obj instanceof Parcel) {
+                    Parcel parcel = (Parcel) msg.obj;
+                    final SubtitleData data = new SubtitleData(parcel);
+                    parcel.recycle();
+
+                    mIntSubtitleDataListener.onSubtitleData(mMediaPlayer, data);
+
+                    if (extSubtitleListener != null) {
+                        if (extSubtitleHandler == null) {
+                            extSubtitleListener.onSubtitleData(mMediaPlayer, data);
+                        } else {
+                            extSubtitleHandler.post(new Runnable() {
+                                @Override
+                                public void run() {
+                                    extSubtitleListener.onSubtitleData(mMediaPlayer, data);
+                                }
+                            });
+                        }
+                    }
+                }
+                return;
+
+            case MEDIA_META_DATA:
+                OnTimedMetaDataAvailableListener onTimedMetaDataAvailableListener =
+                    mOnTimedMetaDataAvailableListener;
+                if (onTimedMetaDataAvailableListener == null) {
+                    return;
+                }
+                if (msg.obj instanceof Parcel) {
+                    Parcel parcel = (Parcel) msg.obj;
+                    TimedMetaData data = TimedMetaData.createTimedMetaDataFromParcel(parcel);
+                    parcel.recycle();
+                    onTimedMetaDataAvailableListener.onTimedMetaDataAvailable(mMediaPlayer, data);
+                }
+                return;
+
+            case MEDIA_NOP: // interface test message - ignore
+                break;
+
+            case MEDIA_AUDIO_ROUTING_CHANGED:
+                    broadcastRoutingChange();
+                    return;
+
+            case MEDIA_TIME_DISCONTINUITY:
+                final OnMediaTimeDiscontinuityListener mediaTimeListener;
+                final Handler mediaTimeHandler;
+                synchronized(this) {
+                    mediaTimeListener = mOnMediaTimeDiscontinuityListener;
+                    mediaTimeHandler = mOnMediaTimeDiscontinuityHandler;
+                }
+                if (mediaTimeListener == null) {
+                    return;
+                }
+                if (msg.obj instanceof Parcel) {
+                    Parcel parcel = (Parcel) msg.obj;
+                    parcel.setDataPosition(0);
+                    long anchorMediaUs = parcel.readLong();
+                    long anchorRealUs = parcel.readLong();
+                    float playbackRate = parcel.readFloat();
+                    parcel.recycle();
+                    final MediaTimestamp timestamp;
+                    if (anchorMediaUs != -1 && anchorRealUs != -1) {
+                        timestamp = new MediaTimestamp(
+                                anchorMediaUs /*Us*/, anchorRealUs * 1000 /*Ns*/, playbackRate);
+                    } else {
+                        timestamp = MediaTimestamp.TIMESTAMP_UNKNOWN;
+                    }
+                    if (mediaTimeHandler == null) {
+                        mediaTimeListener.onMediaTimeDiscontinuity(mMediaPlayer, timestamp);
+                    } else {
+                        mediaTimeHandler.post(new Runnable() {
+                            @Override
+                            public void run() {
+                                mediaTimeListener.onMediaTimeDiscontinuity(mMediaPlayer, timestamp);
+                            }
+                        });
+                    }
+                }
+                return;
+
+            case MEDIA_RTP_RX_NOTICE:
+                final OnRtpRxNoticeListener rtpRxNoticeListener = mOnRtpRxNoticeListener;
+                if (rtpRxNoticeListener == null) {
+                    return;
+                }
+                if (msg.obj instanceof Parcel) {
+                    Parcel parcel = (Parcel) msg.obj;
+                    parcel.setDataPosition(0);
+                    int noticeType;
+                    int[] data;
+                    try {
+                        noticeType = parcel.readInt();
+                        int numOfArgs = parcel.dataAvail() / 4;
+                        data = new int[numOfArgs];
+                        for (int i = 0; i < numOfArgs; i++) {
+                            data[i] = parcel.readInt();
+                        }
+                    } finally {
+                        parcel.recycle();
+                    }
+                    mOnRtpRxNoticeExecutor.execute(() ->
+                            rtpRxNoticeListener
+                                    .onRtpRxNotice(mMediaPlayer, noticeType, data));
+                }
+                return;
+
+            default:
+                Log.e(TAG, "Unknown message type " + msg.what);
+                return;
+            }
+        }
+    }
+
+    /*
+     * Called from native code when an interesting event happens.  This method
+     * just uses the EventHandler system to post the event back to the main app thread.
+     * We use a weak reference to the original MediaPlayer object so that the native
+     * code is safe from the object disappearing from underneath it.  (This is
+     * the cookie passed to native_setup().)
+     */
+    private static void postEventFromNative(Object mediaplayer_ref,
+                                            int what, int arg1, int arg2, Object obj)
+    {
+        final MediaPlayer mp = (MediaPlayer)((WeakReference)mediaplayer_ref).get();
+        if (mp == null) {
+            return;
+        }
+
+        switch (what) {
+        case MEDIA_INFO:
+            if (arg1 == MEDIA_INFO_STARTED_AS_NEXT) {
+                new Thread(new Runnable() {
+                    @Override
+                    public void run() {
+                        // this acquires the wakelock if needed, and sets the client side state
+                        mp.start();
+                    }
+                }).start();
+                Thread.yield();
+            }
+            break;
+
+        case MEDIA_DRM_INFO:
+            // We need to derive mDrmInfo before prepare() returns so processing it here
+            // before the notification is sent to EventHandler below. EventHandler runs in the
+            // notification looper so its handleMessage might process the event after prepare()
+            // has returned.
+            Log.v(TAG, "postEventFromNative MEDIA_DRM_INFO");
+            if (obj instanceof Parcel) {
+                Parcel parcel = (Parcel)obj;
+                DrmInfo drmInfo = new DrmInfo(parcel);
+                synchronized (mp.mDrmLock) {
+                    mp.mDrmInfo = drmInfo;
+                }
+            } else {
+                Log.w(TAG, "MEDIA_DRM_INFO msg.obj of unexpected type " + obj);
+            }
+            break;
+
+        case MEDIA_PREPARED:
+            // By this time, we've learned about DrmInfo's presence or absence. This is meant
+            // mainly for prepareAsync() use case. For prepare(), this still can run to a race
+            // condition b/c MediaPlayerNative releases the prepare() lock before calling notify
+            // so we also set mDrmInfoResolved in prepare().
+            synchronized (mp.mDrmLock) {
+                mp.mDrmInfoResolved = true;
+            }
+            break;
+
+        }
+
+        if (mp.mEventHandler != null) {
+            Message m = mp.mEventHandler.obtainMessage(what, arg1, arg2, obj);
+            mp.mEventHandler.sendMessage(m);
+        }
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when the media
+     * source is ready for playback.
+     */
+    public interface OnPreparedListener
+    {
+        /**
+         * Called when the media file is ready for playback.
+         *
+         * @param mp the MediaPlayer that is ready for playback
+         */
+        void onPrepared(MediaPlayer mp);
+    }
+
+    /**
+     * Register a callback to be invoked when the media source is ready
+     * for playback.
+     *
+     * @param listener the callback that will be run
+     */
+    public void setOnPreparedListener(OnPreparedListener listener)
+    {
+        mOnPreparedListener = listener;
+    }
+
+    @UnsupportedAppUsage
+    private OnPreparedListener mOnPreparedListener;
+
+    /**
+     * Interface definition for a callback to be invoked when playback of
+     * a media source has completed.
+     */
+    public interface OnCompletionListener
+    {
+        /**
+         * Called when the end of a media source is reached during playback.
+         *
+         * @param mp the MediaPlayer that reached the end of the file
+         */
+        void onCompletion(MediaPlayer mp);
+    }
+
+    /**
+     * Register a callback to be invoked when the end of a media source
+     * has been reached during playback.
+     *
+     * @param listener the callback that will be run
+     */
+    public void setOnCompletionListener(OnCompletionListener listener)
+    {
+        mOnCompletionListener = listener;
+    }
+
+    @UnsupportedAppUsage
+    private OnCompletionListener mOnCompletionListener;
+
+    /**
+     * @hide
+     * Internal completion listener to update PlayerBase of the play state. Always "registered".
+     */
+    private final OnCompletionListener mOnCompletionInternalListener = new OnCompletionListener() {
+        @Override
+        public void onCompletion(MediaPlayer mp) {
+            tryToDisableNativeRoutingCallback();
+            baseStop();
+        }
+    };
+
+    /**
+     * Interface definition of a callback to be invoked indicating buffering
+     * status of a media resource being streamed over the network.
+     */
+    public interface OnBufferingUpdateListener
+    {
+        /**
+         * Called to update status in buffering a media stream received through
+         * progressive HTTP download. The received buffering percentage
+         * indicates how much of the content has been buffered or played.
+         * For example a buffering update of 80 percent when half the content
+         * has already been played indicates that the next 30 percent of the
+         * content to play has been buffered.
+         *
+         * @param mp      the MediaPlayer the update pertains to
+         * @param percent the percentage (0-100) of the content
+         *                that has been buffered or played thus far
+         */
+        void onBufferingUpdate(MediaPlayer mp, int percent);
+    }
+
+    /**
+     * Register a callback to be invoked when the status of a network
+     * stream's buffer has changed.
+     *
+     * @param listener the callback that will be run.
+     */
+    public void setOnBufferingUpdateListener(OnBufferingUpdateListener listener)
+    {
+        mOnBufferingUpdateListener = listener;
+    }
+
+    private OnBufferingUpdateListener mOnBufferingUpdateListener;
+
+    /**
+     * Interface definition of a callback to be invoked indicating
+     * the completion of a seek operation.
+     */
+    public interface OnSeekCompleteListener
+    {
+        /**
+         * Called to indicate the completion of a seek operation.
+         *
+         * @param mp the MediaPlayer that issued the seek operation
+         */
+        public void onSeekComplete(MediaPlayer mp);
+    }
+
+    /**
+     * Register a callback to be invoked when a seek operation has been
+     * completed.
+     *
+     * @param listener the callback that will be run
+     */
+    public void setOnSeekCompleteListener(OnSeekCompleteListener listener)
+    {
+        mOnSeekCompleteListener = listener;
+    }
+
+    @UnsupportedAppUsage
+    private OnSeekCompleteListener mOnSeekCompleteListener;
+
+    /**
+     * Interface definition of a callback to be invoked when the
+     * video size is first known or updated
+     */
+    public interface OnVideoSizeChangedListener
+    {
+        /**
+         * Called to indicate the video size
+         *
+         * The video size (width and height) could be 0 if there was no video,
+         * no display surface was set, or the value was not determined yet.
+         *
+         * @param mp        the MediaPlayer associated with this callback
+         * @param width     the width of the video
+         * @param height    the height of the video
+         */
+        public void onVideoSizeChanged(MediaPlayer mp, int width, int height);
+    }
+
+    /**
+     * Register a callback to be invoked when the video size is
+     * known or updated.
+     *
+     * @param listener the callback that will be run
+     */
+    public void setOnVideoSizeChangedListener(OnVideoSizeChangedListener listener)
+    {
+        mOnVideoSizeChangedListener = listener;
+    }
+
+    private OnVideoSizeChangedListener mOnVideoSizeChangedListener;
+
+    /**
+     * Interface definition of a callback to be invoked when a
+     * timed text is available for display.
+     */
+    public interface OnTimedTextListener
+    {
+        /**
+         * Called to indicate an avaliable timed text
+         *
+         * @param mp             the MediaPlayer associated with this callback
+         * @param text           the timed text sample which contains the text
+         *                       needed to be displayed and the display format.
+         */
+        public void onTimedText(MediaPlayer mp, TimedText text);
+    }
+
+    /**
+     * Register a callback to be invoked when a timed text is available
+     * for display.
+     *
+     * @param listener the callback that will be run
+     */
+    public void setOnTimedTextListener(OnTimedTextListener listener)
+    {
+        mOnTimedTextListener = listener;
+    }
+
+    @UnsupportedAppUsage
+    private OnTimedTextListener mOnTimedTextListener;
+
+    /**
+     * Interface definition of a callback to be invoked when a player subtitle track has new
+     * subtitle data available.
+     * See the {@link MediaPlayer#setOnSubtitleDataListener(OnSubtitleDataListener, Handler)}
+     * method for the description of which track will report data through this listener.
+     */
+    public interface OnSubtitleDataListener {
+        /**
+         * Method called when new subtitle data is available
+         * @param mp the player that reports the new subtitle data
+         * @param data the subtitle data
+         */
+        public void onSubtitleData(@NonNull MediaPlayer mp, @NonNull SubtitleData data);
+    }
+
+    /**
+     * Sets the listener to be invoked when a subtitle track has new data available.
+     * The subtitle data comes from a subtitle track previously selected with
+     * {@link #selectTrack(int)}. Use {@link #getTrackInfo()} to determine which tracks are
+     * subtitles (of type {@link TrackInfo#MEDIA_TRACK_TYPE_SUBTITLE}), Subtitle track encodings
+     * can be determined by {@link TrackInfo#getFormat()}).<br>
+     * See {@link SubtitleData} for an example of querying subtitle encoding.
+     * @param listener the listener called when new data is available
+     * @param handler the {@link Handler} that receives the listener events
+     */
+    public void setOnSubtitleDataListener(@NonNull OnSubtitleDataListener listener,
+            @NonNull Handler handler) {
+        if (listener == null) {
+            throw new IllegalArgumentException("Illegal null listener");
+        }
+        if (handler == null) {
+            throw new IllegalArgumentException("Illegal null handler");
+        }
+        setOnSubtitleDataListenerInt(listener, handler);
+    }
+    /**
+     * Sets the listener to be invoked when a subtitle track has new data available.
+     * The subtitle data comes from a subtitle track previously selected with
+     * {@link #selectTrack(int)}. Use {@link #getTrackInfo()} to determine which tracks are
+     * subtitles (of type {@link TrackInfo#MEDIA_TRACK_TYPE_SUBTITLE}), Subtitle track encodings
+     * can be determined by {@link TrackInfo#getFormat()}).<br>
+     * See {@link SubtitleData} for an example of querying subtitle encoding.<br>
+     * The listener will be called on the same thread as the one in which the MediaPlayer was
+     * created.
+     * @param listener the listener called when new data is available
+     */
+    public void setOnSubtitleDataListener(@NonNull OnSubtitleDataListener listener)
+    {
+        if (listener == null) {
+            throw new IllegalArgumentException("Illegal null listener");
+        }
+        setOnSubtitleDataListenerInt(listener, null);
+    }
+
+    /**
+     * Clears the listener previously set with
+     * {@link #setOnSubtitleDataListener(OnSubtitleDataListener)} or
+     * {@link #setOnSubtitleDataListener(OnSubtitleDataListener, Handler)}.
+     */
+    public void clearOnSubtitleDataListener() {
+        setOnSubtitleDataListenerInt(null, null);
+    }
+
+    private void setOnSubtitleDataListenerInt(
+            @Nullable OnSubtitleDataListener listener, @Nullable Handler handler) {
+        synchronized (this) {
+            mExtSubtitleDataListener = listener;
+            mExtSubtitleDataHandler = handler;
+        }
+    }
+
+    private boolean mSubtitleDataListenerDisabled;
+    /** External OnSubtitleDataListener, the one set by {@link #setOnSubtitleDataListener}. */
+    private OnSubtitleDataListener mExtSubtitleDataListener;
+    private Handler mExtSubtitleDataHandler;
+
+    /**
+     * Interface definition of a callback to be invoked when discontinuity in the normal progression
+     * of the media time is detected.
+     * The "normal progression" of media time is defined as the expected increase of the playback
+     * position when playing media, relative to the playback speed (for instance every second, media
+     * time increases by two seconds when playing at 2x).<br>
+     * Discontinuities are encountered in the following cases:
+     * <ul>
+     * <li>when the player is starved for data and cannot play anymore</li>
+     * <li>when the player encounters a playback error</li>
+     * <li>when the a seek operation starts, and when it's completed</li>
+     * <li>when the playback speed changes</li>
+     * <li>when the playback state changes</li>
+     * <li>when the player is reset</li>
+     * </ul>
+     * See the
+     * {@link MediaPlayer#setOnMediaTimeDiscontinuityListener(OnMediaTimeDiscontinuityListener, Handler)}
+     * method to set a listener for these events.
+     */
+    public interface OnMediaTimeDiscontinuityListener {
+        /**
+         * Called to indicate a time discontinuity has occured.
+         * @param mp the MediaPlayer for which the discontinuity has occured.
+         * @param mts the timestamp that correlates media time, system time and clock rate,
+         *     or {@link MediaTimestamp#TIMESTAMP_UNKNOWN} in an error case.
+         */
+        public void onMediaTimeDiscontinuity(@NonNull MediaPlayer mp, @NonNull MediaTimestamp mts);
+    }
+
+    /**
+     * Sets the listener to be invoked when a media time discontinuity is encountered.
+     * @param listener the listener called after a discontinuity
+     * @param handler the {@link Handler} that receives the listener events
+     */
+    public void setOnMediaTimeDiscontinuityListener(
+            @NonNull OnMediaTimeDiscontinuityListener listener, @NonNull Handler handler) {
+        if (listener == null) {
+            throw new IllegalArgumentException("Illegal null listener");
+        }
+        if (handler == null) {
+            throw new IllegalArgumentException("Illegal null handler");
+        }
+        setOnMediaTimeDiscontinuityListenerInt(listener, handler);
+    }
+
+    /**
+     * Sets the listener to be invoked when a media time discontinuity is encountered.
+     * The listener will be called on the same thread as the one in which the MediaPlayer was
+     * created.
+     * @param listener the listener called after a discontinuity
+     */
+    public void setOnMediaTimeDiscontinuityListener(
+            @NonNull OnMediaTimeDiscontinuityListener listener)
+    {
+        if (listener == null) {
+            throw new IllegalArgumentException("Illegal null listener");
+        }
+        setOnMediaTimeDiscontinuityListenerInt(listener, null);
+    }
+
+    /**
+     * Clears the listener previously set with
+     * {@link #setOnMediaTimeDiscontinuityListener(OnMediaTimeDiscontinuityListener)}
+     * or {@link #setOnMediaTimeDiscontinuityListener(OnMediaTimeDiscontinuityListener, Handler)}
+     */
+    public void clearOnMediaTimeDiscontinuityListener() {
+        setOnMediaTimeDiscontinuityListenerInt(null, null);
+    }
+
+    private void setOnMediaTimeDiscontinuityListenerInt(
+            @Nullable OnMediaTimeDiscontinuityListener listener, @Nullable Handler handler) {
+        synchronized (this) {
+            mOnMediaTimeDiscontinuityListener = listener;
+            mOnMediaTimeDiscontinuityHandler = handler;
+        }
+    }
+
+    private OnMediaTimeDiscontinuityListener mOnMediaTimeDiscontinuityListener;
+    private Handler mOnMediaTimeDiscontinuityHandler;
+
+    /**
+     * Interface definition of a callback to be invoked when a
+     * track has timed metadata available.
+     *
+     * @see MediaPlayer#setOnTimedMetaDataAvailableListener(OnTimedMetaDataAvailableListener)
+     */
+    public interface OnTimedMetaDataAvailableListener
+    {
+        /**
+         * Called to indicate avaliable timed metadata
+         * <p>
+         * This method will be called as timed metadata is extracted from the media,
+         * in the same order as it occurs in the media. The timing of this event is
+         * not controlled by the associated timestamp.
+         *
+         * @param mp             the MediaPlayer associated with this callback
+         * @param data           the timed metadata sample associated with this event
+         */
+        public void onTimedMetaDataAvailable(MediaPlayer mp, TimedMetaData data);
+    }
+
+    /**
+     * Interface definition of a callback to be invoked when
+     * RTP Rx connection has a notice.
+     *
+     * @see #setOnRtpRxNoticeListener
+     *
+     * @hide
+     */
+    @SystemApi
+    public interface OnRtpRxNoticeListener
+    {
+        /**
+         * Called when an RTP Rx connection has a notice.
+         * <p>
+         * Basic format. All TYPE and ARG are 4 bytes unsigned integer in native byte order.
+         * <pre>{@code
+         * 0                4               8                12
+         * +----------------+---------------+----------------+----------------+
+         * |      TYPE      |      ARG1     |      ARG2      |      ARG3      |
+         * +----------------+---------------+----------------+----------------+
+         * |      ARG4      |      ARG5     |      ...
+         * +----------------+---------------+-------------
+         * 16               20              24
+         *
+         *
+         * TYPE 100 - A notice of the first rtp packet received. No ARGs.
+         * 0
+         * +----------------+
+         * |      100       |
+         * +----------------+
+         *
+         *
+         * TYPE 101 - A notice of the first rtcp packet received. No ARGs.
+         * 0
+         * +----------------+
+         * |      101       |
+         * +----------------+
+         *
+         *
+         * TYPE 102 - A periodic report of a RTP statistics.
+         * TYPE 103 - An emergency report when serious packet loss has been detected
+         *            in between TYPE 102 events.
+         * 0                4               8                12
+         * +----------------+---------------+----------------+----------------+
+         * |   102 or 103   |   FB type=0   |    Bitrate     |   Top #.Seq    |
+         * +----------------+---------------+----------------+----------------+
+         * |   Base #.Seq   |Prev Expt #.Pkt|   Recv #.Pkt   |Prev Recv #.Pkt |
+         * +----------------+---------------+----------------+----------------+
+         * Feedback (FB) type
+         *      - always 0.
+         * Bitrate
+         *      - amount of data received in this period.
+         * Top number of sequence
+         *      - highest RTP sequence number received in this period.
+         *      - monotonically increasing value.
+         * Base number of sequence
+         *      - the first RTP sequence number of the media stream.
+         * Previous Expected number of Packets
+         *      - expected count of packets received in the previous report.
+         * Received number of packet
+         *      - actual count of packets received in this report.
+         * Previous Received number of packet
+         *      - actual count of packets received in the previous report.
+         *
+         *
+         * TYPE 205 - Transport layer Feedback message. (RFC-5104 Sec.4.2)
+         * 0                4               8                12
+         * +----------------+---------------+----------------+----------------+
+         * |      205       |FB type(1 or 3)|      SSRC      |      Value     |
+         * +----------------+---------------+----------------+----------------+
+         * Feedback (FB) type: determines the type of the event.
+         *      - if 1, we received a NACK request from the remote side.
+         *      - if 3, we received a TMMBR (Temporary Maximum Media Stream Bit Rate Request) from
+         *        the remote side.
+         * SSRC
+         *      - Remote side's SSRC value of the media sender (RFC-3550 Sec.5.1)
+         * Value: the FCI (Feedback Control Information) depending on the value of FB type
+         *      - if FB type is 1, the Generic NACK as specified in RFC-4585 Sec.6.2.1
+         *      - if FB type is 3, the TMMBR as specified in RFC-5104 Sec.4.2.1.1
+         *
+         *
+         * TYPE 206 - Payload-specific Feedback message. (RFC-5104 Sec.4.3)
+         * 0                4               8
+         * +----------------+---------------+----------------+
+         * |      206       |FB type(1 or 4)|      SSRC      |
+         * +----------------+---------------+----------------+
+         * Feedback (FB) type: determines the type of the event.
+         *      - if 1, we received a PLI request from the remote side.
+         *      - if 4, we received a FIR request from the remote side.
+         * SSRC
+         *      - Remote side's SSRC value of the media sender (RFC-3550 Sec.5.1)
+         *
+         *
+         * TYPE 300 - CVO (RTP Extension) message.
+         * 0                4
+         * +----------------+---------------+
+         * |      101       |     value     |
+         * +----------------+---------------+
+         * value
+         *      - clockwise rotation degrees of a received video (6.2.3 of 3GPP R12 TS 26.114).
+         *      - can be 0 (degree 0), 1 (degree 90), 2 (degree 180) or 3 (degree 270).
+         *
+         *
+         * TYPE 400 - Socket failed during receive. No ARGs.
+         * 0
+         * +----------------+
+         * |      400       |
+         * +----------------+
+         * }</pre>
+         *
+         * @param mp the {@code MediaPlayer} associated with this callback.
+         * @param noticeType TYPE of the event.
+         * @param params RTP Rx media data serialized as int[] array.
+         */
+        void onRtpRxNotice(@NonNull MediaPlayer mp, int noticeType, @NonNull int[] params);
+    }
+
+    /**
+     * Sets the listener to be invoked when an RTP Rx connection has a notice.
+     * The listener is required if MediaPlayer is configured for RTPSource by
+     * MediaPlayer.setDataSource(String8 rtpParams) of mediaplayer.h.
+     *
+     * @see OnRtpRxNoticeListener
+     *
+     * @param listener the listener called after a notice from RTP Rx.
+     * @param executor the {@link Executor} on which to post RTP Tx events.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(BIND_IMS_SERVICE)
+    public void setOnRtpRxNoticeListener(
+            @NonNull Context context,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnRtpRxNoticeListener listener) {
+        Objects.requireNonNull(context);
+        Preconditions.checkArgument(
+                context.checkSelfPermission(BIND_IMS_SERVICE) == PERMISSION_GRANTED,
+                BIND_IMS_SERVICE + " permission not granted.");
+        mOnRtpRxNoticeListener = Objects.requireNonNull(listener);
+        mOnRtpRxNoticeExecutor = Objects.requireNonNull(executor);
+    }
+
+    private OnRtpRxNoticeListener mOnRtpRxNoticeListener;
+    private Executor mOnRtpRxNoticeExecutor;
+
+    /**
+     * Register a callback to be invoked when a selected track has timed metadata available.
+     * <p>
+     * Currently only HTTP live streaming data URI's embedded with timed ID3 tags generates
+     * {@link TimedMetaData}.
+     *
+     * @see MediaPlayer#selectTrack(int)
+     * @see MediaPlayer.OnTimedMetaDataAvailableListener
+     * @see TimedMetaData
+     *
+     * @param listener the callback that will be run
+     */
+    public void setOnTimedMetaDataAvailableListener(OnTimedMetaDataAvailableListener listener)
+    {
+        mOnTimedMetaDataAvailableListener = listener;
+    }
+
+    private OnTimedMetaDataAvailableListener mOnTimedMetaDataAvailableListener;
+
+    /* Do not change these values without updating their counterparts
+     * in include/media/mediaplayer.h!
+     */
+    /** Unspecified media player error.
+     * @see android.media.MediaPlayer.OnErrorListener
+     */
+    public static final int MEDIA_ERROR_UNKNOWN = 1;
+
+    /** Media server died. In this case, the application must release the
+     * MediaPlayer object and instantiate a new one.
+     * @see android.media.MediaPlayer.OnErrorListener
+     */
+    public static final int MEDIA_ERROR_SERVER_DIED = 100;
+
+    /** The video is streamed and its container is not valid for progressive
+     * playback i.e the video's index (e.g moov atom) is not at the start of the
+     * file.
+     * @see android.media.MediaPlayer.OnErrorListener
+     */
+    public static final int MEDIA_ERROR_NOT_VALID_FOR_PROGRESSIVE_PLAYBACK = 200;
+
+    /** File or network related operation errors. */
+    public static final int MEDIA_ERROR_IO = -1004;
+    /** Bitstream is not conforming to the related coding standard or file spec. */
+    public static final int MEDIA_ERROR_MALFORMED = -1007;
+    /** Bitstream is conforming to the related coding standard or file spec, but
+     * the media framework does not support the feature. */
+    public static final int MEDIA_ERROR_UNSUPPORTED = -1010;
+    /** Some operation takes too long to complete, usually more than 3-5 seconds. */
+    public static final int MEDIA_ERROR_TIMED_OUT = -110;
+
+    /** Unspecified low-level system error. This value originated from UNKNOWN_ERROR in
+     * system/core/include/utils/Errors.h
+     * @see android.media.MediaPlayer.OnErrorListener
+     * @hide
+     */
+    public static final int MEDIA_ERROR_SYSTEM = -2147483648;
+
+    /**
+     * Interface definition of a callback to be invoked when there
+     * has been an error during an asynchronous operation (other errors
+     * will throw exceptions at method call time).
+     */
+    public interface OnErrorListener
+    {
+        /**
+         * Called to indicate an error.
+         *
+         * @param mp      the MediaPlayer the error pertains to
+         * @param what    the type of error that has occurred:
+         * <ul>
+         * <li>{@link #MEDIA_ERROR_UNKNOWN}
+         * <li>{@link #MEDIA_ERROR_SERVER_DIED}
+         * </ul>
+         * @param extra an extra code, specific to the error. Typically
+         * implementation dependent.
+         * <ul>
+         * <li>{@link #MEDIA_ERROR_IO}
+         * <li>{@link #MEDIA_ERROR_MALFORMED}
+         * <li>{@link #MEDIA_ERROR_UNSUPPORTED}
+         * <li>{@link #MEDIA_ERROR_TIMED_OUT}
+         * <li><code>MEDIA_ERROR_SYSTEM (-2147483648)</code> - low-level system error.
+         * </ul>
+         * @return True if the method handled the error, false if it didn't.
+         * Returning false, or not having an OnErrorListener at all, will
+         * cause the OnCompletionListener to be called.
+         */
+        boolean onError(MediaPlayer mp, int what, int extra);
+    }
+
+    /**
+     * Register a callback to be invoked when an error has happened
+     * during an asynchronous operation.
+     *
+     * @param listener the callback that will be run
+     */
+    public void setOnErrorListener(OnErrorListener listener)
+    {
+        mOnErrorListener = listener;
+    }
+
+    @UnsupportedAppUsage
+    private OnErrorListener mOnErrorListener;
+
+
+    /* Do not change these values without updating their counterparts
+     * in include/media/mediaplayer.h!
+     */
+    /** Unspecified media player info.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_UNKNOWN = 1;
+
+    /** The player was started because it was used as the next player for another
+     * player, which just completed playback.
+     * @see android.media.MediaPlayer#setNextMediaPlayer(MediaPlayer)
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_STARTED_AS_NEXT = 2;
+
+    /** The player just pushed the very first video frame for rendering.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3;
+
+    /** The video is too complex for the decoder: it can't decode frames fast
+     *  enough. Possibly only the audio plays fine at this stage.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700;
+
+    /** MediaPlayer is temporarily pausing playback internally in order to
+     * buffer more data.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_BUFFERING_START = 701;
+
+    /** MediaPlayer is resuming playback after filling buffers.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_BUFFERING_END = 702;
+
+    /** Estimated network bandwidth information (kbps) is available; currently this event fires
+     * simultaneously as {@link #MEDIA_INFO_BUFFERING_START} and {@link #MEDIA_INFO_BUFFERING_END}
+     * when playing network files.
+     * @see android.media.MediaPlayer.OnInfoListener
+     * @hide
+     */
+    public static final int MEDIA_INFO_NETWORK_BANDWIDTH = 703;
+
+    /** Bad interleaving means that a media has been improperly interleaved or
+     * not interleaved at all, e.g has all the video samples first then all the
+     * audio ones. Video is playing but a lot of disk seeks may be happening.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_BAD_INTERLEAVING = 800;
+
+    /** The media cannot be seeked (e.g live stream)
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_NOT_SEEKABLE = 801;
+
+    /** A new set of metadata is available.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_METADATA_UPDATE = 802;
+
+    /** A new set of external-only metadata is available.  Used by
+     *  JAVA framework to avoid triggering track scanning.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public static final int MEDIA_INFO_EXTERNAL_METADATA_UPDATE = 803;
+
+    /** Informs that audio is not playing. Note that playback of the video
+     * is not interrupted.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_AUDIO_NOT_PLAYING = 804;
+
+    /** Informs that video is not playing. Note that playback of the audio
+     * is not interrupted.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805;
+
+    /** Failed to handle timed text track properly.
+     * @see android.media.MediaPlayer.OnInfoListener
+     *
+     * {@hide}
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public static final int MEDIA_INFO_TIMED_TEXT_ERROR = 900;
+
+    /** Subtitle track was not supported by the media framework.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_UNSUPPORTED_SUBTITLE = 901;
+
+    /** Reading the subtitle track takes too long.
+     * @see android.media.MediaPlayer.OnInfoListener
+     */
+    public static final int MEDIA_INFO_SUBTITLE_TIMED_OUT = 902;
+
+    /**
+     * Interface definition of a callback to be invoked to communicate some
+     * info and/or warning about the media or its playback.
+     */
+    public interface OnInfoListener
+    {
+        /**
+         * Called to indicate an info or a warning.
+         *
+         * @param mp      the MediaPlayer the info pertains to.
+         * @param what    the type of info or warning.
+         * <ul>
+         * <li>{@link #MEDIA_INFO_UNKNOWN}
+         * <li>{@link #MEDIA_INFO_VIDEO_TRACK_LAGGING}
+         * <li>{@link #MEDIA_INFO_VIDEO_RENDERING_START}
+         * <li>{@link #MEDIA_INFO_BUFFERING_START}
+         * <li>{@link #MEDIA_INFO_BUFFERING_END}
+         * <li><code>MEDIA_INFO_NETWORK_BANDWIDTH (703)</code> -
+         *     bandwidth information is available (as <code>extra</code> kbps)
+         * <li>{@link #MEDIA_INFO_BAD_INTERLEAVING}
+         * <li>{@link #MEDIA_INFO_NOT_SEEKABLE}
+         * <li>{@link #MEDIA_INFO_METADATA_UPDATE}
+         * <li>{@link #MEDIA_INFO_UNSUPPORTED_SUBTITLE}
+         * <li>{@link #MEDIA_INFO_SUBTITLE_TIMED_OUT}
+         * </ul>
+         * @param extra an extra code, specific to the info. Typically
+         * implementation dependent.
+         * @return True if the method handled the info, false if it didn't.
+         * Returning false, or not having an OnInfoListener at all, will
+         * cause the info to be discarded.
+         */
+        boolean onInfo(MediaPlayer mp, int what, int extra);
+    }
+
+    /**
+     * Register a callback to be invoked when an info/warning is available.
+     *
+     * @param listener the callback that will be run
+     */
+    public void setOnInfoListener(OnInfoListener listener)
+    {
+        mOnInfoListener = listener;
+    }
+
+    @UnsupportedAppUsage
+    private OnInfoListener mOnInfoListener;
+
+    // Modular DRM begin
+
+    /**
+     * Interface definition of a callback to be invoked when the app
+     * can do DRM configuration (get/set properties) before the session
+     * is opened. This facilitates configuration of the properties, like
+     * 'securityLevel', which has to be set after DRM scheme creation but
+     * before the DRM session is opened.
+     *
+     * The only allowed DRM calls in this listener are {@code getDrmPropertyString}
+     * and {@code setDrmPropertyString}.
+     *
+     */
+    public interface OnDrmConfigHelper
+    {
+        /**
+         * Called to give the app the opportunity to configure DRM before the session is created
+         *
+         * @param mp the {@code MediaPlayer} associated with this callback
+         */
+        public void onDrmConfig(MediaPlayer mp);
+    }
+
+    /**
+     * Register a callback to be invoked for configuration of the DRM object before
+     * the session is created.
+     * The callback will be invoked synchronously during the execution
+     * of {@link #prepareDrm(UUID uuid)}.
+     *
+     * @param listener the callback that will be run
+     */
+    public void setOnDrmConfigHelper(OnDrmConfigHelper listener)
+    {
+        synchronized (mDrmLock) {
+            mOnDrmConfigHelper = listener;
+        } // synchronized
+    }
+
+    private OnDrmConfigHelper mOnDrmConfigHelper;
+
+    /**
+     * Interface definition of a callback to be invoked when the
+     * DRM info becomes available
+     */
+    public interface OnDrmInfoListener
+    {
+        /**
+         * Called to indicate DRM info is available
+         *
+         * @param mp the {@code MediaPlayer} associated with this callback
+         * @param drmInfo DRM info of the source including PSSH, and subset
+         *                of crypto schemes supported by this device
+         */
+        public void onDrmInfo(MediaPlayer mp, DrmInfo drmInfo);
+    }
+
+    /**
+     * Register a callback to be invoked when the DRM info is
+     * known.
+     *
+     * @param listener the callback that will be run
+     */
+    public void setOnDrmInfoListener(OnDrmInfoListener listener)
+    {
+        setOnDrmInfoListener(listener, null);
+    }
+
+    /**
+     * Register a callback to be invoked when the DRM info is
+     * known.
+     *
+     * @param listener the callback that will be run
+     */
+    public void setOnDrmInfoListener(OnDrmInfoListener listener, Handler handler)
+    {
+        synchronized (mDrmLock) {
+            if (listener != null) {
+                mOnDrmInfoHandlerDelegate = new OnDrmInfoHandlerDelegate(this, listener, handler);
+            } else {
+                mOnDrmInfoHandlerDelegate = null;
+            }
+        } // synchronized
+    }
+
+    private OnDrmInfoHandlerDelegate mOnDrmInfoHandlerDelegate;
+
+
+    /**
+     * The status codes for {@link OnDrmPreparedListener#onDrmPrepared} listener.
+     * <p>
+     *
+     * DRM preparation has succeeded.
+     */
+    public static final int PREPARE_DRM_STATUS_SUCCESS = 0;
+
+    /**
+     * The device required DRM provisioning but couldn't reach the provisioning server.
+     */
+    public static final int PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR = 1;
+
+    /**
+     * The device required DRM provisioning but the provisioning server denied the request.
+     */
+    public static final int PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR = 2;
+
+    /**
+     * The DRM preparation has failed .
+     */
+    public static final int PREPARE_DRM_STATUS_PREPARATION_ERROR = 3;
+
+
+    /** @hide */
+    @IntDef({
+        PREPARE_DRM_STATUS_SUCCESS,
+        PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR,
+        PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR,
+        PREPARE_DRM_STATUS_PREPARATION_ERROR,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PrepareDrmStatusCode {}
+
+    /**
+     * Interface definition of a callback to notify the app when the
+     * DRM is ready for key request/response
+     */
+    public interface OnDrmPreparedListener
+    {
+        /**
+         * Called to notify the app that prepareDrm is finished and ready for key request/response
+         *
+         * @param mp the {@code MediaPlayer} associated with this callback
+         * @param status the result of DRM preparation which can be
+         * {@link #PREPARE_DRM_STATUS_SUCCESS},
+         * {@link #PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR},
+         * {@link #PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR}, or
+         * {@link #PREPARE_DRM_STATUS_PREPARATION_ERROR}.
+         */
+        public void onDrmPrepared(MediaPlayer mp, @PrepareDrmStatusCode int status);
+    }
+
+    /**
+     * Register a callback to be invoked when the DRM object is prepared.
+     *
+     * @param listener the callback that will be run
+     */
+    public void setOnDrmPreparedListener(OnDrmPreparedListener listener)
+    {
+        setOnDrmPreparedListener(listener, null);
+    }
+
+    /**
+     * Register a callback to be invoked when the DRM object is prepared.
+     *
+     * @param listener the callback that will be run
+     * @param handler the Handler that will receive the callback
+     */
+    public void setOnDrmPreparedListener(OnDrmPreparedListener listener, Handler handler)
+    {
+        synchronized (mDrmLock) {
+            if (listener != null) {
+                mOnDrmPreparedHandlerDelegate = new OnDrmPreparedHandlerDelegate(this,
+                                                            listener, handler);
+            } else {
+                mOnDrmPreparedHandlerDelegate = null;
+            }
+        } // synchronized
+    }
+
+    private OnDrmPreparedHandlerDelegate mOnDrmPreparedHandlerDelegate;
+
+
+    private class OnDrmInfoHandlerDelegate {
+        private MediaPlayer mMediaPlayer;
+        private OnDrmInfoListener mOnDrmInfoListener;
+        private Handler mHandler;
+
+        OnDrmInfoHandlerDelegate(MediaPlayer mp, OnDrmInfoListener listener, Handler handler) {
+            mMediaPlayer = mp;
+            mOnDrmInfoListener = listener;
+
+            // find the looper for our new event handler
+            if (handler != null) {
+                mHandler = handler;
+            } else {
+                // handler == null
+                // Will let OnDrmInfoListener be called in mEventHandler similar to other
+                // legacy notifications. This is because MEDIA_DRM_INFO's notification has to be
+                // sent before MEDIA_PREPARED's (i.e., in the same order they are issued by
+                // mediaserver). As a result, the callback has to be called directly by
+                // EventHandler.handleMessage similar to onPrepared.
+            }
+        }
+
+        void notifyClient(DrmInfo drmInfo) {
+            if (mHandler != null) {
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                       mOnDrmInfoListener.onDrmInfo(mMediaPlayer, drmInfo);
+                    }
+                });
+            }
+            else {  // no handler: direct call by mEventHandler
+                mOnDrmInfoListener.onDrmInfo(mMediaPlayer, drmInfo);
+            }
+        }
+    }
+
+    private class OnDrmPreparedHandlerDelegate {
+        private MediaPlayer mMediaPlayer;
+        private OnDrmPreparedListener mOnDrmPreparedListener;
+        private Handler mHandler;
+
+        OnDrmPreparedHandlerDelegate(MediaPlayer mp, OnDrmPreparedListener listener,
+                Handler handler) {
+            mMediaPlayer = mp;
+            mOnDrmPreparedListener = listener;
+
+            // find the looper for our new event handler
+            if (handler != null) {
+                mHandler = handler;
+            } else if (mEventHandler != null) {
+                // Otherwise, use mEventHandler
+                mHandler = mEventHandler;
+            } else {
+                Log.e(TAG, "OnDrmPreparedHandlerDelegate: Unexpected null mEventHandler");
+            }
+        }
+
+        void notifyClient(int status) {
+            if (mHandler != null) {
+                mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        mOnDrmPreparedListener.onDrmPrepared(mMediaPlayer, status);
+                    }
+                });
+            } else {
+                Log.e(TAG, "OnDrmPreparedHandlerDelegate:notifyClient: Unexpected null mHandler");
+            }
+        }
+    }
+
+    /**
+     * Retrieves the DRM Info associated with the current source
+     *
+     * @throws IllegalStateException if called before prepare()
+     */
+    public DrmInfo getDrmInfo()
+    {
+        DrmInfo drmInfo = null;
+
+        // there is not much point if the app calls getDrmInfo within an OnDrmInfoListenet;
+        // regardless below returns drmInfo anyway instead of raising an exception
+        synchronized (mDrmLock) {
+            if (!mDrmInfoResolved && mDrmInfo == null) {
+                final String msg = "The Player has not been prepared yet";
+                Log.v(TAG, msg);
+                throw new IllegalStateException(msg);
+            }
+
+            if (mDrmInfo != null) {
+                drmInfo = mDrmInfo.makeCopy();
+            }
+        }   // synchronized
+
+        return drmInfo;
+    }
+
+
+    /**
+     * Prepares the DRM for the current source
+     * <p>
+     * If {@code OnDrmConfigHelper} is registered, it will be called during
+     * preparation to allow configuration of the DRM properties before opening the
+     * DRM session. Note that the callback is called synchronously in the thread that called
+     * {@code prepareDrm}. It should be used only for a series of {@code getDrmPropertyString}
+     * and {@code setDrmPropertyString} calls and refrain from any lengthy operation.
+     * <p>
+     * If the device has not been provisioned before, this call also provisions the device
+     * which involves accessing the provisioning server and can take a variable time to
+     * complete depending on the network connectivity.
+     * If {@code OnDrmPreparedListener} is registered, prepareDrm() runs in non-blocking
+     * mode by launching the provisioning in the background and returning. The listener
+     * will be called when provisioning and preparation has finished. If a
+     * {@code OnDrmPreparedListener} is not registered, prepareDrm() waits till provisioning
+     * and preparation has finished, i.e., runs in blocking mode.
+     * <p>
+     * If {@code OnDrmPreparedListener} is registered, it is called to indicate the DRM
+     * session being ready. The application should not make any assumption about its call
+     * sequence (e.g., before or after prepareDrm returns), or the thread context that will
+     * execute the listener (unless the listener is registered with a handler thread).
+     * <p>
+     *
+     * @param uuid The UUID of the crypto scheme. If not known beforehand, it can be retrieved
+     * from the source through {@code getDrmInfo} or registering a {@code onDrmInfoListener}.
+     *
+     * @throws IllegalStateException              if called before prepare(), or the DRM was
+     *                                            prepared already
+     * @throws UnsupportedSchemeException         if the crypto scheme is not supported
+     * @throws ResourceBusyException              if required DRM resources are in use
+     * @throws ProvisioningNetworkErrorException  if provisioning is required but failed due to a
+     *                                            network error
+     * @throws ProvisioningServerErrorException   if provisioning is required but failed due to
+     *                                            the request denied by the provisioning server
+     */
+    public void prepareDrm(@NonNull UUID uuid)
+            throws UnsupportedSchemeException, ResourceBusyException,
+                   ProvisioningNetworkErrorException, ProvisioningServerErrorException
+    {
+        Log.v(TAG, "prepareDrm: uuid: " + uuid + " mOnDrmConfigHelper: " + mOnDrmConfigHelper);
+
+        boolean allDoneWithoutProvisioning = false;
+        // get a snapshot as we'll use them outside the lock
+        OnDrmPreparedHandlerDelegate onDrmPreparedHandlerDelegate = null;
+
+        synchronized (mDrmLock) {
+
+            // only allowing if tied to a protected source; might relax for releasing offline keys
+            if (mDrmInfo == null) {
+                final String msg = "prepareDrm(): Wrong usage: The player must be prepared and " +
+                        "DRM info be retrieved before this call.";
+                Log.e(TAG, msg);
+                throw new IllegalStateException(msg);
+            }
+
+            if (mActiveDrmScheme) {
+                final String msg = "prepareDrm(): Wrong usage: There is already " +
+                        "an active DRM scheme with " + mDrmUUID;
+                Log.e(TAG, msg);
+                throw new IllegalStateException(msg);
+            }
+
+            if (mPrepareDrmInProgress) {
+                final String msg = "prepareDrm(): Wrong usage: There is already " +
+                        "a pending prepareDrm call.";
+                Log.e(TAG, msg);
+                throw new IllegalStateException(msg);
+            }
+
+            if (mDrmProvisioningInProgress) {
+                final String msg = "prepareDrm(): Unexpectd: Provisioning is already in progress.";
+                Log.e(TAG, msg);
+                throw new IllegalStateException(msg);
+            }
+
+            // shouldn't need this; just for safeguard
+            cleanDrmObj();
+
+            mPrepareDrmInProgress = true;
+            // local copy while the lock is held
+            onDrmPreparedHandlerDelegate = mOnDrmPreparedHandlerDelegate;
+
+            try {
+                // only creating the DRM object to allow pre-openSession configuration
+                prepareDrm_createDrmStep(uuid);
+            } catch (Exception e) {
+                Log.w(TAG, "prepareDrm(): Exception ", e);
+                mPrepareDrmInProgress = false;
+                throw e;
+            }
+
+            mDrmConfigAllowed = true;
+        }   // synchronized
+
+
+        // call the callback outside the lock
+        if (mOnDrmConfigHelper != null)  {
+            mOnDrmConfigHelper.onDrmConfig(this);
+        }
+
+        synchronized (mDrmLock) {
+            mDrmConfigAllowed = false;
+            boolean earlyExit = false;
+
+            try {
+                prepareDrm_openSessionStep(uuid);
+
+                mDrmUUID = uuid;
+                mActiveDrmScheme = true;
+
+                allDoneWithoutProvisioning = true;
+            } catch (IllegalStateException e) {
+                final String msg = "prepareDrm(): Wrong usage: The player must be " +
+                        "in the prepared state to call prepareDrm().";
+                Log.e(TAG, msg);
+                earlyExit = true;
+                throw new IllegalStateException(msg);
+            } catch (NotProvisionedException e) {
+                Log.w(TAG, "prepareDrm: NotProvisionedException");
+
+                // handle provisioning internally; it'll reset mPrepareDrmInProgress
+                int result = HandleProvisioninig(uuid);
+
+                // if blocking mode, we're already done;
+                // if non-blocking mode, we attempted to launch background provisioning
+                if (result != PREPARE_DRM_STATUS_SUCCESS) {
+                    earlyExit = true;
+                    String msg;
+
+                    switch (result) {
+                    case PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR:
+                        msg = "prepareDrm: Provisioning was required but failed " +
+                                "due to a network error.";
+                        Log.e(TAG, msg);
+                        throw new ProvisioningNetworkErrorException(msg);
+
+                    case PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR:
+                        msg = "prepareDrm: Provisioning was required but the request " +
+                                "was denied by the server.";
+                        Log.e(TAG, msg);
+                        throw new ProvisioningServerErrorException(msg);
+
+                    case PREPARE_DRM_STATUS_PREPARATION_ERROR:
+                    default: // default for safeguard
+                        msg = "prepareDrm: Post-provisioning preparation failed.";
+                        Log.e(TAG, msg);
+                        throw new IllegalStateException(msg);
+                    }
+                }
+                // nothing else to do;
+                // if blocking or non-blocking, HandleProvisioninig does the re-attempt & cleanup
+            } catch (Exception e) {
+                Log.e(TAG, "prepareDrm: Exception " + e);
+                earlyExit = true;
+                throw e;
+            } finally {
+                if (!mDrmProvisioningInProgress) {// if early exit other than provisioning exception
+                    mPrepareDrmInProgress = false;
+                }
+                if (earlyExit) {    // cleaning up object if didn't succeed
+                    cleanDrmObj();
+                }
+            } // finally
+        }   // synchronized
+
+
+        // if finished successfully without provisioning, call the callback outside the lock
+        if (allDoneWithoutProvisioning) {
+            if (onDrmPreparedHandlerDelegate != null)
+                onDrmPreparedHandlerDelegate.notifyClient(PREPARE_DRM_STATUS_SUCCESS);
+        }
+
+    }
+
+
+    private native void _releaseDrm();
+
+    /**
+     * Releases the DRM session
+     * <p>
+     * The player has to have an active DRM session and be in stopped, or prepared
+     * state before this call is made.
+     * A {@code reset()} call will release the DRM session implicitly.
+     *
+     * @throws NoDrmSchemeException if there is no active DRM session to release
+     */
+    public void releaseDrm()
+            throws NoDrmSchemeException
+    {
+        Log.v(TAG, "releaseDrm:");
+
+        synchronized (mDrmLock) {
+            if (!mActiveDrmScheme) {
+                Log.e(TAG, "releaseDrm(): No active DRM scheme to release.");
+                throw new NoDrmSchemeException("releaseDrm: No active DRM scheme to release.");
+            }
+
+            try {
+                // we don't have the player's state in this layer. The below call raises
+                // exception if we're in a non-stopped/prepared state.
+
+                // for cleaning native/mediaserver crypto object
+                _releaseDrm();
+
+                // for cleaning client-side MediaDrm object; only called if above has succeeded
+                cleanDrmObj();
+
+                mActiveDrmScheme = false;
+            } catch (IllegalStateException e) {
+                Log.w(TAG, "releaseDrm: Exception ", e);
+                throw new IllegalStateException("releaseDrm: The player is not in a valid state.");
+            } catch (Exception e) {
+                Log.e(TAG, "releaseDrm: Exception ", e);
+            }
+        }   // synchronized
+    }
+
+
+    /**
+     * A key request/response exchange occurs between the app and a license server
+     * to obtain or release keys used to decrypt encrypted content.
+     * <p>
+     * getKeyRequest() is used to obtain an opaque key request byte array that is
+     * delivered to the license server.  The opaque key request byte array is returned
+     * in KeyRequest.data.  The recommended URL to deliver the key request to is
+     * returned in KeyRequest.defaultUrl.
+     * <p>
+     * After the app has received the key request response from the server,
+     * it should deliver to the response to the DRM engine plugin using the method
+     * {@link #provideKeyResponse}.
+     *
+     * @param keySetId is the key-set identifier of the offline keys being released when keyType is
+     * {@link MediaDrm#KEY_TYPE_RELEASE}. It should be set to null for other key requests, when
+     * keyType is {@link MediaDrm#KEY_TYPE_STREAMING} or {@link MediaDrm#KEY_TYPE_OFFLINE}.
+     *
+     * @param initData is the container-specific initialization data when the keyType is
+     * {@link MediaDrm#KEY_TYPE_STREAMING} or {@link MediaDrm#KEY_TYPE_OFFLINE}. Its meaning is
+     * interpreted based on the mime type provided in the mimeType parameter.  It could
+     * contain, for example, the content ID, key ID or other data obtained from the content
+     * metadata that is required in generating the key request.
+     * When the keyType is {@link MediaDrm#KEY_TYPE_RELEASE}, it should be set to null.
+     *
+     * @param mimeType identifies the mime type of the content
+     *
+     * @param keyType specifies the type of the request. The request may be to acquire
+     * keys for streaming, {@link MediaDrm#KEY_TYPE_STREAMING}, or for offline content
+     * {@link MediaDrm#KEY_TYPE_OFFLINE}, or to release previously acquired
+     * keys ({@link MediaDrm#KEY_TYPE_RELEASE}), which are identified by a keySetId.
+     *
+     * @param optionalParameters are included in the key request message to
+     * allow a client application to provide additional message parameters to the server.
+     * This may be {@code null} if no additional parameters are to be sent.
+     *
+     * @throws NoDrmSchemeException if there is no active DRM session
+     */
+    @NonNull
+    public MediaDrm.KeyRequest getKeyRequest(@Nullable byte[] keySetId, @Nullable byte[] initData,
+            @Nullable String mimeType, @MediaDrm.KeyType int keyType,
+            @Nullable Map<String, String> optionalParameters)
+            throws NoDrmSchemeException
+    {
+        Log.v(TAG, "getKeyRequest: " +
+                " keySetId: " + keySetId + " initData:" + initData + " mimeType: " + mimeType +
+                " keyType: " + keyType + " optionalParameters: " + optionalParameters);
+
+        synchronized (mDrmLock) {
+            if (!mActiveDrmScheme) {
+                Log.e(TAG, "getKeyRequest NoDrmSchemeException");
+                throw new NoDrmSchemeException("getKeyRequest: Has to set a DRM scheme first.");
+            }
+
+            try {
+                byte[] scope = (keyType != MediaDrm.KEY_TYPE_RELEASE) ?
+                        mDrmSessionId : // sessionId for KEY_TYPE_STREAMING/OFFLINE
+                        keySetId;       // keySetId for KEY_TYPE_RELEASE
+
+                HashMap<String, String> hmapOptionalParameters =
+                                                (optionalParameters != null) ?
+                                                new HashMap<String, String>(optionalParameters) :
+                                                null;
+
+                MediaDrm.KeyRequest request = mDrmObj.getKeyRequest(scope, initData, mimeType,
+                                                              keyType, hmapOptionalParameters);
+                Log.v(TAG, "getKeyRequest:   --> request: " + request);
+
+                return request;
+
+            } catch (NotProvisionedException e) {
+                Log.w(TAG, "getKeyRequest NotProvisionedException: " +
+                        "Unexpected. Shouldn't have reached here.");
+                throw new IllegalStateException("getKeyRequest: Unexpected provisioning error.");
+            } catch (Exception e) {
+                Log.w(TAG, "getKeyRequest Exception " + e);
+                throw e;
+            }
+
+        }   // synchronized
+    }
+
+
+    /**
+     * A key response is received from the license server by the app, then it is
+     * provided to the DRM engine plugin using provideKeyResponse. When the
+     * response is for an offline key request, a key-set identifier is returned that
+     * can be used to later restore the keys to a new session with the method
+     * {@ link # restoreKeys}.
+     * When the response is for a streaming or release request, null is returned.
+     *
+     * @param keySetId When the response is for a release request, keySetId identifies
+     * the saved key associated with the release request (i.e., the same keySetId
+     * passed to the earlier {@ link # getKeyRequest} call. It MUST be null when the
+     * response is for either streaming or offline key requests.
+     *
+     * @param response the byte array response from the server
+     *
+     * @throws NoDrmSchemeException if there is no active DRM session
+     * @throws DeniedByServerException if the response indicates that the
+     * server rejected the request
+     */
+    public byte[] provideKeyResponse(@Nullable byte[] keySetId, @NonNull byte[] response)
+            throws NoDrmSchemeException, DeniedByServerException
+    {
+        Log.v(TAG, "provideKeyResponse: keySetId: " + keySetId + " response: " + response);
+
+        synchronized (mDrmLock) {
+
+            if (!mActiveDrmScheme) {
+                Log.e(TAG, "getKeyRequest NoDrmSchemeException");
+                throw new NoDrmSchemeException("getKeyRequest: Has to set a DRM scheme first.");
+            }
+
+            try {
+                byte[] scope = (keySetId == null) ?
+                                mDrmSessionId :     // sessionId for KEY_TYPE_STREAMING/OFFLINE
+                                keySetId;           // keySetId for KEY_TYPE_RELEASE
+
+                byte[] keySetResult = mDrmObj.provideKeyResponse(scope, response);
+
+                Log.v(TAG, "provideKeyResponse: keySetId: " + keySetId + " response: " + response +
+                        " --> " + keySetResult);
+
+
+                return keySetResult;
+
+            } catch (NotProvisionedException e) {
+                Log.w(TAG, "provideKeyResponse NotProvisionedException: " +
+                        "Unexpected. Shouldn't have reached here.");
+                throw new IllegalStateException("provideKeyResponse: " +
+                        "Unexpected provisioning error.");
+            } catch (Exception e) {
+                Log.w(TAG, "provideKeyResponse Exception " + e);
+                throw e;
+            }
+        }   // synchronized
+    }
+
+
+    /**
+     * Restore persisted offline keys into a new session.  keySetId identifies the
+     * keys to load, obtained from a prior call to {@link #provideKeyResponse}.
+     *
+     * @param keySetId identifies the saved key set to restore
+     */
+    public void restoreKeys(@NonNull byte[] keySetId)
+            throws NoDrmSchemeException
+    {
+        Log.v(TAG, "restoreKeys: keySetId: " + keySetId);
+
+        synchronized (mDrmLock) {
+
+            if (!mActiveDrmScheme) {
+                Log.w(TAG, "restoreKeys NoDrmSchemeException");
+                throw new NoDrmSchemeException("restoreKeys: Has to set a DRM scheme first.");
+            }
+
+            try {
+                mDrmObj.restoreKeys(mDrmSessionId, keySetId);
+            } catch (Exception e) {
+                Log.w(TAG, "restoreKeys Exception " + e);
+                throw e;
+            }
+
+        }   // synchronized
+    }
+
+
+    /**
+     * Read a DRM engine plugin String property value, given the property name string.
+     * <p>
+     * @param propertyName the property name
+     *
+     * Standard fields names are:
+     * {@link MediaDrm#PROPERTY_VENDOR}, {@link MediaDrm#PROPERTY_VERSION},
+     * {@link MediaDrm#PROPERTY_DESCRIPTION}, {@link MediaDrm#PROPERTY_ALGORITHMS}
+     */
+    @NonNull
+    public String getDrmPropertyString(@NonNull @MediaDrm.StringProperty String propertyName)
+            throws NoDrmSchemeException
+    {
+        Log.v(TAG, "getDrmPropertyString: propertyName: " + propertyName);
+
+        String value;
+        synchronized (mDrmLock) {
+
+            if (!mActiveDrmScheme && !mDrmConfigAllowed) {
+                Log.w(TAG, "getDrmPropertyString NoDrmSchemeException");
+                throw new NoDrmSchemeException("getDrmPropertyString: Has to prepareDrm() first.");
+            }
+
+            try {
+                value = mDrmObj.getPropertyString(propertyName);
+            } catch (Exception e) {
+                Log.w(TAG, "getDrmPropertyString Exception " + e);
+                throw e;
+            }
+        }   // synchronized
+
+        Log.v(TAG, "getDrmPropertyString: propertyName: " + propertyName + " --> value: " + value);
+
+        return value;
+    }
+
+
+    /**
+     * Set a DRM engine plugin String property value.
+     * <p>
+     * @param propertyName the property name
+     * @param value the property value
+     *
+     * Standard fields names are:
+     * {@link MediaDrm#PROPERTY_VENDOR}, {@link MediaDrm#PROPERTY_VERSION},
+     * {@link MediaDrm#PROPERTY_DESCRIPTION}, {@link MediaDrm#PROPERTY_ALGORITHMS}
+     */
+    public void setDrmPropertyString(@NonNull @MediaDrm.StringProperty String propertyName,
+                                     @NonNull String value)
+            throws NoDrmSchemeException
+    {
+        Log.v(TAG, "setDrmPropertyString: propertyName: " + propertyName + " value: " + value);
+
+        synchronized (mDrmLock) {
+
+            if ( !mActiveDrmScheme && !mDrmConfigAllowed ) {
+                Log.w(TAG, "setDrmPropertyString NoDrmSchemeException");
+                throw new NoDrmSchemeException("setDrmPropertyString: Has to prepareDrm() first.");
+            }
+
+            try {
+                mDrmObj.setPropertyString(propertyName, value);
+            } catch ( Exception e ) {
+                Log.w(TAG, "setDrmPropertyString Exception " + e);
+                throw e;
+            }
+        }   // synchronized
+    }
+
+    /**
+     * Encapsulates the DRM properties of the source.
+     */
+    public static final class DrmInfo {
+        private Map<UUID, byte[]> mapPssh;
+        private UUID[] supportedSchemes;
+
+        /**
+         * Returns the PSSH info of the data source for each supported DRM scheme.
+         */
+        public Map<UUID, byte[]> getPssh() {
+            return mapPssh;
+        }
+
+        /**
+         * Returns the intersection of the data source and the device DRM schemes.
+         * It effectively identifies the subset of the source's DRM schemes which
+         * are supported by the device too.
+         */
+        public UUID[] getSupportedSchemes() {
+            return supportedSchemes;
+        }
+
+        private DrmInfo(Map<UUID, byte[]> Pssh, UUID[] SupportedSchemes) {
+            mapPssh = Pssh;
+            supportedSchemes = SupportedSchemes;
+        }
+
+        private DrmInfo(Parcel parcel) {
+            Log.v(TAG, "DrmInfo(" + parcel + ") size " + parcel.dataSize());
+
+            int psshsize = parcel.readInt();
+            byte[] pssh = new byte[psshsize];
+            parcel.readByteArray(pssh);
+
+            Log.v(TAG, "DrmInfo() PSSH: " + arrToHex(pssh));
+            mapPssh = parsePSSH(pssh, psshsize);
+            Log.v(TAG, "DrmInfo() PSSH: " + mapPssh);
+
+            int supportedDRMsCount = parcel.readInt();
+            supportedSchemes = new UUID[supportedDRMsCount];
+            for (int i = 0; i < supportedDRMsCount; i++) {
+                byte[] uuid = new byte[16];
+                parcel.readByteArray(uuid);
+
+                supportedSchemes[i] = bytesToUUID(uuid);
+
+                Log.v(TAG, "DrmInfo() supportedScheme[" + i + "]: " +
+                      supportedSchemes[i]);
+            }
+
+            Log.v(TAG, "DrmInfo() Parcel psshsize: " + psshsize +
+                  " supportedDRMsCount: " + supportedDRMsCount);
+        }
+
+        private DrmInfo makeCopy() {
+            return new DrmInfo(this.mapPssh, this.supportedSchemes);
+        }
+
+        private String arrToHex(byte[] bytes) {
+            String out = "0x";
+            for (int i = 0; i < bytes.length; i++) {
+                out += String.format("%02x", bytes[i]);
+            }
+
+            return out;
+        }
+
+        private UUID bytesToUUID(byte[] uuid) {
+            long msb = 0, lsb = 0;
+            for (int i = 0; i < 8; i++) {
+                msb |= ( ((long)uuid[i]   & 0xff) << (8 * (7 - i)) );
+                lsb |= ( ((long)uuid[i+8] & 0xff) << (8 * (7 - i)) );
+            }
+
+            return new UUID(msb, lsb);
+        }
+
+        private Map<UUID, byte[]> parsePSSH(byte[] pssh, int psshsize) {
+            Map<UUID, byte[]> result = new HashMap<UUID, byte[]>();
+
+            final int UUID_SIZE = 16;
+            final int DATALEN_SIZE = 4;
+
+            int len = psshsize;
+            int numentries = 0;
+            int i = 0;
+
+            while (len > 0) {
+                if (len < UUID_SIZE) {
+                    Log.w(TAG, String.format("parsePSSH: len is too short to parse " +
+                                             "UUID: (%d < 16) pssh: %d", len, psshsize));
+                    return null;
+                }
+
+                byte[] subset = Arrays.copyOfRange(pssh, i, i + UUID_SIZE);
+                UUID uuid = bytesToUUID(subset);
+                i += UUID_SIZE;
+                len -= UUID_SIZE;
+
+                // get data length
+                if (len < 4) {
+                    Log.w(TAG, String.format("parsePSSH: len is too short to parse " +
+                                             "datalen: (%d < 4) pssh: %d", len, psshsize));
+                    return null;
+                }
+
+                subset = Arrays.copyOfRange(pssh, i, i+DATALEN_SIZE);
+                int datalen = (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) ?
+                    ((subset[3] & 0xff) << 24) | ((subset[2] & 0xff) << 16) |
+                    ((subset[1] & 0xff) <<  8) |  (subset[0] & 0xff)          :
+                    ((subset[0] & 0xff) << 24) | ((subset[1] & 0xff) << 16) |
+                    ((subset[2] & 0xff) <<  8) |  (subset[3] & 0xff) ;
+                i += DATALEN_SIZE;
+                len -= DATALEN_SIZE;
+
+                if (len < datalen) {
+                    Log.w(TAG, String.format("parsePSSH: len is too short to parse " +
+                                             "data: (%d < %d) pssh: %d", len, datalen, psshsize));
+                    return null;
+                }
+
+                byte[] data = Arrays.copyOfRange(pssh, i, i+datalen);
+
+                // skip the data
+                i += datalen;
+                len -= datalen;
+
+                Log.v(TAG, String.format("parsePSSH[%d]: <%s, %s> pssh: %d",
+                                         numentries, uuid, arrToHex(data), psshsize));
+                numentries++;
+                result.put(uuid, data);
+            }
+
+            return result;
+        }
+
+    };  // DrmInfo
+
+    /**
+     * Thrown when a DRM method is called before preparing a DRM scheme through prepareDrm().
+     * Extends MediaDrm.MediaDrmException
+     */
+    public static final class NoDrmSchemeException extends MediaDrmException {
+        public NoDrmSchemeException(String detailMessage) {
+            super(detailMessage);
+        }
+    }
+
+    /**
+     * Thrown when the device requires DRM provisioning but the provisioning attempt has
+     * failed due to a network error (Internet reachability, timeout, etc.).
+     * Extends MediaDrm.MediaDrmException
+     */
+    public static final class ProvisioningNetworkErrorException extends MediaDrmException {
+        public ProvisioningNetworkErrorException(String detailMessage) {
+            super(detailMessage);
+        }
+    }
+
+    /**
+     * Thrown when the device requires DRM provisioning but the provisioning attempt has
+     * failed due to the provisioning server denying the request.
+     * Extends MediaDrm.MediaDrmException
+     */
+    public static final class ProvisioningServerErrorException extends MediaDrmException {
+        public ProvisioningServerErrorException(String detailMessage) {
+            super(detailMessage);
+        }
+    }
+
+
+    private native void _prepareDrm(@NonNull byte[] uuid, @NonNull byte[] drmSessionId);
+
+        // Modular DRM helpers
+
+    private void prepareDrm_createDrmStep(@NonNull UUID uuid)
+            throws UnsupportedSchemeException {
+        Log.v(TAG, "prepareDrm_createDrmStep: UUID: " + uuid);
+
+        try {
+            mDrmObj = new MediaDrm(uuid);
+            Log.v(TAG, "prepareDrm_createDrmStep: Created mDrmObj=" + mDrmObj);
+        } catch (Exception e) { // UnsupportedSchemeException
+            Log.e(TAG, "prepareDrm_createDrmStep: MediaDrm failed with " + e);
+            throw e;
+        }
+    }
+
+    private void prepareDrm_openSessionStep(@NonNull UUID uuid)
+            throws NotProvisionedException, ResourceBusyException {
+        Log.v(TAG, "prepareDrm_openSessionStep: uuid: " + uuid);
+
+        // TODO: don't need an open session for a future specialKeyReleaseDrm mode but we should do
+        // it anyway so it raises provisioning error if needed. We'd rather handle provisioning
+        // at prepareDrm/openSession rather than getKeyRequest/provideKeyResponse
+        try {
+            mDrmSessionId = mDrmObj.openSession();
+            Log.v(TAG, "prepareDrm_openSessionStep: mDrmSessionId=" + mDrmSessionId);
+
+            // Sending it down to native/mediaserver to create the crypto object
+            // This call could simply fail due to bad player state, e.g., after start().
+            _prepareDrm(getByteArrayFromUUID(uuid), mDrmSessionId);
+            Log.v(TAG, "prepareDrm_openSessionStep: _prepareDrm/Crypto succeeded");
+
+        } catch (Exception e) { //ResourceBusyException, NotProvisionedException
+            Log.e(TAG, "prepareDrm_openSessionStep: open/crypto failed with " + e);
+            throw e;
+        }
+
+    }
+
+    private class ProvisioningThread extends Thread
+    {
+        public static final int TIMEOUT_MS = 60000;
+
+        private UUID uuid;
+        private String urlStr;
+        private Object drmLock;
+        private OnDrmPreparedHandlerDelegate onDrmPreparedHandlerDelegate;
+        private MediaPlayer mediaPlayer;
+        private int status;
+        private boolean finished;
+        public  int status() {
+            return status;
+        }
+
+        public ProvisioningThread initialize(MediaDrm.ProvisionRequest request,
+                                          UUID uuid, MediaPlayer mediaPlayer) {
+            // lock is held by the caller
+            drmLock = mediaPlayer.mDrmLock;
+            onDrmPreparedHandlerDelegate = mediaPlayer.mOnDrmPreparedHandlerDelegate;
+            this.mediaPlayer = mediaPlayer;
+
+            urlStr = request.getDefaultUrl() + "&signedRequest=" + new String(request.getData());
+            this.uuid = uuid;
+
+            status = PREPARE_DRM_STATUS_PREPARATION_ERROR;
+
+            Log.v(TAG, "HandleProvisioninig: Thread is initialised url: " + urlStr);
+            return this;
+        }
+
+        public void run() {
+
+            byte[] response = null;
+            boolean provisioningSucceeded = false;
+            try {
+                URL url = new URL(urlStr);
+                final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+                try {
+                    connection.setRequestMethod("POST");
+                    connection.setDoOutput(false);
+                    connection.setDoInput(true);
+                    connection.setConnectTimeout(TIMEOUT_MS);
+                    connection.setReadTimeout(TIMEOUT_MS);
+
+                    connection.connect();
+                    response = Streams.readFully(connection.getInputStream());
+
+                    Log.v(TAG, "HandleProvisioninig: Thread run: response " +
+                            response.length + " " + response);
+                } catch (Exception e) {
+                    status = PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR;
+                    Log.w(TAG, "HandleProvisioninig: Thread run: connect " + e + " url: " + url);
+                } finally {
+                    connection.disconnect();
+                }
+            } catch (Exception e)   {
+                status = PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR;
+                Log.w(TAG, "HandleProvisioninig: Thread run: openConnection " + e);
+            }
+
+            if (response != null) {
+                try {
+                    mDrmObj.provideProvisionResponse(response);
+                    Log.v(TAG, "HandleProvisioninig: Thread run: " +
+                            "provideProvisionResponse SUCCEEDED!");
+
+                    provisioningSucceeded = true;
+                } catch (Exception e) {
+                    status = PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR;
+                    Log.w(TAG, "HandleProvisioninig: Thread run: " +
+                            "provideProvisionResponse " + e);
+                }
+            }
+
+            boolean succeeded = false;
+
+            // non-blocking mode needs the lock
+            if (onDrmPreparedHandlerDelegate != null) {
+
+                synchronized (drmLock) {
+                    // continuing with prepareDrm
+                    if (provisioningSucceeded) {
+                        succeeded = mediaPlayer.resumePrepareDrm(uuid);
+                        status = (succeeded) ?
+                                PREPARE_DRM_STATUS_SUCCESS :
+                                PREPARE_DRM_STATUS_PREPARATION_ERROR;
+                    }
+                    mediaPlayer.mDrmProvisioningInProgress = false;
+                    mediaPlayer.mPrepareDrmInProgress = false;
+                    if (!succeeded) {
+                        cleanDrmObj();  // cleaning up if it hasn't gone through while in the lock
+                    }
+                } // synchronized
+
+                // calling the callback outside the lock
+                onDrmPreparedHandlerDelegate.notifyClient(status);
+            } else {   // blocking mode already has the lock
+
+                // continuing with prepareDrm
+                if (provisioningSucceeded) {
+                    succeeded = mediaPlayer.resumePrepareDrm(uuid);
+                    status = (succeeded) ?
+                            PREPARE_DRM_STATUS_SUCCESS :
+                            PREPARE_DRM_STATUS_PREPARATION_ERROR;
+                }
+                mediaPlayer.mDrmProvisioningInProgress = false;
+                mediaPlayer.mPrepareDrmInProgress = false;
+                if (!succeeded) {
+                    cleanDrmObj();  // cleaning up if it hasn't gone through
+                }
+            }
+
+            finished = true;
+        }   // run()
+
+    }   // ProvisioningThread
+
+    private int HandleProvisioninig(UUID uuid)
+    {
+        // the lock is already held by the caller
+
+        if (mDrmProvisioningInProgress) {
+            Log.e(TAG, "HandleProvisioninig: Unexpected mDrmProvisioningInProgress");
+            return PREPARE_DRM_STATUS_PREPARATION_ERROR;
+        }
+
+        MediaDrm.ProvisionRequest provReq = mDrmObj.getProvisionRequest();
+        if (provReq == null) {
+            Log.e(TAG, "HandleProvisioninig: getProvisionRequest returned null.");
+            return PREPARE_DRM_STATUS_PREPARATION_ERROR;
+        }
+
+        Log.v(TAG, "HandleProvisioninig provReq " +
+                " data: " + provReq.getData() + " url: " + provReq.getDefaultUrl());
+
+        // networking in a background thread
+        mDrmProvisioningInProgress = true;
+
+        mDrmProvisioningThread = new ProvisioningThread().initialize(provReq, uuid, this);
+        mDrmProvisioningThread.start();
+
+        int result;
+
+        // non-blocking: this is not the final result
+        if (mOnDrmPreparedHandlerDelegate != null) {
+            result = PREPARE_DRM_STATUS_SUCCESS;
+        } else {
+            // if blocking mode, wait till provisioning is done
+            try {
+                mDrmProvisioningThread.join();
+            } catch (Exception e) {
+                Log.w(TAG, "HandleProvisioninig: Thread.join Exception " + e);
+            }
+            result = mDrmProvisioningThread.status();
+            // no longer need the thread
+            mDrmProvisioningThread = null;
+        }
+
+        return result;
+    }
+
+    private boolean resumePrepareDrm(UUID uuid)
+    {
+        Log.v(TAG, "resumePrepareDrm: uuid: " + uuid);
+
+        // mDrmLock is guaranteed to be held
+        boolean success = false;
+        try {
+            // resuming
+            prepareDrm_openSessionStep(uuid);
+
+            mDrmUUID = uuid;
+            mActiveDrmScheme = true;
+
+            success = true;
+        } catch (Exception e) {
+            Log.w(TAG, "HandleProvisioninig: Thread run _prepareDrm resume failed with " + e);
+            // mDrmObj clean up is done by the caller
+        }
+
+        return success;
+    }
+
+    private void resetDrmState()
+    {
+        synchronized (mDrmLock) {
+            Log.v(TAG, "resetDrmState: " +
+                    " mDrmInfo=" + mDrmInfo +
+                    " mDrmProvisioningThread=" + mDrmProvisioningThread +
+                    " mPrepareDrmInProgress=" + mPrepareDrmInProgress +
+                    " mActiveDrmScheme=" + mActiveDrmScheme);
+
+            mDrmInfoResolved = false;
+            mDrmInfo = null;
+
+            if (mDrmProvisioningThread != null) {
+                // timeout; relying on HttpUrlConnection
+                try {
+                    mDrmProvisioningThread.join();
+                }
+                catch (InterruptedException e) {
+                    Log.w(TAG, "resetDrmState: ProvThread.join Exception " + e);
+                }
+                mDrmProvisioningThread = null;
+            }
+
+            mPrepareDrmInProgress = false;
+            mActiveDrmScheme = false;
+
+            cleanDrmObj();
+        }   // synchronized
+    }
+
+    private void cleanDrmObj()
+    {
+        // the caller holds mDrmLock
+        Log.v(TAG, "cleanDrmObj: mDrmObj=" + mDrmObj + " mDrmSessionId=" + mDrmSessionId);
+
+        if (mDrmSessionId != null)    {
+            mDrmObj.closeSession(mDrmSessionId);
+            mDrmSessionId = null;
+        }
+        if (mDrmObj != null) {
+            mDrmObj.release();
+            mDrmObj = null;
+        }
+    }
+
+    private static final byte[] getByteArrayFromUUID(@NonNull UUID uuid) {
+        long msb = uuid.getMostSignificantBits();
+        long lsb = uuid.getLeastSignificantBits();
+
+        byte[] uuidBytes = new byte[16];
+        for (int i = 0; i < 8; ++i) {
+            uuidBytes[i] = (byte)(msb >>> (8 * (7 - i)));
+            uuidBytes[8 + i] = (byte)(lsb >>> (8 * (7 - i)));
+        }
+
+        return uuidBytes;
+    }
+
+    // Modular DRM end
+
+    /*
+     * Test whether a given video scaling mode is supported.
+     */
+    private boolean isVideoScalingModeSupported(int mode) {
+        return (mode == VIDEO_SCALING_MODE_SCALE_TO_FIT ||
+                mode == VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING);
+    }
+
+    /** @hide */
+    static class TimeProvider implements MediaPlayer.OnSeekCompleteListener,
+            MediaTimeProvider {
+        private static final String TAG = "MTP";
+        private static final long MAX_NS_WITHOUT_POSITION_CHECK = 5000000000L;
+        private static final long MAX_EARLY_CALLBACK_US = 1000;
+        private static final long TIME_ADJUSTMENT_RATE = 2;  /* meaning 1/2 */
+        private long mLastTimeUs = 0;
+        private MediaPlayer mPlayer;
+        private boolean mPaused = true;
+        private boolean mStopped = true;
+        private boolean mBuffering;
+        private long mLastReportedTime;
+        // since we are expecting only a handful listeners per stream, there is
+        // no need for log(N) search performance
+        private MediaTimeProvider.OnMediaTimeListener mListeners[];
+        private long mTimes[];
+        private Handler mEventHandler;
+        private boolean mRefresh = false;
+        private boolean mPausing = false;
+        private boolean mSeeking = false;
+        private static final int NOTIFY = 1;
+        private static final int NOTIFY_TIME = 0;
+        private static final int NOTIFY_STOP = 2;
+        private static final int NOTIFY_SEEK = 3;
+        private static final int NOTIFY_TRACK_DATA = 4;
+        private HandlerThread mHandlerThread;
+
+        /** @hide */
+        public boolean DEBUG = false;
+
+        public TimeProvider(MediaPlayer mp) {
+            mPlayer = mp;
+            try {
+                getCurrentTimeUs(true, false);
+            } catch (IllegalStateException e) {
+                // we assume starting position
+                mRefresh = true;
+            }
+
+            Looper looper;
+            if ((looper = Looper.myLooper()) == null &&
+                (looper = Looper.getMainLooper()) == null) {
+                // Create our own looper here in case MP was created without one
+                mHandlerThread = new HandlerThread("MediaPlayerMTPEventThread",
+                      Process.THREAD_PRIORITY_FOREGROUND);
+                mHandlerThread.start();
+                looper = mHandlerThread.getLooper();
+            }
+            mEventHandler = new EventHandler(looper);
+
+            mListeners = new MediaTimeProvider.OnMediaTimeListener[0];
+            mTimes = new long[0];
+            mLastTimeUs = 0;
+        }
+
+        private void scheduleNotification(int type, long delayUs) {
+            // ignore time notifications until seek is handled
+            if (mSeeking && type == NOTIFY_TIME) {
+                return;
+            }
+
+            if (DEBUG) Log.v(TAG, "scheduleNotification " + type + " in " + delayUs);
+            mEventHandler.removeMessages(NOTIFY);
+            Message msg = mEventHandler.obtainMessage(NOTIFY, type, 0);
+            mEventHandler.sendMessageDelayed(msg, (int) (delayUs / 1000));
+        }
+
+        /** @hide */
+        public void close() {
+            mEventHandler.removeMessages(NOTIFY);
+            if (mHandlerThread != null) {
+                mHandlerThread.quitSafely();
+                mHandlerThread = null;
+            }
+        }
+
+        /** @hide */
+        protected void finalize() {
+            if (mHandlerThread != null) {
+                mHandlerThread.quitSafely();
+            }
+        }
+
+        /** @hide */
+        public void onNotifyTime() {
+            synchronized (this) {
+                if (DEBUG) Log.d(TAG, "onNotifyTime: ");
+                scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+            }
+        }
+
+        /** @hide */
+        public void onPaused(boolean paused) {
+            synchronized(this) {
+                if (DEBUG) Log.d(TAG, "onPaused: " + paused);
+                if (mStopped) { // handle as seek if we were stopped
+                    mStopped = false;
+                    mSeeking = true;
+                    scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
+                } else {
+                    mPausing = paused;  // special handling if player disappeared
+                    mSeeking = false;
+                    scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+                }
+            }
+        }
+
+        /** @hide */
+        public void onBuffering(boolean buffering) {
+            synchronized (this) {
+                if (DEBUG) Log.d(TAG, "onBuffering: " + buffering);
+                mBuffering = buffering;
+                scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+            }
+        }
+
+        /** @hide */
+        public void onStopped() {
+            synchronized(this) {
+                if (DEBUG) Log.d(TAG, "onStopped");
+                mPaused = true;
+                mStopped = true;
+                mSeeking = false;
+                mBuffering = false;
+                scheduleNotification(NOTIFY_STOP, 0 /* delay */);
+            }
+        }
+
+        /** @hide */
+        @Override
+        public void onSeekComplete(MediaPlayer mp) {
+            synchronized(this) {
+                mStopped = false;
+                mSeeking = true;
+                scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
+            }
+        }
+
+        /** @hide */
+        public void onNewPlayer() {
+            if (mRefresh) {
+                synchronized(this) {
+                    mStopped = false;
+                    mSeeking = true;
+                    mBuffering = false;
+                    scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
+                }
+            }
+        }
+
+        private synchronized void notifySeek() {
+            mSeeking = false;
+            try {
+                long timeUs = getCurrentTimeUs(true, false);
+                if (DEBUG) Log.d(TAG, "onSeekComplete at " + timeUs);
+
+                for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
+                    if (listener == null) {
+                        break;
+                    }
+                    listener.onSeek(timeUs);
+                }
+            } catch (IllegalStateException e) {
+                // we should not be there, but at least signal pause
+                if (DEBUG) Log.d(TAG, "onSeekComplete but no player");
+                mPausing = true;  // special handling if player disappeared
+                notifyTimedEvent(false /* refreshTime */);
+            }
+        }
+
+        private synchronized void notifyTrackData(Pair<SubtitleTrack, byte[]> trackData) {
+            SubtitleTrack track = trackData.first;
+            byte[] data = trackData.second;
+            track.onData(data, true /* eos */, ~0 /* runID: keep forever */);
+        }
+
+        private synchronized void notifyStop() {
+            for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
+                if (listener == null) {
+                    break;
+                }
+                listener.onStop();
+            }
+        }
+
+        private int registerListener(MediaTimeProvider.OnMediaTimeListener listener) {
+            int i = 0;
+            for (; i < mListeners.length; i++) {
+                if (mListeners[i] == listener || mListeners[i] == null) {
+                    break;
+                }
+            }
+
+            // new listener
+            if (i >= mListeners.length) {
+                MediaTimeProvider.OnMediaTimeListener[] newListeners =
+                    new MediaTimeProvider.OnMediaTimeListener[i + 1];
+                long[] newTimes = new long[i + 1];
+                System.arraycopy(mListeners, 0, newListeners, 0, mListeners.length);
+                System.arraycopy(mTimes, 0, newTimes, 0, mTimes.length);
+                mListeners = newListeners;
+                mTimes = newTimes;
+            }
+
+            if (mListeners[i] == null) {
+                mListeners[i] = listener;
+                mTimes[i] = MediaTimeProvider.NO_TIME;
+            }
+            return i;
+        }
+
+        public void notifyAt(
+                long timeUs, MediaTimeProvider.OnMediaTimeListener listener) {
+            synchronized(this) {
+                if (DEBUG) Log.d(TAG, "notifyAt " + timeUs);
+                mTimes[registerListener(listener)] = timeUs;
+                scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+            }
+        }
+
+        public void scheduleUpdate(MediaTimeProvider.OnMediaTimeListener listener) {
+            synchronized(this) {
+                if (DEBUG) Log.d(TAG, "scheduleUpdate");
+                int i = registerListener(listener);
+
+                if (!mStopped) {
+                    mTimes[i] = 0;
+                    scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+                }
+            }
+        }
+
+        public void cancelNotifications(
+                MediaTimeProvider.OnMediaTimeListener listener) {
+            synchronized(this) {
+                int i = 0;
+                for (; i < mListeners.length; i++) {
+                    if (mListeners[i] == listener) {
+                        System.arraycopy(mListeners, i + 1,
+                                mListeners, i, mListeners.length - i - 1);
+                        System.arraycopy(mTimes, i + 1,
+                                mTimes, i, mTimes.length - i - 1);
+                        mListeners[mListeners.length - 1] = null;
+                        mTimes[mTimes.length - 1] = NO_TIME;
+                        break;
+                    } else if (mListeners[i] == null) {
+                        break;
+                    }
+                }
+
+                scheduleNotification(NOTIFY_TIME, 0 /* delay */);
+            }
+        }
+
+        private synchronized void notifyTimedEvent(boolean refreshTime) {
+            // figure out next callback
+            long nowUs;
+            try {
+                nowUs = getCurrentTimeUs(refreshTime, true);
+            } catch (IllegalStateException e) {
+                // assume we paused until new player arrives
+                mRefresh = true;
+                mPausing = true; // this ensures that call succeeds
+                nowUs = getCurrentTimeUs(refreshTime, true);
+            }
+            long nextTimeUs = nowUs;
+
+            if (mSeeking) {
+                // skip timed-event notifications until seek is complete
+                return;
+            }
+
+            if (DEBUG) {
+                StringBuilder sb = new StringBuilder();
+                sb.append("notifyTimedEvent(").append(mLastTimeUs).append(" -> ")
+                        .append(nowUs).append(") from {");
+                boolean first = true;
+                for (long time: mTimes) {
+                    if (time == NO_TIME) {
+                        continue;
+                    }
+                    if (!first) sb.append(", ");
+                    sb.append(time);
+                    first = false;
+                }
+                sb.append("}");
+                Log.d(TAG, sb.toString());
+            }
+
+            Vector<MediaTimeProvider.OnMediaTimeListener> activatedListeners =
+                new Vector<MediaTimeProvider.OnMediaTimeListener>();
+            for (int ix = 0; ix < mTimes.length; ix++) {
+                if (mListeners[ix] == null) {
+                    break;
+                }
+                if (mTimes[ix] <= NO_TIME) {
+                    // ignore, unless we were stopped
+                } else if (mTimes[ix] <= nowUs + MAX_EARLY_CALLBACK_US) {
+                    activatedListeners.add(mListeners[ix]);
+                    if (DEBUG) Log.d(TAG, "removed");
+                    mTimes[ix] = NO_TIME;
+                } else if (nextTimeUs == nowUs || mTimes[ix] < nextTimeUs) {
+                    nextTimeUs = mTimes[ix];
+                }
+            }
+
+            if (nextTimeUs > nowUs && !mPaused) {
+                // schedule callback at nextTimeUs
+                if (DEBUG) Log.d(TAG, "scheduling for " + nextTimeUs + " and " + nowUs);
+                mPlayer.notifyAt(nextTimeUs);
+            } else {
+                mEventHandler.removeMessages(NOTIFY);
+                // no more callbacks
+            }
+
+            for (MediaTimeProvider.OnMediaTimeListener listener: activatedListeners) {
+                listener.onTimedEvent(nowUs);
+            }
+        }
+
+        public long getCurrentTimeUs(boolean refreshTime, boolean monotonic)
+                throws IllegalStateException {
+            synchronized (this) {
+                // we always refresh the time when the paused-state changes, because
+                // we expect to have received the pause-change event delayed.
+                if (mPaused && !refreshTime) {
+                    return mLastReportedTime;
+                }
+
+                try {
+                    mLastTimeUs = mPlayer.getCurrentPosition() * 1000L;
+                    mPaused = !mPlayer.isPlaying() || mBuffering;
+                    if (DEBUG) Log.v(TAG, (mPaused ? "paused" : "playing") + " at " + mLastTimeUs);
+                } catch (IllegalStateException e) {
+                    if (mPausing) {
+                        // if we were pausing, get last estimated timestamp
+                        mPausing = false;
+                        if (!monotonic || mLastReportedTime < mLastTimeUs) {
+                            mLastReportedTime = mLastTimeUs;
+                        }
+                        mPaused = true;
+                        if (DEBUG) Log.d(TAG, "illegal state, but pausing: estimating at " + mLastReportedTime);
+                        return mLastReportedTime;
+                    }
+                    // TODO get time when prepared
+                    throw e;
+                }
+                if (monotonic && mLastTimeUs < mLastReportedTime) {
+                    /* have to adjust time */
+                    if (mLastReportedTime - mLastTimeUs > 1000000) {
+                        // schedule seeked event if time jumped significantly
+                        // TODO: do this properly by introducing an exception
+                        mStopped = false;
+                        mSeeking = true;
+                        scheduleNotification(NOTIFY_SEEK, 0 /* delay */);
+                    }
+                } else {
+                    mLastReportedTime = mLastTimeUs;
+                }
+
+                return mLastReportedTime;
+            }
+        }
+
+        private class EventHandler extends Handler {
+            public EventHandler(Looper looper) {
+                super(looper);
+            }
+
+            @Override
+            public void handleMessage(Message msg) {
+                if (msg.what == NOTIFY) {
+                    switch (msg.arg1) {
+                    case NOTIFY_TIME:
+                        notifyTimedEvent(true /* refreshTime */);
+                        break;
+                    case NOTIFY_STOP:
+                        notifyStop();
+                        break;
+                    case NOTIFY_SEEK:
+                        notifySeek();
+                        break;
+                    case NOTIFY_TRACK_DATA:
+                        notifyTrackData((Pair<SubtitleTrack, byte[]>)msg.obj);
+                        break;
+                    }
+                }
+            }
+        }
+    }
+
+    public final static class MetricsConstants
+    {
+        private MetricsConstants() {}
+
+        /**
+         * Key to extract the MIME type of the video track
+         * from the {@link MediaPlayer#getMetrics} return value.
+         * The value is a String.
+         */
+        public static final String MIME_TYPE_VIDEO = "android.media.mediaplayer.video.mime";
+
+        /**
+         * Key to extract the codec being used to decode the video track
+         * from the {@link MediaPlayer#getMetrics} return value.
+         * The value is a String.
+         */
+        public static final String CODEC_VIDEO = "android.media.mediaplayer.video.codec";
+
+        /**
+         * Key to extract the width (in pixels) of the video track
+         * from the {@link MediaPlayer#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String WIDTH = "android.media.mediaplayer.width";
+
+        /**
+         * Key to extract the height (in pixels) of the video track
+         * from the {@link MediaPlayer#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String HEIGHT = "android.media.mediaplayer.height";
+
+        /**
+         * Key to extract the count of video frames played
+         * from the {@link MediaPlayer#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String FRAMES = "android.media.mediaplayer.frames";
+
+        /**
+         * Key to extract the count of video frames dropped
+         * from the {@link MediaPlayer#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String FRAMES_DROPPED = "android.media.mediaplayer.dropped";
+
+        /**
+         * Key to extract the MIME type of the audio track
+         * from the {@link MediaPlayer#getMetrics} return value.
+         * The value is a String.
+         */
+        public static final String MIME_TYPE_AUDIO = "android.media.mediaplayer.audio.mime";
+
+        /**
+         * Key to extract the codec being used to decode the audio track
+         * from the {@link MediaPlayer#getMetrics} return value.
+         * The value is a String.
+         */
+        public static final String CODEC_AUDIO = "android.media.mediaplayer.audio.codec";
+
+        /**
+         * Key to extract the duration (in milliseconds) of the
+         * media being played
+         * from the {@link MediaPlayer#getMetrics} return value.
+         * The value is a long.
+         */
+        public static final String DURATION = "android.media.mediaplayer.durationMs";
+
+        /**
+         * Key to extract the playing time (in milliseconds) of the
+         * media being played
+         * from the {@link MediaPlayer#getMetrics} return value.
+         * The value is a long.
+         */
+        public static final String PLAYING = "android.media.mediaplayer.playingMs";
+
+        /**
+         * Key to extract the count of errors encountered while
+         * playing the media
+         * from the {@link MediaPlayer#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String ERRORS = "android.media.mediaplayer.err";
+
+        /**
+         * Key to extract an (optional) error code detected while
+         * playing the media
+         * from the {@link MediaPlayer#getMetrics} return value.
+         * The value is an integer.
+         */
+        public static final String ERROR_CODE = "android.media.mediaplayer.errcode";
+
+    }
+}
diff --git a/android/media/MediaRecorder.java b/android/media/MediaRecorder.java
new file mode 100644
index 0000000..7d80e93
--- /dev/null
+++ b/android/media/MediaRecorder.java
@@ -0,0 +1,2064 @@
+/*
+ * Copyright (C) 2007 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.annotation.CallbackExecutor;
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.app.ActivityThread;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
+import android.content.AttributionSource.ScopedParcelState;
+import android.content.Context;
+import android.hardware.Camera;
+import android.media.metrics.LogSessionId;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.PersistableBundle;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Pair;
+import android.view.Surface;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * Used to record audio and video. The recording control is based on a
+ * simple state machine (see below).
+ *
+ * <p><img src="{@docRoot}images/mediarecorder_state_diagram.gif" border="0" />
+ * </p>
+ *
+ * <p>A common case of using MediaRecorder to record audio works as follows:
+ *
+ * <pre>MediaRecorder recorder = new MediaRecorder();
+ * recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
+ * recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
+ * recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
+ * recorder.setOutputFile(PATH_NAME);
+ * recorder.prepare();
+ * recorder.start();   // Recording is now started
+ * ...
+ * recorder.stop();
+ * recorder.reset();   // You can reuse the object by going back to setAudioSource() step
+ * recorder.release(); // Now the object cannot be reused
+ * </pre>
+ *
+ * <p>Applications may want to register for informational and error
+ * events in order to be informed of some internal update and possible
+ * runtime errors during recording. Registration for such events is
+ * done by setting the appropriate listeners (via calls
+ * (to {@link #setOnInfoListener(OnInfoListener)}setOnInfoListener and/or
+ * {@link #setOnErrorListener(OnErrorListener)}setOnErrorListener).
+ * In order to receive the respective callback associated with these listeners,
+ * applications are required to create MediaRecorder objects on threads with a
+ * Looper running (the main UI thread by default already has a Looper running).
+ *
+ * <p><strong>Note:</strong> Currently, MediaRecorder does not work on the emulator.
+ *
+ * <div class="special reference">
+ * <h3>Developer Guides</h3>
+ * <p>For more information about how to use MediaRecorder for recording video, read the
+ * <a href="{@docRoot}guide/topics/media/camera.html#capture-video">Camera</a> developer guide.
+ * For more information about how to use MediaRecorder for recording sound, read the
+ * <a href="{@docRoot}guide/topics/media/audio-capture.html">Audio Capture</a> developer guide.</p>
+ * </div>
+ */
+public class MediaRecorder implements AudioRouting,
+                                      AudioRecordingMonitor,
+                                      AudioRecordingMonitorClient,
+                                      MicrophoneDirection
+{
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+    private final static String TAG = "MediaRecorder";
+
+    // The two fields below are accessed by native methods
+    @SuppressWarnings("unused")
+    private long mNativeContext;
+
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private Surface mSurface;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private String mPath;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private FileDescriptor mFd;
+    private File mFile;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private EventHandler mEventHandler;
+    @UnsupportedAppUsage
+    private OnErrorListener mOnErrorListener;
+    @UnsupportedAppUsage
+    private OnInfoListener mOnInfoListener;
+
+    private int mChannelCount;
+
+    @NonNull private LogSessionId mLogSessionId = LogSessionId.LOG_SESSION_ID_NONE;
+
+    /**
+     * Default constructor.
+     *
+     * @deprecated Use {@link #MediaRecorder(Context)} instead
+     */
+    @Deprecated
+    public MediaRecorder() {
+        this(ActivityThread.currentApplication());
+    }
+
+    /**
+     * Default constructor.
+     *
+     * @param context Context the recorder belongs to
+     */
+    public MediaRecorder(@NonNull Context context) {
+        Objects.requireNonNull(context);
+        Looper looper;
+        if ((looper = Looper.myLooper()) != null) {
+            mEventHandler = new EventHandler(this, looper);
+        } else if ((looper = Looper.getMainLooper()) != null) {
+            mEventHandler = new EventHandler(this, looper);
+        } else {
+            mEventHandler = null;
+        }
+
+        mChannelCount = 1;
+        /* Native setup requires a weak reference to our object.
+         * It's easier to create it here than in C++.
+         */
+        try (ScopedParcelState attributionSourceState = context.getAttributionSource()
+                .asScopedParcelState()) {
+            native_setup(new WeakReference<>(this), ActivityThread.currentPackageName(),
+                    attributionSourceState.getParcel());
+        }
+    }
+
+    /**
+     * Sets the {@link LogSessionId} for MediaRecorder.
+     *
+     * @param id the global ID for monitoring the MediaRecorder performance
+     */
+    public void setLogSessionId(@NonNull LogSessionId id) {
+        Objects.requireNonNull(id);
+        mLogSessionId = id;
+        setParameter("log-session-id=" + id.getStringId());
+    }
+
+    /**
+     * Returns the {@link LogSessionId} for MediaRecorder.
+     *
+     * @return the global ID for monitoring the MediaRecorder performance
+     */
+    @NonNull
+    public LogSessionId getLogSessionId() {
+        return mLogSessionId;
+    }
+
+    /**
+     * Sets a {@link android.hardware.Camera} to use for recording.
+     *
+     * <p>Use this function to switch quickly between preview and capture mode without a teardown of
+     * the camera object. {@link android.hardware.Camera#unlock()} should be called before
+     * this. Must call before {@link #prepare}.</p>
+     *
+     * @param c the Camera to use for recording
+     * @deprecated Use {@link #getSurface} and the {@link android.hardware.camera2} API instead.
+     */
+    @Deprecated
+    public native void setCamera(Camera c);
+
+    /**
+     * Gets the surface to record from when using SURFACE video source.
+     *
+     * <p> May only be called after {@link #prepare}. Frames rendered to the Surface before
+     * {@link #start} will be discarded.</p>
+     *
+     * @throws IllegalStateException if it is called before {@link #prepare}, after
+     * {@link #stop}, or is called when VideoSource is not set to SURFACE.
+     * @see android.media.MediaRecorder.VideoSource
+     */
+    public native Surface getSurface();
+
+    /**
+     * Configures the recorder to use a persistent surface when using SURFACE video source.
+     * <p> May only be called before {@link #prepare}. If called, {@link #getSurface} should
+     * not be used and will throw IllegalStateException. Frames rendered to the Surface
+     * before {@link #start} will be discarded.</p>
+
+     * @param surface a persistent input surface created by
+     *           {@link MediaCodec#createPersistentInputSurface}
+     * @throws IllegalStateException if it is called after {@link #prepare} and before
+     * {@link #stop}.
+     * @throws IllegalArgumentException if the surface was not created by
+     *           {@link MediaCodec#createPersistentInputSurface}.
+     * @see MediaCodec#createPersistentInputSurface
+     * @see MediaRecorder.VideoSource
+     */
+    public void setInputSurface(@NonNull Surface surface) {
+        if (!(surface instanceof MediaCodec.PersistentSurface)) {
+            throw new IllegalArgumentException("not a PersistentSurface");
+        }
+        native_setInputSurface(surface);
+    }
+
+    private native final void native_setInputSurface(@NonNull Surface surface);
+
+    /**
+     * Sets a Surface to show a preview of recorded media (video). Calls this
+     * before prepare() to make sure that the desirable preview display is
+     * set. If {@link #setCamera(Camera)} is used and the surface has been
+     * already set to the camera, application do not need to call this. If
+     * this is called with non-null surface, the preview surface of the camera
+     * will be replaced by the new surface. If this method is called with null
+     * surface or not called at all, media recorder will not change the preview
+     * surface of the camera.
+     *
+     * @param sv the Surface to use for the preview
+     * @see android.hardware.Camera#setPreviewDisplay(android.view.SurfaceHolder)
+     */
+    public void setPreviewDisplay(Surface sv) {
+        mSurface = sv;
+    }
+
+    /**
+     * Defines the audio source.
+     * An audio source defines both a default physical source of audio signal, and a recording
+     * configuration. These constants are for instance used
+     * in {@link MediaRecorder#setAudioSource(int)} or
+     * {@link AudioRecord.Builder#setAudioSource(int)}.
+     */
+    public final class AudioSource {
+
+        private AudioSource() {}
+
+        /** @hide */
+        public final static int AUDIO_SOURCE_INVALID = -1;
+
+      /* Do not change these values without updating their counterparts
+       * in system/media/audio/include/system/audio.h!
+       */
+
+        /** Default audio source **/
+        public static final int DEFAULT = 0;
+
+        /** Microphone audio source */
+        public static final int MIC = 1;
+
+        /** Voice call uplink (Tx) audio source.
+         * <p>
+         * Capturing from <code>VOICE_UPLINK</code> source requires the
+         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
+         * This permission is reserved for use by system components and is not available to
+         * third-party applications.
+         * </p>
+         */
+        public static final int VOICE_UPLINK = 2;
+
+        /** Voice call downlink (Rx) audio source.
+         * <p>
+         * Capturing from <code>VOICE_DOWNLINK</code> source requires the
+         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
+         * This permission is reserved for use by system components and is not available to
+         * third-party applications.
+         * </p>
+         */
+        public static final int VOICE_DOWNLINK = 3;
+
+        /** Voice call uplink + downlink audio source
+         * <p>
+         * Capturing from <code>VOICE_CALL</code> source requires the
+         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
+         * This permission is reserved for use by system components and is not available to
+         * third-party applications.
+         * </p>
+         */
+        public static final int VOICE_CALL = 4;
+
+        /** Microphone audio source tuned for video recording, with the same orientation
+         *  as the camera if available. */
+        public static final int CAMCORDER = 5;
+
+        /** Microphone audio source tuned for voice recognition. */
+        public static final int VOICE_RECOGNITION = 6;
+
+        /** Microphone audio source tuned for voice communications such as VoIP. It
+         *  will for instance take advantage of echo cancellation or automatic gain control
+         *  if available.
+         */
+        public static final int VOICE_COMMUNICATION = 7;
+
+        /**
+         * Audio source for a submix of audio streams to be presented remotely.
+         * <p>
+         * An application can use this audio source to capture a mix of audio streams
+         * that should be transmitted to a remote receiver such as a Wifi display.
+         * While recording is active, these audio streams are redirected to the remote
+         * submix instead of being played on the device speaker or headset.
+         * </p><p>
+         * Certain streams are excluded from the remote submix, including
+         * {@link AudioManager#STREAM_RING}, {@link AudioManager#STREAM_ALARM},
+         * and {@link AudioManager#STREAM_NOTIFICATION}.  These streams will continue
+         * to be presented locally as usual.
+         * </p><p>
+         * Capturing the remote submix audio requires the
+         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
+         * This permission is reserved for use by system components and is not available to
+         * third-party applications.
+         * </p>
+         */
+        @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)
+        public static final int REMOTE_SUBMIX = 8;
+
+        /** Microphone audio source tuned for unprocessed (raw) sound if available, behaves like
+         *  {@link #DEFAULT} otherwise. */
+        public static final int UNPROCESSED = 9;
+
+
+        /**
+         * Source for capturing audio meant to be processed in real time and played back for live
+         * performance (e.g karaoke).
+         * <p>
+         * The capture path will minimize latency and coupling with
+         * playback path.
+         * </p>
+         */
+        public static final int VOICE_PERFORMANCE = 10;
+
+        /**
+         * Source for an echo canceller to capture the reference signal to be cancelled.
+         * <p>
+         * The echo reference signal will be captured as close as possible to the DAC in order
+         * to include all post processing applied to the playback path.
+         * </p><p>
+         * Capturing the echo reference requires the
+         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
+         * This permission is reserved for use by system components and is not available to
+         * third-party applications.
+         * </p>
+         * @hide
+         */
+        @SystemApi
+        @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)
+        public static final int ECHO_REFERENCE = 1997;
+
+        /**
+         * Audio source for capturing broadcast radio tuner output.
+         * Capturing the radio tuner output requires the
+         * {@link android.Manifest.permission#CAPTURE_AUDIO_OUTPUT} permission.
+         * This permission is reserved for use by system components and is not available to
+         * third-party applications.
+         * @hide
+         */
+        @SystemApi
+        @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_OUTPUT)
+        public static final int RADIO_TUNER = 1998;
+
+        /**
+         * Audio source for preemptible, low-priority software hotword detection
+         * It presents the same gain and pre-processing tuning as {@link #VOICE_RECOGNITION}.
+         * <p>
+         * An application should use this audio source when it wishes to do
+         * always-on software hotword detection, while gracefully giving in to any other application
+         * that might want to read from the microphone.
+         * </p>
+         * This is a hidden audio source.
+         * @hide
+         */
+        @SystemApi
+        @RequiresPermission(android.Manifest.permission.CAPTURE_AUDIO_HOTWORD)
+        public static final int HOTWORD = 1999;
+    }
+
+    /** @hide */
+    @IntDef({
+        AudioSource.DEFAULT,
+        AudioSource.MIC,
+        AudioSource.VOICE_UPLINK,
+        AudioSource.VOICE_DOWNLINK,
+        AudioSource.VOICE_CALL,
+        AudioSource.CAMCORDER,
+        AudioSource.VOICE_RECOGNITION,
+        AudioSource.VOICE_COMMUNICATION,
+        AudioSource.UNPROCESSED,
+        AudioSource.VOICE_PERFORMANCE,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Source {}
+
+    /** @hide */
+    @IntDef({
+        AudioSource.DEFAULT,
+        AudioSource.MIC,
+        AudioSource.VOICE_UPLINK,
+        AudioSource.VOICE_DOWNLINK,
+        AudioSource.VOICE_CALL,
+        AudioSource.CAMCORDER,
+        AudioSource.VOICE_RECOGNITION,
+        AudioSource.VOICE_COMMUNICATION,
+        AudioSource.REMOTE_SUBMIX,
+        AudioSource.UNPROCESSED,
+        AudioSource.VOICE_PERFORMANCE,
+        AudioSource.ECHO_REFERENCE,
+        AudioSource.RADIO_TUNER,
+        AudioSource.HOTWORD,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SystemSource {}
+
+    // TODO make AudioSource static (API change) and move this method inside the AudioSource class
+    /**
+     * @hide
+     * @param source An audio source to test
+     * @return true if the source is only visible to system components
+     */
+    public static boolean isSystemOnlyAudioSource(int source) {
+        switch(source) {
+        case AudioSource.DEFAULT:
+        case AudioSource.MIC:
+        case AudioSource.VOICE_UPLINK:
+        case AudioSource.VOICE_DOWNLINK:
+        case AudioSource.VOICE_CALL:
+        case AudioSource.CAMCORDER:
+        case AudioSource.VOICE_RECOGNITION:
+        case AudioSource.VOICE_COMMUNICATION:
+        //case REMOTE_SUBMIX:  considered "system" as it requires system permissions
+        case AudioSource.UNPROCESSED:
+        case AudioSource.VOICE_PERFORMANCE:
+            return false;
+        default:
+            return true;
+        }
+    }
+
+    /**
+     * @hide
+     * @param source An audio source to test
+     * @return true if the source is a valid one
+     */
+    public static boolean isValidAudioSource(int source) {
+        switch(source) {
+            case AudioSource.MIC:
+            case AudioSource.VOICE_UPLINK:
+            case AudioSource.VOICE_DOWNLINK:
+            case AudioSource.VOICE_CALL:
+            case AudioSource.CAMCORDER:
+            case AudioSource.VOICE_RECOGNITION:
+            case AudioSource.VOICE_COMMUNICATION:
+            case AudioSource.REMOTE_SUBMIX:
+            case AudioSource.UNPROCESSED:
+            case AudioSource.VOICE_PERFORMANCE:
+            case AudioSource.ECHO_REFERENCE:
+            case AudioSource.RADIO_TUNER:
+            case AudioSource.HOTWORD:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /** @hide */
+    public static final String toLogFriendlyAudioSource(int source) {
+        switch(source) {
+        case AudioSource.DEFAULT:
+            return "DEFAULT";
+        case AudioSource.MIC:
+            return "MIC";
+        case AudioSource.VOICE_UPLINK:
+            return "VOICE_UPLINK";
+        case AudioSource.VOICE_DOWNLINK:
+            return "VOICE_DOWNLINK";
+        case AudioSource.VOICE_CALL:
+            return "VOICE_CALL";
+        case AudioSource.CAMCORDER:
+            return "CAMCORDER";
+        case AudioSource.VOICE_RECOGNITION:
+            return "VOICE_RECOGNITION";
+        case AudioSource.VOICE_COMMUNICATION:
+            return "VOICE_COMMUNICATION";
+        case AudioSource.REMOTE_SUBMIX:
+            return "REMOTE_SUBMIX";
+        case AudioSource.UNPROCESSED:
+            return "UNPROCESSED";
+        case AudioSource.ECHO_REFERENCE:
+            return "ECHO_REFERENCE";
+        case AudioSource.VOICE_PERFORMANCE:
+            return "VOICE_PERFORMANCE";
+        case AudioSource.RADIO_TUNER:
+            return "RADIO_TUNER";
+        case AudioSource.HOTWORD:
+            return "HOTWORD";
+        case AudioSource.AUDIO_SOURCE_INVALID:
+            return "AUDIO_SOURCE_INVALID";
+        default:
+            return "unknown source " + source;
+        }
+    }
+
+    /**
+     * Defines the video source. These constants are used with
+     * {@link MediaRecorder#setVideoSource(int)}.
+     */
+    public final class VideoSource {
+      /* Do not change these values without updating their counterparts
+       * in include/media/mediarecorder.h!
+       */
+        private VideoSource() {}
+        public static final int DEFAULT = 0;
+        /** Camera video source
+         * <p>
+         * Using the {@link android.hardware.Camera} API as video source.
+         * </p>
+         */
+        public static final int CAMERA = 1;
+        /** Surface video source
+         * <p>
+         * Using a Surface as video source.
+         * </p><p>
+         * This flag must be used when recording from an
+         * {@link android.hardware.camera2} API source.
+         * </p><p>
+         * When using this video source type, use {@link MediaRecorder#getSurface()}
+         * to retrieve the surface created by MediaRecorder.
+         */
+        public static final int SURFACE = 2;
+    }
+
+    /**
+     * Defines the output format. These constants are used with
+     * {@link MediaRecorder#setOutputFormat(int)}.
+     */
+    public final class OutputFormat {
+      /* Do not change these values without updating their counterparts
+       * in include/media/mediarecorder.h!
+       */
+        private OutputFormat() {}
+        public static final int DEFAULT = 0;
+        /** 3GPP media file format*/
+        public static final int THREE_GPP = 1;
+        /** MPEG4 media file format*/
+        public static final int MPEG_4 = 2;
+
+        /** The following formats are audio only .aac or .amr formats */
+
+        /**
+         * AMR NB file format
+         * @deprecated  Deprecated in favor of MediaRecorder.OutputFormat.AMR_NB
+         */
+        public static final int RAW_AMR = 3;
+
+        /** AMR NB file format */
+        public static final int AMR_NB = 3;
+
+        /** AMR WB file format */
+        public static final int AMR_WB = 4;
+
+        /** @hide AAC ADIF file format */
+        public static final int AAC_ADIF = 5;
+
+        /** AAC ADTS file format */
+        public static final int AAC_ADTS = 6;
+
+        /** @hide Stream over a socket, limited to a single stream */
+        public static final int OUTPUT_FORMAT_RTP_AVP = 7;
+
+        /** H.264/AAC data encapsulated in MPEG2/TS */
+        public static final int MPEG_2_TS = 8;
+
+        /** VP8/VORBIS data in a WEBM container */
+        public static final int WEBM = 9;
+
+        /** @hide HEIC data in a HEIF container */
+        public static final int HEIF = 10;
+
+        /** Opus data in a Ogg container */
+        public static final int OGG = 11;
+    };
+
+    /**
+     * @hide
+     */
+    @IntDef({
+        OutputFormat.DEFAULT,
+        OutputFormat.THREE_GPP,
+        OutputFormat.MPEG_4,
+        OutputFormat.AMR_NB,
+        OutputFormat.AMR_WB,
+        OutputFormat.AAC_ADIF,
+        OutputFormat.AAC_ADTS,
+        OutputFormat.MPEG_2_TS,
+        OutputFormat.WEBM,
+        OutputFormat.HEIF,
+        OutputFormat.OGG,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface OutputFormatValues {}
+
+    /**
+     * Defines the audio encoding. These constants are used with
+     * {@link MediaRecorder#setAudioEncoder(int)}.
+     */
+    public final class AudioEncoder {
+      /* Do not change these values without updating their counterparts
+       * in include/media/mediarecorder.h!
+       */
+        private AudioEncoder() {}
+        public static final int DEFAULT = 0;
+        /** AMR (Narrowband) audio codec */
+        public static final int AMR_NB = 1;
+        /** AMR (Wideband) audio codec */
+        public static final int AMR_WB = 2;
+        /** AAC Low Complexity (AAC-LC) audio codec */
+        public static final int AAC = 3;
+        /** High Efficiency AAC (HE-AAC) audio codec */
+        public static final int HE_AAC = 4;
+        /** Enhanced Low Delay AAC (AAC-ELD) audio codec */
+        public static final int AAC_ELD = 5;
+        /** Ogg Vorbis audio codec (Support is optional) */
+        public static final int VORBIS = 6;
+        /** Opus audio codec */
+        public static final int OPUS = 7;
+    }
+
+    /**
+     * @hide
+     */
+    @IntDef({
+        AudioEncoder.DEFAULT,
+        AudioEncoder.AMR_NB,
+        AudioEncoder.AMR_WB,
+        AudioEncoder.AAC,
+        AudioEncoder.HE_AAC,
+        AudioEncoder.AAC_ELD,
+        AudioEncoder.VORBIS,
+        AudioEncoder.OPUS,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioEncoderValues {}
+
+    /**
+     * Defines the video encoding. These constants are used with
+     * {@link MediaRecorder#setVideoEncoder(int)}.
+     */
+    public final class VideoEncoder {
+      /* Do not change these values without updating their counterparts
+       * in include/media/mediarecorder.h!
+       */
+        private VideoEncoder() {}
+        public static final int DEFAULT = 0;
+        public static final int H263 = 1;
+        public static final int H264 = 2;
+        public static final int MPEG_4_SP = 3;
+        public static final int VP8 = 4;
+        public static final int HEVC = 5;
+    }
+
+    /**
+     * @hide
+     */
+    @IntDef({
+        VideoEncoder.DEFAULT,
+        VideoEncoder.H263,
+        VideoEncoder.H264,
+        VideoEncoder.MPEG_4_SP,
+        VideoEncoder.VP8,
+        VideoEncoder.HEVC,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface VideoEncoderValues {}
+
+    /**
+     * Sets the audio source to be used for recording. If this method is not
+     * called, the output file will not contain an audio track. The source needs
+     * to be specified before setting recording-parameters or encoders. Call
+     * this only before setOutputFormat().
+     *
+     * @param audioSource the audio source to use
+     * @throws IllegalStateException if it is called after setOutputFormat()
+     * @see android.media.MediaRecorder.AudioSource
+     */
+    public native void setAudioSource(@Source int audioSource)
+            throws IllegalStateException;
+
+    /**
+     * Gets the maximum value for audio sources.
+     * @see android.media.MediaRecorder.AudioSource
+     */
+    public static final int getAudioSourceMax() {
+        return AudioSource.VOICE_PERFORMANCE;
+    }
+
+    /**
+     * Indicates that this capture request is privacy sensitive and that
+     * any concurrent capture is not permitted.
+     * <p>
+     * The default is not privacy sensitive except when the audio source set with
+     * {@link #setAudioSource(int)} is {@link AudioSource#VOICE_COMMUNICATION} or
+     * {@link AudioSource#CAMCORDER}.
+     * <p>
+     * Always takes precedence over default from audio source when set explicitly.
+     * <p>
+     * Using this API is only permitted when the audio source is one of:
+     * <ul>
+     * <li>{@link AudioSource#MIC}</li>
+     * <li>{@link AudioSource#CAMCORDER}</li>
+     * <li>{@link AudioSource#VOICE_RECOGNITION}</li>
+     * <li>{@link AudioSource#VOICE_COMMUNICATION}</li>
+     * <li>{@link AudioSource#UNPROCESSED}</li>
+     * <li>{@link AudioSource#VOICE_PERFORMANCE}</li>
+     * </ul>
+     * Invoking {@link #prepare()} will throw an IOException if this
+     * condition is not met.
+     * <p>
+     * Must be called after {@link #setAudioSource(int)} and before {@link #setOutputFormat(int)}.
+     * @param privacySensitive True if capture from this MediaRecorder must be marked as privacy
+     * sensitive, false otherwise.
+     * @throws IllegalStateException if called before {@link #setAudioSource(int)}
+     * or after {@link #setOutputFormat(int)}
+     */
+    public native void setPrivacySensitive(boolean privacySensitive);
+
+    /**
+     * Returns whether this MediaRecorder is marked as privacy sensitive or not with
+     * regard to audio capture.
+     * <p>
+     * See {@link #setPrivacySensitive(boolean)}
+     * <p>
+     * @return true if privacy sensitive, false otherwise
+     */
+    public native boolean isPrivacySensitive();
+
+    /**
+     * Sets the video source to be used for recording. If this method is not
+     * called, the output file will not contain an video track. The source needs
+     * to be specified before setting recording-parameters or encoders. Call
+     * this only before setOutputFormat().
+     *
+     * @param video_source the video source to use
+     * @throws IllegalStateException if it is called after setOutputFormat()
+     * @see android.media.MediaRecorder.VideoSource
+     */
+    public native void setVideoSource(int video_source)
+            throws IllegalStateException;
+
+    /**
+     * Uses the settings from a CamcorderProfile object for recording. This method should
+     * be called after the video AND audio sources are set, and before setOutputFile().
+     * If a time lapse CamcorderProfile is used, audio related source or recording
+     * parameters are ignored.
+     *
+     * @param profile the CamcorderProfile to use
+     * @see android.media.CamcorderProfile
+     */
+    public void setProfile(CamcorderProfile profile) {
+        setOutputFormat(profile.fileFormat);
+        setVideoFrameRate(profile.videoFrameRate);
+        setVideoSize(profile.videoFrameWidth, profile.videoFrameHeight);
+        setVideoEncodingBitRate(profile.videoBitRate);
+        setVideoEncoder(profile.videoCodec);
+        if (profile.quality >= CamcorderProfile.QUALITY_TIME_LAPSE_LOW &&
+             profile.quality <= CamcorderProfile.QUALITY_TIME_LAPSE_QVGA) {
+            // Nothing needs to be done. Call to setCaptureRate() enables
+            // time lapse video recording.
+        } else {
+            setAudioEncodingBitRate(profile.audioBitRate);
+            setAudioChannels(profile.audioChannels);
+            setAudioSamplingRate(profile.audioSampleRate);
+            setAudioEncoder(profile.audioCodec);
+        }
+    }
+
+    /**
+     * Uses the settings from an AudioProfile for recording.
+     * <p>
+     * This method should be called after the video AND audio sources are set, and before
+     * setOutputFile().
+     * <p>
+     * This method can be used instead of {@link #setProfile} when using EncoderProfiles.
+     *
+     * @param profile the AudioProfile to use
+     * @see android.media.EncoderProfiles
+     * @see android.media.CamcorderProfile#getAll
+     */
+    public void setAudioProfile(@NonNull EncoderProfiles.AudioProfile profile) {
+        setAudioEncodingBitRate(profile.getBitrate());
+        setAudioChannels(profile.getChannels());
+        setAudioSamplingRate(profile.getSampleRate());
+        setAudioEncoder(profile.getCodec());
+    }
+
+    /**
+     * Uses the settings from a VideoProfile object for recording.
+     * <p>
+     * This method should be called after the video AND audio sources are set, and before
+     * setOutputFile().
+     * <p>
+     * This method can be used instead of {@link #setProfile} when using EncoderProfiles.
+     *
+     * @param profile the VideoProfile to use
+     * @see android.media.EncoderProfiles
+     * @see android.media.CamcorderProfile#getAll
+     */
+    public void setVideoProfile(@NonNull EncoderProfiles.VideoProfile profile) {
+        setVideoFrameRate(profile.getFrameRate());
+        setVideoSize(profile.getWidth(), profile.getHeight());
+        setVideoEncodingBitRate(profile.getBitrate());
+        setVideoEncoder(profile.getCodec());
+        if (profile.getProfile() >= 0) {
+            setVideoEncodingProfileLevel(profile.getProfile(), 0 /* level */);
+        }
+    }
+
+    /**
+     * Set video frame capture rate. This can be used to set a different video frame capture
+     * rate than the recorded video's playback rate. This method also sets the recording mode
+     * to time lapse. In time lapse video recording, only video is recorded. Audio related
+     * parameters are ignored when a time lapse recording session starts, if an application
+     * sets them.
+     *
+     * @param fps Rate at which frames should be captured in frames per second.
+     * The fps can go as low as desired. However the fastest fps will be limited by the hardware.
+     * For resolutions that can be captured by the video camera, the fastest fps can be computed using
+     * {@link android.hardware.Camera.Parameters#getPreviewFpsRange(int[])}. For higher
+     * resolutions the fastest fps may be more restrictive.
+     * Note that the recorder cannot guarantee that frames will be captured at the
+     * given rate due to camera/encoder limitations. However it tries to be as close as
+     * possible.
+     */
+    public void setCaptureRate(double fps) {
+        // Make sure that time lapse is enabled when this method is called.
+        setParameter("time-lapse-enable=1");
+        setParameter("time-lapse-fps=" + fps);
+    }
+
+    /**
+     * Sets the orientation hint for output video playback.
+     * This method should be called before prepare(). This method will not
+     * trigger the source video frame to rotate during video recording, but to
+     * add a composition matrix containing the rotation angle in the output
+     * video if the output format is OutputFormat.THREE_GPP or
+     * OutputFormat.MPEG_4 so that a video player can choose the proper
+     * orientation for playback. Note that some video players may choose
+     * to ignore the compostion matrix in a video during playback.
+     *
+     * @param degrees the angle to be rotated clockwise in degrees.
+     * The supported angles are 0, 90, 180, and 270 degrees.
+     * @throws IllegalArgumentException if the angle is not supported.
+     *
+     */
+    public void setOrientationHint(int degrees) {
+        if (degrees != 0   &&
+            degrees != 90  &&
+            degrees != 180 &&
+            degrees != 270) {
+            throw new IllegalArgumentException("Unsupported angle: " + degrees);
+        }
+        setParameter("video-param-rotation-angle-degrees=" + degrees);
+    }
+
+    /**
+     * Set and store the geodata (latitude and longitude) in the output file.
+     * This method should be called before prepare(). The geodata is
+     * stored in udta box if the output format is OutputFormat.THREE_GPP
+     * or OutputFormat.MPEG_4, and is ignored for other output formats.
+     * The geodata is stored according to ISO-6709 standard.
+     *
+     * @param latitude latitude in degrees. Its value must be in the
+     * range [-90, 90].
+     * @param longitude longitude in degrees. Its value must be in the
+     * range [-180, 180].
+     *
+     * @throws IllegalArgumentException if the given latitude or
+     * longitude is out of range.
+     *
+     */
+    public void setLocation(float latitude, float longitude) {
+        int latitudex10000  = (int) (latitude * 10000 + 0.5);
+        int longitudex10000 = (int) (longitude * 10000 + 0.5);
+
+        if (latitudex10000 > 900000 || latitudex10000 < -900000) {
+            String msg = "Latitude: " + latitude + " out of range.";
+            throw new IllegalArgumentException(msg);
+        }
+        if (longitudex10000 > 1800000 || longitudex10000 < -1800000) {
+            String msg = "Longitude: " + longitude + " out of range";
+            throw new IllegalArgumentException(msg);
+        }
+
+        setParameter("param-geotag-latitude=" + latitudex10000);
+        setParameter("param-geotag-longitude=" + longitudex10000);
+    }
+
+    /**
+     * Sets the format of the output file produced during recording. Call this
+     * after setAudioSource()/setVideoSource() but before prepare().
+     *
+     * <p>It is recommended to always use 3GP format when using the H.263
+     * video encoder and AMR audio encoder. Using an MPEG-4 container format
+     * may confuse some desktop players.</p>
+     *
+     * @param output_format the output format to use. The output format
+     * needs to be specified before setting recording-parameters or encoders.
+     * @throws IllegalStateException if it is called after prepare() or before
+     * setAudioSource()/setVideoSource().
+     * @see android.media.MediaRecorder.OutputFormat
+     */
+    public native void setOutputFormat(@OutputFormatValues int output_format)
+            throws IllegalStateException;
+
+    /**
+     * Sets the width and height of the video to be captured.  Must be called
+     * after setVideoSource(). Call this after setOutputFormat() but before
+     * prepare().
+     *
+     * @param width the width of the video to be captured
+     * @param height the height of the video to be captured
+     * @throws IllegalStateException if it is called after
+     * prepare() or before setOutputFormat()
+     */
+    public native void setVideoSize(int width, int height)
+            throws IllegalStateException;
+
+    /**
+     * Sets the frame rate of the video to be captured.  Must be called
+     * after setVideoSource(). Call this after setOutputFormat() but before
+     * prepare().
+     *
+     * @param rate the number of frames per second of video to capture
+     * @throws IllegalStateException if it is called after
+     * prepare() or before setOutputFormat().
+     *
+     * NOTE: On some devices that have auto-frame rate, this sets the
+     * maximum frame rate, not a constant frame rate. Actual frame rate
+     * will vary according to lighting conditions.
+     */
+    public native void setVideoFrameRate(int rate) throws IllegalStateException;
+
+    /**
+     * Sets the maximum duration (in ms) of the recording session.
+     * Call this after setOutputFormat() but before prepare().
+     * After recording reaches the specified duration, a notification
+     * will be sent to the {@link android.media.MediaRecorder.OnInfoListener}
+     * with a "what" code of {@link #MEDIA_RECORDER_INFO_MAX_DURATION_REACHED}
+     * and recording will be stopped. Stopping happens asynchronously, there
+     * is no guarantee that the recorder will have stopped by the time the
+     * listener is notified.
+     *
+     * <p>When using MPEG-4 container ({@link #setOutputFormat(int)} with
+     * {@link OutputFormat#MPEG_4}), it is recommended to set maximum duration that fits the use
+     * case. Setting a larger than required duration may result in a larger than needed output file
+     * because of space reserved for MOOV box expecting large movie data in this recording session.
+     *  Unused space of MOOV box is turned into FREE box in the output file.</p>
+     *
+     * @param max_duration_ms the maximum duration in ms (if zero or negative, disables the duration limit)
+     *
+     */
+    public native void setMaxDuration(int max_duration_ms) throws IllegalArgumentException;
+
+    /**
+     * Sets the maximum filesize (in bytes) of the recording session.
+     * Call this after setOutputFormat() but before prepare().
+     * After recording reaches the specified filesize, a notification
+     * will be sent to the {@link android.media.MediaRecorder.OnInfoListener}
+     * with a "what" code of {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED}
+     * and recording will be stopped. Stopping happens asynchronously, there
+     * is no guarantee that the recorder will have stopped by the time the
+     * listener is notified.
+     *
+     * <p>When using MPEG-4 container ({@link #setOutputFormat(int)} with
+     * {@link OutputFormat#MPEG_4}), it is recommended to set maximum filesize that fits the use
+     * case. Setting a larger than required filesize may result in a larger than needed output file
+     * because of space reserved for MOOV box expecting large movie data in this recording session.
+     * Unused space of MOOV box is turned into FREE box in the output file.</p>
+     *
+     * @param max_filesize_bytes the maximum filesize in bytes (if zero or negative, disables the limit)
+     *
+     */
+    public native void setMaxFileSize(long max_filesize_bytes) throws IllegalArgumentException;
+
+    /**
+     * Sets the audio encoder to be used for recording. If this method is not
+     * called, the output file will not contain an audio track. Call this after
+     * setOutputFormat() but before prepare().
+     *
+     * @param audio_encoder the audio encoder to use.
+     * @throws IllegalStateException if it is called before
+     * setOutputFormat() or after prepare().
+     * @see android.media.MediaRecorder.AudioEncoder
+     */
+    public native void setAudioEncoder(@AudioEncoderValues int audio_encoder)
+            throws IllegalStateException;
+
+    /**
+     * Sets the video encoder to be used for recording. If this method is not
+     * called, the output file will not contain an video track. Call this after
+     * setOutputFormat() and before prepare().
+     *
+     * @param video_encoder the video encoder to use.
+     * @throws IllegalStateException if it is called before
+     * setOutputFormat() or after prepare()
+     * @see android.media.MediaRecorder.VideoEncoder
+     */
+    public native void setVideoEncoder(@VideoEncoderValues int video_encoder)
+            throws IllegalStateException;
+
+    /**
+     * Sets the audio sampling rate for recording. Call this method before prepare().
+     * Prepare() may perform additional checks on the parameter to make sure whether
+     * the specified audio sampling rate is applicable. The sampling rate really depends
+     * on the format for the audio recording, as well as the capabilities of the platform.
+     * For instance, the sampling rate supported by AAC audio coding standard ranges
+     * from 8 to 96 kHz, the sampling rate supported by AMRNB is 8kHz, and the sampling
+     * rate supported by AMRWB is 16kHz. Please consult with the related audio coding
+     * standard for the supported audio sampling rate.
+     *
+     * @param samplingRate the sampling rate for audio in samples per second.
+     */
+    public void setAudioSamplingRate(int samplingRate) {
+        if (samplingRate <= 0) {
+            throw new IllegalArgumentException("Audio sampling rate is not positive");
+        }
+        setParameter("audio-param-sampling-rate=" + samplingRate);
+    }
+
+    /**
+     * Sets the number of audio channels for recording. Call this method before prepare().
+     * Prepare() may perform additional checks on the parameter to make sure whether the
+     * specified number of audio channels are applicable.
+     *
+     * @param numChannels the number of audio channels. Usually it is either 1 (mono) or 2
+     * (stereo).
+     */
+    public void setAudioChannels(int numChannels) {
+        if (numChannels <= 0) {
+            throw new IllegalArgumentException("Number of channels is not positive");
+        }
+        mChannelCount = numChannels;
+        setParameter("audio-param-number-of-channels=" + numChannels);
+    }
+
+    /**
+     * Sets the audio encoding bit rate for recording. Call this method before prepare().
+     * Prepare() may perform additional checks on the parameter to make sure whether the
+     * specified bit rate is applicable, and sometimes the passed bitRate will be clipped
+     * internally to ensure the audio recording can proceed smoothly based on the
+     * capabilities of the platform.
+     *
+     * @param bitRate the audio encoding bit rate in bits per second.
+     */
+    public void setAudioEncodingBitRate(int bitRate) {
+        if (bitRate <= 0) {
+            throw new IllegalArgumentException("Audio encoding bit rate is not positive");
+        }
+        setParameter("audio-param-encoding-bitrate=" + bitRate);
+    }
+
+    /**
+     * Sets the video encoding bit rate for recording. Call this method before prepare().
+     * Prepare() may perform additional checks on the parameter to make sure whether the
+     * specified bit rate is applicable, and sometimes the passed bitRate will be
+     * clipped internally to ensure the video recording can proceed smoothly based on
+     * the capabilities of the platform.
+     *
+     * <p>
+     * NB: the actual bitrate and other encoding characteristics may be affected by
+     * the minimum quality floor behavior introduced in
+     * {@link android.os.Build.VERSION_CODES#S}. More detail on how and where this
+     * impacts video encoding can be found in the
+     * {@link MediaCodec} page and looking for "quality floor" (near the top of the page).
+     *
+     * @param bitRate the video encoding bit rate in bits per second.
+     */
+    public void setVideoEncodingBitRate(int bitRate) {
+        if (bitRate <= 0) {
+            throw new IllegalArgumentException("Video encoding bit rate is not positive");
+        }
+        setParameter("video-param-encoding-bitrate=" + bitRate);
+    }
+
+    /**
+     * Sets the desired video encoding profile and level for recording. The profile and level
+     * must be valid for the video encoder set by {@link #setVideoEncoder}. This method can
+     * called before or after {@link #setVideoEncoder} but it must be called before {@link #prepare}.
+     * {@code prepare()} may perform additional checks on the parameter to make sure that the specified
+     * profile and level are applicable, and sometimes the passed profile or level will be
+     * discarded due to codec capablity or to ensure the video recording can proceed smoothly
+     * based on the capabilities of the platform. <br>Application can also use the
+     * {@link MediaCodecInfo.CodecCapabilities#profileLevels} to query applicable combination of profile
+     * and level for the corresponding format. Note that the requested profile/level may not be supported by
+     * the codec that is actually being used by this MediaRecorder instance.
+     * @param profile declared in {@link MediaCodecInfo.CodecProfileLevel}.
+     * @param level declared in {@link MediaCodecInfo.CodecProfileLevel}.
+     * @throws IllegalArgumentException when an invalid profile or level value is used.
+     */
+    public void setVideoEncodingProfileLevel(int profile, int level) {
+        if (profile < 0)  {
+            throw new IllegalArgumentException("Video encoding profile is not positive");
+        }
+        if (level < 0)  {
+            throw new IllegalArgumentException("Video encoding level is not positive");
+        }
+        setParameter("video-param-encoder-profile=" + profile);
+        setParameter("video-param-encoder-level=" + level);
+    }
+
+    /**
+     * Currently not implemented. It does nothing.
+     * @deprecated Time lapse mode video recording using camera still image capture
+     * is not desirable, and will not be supported.
+     * @hide
+     */
+    public void setAuxiliaryOutputFile(FileDescriptor fd)
+    {
+        Log.w(TAG, "setAuxiliaryOutputFile(FileDescriptor) is no longer supported.");
+    }
+
+    /**
+     * Currently not implemented. It does nothing.
+     * @deprecated Time lapse mode video recording using camera still image capture
+     * is not desirable, and will not be supported.
+     * @hide
+     */
+    public void setAuxiliaryOutputFile(String path)
+    {
+        Log.w(TAG, "setAuxiliaryOutputFile(String) is no longer supported.");
+    }
+
+    /**
+     * Pass in the file descriptor of the file to be written. Call this after
+     * setOutputFormat() but before prepare().
+     *
+     * @param fd an open file descriptor to be written into.
+     * @throws IllegalStateException if it is called before
+     * setOutputFormat() or after prepare()
+     */
+    public void setOutputFile(FileDescriptor fd) throws IllegalStateException
+    {
+        mPath = null;
+        mFile = null;
+        mFd = fd;
+    }
+
+    /**
+     * Pass in the file object to be written. Call this after setOutputFormat() but before prepare().
+     * File should be seekable. After setting the next output file, application should not use the
+     * file until {@link #stop}. Application is responsible for cleaning up unused files after
+     * {@link #stop} is called.
+     *
+     * @param file the file object to be written into.
+     */
+    public void setOutputFile(File file)
+    {
+        mPath = null;
+        mFd = null;
+        mFile = file;
+    }
+
+    /**
+     * Sets the next output file descriptor to be used when the maximum filesize is reached
+     * on the prior output {@link #setOutputFile} or {@link #setNextOutputFile}). File descriptor
+     * must be seekable and writable. After setting the next output file, application should not
+     * use the file referenced by this file descriptor until {@link #stop}. It is the application's
+     * responsibility to close the file descriptor. It is safe to do so as soon as this call returns.
+     * Application must call this after receiving on the
+     * {@link android.media.MediaRecorder.OnInfoListener} a "what" code of
+     * {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING} and before receiving a "what" code of
+     * {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED}. The file is not used until switching to
+     * that output. Application will receive{@link #MEDIA_RECORDER_INFO_NEXT_OUTPUT_FILE_STARTED}
+     * when the next output file is used. Application will not be able to set a new output file if
+     * the previous one has not been used. Application is responsible for cleaning up unused files
+     * after {@link #stop} is called.
+     *
+     * @param fd an open file descriptor to be written into.
+     * @throws IllegalStateException if it is called before prepare().
+     * @throws IOException if setNextOutputFile fails otherwise.
+     */
+    public void setNextOutputFile(FileDescriptor fd) throws IOException
+    {
+        _setNextOutputFile(fd);
+    }
+
+    /**
+     * Sets the path of the output file to be produced. Call this after
+     * setOutputFormat() but before prepare().
+     *
+     * @param path The pathname to use.
+     * @throws IllegalStateException if it is called before
+     * setOutputFormat() or after prepare()
+     */
+    public void setOutputFile(String path) throws IllegalStateException
+    {
+        mFd = null;
+        mFile = null;
+        mPath = path;
+    }
+
+    /**
+     * Sets the next output file to be used when the maximum filesize is reached on the prior
+     * output {@link #setOutputFile} or {@link #setNextOutputFile}). File should be seekable.
+     * After setting the next output file, application should not use the file until {@link #stop}.
+     * Application must call this after receiving on the
+     * {@link android.media.MediaRecorder.OnInfoListener} a "what" code of
+     * {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING} and before receiving a "what" code of
+     * {@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED}. The file is not used until switching to
+     * that output. Application will receive {@link #MEDIA_RECORDER_INFO_NEXT_OUTPUT_FILE_STARTED}
+     * when the next output file is used. Application will not be able to set a new output file if
+     * the previous one has not been used. Application is responsible for cleaning up unused files
+     * after {@link #stop} is called.
+     *
+     * @param  file The file to use.
+     * @throws IllegalStateException if it is called before prepare().
+     * @throws IOException if setNextOutputFile fails otherwise.
+     */
+    public void setNextOutputFile(File file) throws IOException
+    {
+        RandomAccessFile f = new RandomAccessFile(file, "rw");
+        try {
+            _setNextOutputFile(f.getFD());
+        } finally {
+            f.close();
+        }
+    }
+
+    // native implementation
+    private native void _setOutputFile(FileDescriptor fd) throws IllegalStateException, IOException;
+    private native void _setNextOutputFile(FileDescriptor fd) throws IllegalStateException, IOException;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private native void _prepare() throws IllegalStateException, IOException;
+
+    /**
+     * Prepares the recorder to begin capturing and encoding data. This method
+     * must be called after setting up the desired audio and video sources,
+     * encoders, file format, etc., but before start().
+     *
+     * @throws IllegalStateException if it is called after
+     * start() or before setOutputFormat().
+     * @throws IOException if prepare fails otherwise.
+     */
+    public void prepare() throws IllegalStateException, IOException
+    {
+        if (mPath != null) {
+            RandomAccessFile file = new RandomAccessFile(mPath, "rw");
+            try {
+                _setOutputFile(file.getFD());
+            } finally {
+                file.close();
+            }
+        } else if (mFd != null) {
+            _setOutputFile(mFd);
+        } else if (mFile != null) {
+            RandomAccessFile file = new RandomAccessFile(mFile, "rw");
+            try {
+                _setOutputFile(file.getFD());
+            } finally {
+                file.close();
+            }
+        } else {
+            throw new IOException("No valid output file");
+        }
+
+        _prepare();
+    }
+
+    /**
+     * Begins capturing and encoding data to the file specified with
+     * setOutputFile(). Call this after prepare().
+     *
+     * <p>Since API level 13, if applications set a camera via
+     * {@link #setCamera(Camera)}, the apps can use the camera after this method
+     * call. The apps do not need to lock the camera again. However, if this
+     * method fails, the apps should still lock the camera back. The apps should
+     * not start another recording session during recording.
+     *
+     * @throws IllegalStateException if it is called before
+     * prepare() or when the camera is already in use by another app.
+     */
+    public native void start() throws IllegalStateException;
+
+    /**
+     * Stops recording. Call this after start(). Once recording is stopped,
+     * you will have to configure it again as if it has just been constructed.
+     * Note that a RuntimeException is intentionally thrown to the
+     * application, if no valid audio/video data has been received when stop()
+     * is called. This happens if stop() is called immediately after
+     * start(). The failure lets the application take action accordingly to
+     * clean up the output file (delete the output file, for instance), since
+     * the output file is not properly constructed when this happens.
+     *
+     * @throws IllegalStateException if it is called before start()
+     */
+    public native void stop() throws IllegalStateException;
+
+    /**
+     * Pauses recording. Call this after start(). You may resume recording
+     * with resume() without reconfiguration, as opposed to stop(). It does
+     * nothing if the recording is already paused.
+     *
+     * When the recording is paused and resumed, the resulting output would
+     * be as if nothing happend during paused period, immediately switching
+     * to the resumed scene.
+     *
+     * @throws IllegalStateException if it is called before start() or after
+     * stop()
+     */
+    public native void pause() throws IllegalStateException;
+
+    /**
+     * Resumes recording. Call this after start(). It does nothing if the
+     * recording is not paused.
+     *
+     * @throws IllegalStateException if it is called before start() or after
+     * stop()
+     * @see android.media.MediaRecorder#pause
+     */
+    public native void resume() throws IllegalStateException;
+
+    /**
+     * Restarts the MediaRecorder to its idle state. After calling
+     * this method, you will have to configure it again as if it had just been
+     * constructed.
+     */
+    public void reset() {
+        native_reset();
+
+        // make sure none of the listeners get called anymore
+        mEventHandler.removeCallbacksAndMessages(null);
+    }
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private native void native_reset();
+
+    /**
+     * Returns the maximum absolute amplitude that was sampled since the last
+     * call to this method. Call this only after the setAudioSource().
+     *
+     * @return the maximum absolute amplitude measured since the last call, or
+     * 0 when called for the first time
+     * @throws IllegalStateException if it is called before
+     * the audio source has been set.
+     */
+    public native int getMaxAmplitude() throws IllegalStateException;
+
+    /* Do not change this value without updating its counterpart
+     * in include/media/mediarecorder.h or mediaplayer.h!
+     */
+    /** Unspecified media recorder error.
+     * @see android.media.MediaRecorder.OnErrorListener
+     */
+    public static final int MEDIA_RECORDER_ERROR_UNKNOWN = 1;
+    /** Media server died. In this case, the application must release the
+     * MediaRecorder object and instantiate a new one.
+     * @see android.media.MediaRecorder.OnErrorListener
+     */
+    public static final int MEDIA_ERROR_SERVER_DIED = 100;
+
+    /**
+     * Interface definition for a callback to be invoked when an error
+     * occurs while recording.
+     */
+    public interface OnErrorListener
+    {
+        /**
+         * Called when an error occurs while recording.
+         *
+         * @param mr the MediaRecorder that encountered the error
+         * @param what    the type of error that has occurred:
+         * <ul>
+         * <li>{@link #MEDIA_RECORDER_ERROR_UNKNOWN}
+         * <li>{@link #MEDIA_ERROR_SERVER_DIED}
+         * </ul>
+         * @param extra   an extra code, specific to the error type
+         */
+        void onError(MediaRecorder mr, int what, int extra);
+    }
+
+    /**
+     * Register a callback to be invoked when an error occurs while
+     * recording.
+     *
+     * @param l the callback that will be run
+     */
+    public void setOnErrorListener(OnErrorListener l)
+    {
+        mOnErrorListener = l;
+    }
+
+    /* Do not change these values without updating their counterparts
+     * in include/media/mediarecorder.h!
+     */
+    /** Unspecified media recorder info.
+     * @see android.media.MediaRecorder.OnInfoListener
+     */
+    public static final int MEDIA_RECORDER_INFO_UNKNOWN              = 1;
+    /** A maximum duration had been setup and has now been reached.
+     * @see android.media.MediaRecorder.OnInfoListener
+     */
+    public static final int MEDIA_RECORDER_INFO_MAX_DURATION_REACHED = 800;
+    /** A maximum filesize had been setup and has now been reached.
+     * Note: This event will not be sent if application already set
+     * next output file through {@link #setNextOutputFile}.
+     * @see android.media.MediaRecorder.OnInfoListener
+     */
+    public static final int MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED = 801;
+    /** A maximum filesize had been setup and current recorded file size
+     * has reached 90% of the limit. This is sent once per file upon
+     * reaching/passing the 90% limit. To continue the recording, applicaiton
+     * should use {@link #setNextOutputFile} to set the next output file.
+     * Otherwise, recording will stop when reaching maximum file size.
+     * @see android.media.MediaRecorder.OnInfoListener
+     */
+    public static final int MEDIA_RECORDER_INFO_MAX_FILESIZE_APPROACHING = 802;
+    /** A maximum filesize had been reached and MediaRecorder has switched
+     * output to a new file set by application {@link #setNextOutputFile}.
+     * For best practice, application should use this event to keep track
+     * of whether the file previously set has been used or not.
+     * @see android.media.MediaRecorder.OnInfoListener
+     */
+    public static final int MEDIA_RECORDER_INFO_NEXT_OUTPUT_FILE_STARTED = 803;
+
+    /** informational events for individual tracks, for testing purpose.
+     * The track informational event usually contains two parts in the ext1
+     * arg of the onInfo() callback: bit 31-28 contains the track id; and
+     * the rest of the 28 bits contains the informational event defined here.
+     * For example, ext1 = (1 << 28 | MEDIA_RECORDER_TRACK_INFO_TYPE) if the
+     * track id is 1 for informational event MEDIA_RECORDER_TRACK_INFO_TYPE;
+     * while ext1 = (0 << 28 | MEDIA_RECORDER_TRACK_INFO_TYPE) if the track
+     * id is 0 for informational event MEDIA_RECORDER_TRACK_INFO_TYPE. The
+     * application should extract the track id and the type of informational
+     * event from ext1, accordingly.
+     *
+     * FIXME:
+     * Please update the comment for onInfo also when these
+     * events are unhidden so that application knows how to extract the track
+     * id and the informational event type from onInfo callback.
+     *
+     * {@hide}
+     */
+    public static final int MEDIA_RECORDER_TRACK_INFO_LIST_START        = 1000;
+    /** Signal the completion of the track for the recording session.
+     * {@hide}
+     */
+    public static final int MEDIA_RECORDER_TRACK_INFO_COMPLETION_STATUS = 1000;
+    /** Indicate the recording progress in time (ms) during recording.
+     * {@hide}
+     */
+    public static final int MEDIA_RECORDER_TRACK_INFO_PROGRESS_IN_TIME  = 1001;
+    /** Indicate the track type: 0 for Audio and 1 for Video.
+     * {@hide}
+     */
+    public static final int MEDIA_RECORDER_TRACK_INFO_TYPE              = 1002;
+    /** Provide the track duration information.
+     * {@hide}
+     */
+    public static final int MEDIA_RECORDER_TRACK_INFO_DURATION_MS       = 1003;
+    /** Provide the max chunk duration in time (ms) for the given track.
+     * {@hide}
+     */
+    public static final int MEDIA_RECORDER_TRACK_INFO_MAX_CHUNK_DUR_MS  = 1004;
+    /** Provide the total number of recordd frames.
+     * {@hide}
+     */
+    public static final int MEDIA_RECORDER_TRACK_INFO_ENCODED_FRAMES    = 1005;
+    /** Provide the max spacing between neighboring chunks for the given track.
+     * {@hide}
+     */
+    public static final int MEDIA_RECORDER_TRACK_INTER_CHUNK_TIME_MS    = 1006;
+    /** Provide the elapsed time measuring from the start of the recording
+     * till the first output frame of the given track is received, excluding
+     * any intentional start time offset of a recording session for the
+     * purpose of eliminating the recording sound in the recorded file.
+     * {@hide}
+     */
+    public static final int MEDIA_RECORDER_TRACK_INFO_INITIAL_DELAY_MS  = 1007;
+    /** Provide the start time difference (delay) betweeen this track and
+     * the start of the movie.
+     * {@hide}
+     */
+    public static final int MEDIA_RECORDER_TRACK_INFO_START_OFFSET_MS   = 1008;
+    /** Provide the total number of data (in kilo-bytes) encoded.
+     * {@hide}
+     */
+    public static final int MEDIA_RECORDER_TRACK_INFO_DATA_KBYTES       = 1009;
+    /**
+     * {@hide}
+     */
+    public static final int MEDIA_RECORDER_TRACK_INFO_LIST_END          = 2000;
+
+
+    /**
+     * Interface definition of a callback to be invoked to communicate some
+     * info and/or warning about the recording.
+     */
+    public interface OnInfoListener
+    {
+        /**
+         * Called to indicate an info or a warning during recording.
+         *
+         * @param mr   the MediaRecorder the info pertains to
+         * @param what the type of info or warning that has occurred
+         * <ul>
+         * <li>{@link #MEDIA_RECORDER_INFO_UNKNOWN}
+         * <li>{@link #MEDIA_RECORDER_INFO_MAX_DURATION_REACHED}
+         * <li>{@link #MEDIA_RECORDER_INFO_MAX_FILESIZE_REACHED}
+         * </ul>
+         * @param extra   an extra code, specific to the info type
+         */
+        void onInfo(MediaRecorder mr, int what, int extra);
+    }
+
+    /**
+     * Register a callback to be invoked when an informational event occurs while
+     * recording.
+     *
+     * @param listener the callback that will be run
+     */
+    public void setOnInfoListener(OnInfoListener listener)
+    {
+        mOnInfoListener = listener;
+    }
+
+    private class EventHandler extends Handler
+    {
+        private MediaRecorder mMediaRecorder;
+
+        public EventHandler(MediaRecorder mr, Looper looper) {
+            super(looper);
+            mMediaRecorder = mr;
+        }
+
+        /* Do not change these values without updating their counterparts
+         * in include/media/mediarecorder.h!
+         */
+        private static final int MEDIA_RECORDER_EVENT_LIST_START = 1;
+        private static final int MEDIA_RECORDER_EVENT_ERROR      = 1;
+        private static final int MEDIA_RECORDER_EVENT_INFO       = 2;
+        private static final int MEDIA_RECORDER_EVENT_LIST_END   = 99;
+
+        /* Events related to individual tracks */
+        private static final int MEDIA_RECORDER_TRACK_EVENT_LIST_START = 100;
+        private static final int MEDIA_RECORDER_TRACK_EVENT_ERROR      = 100;
+        private static final int MEDIA_RECORDER_TRACK_EVENT_INFO       = 101;
+        private static final int MEDIA_RECORDER_TRACK_EVENT_LIST_END   = 1000;
+
+        private static final int MEDIA_RECORDER_AUDIO_ROUTING_CHANGED  = 10000;
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (mMediaRecorder.mNativeContext == 0) {
+                Log.w(TAG, "mediarecorder went away with unhandled events");
+                return;
+            }
+            switch(msg.what) {
+            case MEDIA_RECORDER_EVENT_ERROR:
+            case MEDIA_RECORDER_TRACK_EVENT_ERROR:
+                if (mOnErrorListener != null)
+                    mOnErrorListener.onError(mMediaRecorder, msg.arg1, msg.arg2);
+
+                return;
+
+            case MEDIA_RECORDER_EVENT_INFO:
+            case MEDIA_RECORDER_TRACK_EVENT_INFO:
+                if (mOnInfoListener != null)
+                    mOnInfoListener.onInfo(mMediaRecorder, msg.arg1, msg.arg2);
+
+                return;
+
+            case MEDIA_RECORDER_AUDIO_ROUTING_CHANGED:
+                AudioManager.resetAudioPortGeneration();
+                synchronized (mRoutingChangeListeners) {
+                    for (NativeRoutingEventHandlerDelegate delegate
+                            : mRoutingChangeListeners.values()) {
+                        delegate.notifyClient();
+                    }
+                }
+                return;
+
+            default:
+                Log.e(TAG, "Unknown message type " + msg.what);
+                return;
+            }
+        }
+    }
+
+    //--------------------------------------------------------------------------
+    // Explicit Routing
+    //--------------------
+    private AudioDeviceInfo mPreferredDevice = null;
+
+    /**
+     * Specifies an audio device (via an {@link AudioDeviceInfo} object) to route
+     * the input from this MediaRecorder.
+     * @param deviceInfo The {@link AudioDeviceInfo} specifying the audio source.
+     *  If deviceInfo is null, default routing is restored.
+     * @return true if succesful, false if the specified {@link AudioDeviceInfo} is non-null and
+     * does not correspond to a valid audio input device.
+     */
+    @Override
+    public boolean setPreferredDevice(AudioDeviceInfo deviceInfo) {
+        if (deviceInfo != null && !deviceInfo.isSource()) {
+            return false;
+        }
+        int preferredDeviceId = deviceInfo != null ? deviceInfo.getId() : 0;
+        boolean status = native_setInputDevice(preferredDeviceId);
+        if (status == true) {
+            synchronized (this) {
+                mPreferredDevice = deviceInfo;
+            }
+        }
+        return status;
+    }
+
+    /**
+     * Returns the selected input device specified by {@link #setPreferredDevice}. Note that this
+     * is not guaranteed to correspond to the actual device being used for recording.
+     */
+    @Override
+    public AudioDeviceInfo getPreferredDevice() {
+        synchronized (this) {
+            return mPreferredDevice;
+        }
+    }
+
+    /**
+     * Returns an {@link AudioDeviceInfo} identifying the current routing of this MediaRecorder
+     * Note: The query is only valid if the MediaRecorder is currently recording.
+     * If the recorder is not recording, the returned device can be null or correspond to previously
+     * selected device when the recorder was last active.
+     */
+    @Override
+    public AudioDeviceInfo getRoutedDevice() {
+        int deviceId = native_getRoutedDeviceId();
+        if (deviceId == 0) {
+            return null;
+        }
+        return AudioManager.getDeviceForPortId(deviceId, AudioManager.GET_DEVICES_INPUTS);
+    }
+
+    /*
+     * Call BEFORE adding a routing callback handler or AFTER removing a routing callback handler.
+     */
+    @GuardedBy("mRoutingChangeListeners")
+    private void enableNativeRoutingCallbacksLocked(boolean enabled) {
+        if (mRoutingChangeListeners.size() == 0) {
+            native_enableDeviceCallback(enabled);
+        }
+    }
+
+    /**
+     * The list of AudioRouting.OnRoutingChangedListener interfaces added (with
+     * {@link #addOnRoutingChangedListener(android.media.AudioRouting.OnRoutingChangedListener, Handler)}
+     * by an app to receive (re)routing notifications.
+     */
+    @GuardedBy("mRoutingChangeListeners")
+    private ArrayMap<AudioRouting.OnRoutingChangedListener,
+            NativeRoutingEventHandlerDelegate> mRoutingChangeListeners = new ArrayMap<>();
+
+    /**
+     * Adds an {@link AudioRouting.OnRoutingChangedListener} to receive notifications of routing
+     * changes on this MediaRecorder.
+     * @param listener The {@link AudioRouting.OnRoutingChangedListener} interface to receive
+     * notifications of rerouting events.
+     * @param handler  Specifies the {@link Handler} object for the thread on which to execute
+     * the callback. If <code>null</code>, the handler on the main looper will be used.
+     */
+    @Override
+    public void addOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener,
+                                            Handler handler) {
+        synchronized (mRoutingChangeListeners) {
+            if (listener != null && !mRoutingChangeListeners.containsKey(listener)) {
+                enableNativeRoutingCallbacksLocked(true);
+                mRoutingChangeListeners.put(
+                        listener, new NativeRoutingEventHandlerDelegate(this, listener,
+                                handler != null ? handler : mEventHandler));
+            }
+        }
+    }
+
+    /**
+     * Removes an {@link AudioRouting.OnRoutingChangedListener} which has been previously added
+     * to receive rerouting notifications.
+     * @param listener The previously added {@link AudioRouting.OnRoutingChangedListener} interface
+     * to remove.
+     */
+    @Override
+    public void removeOnRoutingChangedListener(AudioRouting.OnRoutingChangedListener listener) {
+        synchronized (mRoutingChangeListeners) {
+            if (mRoutingChangeListeners.containsKey(listener)) {
+                mRoutingChangeListeners.remove(listener);
+                enableNativeRoutingCallbacksLocked(false);
+            }
+        }
+    }
+
+    private native final boolean native_setInputDevice(int deviceId);
+    private native final int native_getRoutedDeviceId();
+    private native final void native_enableDeviceCallback(boolean enabled);
+
+    //--------------------------------------------------------------------------
+    // Microphone information
+    //--------------------
+    /**
+     * Return A lists of {@link MicrophoneInfo} representing the active microphones.
+     * By querying channel mapping for each active microphone, developer can know how
+     * the microphone is used by each channels or a capture stream.
+     *
+     * @return a lists of {@link MicrophoneInfo} representing the active microphones
+     * @throws IOException if an error occurs
+     */
+    public List<MicrophoneInfo> getActiveMicrophones() throws IOException {
+        ArrayList<MicrophoneInfo> activeMicrophones = new ArrayList<>();
+        int status = native_getActiveMicrophones(activeMicrophones);
+        if (status != AudioManager.SUCCESS) {
+            if (status != AudioManager.ERROR_INVALID_OPERATION) {
+                Log.e(TAG, "getActiveMicrophones failed:" + status);
+            }
+            Log.i(TAG, "getActiveMicrophones failed, fallback on routed device info");
+        }
+        AudioManager.setPortIdForMicrophones(activeMicrophones);
+
+        // Use routed device when there is not information returned by hal.
+        if (activeMicrophones.size() == 0) {
+            AudioDeviceInfo device = getRoutedDevice();
+            if (device != null) {
+                MicrophoneInfo microphone = AudioManager.microphoneInfoFromAudioDeviceInfo(device);
+                ArrayList<Pair<Integer, Integer>> channelMapping = new ArrayList<>();
+                for (int i = 0; i < mChannelCount; i++) {
+                    channelMapping.add(new Pair(i, MicrophoneInfo.CHANNEL_MAPPING_DIRECT));
+                }
+                microphone.setChannelMapping(channelMapping);
+                activeMicrophones.add(microphone);
+            }
+        }
+        return activeMicrophones;
+    }
+
+    private native final int native_getActiveMicrophones(
+            ArrayList<MicrophoneInfo> activeMicrophones);
+
+    //--------------------------------------------------------------------------
+    // MicrophoneDirection
+    //--------------------
+    /**
+     * Specifies the logical microphone (for processing).
+     *
+     * @param direction Direction constant.
+     * @return true if sucessful.
+     */
+    public boolean setPreferredMicrophoneDirection(@DirectionMode int direction) {
+        return native_setPreferredMicrophoneDirection(direction) == 0;
+    }
+
+    /**
+     * Specifies the zoom factor (i.e. the field dimension) for the selected microphone
+     * (for processing). The selected microphone is determined by the use-case for the stream.
+     *
+     * @param zoom the desired field dimension of microphone capture. Range is from -1 (wide angle),
+     * though 0 (no zoom) to 1 (maximum zoom).
+     * @return true if sucessful.
+     */
+    public boolean setPreferredMicrophoneFieldDimension(
+                            @FloatRange(from = -1.0, to = 1.0) float zoom) {
+        Preconditions.checkArgument(
+                zoom >= -1 && zoom <= 1, "Argument must fall between -1 & 1 (inclusive)");
+        return native_setPreferredMicrophoneFieldDimension(zoom) == 0;
+    }
+
+    private native int native_setPreferredMicrophoneDirection(int direction);
+    private native int native_setPreferredMicrophoneFieldDimension(float zoom);
+
+    //--------------------------------------------------------------------------
+    // Implementation of AudioRecordingMonitor interface
+    //--------------------
+
+    AudioRecordingMonitorImpl mRecordingInfoImpl =
+            new AudioRecordingMonitorImpl((AudioRecordingMonitorClient) this);
+
+    /**
+     * Register a callback to be notified of audio capture changes via a
+     * {@link AudioManager.AudioRecordingCallback}. A callback is received when the capture path
+     * configuration changes (pre-processing, format, sampling rate...) or capture is
+     * silenced/unsilenced by the system.
+     * @param executor {@link Executor} to handle the callbacks.
+     * @param cb non-null callback to register
+     */
+    public void registerAudioRecordingCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull AudioManager.AudioRecordingCallback cb) {
+        mRecordingInfoImpl.registerAudioRecordingCallback(executor, cb);
+    }
+
+    /**
+     * Unregister an audio recording callback previously registered with
+     * {@link #registerAudioRecordingCallback(Executor, AudioManager.AudioRecordingCallback)}.
+     * @param cb non-null callback to unregister
+     */
+    public void unregisterAudioRecordingCallback(@NonNull AudioManager.AudioRecordingCallback cb) {
+        mRecordingInfoImpl.unregisterAudioRecordingCallback(cb);
+    }
+
+    /**
+     * Returns the current active audio recording for this audio recorder.
+     * @return a valid {@link AudioRecordingConfiguration} if this recorder is active
+     * or null otherwise.
+     * @see AudioRecordingConfiguration
+     */
+    public @Nullable AudioRecordingConfiguration getActiveRecordingConfiguration() {
+        return mRecordingInfoImpl.getActiveRecordingConfiguration();
+    }
+
+    //---------------------------------------------------------
+    // Implementation of AudioRecordingMonitorClient interface
+    //--------------------
+    /**
+     * @hide
+     */
+    public int getPortId() {
+        if (mNativeContext == 0) {
+            return 0;
+        }
+        return native_getPortId();
+    }
+
+    private native int native_getPortId();
+
+    /**
+     * Called from native code when an interesting event happens.  This method
+     * just uses the EventHandler system to post the event back to the main app thread.
+     * We use a weak reference to the original MediaRecorder object so that the native
+     * code is safe from the object disappearing from underneath it.  (This is
+     * the cookie passed to native_setup().)
+     */
+    private static void postEventFromNative(Object mediarecorder_ref,
+                                            int what, int arg1, int arg2, Object obj)
+    {
+        MediaRecorder mr = (MediaRecorder)((WeakReference)mediarecorder_ref).get();
+        if (mr == null) {
+            return;
+        }
+
+        if (mr.mEventHandler != null) {
+            Message m = mr.mEventHandler.obtainMessage(what, arg1, arg2, obj);
+            mr.mEventHandler.sendMessage(m);
+        }
+    }
+
+    /**
+     * Releases resources associated with this MediaRecorder object.
+     * It is good practice to call this method when you're done
+     * using the MediaRecorder. In particular, whenever an Activity
+     * of an application is paused (its onPause() method is called),
+     * or stopped (its onStop() method is called), this method should be
+     * invoked to release the MediaRecorder object, unless the application
+     * has a special need to keep the object around. In addition to
+     * unnecessary resources (such as memory and instances of codecs)
+     * being held, failure to call this method immediately if a
+     * MediaRecorder object is no longer needed may also lead to
+     * continuous battery consumption for mobile devices, and recording
+     * failure for other applications if no multiple instances of the
+     * same codec are supported on a device. Even if multiple instances
+     * of the same codec are supported, some performance degradation
+     * may be expected when unnecessary multiple instances are used
+     * at the same time.
+     */
+    public native void release();
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private static native final void native_init();
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R,
+            publicAlternatives = "{@link MediaRecorder}")
+    private void native_setup(Object mediarecorderThis,
+            String clientName, String opPackageName) throws IllegalStateException {
+        AttributionSource attributionSource = AttributionSource.myAttributionSource()
+                .withPackageName(opPackageName);
+        try (ScopedParcelState attributionSourceState = attributionSource.asScopedParcelState()) {
+            native_setup(mediarecorderThis, clientName, attributionSourceState.getParcel());
+        }
+    }
+
+    private native void native_setup(Object mediarecorderThis,
+            String clientName, @NonNull Parcel attributionSource)
+            throws IllegalStateException;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private native void native_finalize();
+
+    @UnsupportedAppUsage
+    private native void setParameter(String nameValuePair);
+
+    /**
+     *  Return Metrics data about the current Mediarecorder instance.
+     *
+     * @return a {@link PersistableBundle} containing the set of attributes and values
+     * available for the media being generated by this instance of
+     * MediaRecorder.
+     * The attributes are descibed in {@link MetricsConstants}.
+     *
+     *  Additional vendor-specific fields may also be present in
+     *  the return value.
+     */
+    public PersistableBundle getMetrics() {
+        PersistableBundle bundle = native_getMetrics();
+        return bundle;
+    }
+
+    private native PersistableBundle native_getMetrics();
+
+    @Override
+    protected void finalize() { native_finalize(); }
+
+    public final static class MetricsConstants
+    {
+        private MetricsConstants() {}
+
+        /**
+         * Key to extract the audio bitrate
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         */
+        public static final String AUDIO_BITRATE = "android.media.mediarecorder.audio-bitrate";
+
+        /**
+         * Key to extract the number of audio channels
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         */
+        public static final String AUDIO_CHANNELS = "android.media.mediarecorder.audio-channels";
+
+        /**
+         * Key to extract the audio samplerate
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         */
+        public static final String AUDIO_SAMPLERATE = "android.media.mediarecorder.audio-samplerate";
+
+        /**
+         * Key to extract the audio timescale
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         */
+        public static final String AUDIO_TIMESCALE = "android.media.mediarecorder.audio-timescale";
+
+        /**
+         * Key to extract the video capture frame rate
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is a double.
+         */
+        public static final String CAPTURE_FPS = "android.media.mediarecorder.capture-fps";
+
+        /**
+         * Key to extract the video capture framerate enable value
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         */
+        public static final String CAPTURE_FPS_ENABLE = "android.media.mediarecorder.capture-fpsenable";
+
+        /**
+         * Key to extract the intended playback frame rate
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         */
+        public static final String FRAMERATE = "android.media.mediarecorder.frame-rate";
+
+        /**
+         * Key to extract the height (in pixels) of the captured video
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         */
+        public static final String HEIGHT = "android.media.mediarecorder.height";
+
+        /**
+         * Key to extract the recorded movies time units
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         * A value of 1000 indicates that the movie's timing is in milliseconds.
+         */
+        public static final String MOVIE_TIMESCALE = "android.media.mediarecorder.movie-timescale";
+
+        /**
+         * Key to extract the rotation (in degrees) to properly orient the video
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         */
+        public static final String ROTATION = "android.media.mediarecorder.rotation";
+
+        /**
+         * Key to extract the video bitrate from being used
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         */
+        public static final String VIDEO_BITRATE = "android.media.mediarecorder.video-bitrate";
+
+        /**
+         * Key to extract the value for how often video iframes are generated
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         */
+        public static final String VIDEO_IFRAME_INTERVAL = "android.media.mediarecorder.video-iframe-interval";
+
+        /**
+         * Key to extract the video encoding level
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         */
+        public static final String VIDEO_LEVEL = "android.media.mediarecorder.video-encoder-level";
+
+        /**
+         * Key to extract the video encoding profile
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         */
+        public static final String VIDEO_PROFILE = "android.media.mediarecorder.video-encoder-profile";
+
+        /**
+         * Key to extract the recorded video time units
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         * A value of 1000 indicates that the video's timing is in milliseconds.
+         */
+        public static final String VIDEO_TIMESCALE = "android.media.mediarecorder.video-timescale";
+
+        /**
+         * Key to extract the width (in pixels) of the captured video
+         * from the {@link MediaRecorder#getMetrics} return.
+         * The value is an integer.
+         */
+        public static final String WIDTH = "android.media.mediarecorder.width";
+
+    }
+}
diff --git a/android/media/MediaRoute2Info.java b/android/media/MediaRoute2Info.java
new file mode 100644
index 0000000..7e9d2d8
--- /dev/null
+++ b/android/media/MediaRoute2Info.java
@@ -0,0 +1,932 @@
+/*
+ * Copyright 2019 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.MediaRouter2Utils.toUniqueId;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Describes the properties of a route.
+ */
+public final class MediaRoute2Info implements Parcelable {
+    @NonNull
+    public static final Creator<MediaRoute2Info> CREATOR = new Creator<MediaRoute2Info>() {
+        @Override
+        public MediaRoute2Info createFromParcel(Parcel in) {
+            return new MediaRoute2Info(in);
+        }
+
+        @Override
+        public MediaRoute2Info[] newArray(int size) {
+            return new MediaRoute2Info[size];
+        }
+    };
+
+    /** @hide */
+    @IntDef({CONNECTION_STATE_DISCONNECTED, CONNECTION_STATE_CONNECTING,
+            CONNECTION_STATE_CONNECTED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ConnectionState {}
+
+    /**
+     * The default connection state indicating the route is disconnected.
+     *
+     * @see #getConnectionState
+     */
+    public static final int CONNECTION_STATE_DISCONNECTED = 0;
+
+    /**
+     * A connection state indicating the route is in the process of connecting and is not yet
+     * ready for use.
+     *
+     * @see #getConnectionState
+     */
+    public static final int CONNECTION_STATE_CONNECTING = 1;
+
+    /**
+     * A connection state indicating the route is connected.
+     *
+     * @see #getConnectionState
+     */
+    public static final int CONNECTION_STATE_CONNECTED = 2;
+
+    /** @hide */
+    @IntDef({PLAYBACK_VOLUME_FIXED, PLAYBACK_VOLUME_VARIABLE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PlaybackVolume {}
+
+    /**
+     * Playback information indicating the playback volume is fixed, i&#46;e&#46; it cannot be
+     * controlled from this object. An example of fixed playback volume is a remote player,
+     * playing over HDMI where the user prefers to control the volume on the HDMI sink, rather
+     * than attenuate at the source.
+     *
+     * @see #getVolumeHandling()
+     */
+    public static final int PLAYBACK_VOLUME_FIXED = 0;
+    /**
+     * Playback information indicating the playback volume is variable and can be controlled
+     * from this object.
+     *
+     * @see #getVolumeHandling()
+     */
+    public static final int PLAYBACK_VOLUME_VARIABLE = 1;
+
+    /** @hide */
+    @IntDef({
+            TYPE_UNKNOWN, TYPE_BUILTIN_SPEAKER, TYPE_WIRED_HEADSET,
+            TYPE_WIRED_HEADPHONES, TYPE_BLUETOOTH_A2DP, TYPE_HDMI, TYPE_USB_DEVICE,
+            TYPE_USB_ACCESSORY, TYPE_DOCK, TYPE_USB_HEADSET, TYPE_HEARING_AID,
+            TYPE_REMOTE_TV, TYPE_REMOTE_SPEAKER, TYPE_GROUP})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {}
+
+    /**
+     * The default route type indicating the type is unknown.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_UNKNOWN = 0;
+
+    /**
+     * A route type describing the speaker system (i.e. a mono speaker or stereo speakers) built
+     * in a device.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_BUILTIN_SPEAKER = AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
+
+    /**
+     * A route type describing a headset, which is the combination of a headphones and microphone.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_WIRED_HEADSET = AudioDeviceInfo.TYPE_WIRED_HEADSET;
+
+    /**
+     * A route type describing a pair of wired headphones.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_WIRED_HEADPHONES = AudioDeviceInfo.TYPE_WIRED_HEADPHONES;
+
+    /**
+     * A route type indicating the presentation of the media is happening
+     * on a bluetooth device such as a bluetooth speaker.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_BLUETOOTH_A2DP = AudioDeviceInfo.TYPE_BLUETOOTH_A2DP;
+
+    /**
+     * A route type describing an HDMI connection.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_HDMI = AudioDeviceInfo.TYPE_HDMI;
+
+    /**
+     * A route type describing a USB audio device.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_USB_DEVICE = AudioDeviceInfo.TYPE_USB_DEVICE;
+
+    /**
+     * A route type describing a USB audio device in accessory mode.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_USB_ACCESSORY = AudioDeviceInfo.TYPE_USB_ACCESSORY;
+
+    /**
+     * A route type describing the audio device associated with a dock.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_DOCK = AudioDeviceInfo.TYPE_DOCK;
+
+    /**
+     * A device type describing a USB audio headset.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_USB_HEADSET = AudioDeviceInfo.TYPE_USB_HEADSET;
+
+    /**
+     * A route type describing a Hearing Aid.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_HEARING_AID = AudioDeviceInfo.TYPE_HEARING_AID;
+
+    /**
+     * A route type indicating the presentation of the media is happening on a TV.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_REMOTE_TV = 1001;
+
+    /**
+     * A route type indicating the presentation of the media is happening on a speaker.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_REMOTE_SPEAKER = 1002;
+
+    /**
+     * A route type indicating the presentation of the media is happening on multiple devices.
+     *
+     * @see #getType
+     * @hide
+     */
+    public static final int TYPE_GROUP = 2000;
+
+    /**
+     * Route feature: Live audio.
+     * <p>
+     * A route that supports live audio routing will allow the media audio stream
+     * to be sent to supported destinations.  This can include internal speakers or
+     * audio jacks on the device itself, A2DP devices, and more.
+     * </p><p>
+     * When a live audio route is selected, audio routing is transparent to the application.
+     * All audio played on the media stream will be routed to the selected destination.
+     * </p><p>
+     * Refer to the class documentation for details about live audio routes.
+     * </p>
+     */
+    public static final String FEATURE_LIVE_AUDIO = "android.media.route.feature.LIVE_AUDIO";
+
+    /**
+     * Route feature: Live video.
+     * <p>
+     * A route that supports live video routing will allow a mirrored version
+     * of the device's primary display or a customized
+     * {@link android.app.Presentation Presentation} to be sent to supported
+     * destinations.
+     * </p><p>
+     * When a live video route is selected, audio and video routing is transparent
+     * to the application.  By default, audio and video is routed to the selected
+     * destination.  For certain live video routes, the application may also use a
+     * {@link android.app.Presentation Presentation} to replace the mirrored view
+     * on the external display with different content.
+     * </p><p>
+     * Refer to the class documentation for details about live video routes.
+     * </p>
+     *
+     * @see android.app.Presentation
+     */
+    public static final String FEATURE_LIVE_VIDEO = "android.media.route.feature.LIVE_VIDEO";
+
+    /**
+     * Route feature: Local playback.
+     * @hide
+     */
+    public static final String FEATURE_LOCAL_PLAYBACK =
+            "android.media.route.feature.LOCAL_PLAYBACK";
+
+    /**
+     * Route feature: Remote playback.
+     * <p>
+     * A route that supports remote playback routing will allow an application to send
+     * requests to play content remotely to supported destinations.
+     * A route may only support {@link #FEATURE_REMOTE_AUDIO_PLAYBACK audio playback} or
+     * {@link #FEATURE_REMOTE_VIDEO_PLAYBACK video playback}.
+     * </p><p>
+     * Remote playback routes destinations operate independently of the local device.
+     * When a remote playback route is selected, the application can control the content
+     * playing on the destination using {@link MediaRouter2.RoutingController#getControlHints()}.
+     * The application may also receive status updates from the route regarding remote playback.
+     * </p><p>
+     * Refer to the class documentation for details about remote playback routes.
+     * </p>
+     * @see #FEATURE_REMOTE_AUDIO_PLAYBACK
+     * @see #FEATURE_REMOTE_VIDEO_PLAYBACK
+     */
+    public static final String FEATURE_REMOTE_PLAYBACK =
+            "android.media.route.feature.REMOTE_PLAYBACK";
+
+    /**
+     * Route feature: Remote audio playback.
+     * <p>
+     * A route that supports remote audio playback routing will allow an application to send
+     * requests to play audio content remotely to supported destinations.
+     *
+     * @see #FEATURE_REMOTE_PLAYBACK
+     * @see #FEATURE_REMOTE_VIDEO_PLAYBACK
+     */
+    public static final String FEATURE_REMOTE_AUDIO_PLAYBACK =
+            "android.media.route.feature.REMOTE_AUDIO_PLAYBACK";
+
+    /**
+     * Route feature: Remote video playback.
+     * <p>
+     * A route that supports remote video playback routing will allow an application to send
+     * requests to play video content remotely to supported destinations.
+     *
+     * @see #FEATURE_REMOTE_PLAYBACK
+     * @see #FEATURE_REMOTE_AUDIO_PLAYBACK
+     */
+    public static final String FEATURE_REMOTE_VIDEO_PLAYBACK =
+            "android.media.route.feature.REMOTE_VIDEO_PLAYBACK";
+
+    /**
+     * Route feature: Remote group playback.
+     * <p>
+     * @hide
+     */
+    public static final String FEATURE_REMOTE_GROUP_PLAYBACK =
+            "android.media.route.feature.REMOTE_GROUP_PLAYBACK";
+
+    final String mId;
+    final CharSequence mName;
+    final List<String> mFeatures;
+    @Type
+    final int mType;
+    final boolean mIsSystem;
+    final Uri mIconUri;
+    final CharSequence mDescription;
+    @ConnectionState
+    final int mConnectionState;
+    final String mClientPackageName;
+    final int mVolumeHandling;
+    final int mVolumeMax;
+    final int mVolume;
+    final String mAddress;
+    final Bundle mExtras;
+    final String mProviderId;
+
+    MediaRoute2Info(@NonNull Builder builder) {
+        mId = builder.mId;
+        mName = builder.mName;
+        mFeatures = builder.mFeatures;
+        mType = builder.mType;
+        mIsSystem = builder.mIsSystem;
+        mIconUri = builder.mIconUri;
+        mDescription = builder.mDescription;
+        mConnectionState = builder.mConnectionState;
+        mClientPackageName = builder.mClientPackageName;
+        mVolumeHandling = builder.mVolumeHandling;
+        mVolumeMax = builder.mVolumeMax;
+        mVolume = builder.mVolume;
+        mAddress = builder.mAddress;
+        mExtras = builder.mExtras;
+        mProviderId = builder.mProviderId;
+    }
+
+    MediaRoute2Info(@NonNull Parcel in) {
+        mId = in.readString();
+        mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+        mFeatures = in.createStringArrayList();
+        mType = in.readInt();
+        mIsSystem = in.readBoolean();
+        mIconUri = in.readParcelable(null);
+        mDescription = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+        mConnectionState = in.readInt();
+        mClientPackageName = in.readString();
+        mVolumeHandling = in.readInt();
+        mVolumeMax = in.readInt();
+        mVolume = in.readInt();
+        mAddress = in.readString();
+        mExtras = in.readBundle();
+        mProviderId = in.readString();
+    }
+
+    /**
+     * Gets the id of the route. The routes which are given by {@link MediaRouter2} will have
+     * unique IDs.
+     * <p>
+     * In order to ensure uniqueness in {@link MediaRouter2} side, the value of this method
+     * can be different from what was set in {@link MediaRoute2ProviderService}.
+     *
+     * @see Builder#Builder(String, CharSequence)
+     */
+    @NonNull
+    public String getId() {
+        if (mProviderId != null) {
+            return toUniqueId(mProviderId, mId);
+        } else {
+            return mId;
+        }
+    }
+
+    /**
+     * Gets the user-visible name of the route.
+     */
+    @NonNull
+    public CharSequence getName() {
+        return mName;
+    }
+
+    /**
+     * Gets the supported features of the route.
+     */
+    @NonNull
+    public List<String> getFeatures() {
+        return mFeatures;
+    }
+
+    /**
+     * Gets the type of this route.
+     *
+     * @return The type of this route:
+     * {@link #TYPE_UNKNOWN},
+     * {@link #TYPE_BUILTIN_SPEAKER}, {@link #TYPE_WIRED_HEADSET}, {@link #TYPE_WIRED_HEADPHONES},
+     * {@link #TYPE_BLUETOOTH_A2DP}, {@link #TYPE_HDMI}, {@link #TYPE_DOCK},
+     * {@Link #TYPE_USB_DEVICE}, {@link #TYPE_USB_ACCESSORY}, {@link #TYPE_USB_HEADSET}
+     * {@link #TYPE_HEARING_AID},
+     * {@link #TYPE_REMOTE_TV}, {@link #TYPE_REMOTE_SPEAKER}, {@link #TYPE_GROUP}.
+     * @hide
+     */
+    @Type
+    public int getType() {
+        return mType;
+    }
+
+    /**
+     * Returns whether the route is a system route or not.
+     * <p>
+     * System routes are media routes directly controlled by the system
+     * such as phone speaker, wired headset, and Bluetooth devices.
+     * </p>
+     */
+    public boolean isSystemRoute() {
+        return mIsSystem;
+    }
+
+    /**
+     * Gets the URI of the icon representing this route.
+     * <p>
+     * This icon will be used in picker UIs if available.
+     *
+     * @return The URI of the icon representing this route, or null if none.
+     */
+    @Nullable
+    public Uri getIconUri() {
+        return mIconUri;
+    }
+
+    /**
+     * Gets the user-visible description of the route.
+     */
+    @Nullable
+    public CharSequence getDescription() {
+        return mDescription;
+    }
+
+    /**
+     * Gets the connection state of the route.
+     *
+     * @return The connection state of this route: {@link #CONNECTION_STATE_DISCONNECTED},
+     * {@link #CONNECTION_STATE_CONNECTING}, or {@link #CONNECTION_STATE_CONNECTED}.
+     */
+    @ConnectionState
+    public int getConnectionState() {
+        return mConnectionState;
+    }
+
+    /**
+     * Gets the package name of the app using the route.
+     * Returns null if no apps are using this route.
+     */
+    @Nullable
+    public String getClientPackageName() {
+        return mClientPackageName;
+    }
+
+    /**
+     * Gets information about how volume is handled on the route.
+     *
+     * @return {@link #PLAYBACK_VOLUME_FIXED} or {@link #PLAYBACK_VOLUME_VARIABLE}
+     */
+    @PlaybackVolume
+    public int getVolumeHandling() {
+        return mVolumeHandling;
+    }
+
+    /**
+     * Gets the maximum volume of the route.
+     */
+    public int getVolumeMax() {
+        return mVolumeMax;
+    }
+
+    /**
+     * Gets the current volume of the route. This may be invalid if the route is not selected.
+     */
+    public int getVolume() {
+        return mVolume;
+    }
+
+    /**
+     * Gets the hardware address of the route if available.
+     * @hide
+     */
+    @Nullable
+    public String getAddress() {
+        return mAddress;
+    }
+
+    @Nullable
+    public Bundle getExtras() {
+        return mExtras == null ? null : new Bundle(mExtras);
+    }
+
+    /**
+     * Gets the original id set by {@link Builder#Builder(String, CharSequence)}.
+     * @hide
+     */
+    @NonNull
+    @TestApi
+    public String getOriginalId() {
+        return mId;
+    }
+
+    /**
+     * Gets the provider id of the route. It is assigned automatically by
+     * {@link com.android.server.media.MediaRouterService}.
+     *
+     * @return provider id of the route or null if it's not set.
+     * @hide
+     */
+    @Nullable
+    public String getProviderId() {
+        return mProviderId;
+    }
+
+    /**
+     * Returns if the route has at least one of the specified route features.
+     *
+     * @param features the list of route features to consider
+     * @return true if the route has at least one feature in the list
+     * @hide
+     */
+    public boolean hasAnyFeatures(@NonNull Collection<String> features) {
+        Objects.requireNonNull(features, "features must not be null");
+        for (String feature : features) {
+            if (getFeatures().contains(feature)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Returns true if the route info has all of the required field.
+     * A route is valid if and only if it is obtained from
+     * {@link com.android.server.media.MediaRouterService}.
+     * @hide
+     */
+    public boolean isValid() {
+        if (TextUtils.isEmpty(getId()) || TextUtils.isEmpty(getName())
+                || TextUtils.isEmpty(getProviderId())) {
+            return false;
+        }
+        return true;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof MediaRoute2Info)) {
+            return false;
+        }
+        MediaRoute2Info other = (MediaRoute2Info) obj;
+
+        // Note: mExtras is not included.
+        return Objects.equals(mId, other.mId)
+                && Objects.equals(mName, other.mName)
+                && Objects.equals(mFeatures, other.mFeatures)
+                && (mType == other.mType)
+                && (mIsSystem == other.mIsSystem)
+                && Objects.equals(mIconUri, other.mIconUri)
+                && Objects.equals(mDescription, other.mDescription)
+                && (mConnectionState == other.mConnectionState)
+                && Objects.equals(mClientPackageName, other.mClientPackageName)
+                && (mVolumeHandling == other.mVolumeHandling)
+                && (mVolumeMax == other.mVolumeMax)
+                && (mVolume == other.mVolume)
+                && Objects.equals(mAddress, other.mAddress)
+                && Objects.equals(mProviderId, other.mProviderId);
+    }
+
+    @Override
+    public int hashCode() {
+        // Note: mExtras is not included.
+        return Objects.hash(mId, mName, mFeatures, mType, mIsSystem, mIconUri, mDescription,
+                mConnectionState, mClientPackageName, mVolumeHandling, mVolumeMax, mVolume,
+                mAddress, mProviderId);
+    }
+
+    @Override
+    public String toString() {
+        // Note: mExtras is not printed here.
+        StringBuilder result = new StringBuilder()
+                .append("MediaRoute2Info{ ")
+                .append("id=").append(getId())
+                .append(", name=").append(getName())
+                .append(", features=").append(getFeatures())
+                .append(", iconUri=").append(getIconUri())
+                .append(", description=").append(getDescription())
+                .append(", connectionState=").append(getConnectionState())
+                .append(", clientPackageName=").append(getClientPackageName())
+                .append(", volumeHandling=").append(getVolumeHandling())
+                .append(", volumeMax=").append(getVolumeMax())
+                .append(", volume=").append(getVolume())
+                .append(", providerId=").append(getProviderId())
+                .append(" }");
+        return result.toString();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mId);
+        TextUtils.writeToParcel(mName, dest, flags);
+        dest.writeStringList(mFeatures);
+        dest.writeInt(mType);
+        dest.writeBoolean(mIsSystem);
+        dest.writeParcelable(mIconUri, flags);
+        TextUtils.writeToParcel(mDescription, dest, flags);
+        dest.writeInt(mConnectionState);
+        dest.writeString(mClientPackageName);
+        dest.writeInt(mVolumeHandling);
+        dest.writeInt(mVolumeMax);
+        dest.writeInt(mVolume);
+        dest.writeString(mAddress);
+        dest.writeBundle(mExtras);
+        dest.writeString(mProviderId);
+    }
+
+    /**
+     * Builder for {@link MediaRoute2Info media route info}.
+     */
+    public static final class Builder {
+        final String mId;
+        final CharSequence mName;
+        final List<String> mFeatures;
+
+        @Type
+        int mType = TYPE_UNKNOWN;
+        boolean mIsSystem;
+        Uri mIconUri;
+        CharSequence mDescription;
+        @ConnectionState
+        int mConnectionState;
+        String mClientPackageName;
+        int mVolumeHandling = PLAYBACK_VOLUME_FIXED;
+        int mVolumeMax;
+        int mVolume;
+        String mAddress;
+        Bundle mExtras;
+        String mProviderId;
+
+        /**
+         * Constructor for builder to create {@link MediaRoute2Info}.
+         * <p>
+         * In order to ensure ID uniqueness, the {@link MediaRoute2Info#getId() ID} of a route info
+         * obtained from {@link MediaRouter2} can be different from what was set in
+         * {@link MediaRoute2ProviderService}.
+         * </p>
+         * @param id The ID of the route. Must not be empty.
+         * @param name The user-visible name of the route.
+         */
+        public Builder(@NonNull String id, @NonNull CharSequence name) {
+            if (TextUtils.isEmpty(id)) {
+                throw new IllegalArgumentException("id must not be empty");
+            }
+            if (TextUtils.isEmpty(name)) {
+                throw new IllegalArgumentException("name must not be empty");
+            }
+            mId = id;
+            mName = name;
+            mFeatures = new ArrayList<>();
+        }
+
+        /**
+         * Constructor for builder to create {@link MediaRoute2Info} with existing
+         * {@link MediaRoute2Info} instance.
+         *
+         * @param routeInfo the existing instance to copy data from.
+         */
+        public Builder(@NonNull MediaRoute2Info routeInfo) {
+            this(routeInfo.mId, routeInfo);
+        }
+
+        /**
+         * Constructor for builder to create {@link MediaRoute2Info} with existing
+         * {@link MediaRoute2Info} instance and replace ID with the given {@code id}.
+         *
+         * @param id The ID of the new route. Must not be empty.
+         * @param routeInfo the existing instance to copy data from.
+         * @hide
+         */
+        public Builder(@NonNull String id, @NonNull MediaRoute2Info routeInfo) {
+            if (TextUtils.isEmpty(id)) {
+                throw new IllegalArgumentException("id must not be empty");
+            }
+            Objects.requireNonNull(routeInfo, "routeInfo must not be null");
+
+            mId = id;
+            mName = routeInfo.mName;
+            mFeatures = new ArrayList<>(routeInfo.mFeatures);
+            mType = routeInfo.mType;
+            mIsSystem = routeInfo.mIsSystem;
+            mIconUri = routeInfo.mIconUri;
+            mDescription = routeInfo.mDescription;
+            mConnectionState = routeInfo.mConnectionState;
+            mClientPackageName = routeInfo.mClientPackageName;
+            mVolumeHandling = routeInfo.mVolumeHandling;
+            mVolumeMax = routeInfo.mVolumeMax;
+            mVolume = routeInfo.mVolume;
+            mAddress = routeInfo.mAddress;
+            if (routeInfo.mExtras != null) {
+                mExtras = new Bundle(routeInfo.mExtras);
+            }
+            mProviderId = routeInfo.mProviderId;
+        }
+
+        /**
+         * Adds a feature for the route.
+         * @param feature a feature that the route has. May be one of predefined features
+         *                such as {@link #FEATURE_LIVE_AUDIO}, {@link #FEATURE_LIVE_VIDEO} or
+         *                {@link #FEATURE_REMOTE_PLAYBACK} or a custom feature defined by
+         *                a provider.
+         *
+         * @see #addFeatures(Collection)
+         */
+        @NonNull
+        public Builder addFeature(@NonNull String feature) {
+            if (TextUtils.isEmpty(feature)) {
+                throw new IllegalArgumentException("feature must not be null or empty");
+            }
+            mFeatures.add(feature);
+            return this;
+        }
+
+        /**
+         * Adds features for the route. A route must support at least one route type.
+         * @param features features that the route has. May include predefined features
+         *                such as {@link #FEATURE_LIVE_AUDIO}, {@link #FEATURE_LIVE_VIDEO} or
+         *                {@link #FEATURE_REMOTE_PLAYBACK} or custom features defined by
+         *                a provider.
+         *
+         * @see #addFeature(String)
+         */
+        @NonNull
+        public Builder addFeatures(@NonNull Collection<String> features) {
+            Objects.requireNonNull(features, "features must not be null");
+            for (String feature : features) {
+                addFeature(feature);
+            }
+            return this;
+        }
+
+        /**
+         * Clears the features of the route. A route must support at least one route type.
+         */
+        @NonNull
+        public Builder clearFeatures() {
+            mFeatures.clear();
+            return this;
+        }
+
+        /**
+         * Sets the route's type.
+         * @hide
+         */
+        @NonNull
+        public Builder setType(@Type int type) {
+            mType = type;
+            return this;
+        }
+
+        /**
+         * Sets whether the route is a system route or not.
+         * @hide
+         */
+        @NonNull
+        public Builder setSystemRoute(boolean isSystem) {
+            mIsSystem = isSystem;
+            return this;
+        }
+
+        /**
+         * Sets the URI of the icon representing this route.
+         * <p>
+         * This icon will be used in picker UIs if available.
+         * </p><p>
+         * The URI must be one of the following formats:
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         * </p>
+         */
+        @NonNull
+        public Builder setIconUri(@Nullable Uri iconUri) {
+            mIconUri = iconUri;
+            return this;
+        }
+
+        /**
+         * Sets the user-visible description of the route.
+         */
+        @NonNull
+        public Builder setDescription(@Nullable CharSequence description) {
+            mDescription = description;
+            return this;
+        }
+
+        /**
+        * Sets the route's connection state.
+        *
+        * {@link #CONNECTION_STATE_DISCONNECTED},
+        * {@link #CONNECTION_STATE_CONNECTING}, or
+        * {@link #CONNECTION_STATE_CONNECTED}.
+        */
+        @NonNull
+        public Builder setConnectionState(@ConnectionState int connectionState) {
+            mConnectionState = connectionState;
+            return this;
+        }
+
+        /**
+         * Sets the package name of the app using the route.
+         */
+        @NonNull
+        public Builder setClientPackageName(@Nullable String packageName) {
+            mClientPackageName = packageName;
+            return this;
+        }
+
+        /**
+         * Sets the route's volume handling.
+         */
+        @NonNull
+        public Builder setVolumeHandling(@PlaybackVolume int volumeHandling) {
+            mVolumeHandling = volumeHandling;
+            return this;
+        }
+
+        /**
+         * Sets the route's maximum volume, or 0 if unknown.
+         */
+        @NonNull
+        public Builder setVolumeMax(int volumeMax) {
+            mVolumeMax = volumeMax;
+            return this;
+        }
+
+        /**
+         * Sets the route's current volume, or 0 if unknown.
+         */
+        @NonNull
+        public Builder setVolume(int volume) {
+            mVolume = volume;
+            return this;
+        }
+
+        /**
+         * Sets the hardware address of the route.
+         * @hide
+         */
+        @NonNull
+        public Builder setAddress(String address) {
+            mAddress = address;
+            return this;
+        }
+
+        /**
+         * Sets a bundle of extras for the route.
+         * <p>
+         * Note: The extras will not affect the result of {@link MediaRoute2Info#equals(Object)}.
+         */
+        @NonNull
+        public Builder setExtras(@Nullable Bundle extras) {
+            if (extras == null) {
+                mExtras = null;
+                return this;
+            }
+            mExtras = new Bundle(extras);
+            return this;
+        }
+
+        /**
+         * Sets the provider id of the route.
+         * @hide
+         */
+        @NonNull
+        public Builder setProviderId(@NonNull String providerId) {
+            if (TextUtils.isEmpty(providerId)) {
+                throw new IllegalArgumentException("providerId must not be null or empty");
+            }
+            mProviderId = providerId;
+            return this;
+        }
+
+        /**
+         * Builds the {@link MediaRoute2Info media route info}.
+         *
+         * @throws IllegalArgumentException if no features are added.
+         */
+        @NonNull
+        public MediaRoute2Info build() {
+            if (mFeatures.isEmpty()) {
+                throw new IllegalArgumentException("features must not be empty!");
+            }
+            return new MediaRoute2Info(this);
+        }
+    }
+}
diff --git a/android/media/MediaRoute2ProviderInfo.java b/android/media/MediaRoute2ProviderInfo.java
new file mode 100644
index 0000000..afe002e
--- /dev/null
+++ b/android/media/MediaRoute2ProviderInfo.java
@@ -0,0 +1,241 @@
+/*
+ * Copyright 2019 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * Describes the state of a media router provider and the routes that it publishes.
+ * @hide
+ */
+public final class MediaRoute2ProviderInfo implements Parcelable {
+    @NonNull
+    public static final Creator<MediaRoute2ProviderInfo> CREATOR =
+            new Creator<MediaRoute2ProviderInfo>() {
+        @Override
+        public MediaRoute2ProviderInfo createFromParcel(Parcel in) {
+            return new MediaRoute2ProviderInfo(in);
+        }
+        @Override
+        public MediaRoute2ProviderInfo[] newArray(int size) {
+            return new MediaRoute2ProviderInfo[size];
+        }
+    };
+
+    @Nullable
+    final String mUniqueId;
+    @NonNull
+    final ArrayMap<String, MediaRoute2Info> mRoutes;
+
+    MediaRoute2ProviderInfo(@NonNull Builder builder) {
+        Objects.requireNonNull(builder, "builder must not be null.");
+
+        mUniqueId = builder.mUniqueId;
+        mRoutes = builder.mRoutes;
+    }
+
+    MediaRoute2ProviderInfo(@NonNull Parcel src) {
+        mUniqueId = src.readString();
+        ArrayMap<String, MediaRoute2Info> routes = src.createTypedArrayMap(MediaRoute2Info.CREATOR);
+        mRoutes = (routes == null) ? ArrayMap.EMPTY : routes;
+    }
+
+    /**
+     * Returns true if the information of the provider and all of it's routes have all
+     * of the required fields.
+     * @hide
+     */
+    public boolean isValid() {
+        if (mUniqueId == null) {
+            return false;
+        }
+        final int count = mRoutes.size();
+        for (int i = 0; i < count; i++) {
+            MediaRoute2Info route = mRoutes.valueAt(i);
+            if (route == null || !route.isValid()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * @hide
+     */
+    @Nullable
+    public String getUniqueId() {
+        return mUniqueId;
+    }
+
+    /**
+     * Gets the route for the given route id or null if no matching route exists.
+     * Please note that id should be original id.
+     *
+     * @see MediaRoute2Info#getOriginalId()
+     */
+    @Nullable
+    public MediaRoute2Info getRoute(@NonNull String routeId) {
+        return mRoutes.get(Objects.requireNonNull(routeId, "routeId must not be null"));
+    }
+
+    /**
+     * Gets the unmodifiable list of all routes that this provider has published.
+     */
+    @NonNull
+    public Collection<MediaRoute2Info> getRoutes() {
+        return mRoutes.values();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mUniqueId);
+        dest.writeTypedArrayMap(mRoutes, flags);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder()
+                .append("MediaRouteProviderInfo { ")
+                .append("uniqueId=").append(mUniqueId)
+                .append(", routes=").append(Arrays.toString(getRoutes().toArray()))
+                .append(" }");
+        return result.toString();
+    }
+
+    /**
+     * Builder for {@link MediaRoute2ProviderInfo media route provider info}.
+     */
+    public static final class Builder {
+        @NonNull
+        final ArrayMap<String, MediaRoute2Info> mRoutes;
+        String mUniqueId;
+
+        public Builder() {
+            mRoutes = new ArrayMap<>();
+        }
+
+        public Builder(@NonNull MediaRoute2ProviderInfo descriptor) {
+            Objects.requireNonNull(descriptor, "descriptor must not be null");
+
+            mUniqueId = descriptor.mUniqueId;
+            mRoutes = new ArrayMap<>(descriptor.mRoutes);
+        }
+
+        /**
+         * Sets the unique id of the provider info.
+         * <p>
+         * The unique id is automatically set by
+         * {@link com.android.server.media.MediaRouterService} and used to identify providers.
+         * The id set by {@link MediaRoute2ProviderService} will be ignored.
+         * </p>
+         * @hide
+         */
+        @NonNull
+        public Builder setUniqueId(@Nullable String uniqueId) {
+            if (TextUtils.equals(mUniqueId, uniqueId)) {
+                return this;
+            }
+            mUniqueId = uniqueId;
+
+            final ArrayMap<String, MediaRoute2Info> newRoutes = new ArrayMap<>();
+            for (Map.Entry<String, MediaRoute2Info> entry : mRoutes.entrySet()) {
+                MediaRoute2Info routeWithProviderId = new MediaRoute2Info.Builder(entry.getValue())
+                        .setProviderId(mUniqueId)
+                        .build();
+                newRoutes.put(routeWithProviderId.getOriginalId(), routeWithProviderId);
+            }
+
+            mRoutes.clear();
+            mRoutes.putAll(newRoutes);
+            return this;
+        }
+
+        /**
+         * Sets whether the provider provides system routes or not
+         */
+        @NonNull
+        public Builder setSystemRouteProvider(boolean isSystem) {
+            int count = mRoutes.size();
+            for (int i = 0; i < count; i++) {
+                MediaRoute2Info route = mRoutes.valueAt(i);
+                if (route.isSystemRoute() != isSystem) {
+                    mRoutes.setValueAt(i, new MediaRoute2Info.Builder(route)
+                            .setSystemRoute(isSystem)
+                            .build());
+                }
+            }
+            return this;
+        }
+
+        /**
+         * Adds a route to the provider
+         */
+        @NonNull
+        public Builder addRoute(@NonNull MediaRoute2Info route) {
+            Objects.requireNonNull(route, "route must not be null");
+
+            if (mRoutes.containsKey(route.getOriginalId())) {
+                throw new IllegalArgumentException("A route with the same id is already added");
+            }
+            if (mUniqueId != null) {
+                mRoutes.put(route.getOriginalId(),
+                        new MediaRoute2Info.Builder(route).setProviderId(mUniqueId).build());
+            } else {
+                mRoutes.put(route.getOriginalId(), route);
+            }
+            return this;
+        }
+
+        /**
+         * Adds a list of routes to the provider
+         */
+        @NonNull
+        public Builder addRoutes(@NonNull Collection<MediaRoute2Info> routes) {
+            Objects.requireNonNull(routes, "routes must not be null");
+
+            if (!routes.isEmpty()) {
+                for (MediaRoute2Info route : routes) {
+                    addRoute(route);
+                }
+            }
+            return this;
+        }
+
+        /**
+         * Builds {@link MediaRoute2ProviderInfo media route provider info}.
+         */
+        @NonNull
+        public MediaRoute2ProviderInfo build() {
+            return new MediaRoute2ProviderInfo(this);
+        }
+    }
+}
diff --git a/android/media/MediaRoute2ProviderService.java b/android/media/MediaRoute2ProviderService.java
new file mode 100644
index 0000000..49e0411
--- /dev/null
+++ b/android/media/MediaRoute2ProviderService.java
@@ -0,0 +1,706 @@
+/*
+ * Copyright 2019 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 com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.CallSuper;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.app.Service;
+import android.content.Intent;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Process;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayDeque;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Deque;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+/**
+ * Base class for media route provider services.
+ * <p>
+ * Media route provider services are used to publish {@link MediaRoute2Info media routes} such as
+ * speakers, TVs, etc. The routes are published by calling {@link #notifyRoutes(Collection)}.
+ * Media apps which use {@link MediaRouter2} can request to play their media on the routes.
+ * </p><p>
+ * When {@link MediaRouter2 media router} wants to play media on a route,
+ * {@link #onCreateSession(long, String, String, Bundle)} will be called to handle the request.
+ * A session can be considered as a group of currently selected routes for each connection.
+ * Create and manage the sessions by yourself, and notify the {@link RoutingSessionInfo
+ * session infos} when there are any changes.
+ * </p><p>
+ * The system media router service will bind to media route provider services when a
+ * {@link RouteDiscoveryPreference discovery preference} is registered via
+ * a {@link MediaRouter2 media router} by an application. See
+ * {@link #onDiscoveryPreferenceChanged(RouteDiscoveryPreference)} for the details.
+ * </p>
+ * Use {@link #notifyRequestFailed(long, int)} to notify the failure with previously received
+ * request ID.
+ */
+public abstract class MediaRoute2ProviderService extends Service {
+    private static final String TAG = "MR2ProviderService";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    /**
+     * The {@link Intent} action that must be declared as handled by the service.
+     * Put this in your manifest to provide media routes.
+     */
+    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+    public static final String SERVICE_INTERFACE = "android.media.MediaRoute2ProviderService";
+
+    /**
+     * The request ID to pass {@link #notifySessionCreated(long, RoutingSessionInfo)}
+     * when {@link MediaRoute2ProviderService} created a session although there was no creation
+     * request.
+     *
+     * @see #notifySessionCreated(long, RoutingSessionInfo)
+     */
+    public static final long REQUEST_ID_NONE = 0;
+
+    /**
+     * The request has failed due to unknown reason.
+     *
+     * @see #notifyRequestFailed(long, int)
+     */
+    public static final int REASON_UNKNOWN_ERROR = 0;
+
+    /**
+     * The request has failed since this service rejected the request.
+     *
+     * @see #notifyRequestFailed(long, int)
+     */
+    public static final int REASON_REJECTED = 1;
+
+    /**
+     * The request has failed due to a network error.
+     *
+     * @see #notifyRequestFailed(long, int)
+     */
+    public static final int REASON_NETWORK_ERROR = 2;
+
+    /**
+     * The request has failed since the requested route is no longer available.
+     *
+     * @see #notifyRequestFailed(long, int)
+     */
+    public static final int REASON_ROUTE_NOT_AVAILABLE = 3;
+
+    /**
+     * The request has failed since the request is not valid. For example, selecting a route
+     * which is not selectable.
+     *
+     * @see #notifyRequestFailed(long, int)
+     */
+    public static final int REASON_INVALID_COMMAND = 4;
+
+    /**
+     * @hide
+     */
+    @IntDef(prefix = "REASON_", value = {
+            REASON_UNKNOWN_ERROR, REASON_REJECTED, REASON_NETWORK_ERROR, REASON_ROUTE_NOT_AVAILABLE,
+            REASON_INVALID_COMMAND
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Reason {}
+
+    private static final int MAX_REQUEST_IDS_SIZE = 500;
+
+    private final Handler mHandler;
+    private final Object mSessionLock = new Object();
+    private final Object mRequestIdsLock = new Object();
+    private final AtomicBoolean mStatePublishScheduled = new AtomicBoolean(false);
+    private final AtomicBoolean mSessionUpdateScheduled = new AtomicBoolean(false);
+    private MediaRoute2ProviderServiceStub mStub;
+    private IMediaRoute2ProviderServiceCallback mRemoteCallback;
+    private volatile MediaRoute2ProviderInfo mProviderInfo;
+
+    @GuardedBy("mRequestIdsLock")
+    private final Deque<Long> mRequestIds = new ArrayDeque<>(MAX_REQUEST_IDS_SIZE);
+
+    @GuardedBy("mSessionLock")
+    private final ArrayMap<String, RoutingSessionInfo> mSessionInfo = new ArrayMap<>();
+
+    public MediaRoute2ProviderService() {
+        mHandler = new Handler(Looper.getMainLooper());
+    }
+
+    /**
+     * If overriding this method, call through to the super method for any unknown actions.
+     * <p>
+     * {@inheritDoc}
+     */
+    @CallSuper
+    @Override
+    @Nullable
+    public IBinder onBind(@NonNull Intent intent) {
+        if (SERVICE_INTERFACE.equals(intent.getAction())) {
+            if (mStub == null) {
+                mStub = new MediaRoute2ProviderServiceStub();
+            }
+            return mStub;
+        }
+        return null;
+    }
+
+    /**
+     * Called when a volume setting is requested on a route of the provider
+     *
+     * @param requestId the ID of this request
+     * @param routeId the ID of the route
+     * @param volume the target volume
+     * @see MediaRoute2Info.Builder#setVolume(int)
+     */
+    public abstract void onSetRouteVolume(long requestId, @NonNull String routeId, int volume);
+
+    /**
+     * Called when {@link MediaRouter2.RoutingController#setVolume(int)} is called on
+     * a routing session of the provider
+     *
+     * @param requestId the ID of this request
+     * @param sessionId the ID of the routing session
+     * @param volume the target volume
+     * @see RoutingSessionInfo.Builder#setVolume(int)
+     */
+    public abstract void onSetSessionVolume(long requestId, @NonNull String sessionId, int volume);
+
+    /**
+     * Gets information of the session with the given id.
+     *
+     * @param sessionId the ID of the session
+     * @return information of the session with the given id.
+     *         null if the session is released or ID is not valid.
+     */
+    @Nullable
+    public final RoutingSessionInfo getSessionInfo(@NonNull String sessionId) {
+        if (TextUtils.isEmpty(sessionId)) {
+            throw new IllegalArgumentException("sessionId must not be empty");
+        }
+        synchronized (mSessionLock) {
+            return mSessionInfo.get(sessionId);
+        }
+    }
+
+    /**
+     * Gets the list of {@link RoutingSessionInfo session info} that the provider service maintains.
+     */
+    @NonNull
+    public final List<RoutingSessionInfo> getAllSessionInfo() {
+        synchronized (mSessionLock) {
+            return new ArrayList<>(mSessionInfo.values());
+        }
+    }
+
+    /**
+     * Notifies clients of that the session is created and ready for use.
+     * <p>
+     * If this session is created without any creation request, use {@link #REQUEST_ID_NONE}
+     * as the request ID.
+     *
+     * @param requestId the ID of the previous request to create this session provided in
+     *                  {@link #onCreateSession(long, String, String, Bundle)}. Can be
+     *                  {@link #REQUEST_ID_NONE} if this session is created without any request.
+     * @param sessionInfo information of the new session.
+     *                    The {@link RoutingSessionInfo#getId() id} of the session must be unique.
+     * @see #onCreateSession(long, String, String, Bundle)
+     * @see #getSessionInfo(String)
+     */
+    public final void notifySessionCreated(long requestId,
+            @NonNull RoutingSessionInfo sessionInfo) {
+        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+
+        if (DEBUG) {
+            Log.d(TAG, "notifySessionCreated: Creating a session. requestId=" + requestId
+                    + ", sessionInfo=" + sessionInfo);
+        }
+
+        if (requestId != REQUEST_ID_NONE && !removeRequestId(requestId)) {
+            Log.w(TAG, "notifySessionCreated: The requestId doesn't exist. requestId=" + requestId);
+            return;
+        }
+
+        String sessionId = sessionInfo.getId();
+        synchronized (mSessionLock) {
+            if (mSessionInfo.containsKey(sessionId)) {
+                Log.w(TAG, "notifySessionCreated: Ignoring duplicate session id.");
+                return;
+            }
+            mSessionInfo.put(sessionInfo.getId(), sessionInfo);
+
+            if (mRemoteCallback == null) {
+                return;
+            }
+            try {
+                mRemoteCallback.notifySessionCreated(requestId, sessionInfo);
+            } catch (RemoteException ex) {
+                Log.w(TAG, "Failed to notify session created.");
+            }
+        }
+    }
+
+    /**
+     * Notifies the existing session is updated. For example, when
+     * {@link RoutingSessionInfo#getSelectedRoutes() selected routes} are changed.
+     */
+    public final void notifySessionUpdated(@NonNull RoutingSessionInfo sessionInfo) {
+        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+
+        if (DEBUG) {
+            Log.d(TAG, "notifySessionUpdated: Updating session id=" + sessionInfo);
+        }
+
+        String sessionId = sessionInfo.getId();
+        synchronized (mSessionLock) {
+            if (mSessionInfo.containsKey(sessionId)) {
+                mSessionInfo.put(sessionId, sessionInfo);
+            } else {
+                Log.w(TAG, "notifySessionUpdated: Ignoring unknown session info.");
+                return;
+            }
+        }
+        scheduleUpdateSessions();
+    }
+
+    /**
+     * Notifies that the session is released.
+     *
+     * @param sessionId the ID of the released session.
+     * @see #onReleaseSession(long, String)
+     */
+    public final void notifySessionReleased(@NonNull String sessionId) {
+        if (TextUtils.isEmpty(sessionId)) {
+            throw new IllegalArgumentException("sessionId must not be empty");
+        }
+        if (DEBUG) {
+            Log.d(TAG, "notifySessionReleased: Releasing session id=" + sessionId);
+        }
+
+        RoutingSessionInfo sessionInfo;
+        synchronized (mSessionLock) {
+            sessionInfo = mSessionInfo.remove(sessionId);
+
+            if (sessionInfo == null) {
+                Log.w(TAG, "notifySessionReleased: Ignoring unknown session info.");
+                return;
+            }
+
+            if (mRemoteCallback == null) {
+                return;
+            }
+            try {
+                mRemoteCallback.notifySessionReleased(sessionInfo);
+            } catch (RemoteException ex) {
+                Log.w(TAG, "Failed to notify session released.", ex);
+            }
+        }
+    }
+
+    /**
+     * Notifies to the client that the request has failed.
+     *
+     * @param requestId the ID of the previous request
+     * @param reason the reason why the request has failed
+     *
+     * @see #REASON_UNKNOWN_ERROR
+     * @see #REASON_REJECTED
+     * @see #REASON_NETWORK_ERROR
+     * @see #REASON_ROUTE_NOT_AVAILABLE
+     * @see #REASON_INVALID_COMMAND
+     */
+    public final void notifyRequestFailed(long requestId, @Reason int reason) {
+        if (mRemoteCallback == null) {
+            return;
+        }
+
+        if (!removeRequestId(requestId)) {
+            Log.w(TAG, "notifyRequestFailed: The requestId doesn't exist. requestId="
+                    + requestId);
+            return;
+        }
+
+        try {
+            mRemoteCallback.notifyRequestFailed(requestId, reason);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Failed to notify that the request has failed.");
+        }
+    }
+
+    /**
+     * Called when the service receives a request to create a session.
+     * <p>
+     * You should create and maintain your own session and notifies the client of
+     * session info. Call {@link #notifySessionCreated(long, RoutingSessionInfo)}
+     * with the given {@code requestId} to notify the information of a new session.
+     * The created session must have the same route feature and must include the given route
+     * specified by {@code routeId}.
+     * <p>
+     * If the session can be controlled, you can optionally pass the control hints to
+     * {@link RoutingSessionInfo.Builder#setControlHints(Bundle)}. Control hints is a
+     * {@link Bundle} which contains how to control the session.
+     * <p>
+     * If you can't create the session or want to reject the request, call
+     * {@link #notifyRequestFailed(long, int)} with the given {@code requestId}.
+     *
+     * @param requestId the ID of this request
+     * @param packageName the package name of the application that selected the route
+     * @param routeId the ID of the route initially being connected
+     * @param sessionHints an optional bundle of app-specific arguments sent by
+     *                     {@link MediaRouter2}, or null if none. The contents of this bundle
+     *                     may affect the result of session creation.
+     *
+     * @see RoutingSessionInfo.Builder#Builder(String, String)
+     * @see RoutingSessionInfo.Builder#addSelectedRoute(String)
+     * @see RoutingSessionInfo.Builder#setControlHints(Bundle)
+     */
+    public abstract void onCreateSession(long requestId, @NonNull String packageName,
+            @NonNull String routeId, @Nullable Bundle sessionHints);
+
+    /**
+     * Called when the session should be released. A client of the session or system can request
+     * a session to be released.
+     * <p>
+     * After releasing the session, call {@link #notifySessionReleased(String)}
+     * with the ID of the released session.
+     *
+     * Note: Calling {@link #notifySessionReleased(String)} will <em>NOT</em> trigger
+     * this method to be called.
+     *
+     * @param requestId the ID of this request
+     * @param sessionId the ID of the session being released.
+     * @see #notifySessionReleased(String)
+     * @see #getSessionInfo(String)
+     */
+    public abstract void onReleaseSession(long requestId, @NonNull String sessionId);
+
+    /**
+     * Called when a client requests selecting a route for the session.
+     * After the route is selected, call {@link #notifySessionUpdated(RoutingSessionInfo)}
+     * to update session info.
+     *
+     * @param requestId the ID of this request
+     * @param sessionId the ID of the session
+     * @param routeId the ID of the route
+     */
+    public abstract void onSelectRoute(long requestId, @NonNull String sessionId,
+            @NonNull String routeId);
+
+    /**
+     * Called when a client requests deselecting a route from the session.
+     * After the route is deselected, call {@link #notifySessionUpdated(RoutingSessionInfo)}
+     * to update session info.
+     *
+     * @param requestId the ID of this request
+     * @param sessionId the ID of the session
+     * @param routeId the ID of the route
+     */
+    public abstract void onDeselectRoute(long requestId, @NonNull String sessionId,
+            @NonNull String routeId);
+
+    /**
+     * Called when a client requests transferring a session to a route.
+     * After the transfer is finished, call {@link #notifySessionUpdated(RoutingSessionInfo)}
+     * to update session info.
+     *
+     * @param requestId the ID of this request
+     * @param sessionId the ID of the session
+     * @param routeId the ID of the route
+     */
+    public abstract void onTransferToRoute(long requestId, @NonNull String sessionId,
+            @NonNull String routeId);
+
+    /**
+     * Called when the {@link RouteDiscoveryPreference discovery preference} has changed.
+     * <p>
+     * Whenever an application registers a {@link MediaRouter2.RouteCallback callback},
+     * it also provides a discovery preference to specify features of routes that it is interested
+     * in. The media router combines all of these discovery request into a single discovery
+     * preference and notifies each provider.
+     * </p><p>
+     * The provider should examine {@link RouteDiscoveryPreference#getPreferredFeatures()
+     * preferred features} in the discovery preference to determine what kind of routes it should
+     * try to discover and whether it should perform active or passive scans. In many cases,
+     * the provider may be able to save power by not performing any scans when the request doesn't
+     * have any matching route features.
+     * </p>
+     *
+     * @param preference the new discovery preference
+     */
+    public void onDiscoveryPreferenceChanged(@NonNull RouteDiscoveryPreference preference) {}
+
+    /**
+     * Updates routes of the provider and notifies the system media router service.
+     */
+    public final void notifyRoutes(@NonNull Collection<MediaRoute2Info> routes) {
+        Objects.requireNonNull(routes, "routes must not be null");
+        mProviderInfo = new MediaRoute2ProviderInfo.Builder()
+                .addRoutes(routes)
+                .build();
+        schedulePublishState();
+    }
+
+    void setCallback(IMediaRoute2ProviderServiceCallback callback) {
+        mRemoteCallback = callback;
+        schedulePublishState();
+        scheduleUpdateSessions();
+    }
+
+    void schedulePublishState() {
+        if (mStatePublishScheduled.compareAndSet(false, true)) {
+            mHandler.post(this::publishState);
+        }
+    }
+
+    private void publishState() {
+        if (!mStatePublishScheduled.compareAndSet(true, false)) {
+            return;
+        }
+
+        if (mRemoteCallback == null) {
+            return;
+        }
+
+        try {
+            mRemoteCallback.notifyProviderUpdated(mProviderInfo);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Failed to publish provider state.", ex);
+        }
+    }
+
+    void scheduleUpdateSessions() {
+        if (mSessionUpdateScheduled.compareAndSet(false, true)) {
+            mHandler.post(this::updateSessions);
+        }
+    }
+
+    private void updateSessions() {
+        if (!mSessionUpdateScheduled.compareAndSet(true, false)) {
+            return;
+        }
+
+        if (mRemoteCallback == null) {
+            return;
+        }
+
+        List<RoutingSessionInfo> sessions;
+        synchronized (mSessionLock) {
+            sessions = new ArrayList<>(mSessionInfo.values());
+        }
+
+        try {
+            mRemoteCallback.notifySessionsUpdated(sessions);
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Failed to notify session info changed.");
+        }
+
+    }
+
+    /**
+     * Adds a requestId in the request ID list whose max size is {@link #MAX_REQUEST_IDS_SIZE}.
+     * When the max size is reached, the first element is removed (FIFO).
+     */
+    private void addRequestId(long requestId) {
+        synchronized (mRequestIdsLock) {
+            if (mRequestIds.size() >= MAX_REQUEST_IDS_SIZE) {
+                mRequestIds.removeFirst();
+            }
+            mRequestIds.addLast(requestId);
+        }
+    }
+
+    /**
+     * Removes the given {@code requestId} from received request ID list.
+     * <p>
+     * Returns whether the list contains the {@code requestId}. These are the cases when the list
+     * doesn't contain the given {@code requestId}:
+     * <ul>
+     *     <li>This service has never received a request with the requestId. </li>
+     *     <li>{@link #notifyRequestFailed} or {@link #notifySessionCreated} already has been called
+     *         for the requestId. </li>
+     * </ul>
+     */
+    private boolean removeRequestId(long requestId) {
+        synchronized (mRequestIdsLock) {
+            return mRequestIds.removeFirstOccurrence(requestId);
+        }
+    }
+
+    final class MediaRoute2ProviderServiceStub extends IMediaRoute2ProviderService.Stub {
+        MediaRoute2ProviderServiceStub() { }
+
+        private boolean checkCallerIsSystem() {
+            return Binder.getCallingUid() == Process.SYSTEM_UID;
+        }
+
+        private boolean checkSessionIdIsValid(String sessionId, String description) {
+            if (TextUtils.isEmpty(sessionId)) {
+                Log.w(TAG, description + ": Ignoring empty sessionId from system service.");
+                return false;
+            }
+            if (getSessionInfo(sessionId) == null) {
+                Log.w(TAG, description + ": Ignoring unknown session from system service. "
+                        + "sessionId=" + sessionId);
+                return false;
+            }
+            return true;
+        }
+
+        private boolean checkRouteIdIsValid(String routeId, String description) {
+            if (TextUtils.isEmpty(routeId)) {
+                Log.w(TAG, description + ": Ignoring empty routeId from system service.");
+                return false;
+            }
+            if (mProviderInfo == null || mProviderInfo.getRoute(routeId) == null) {
+                Log.w(TAG, description + ": Ignoring unknown route from system service. "
+                        + "routeId=" + routeId);
+                return false;
+            }
+            return true;
+        }
+
+        @Override
+        public void setCallback(IMediaRoute2ProviderServiceCallback callback) {
+            if (!checkCallerIsSystem()) {
+                return;
+            }
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::setCallback,
+                    MediaRoute2ProviderService.this, callback));
+        }
+
+        @Override
+        public void updateDiscoveryPreference(RouteDiscoveryPreference discoveryPreference) {
+            if (!checkCallerIsSystem()) {
+                return;
+            }
+            mHandler.sendMessage(obtainMessage(
+                    MediaRoute2ProviderService::onDiscoveryPreferenceChanged,
+                    MediaRoute2ProviderService.this, discoveryPreference));
+        }
+
+        @Override
+        public void setRouteVolume(long requestId, String routeId, int volume) {
+            if (!checkCallerIsSystem()) {
+                return;
+            }
+            if (!checkRouteIdIsValid(routeId, "setRouteVolume")) {
+                return;
+            }
+            addRequestId(requestId);
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetRouteVolume,
+                    MediaRoute2ProviderService.this, requestId, routeId, volume));
+        }
+
+        @Override
+        public void requestCreateSession(long requestId, String packageName, String routeId,
+                @Nullable Bundle requestCreateSession) {
+            if (!checkCallerIsSystem()) {
+                return;
+            }
+            if (!checkRouteIdIsValid(routeId, "requestCreateSession")) {
+                return;
+            }
+            addRequestId(requestId);
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onCreateSession,
+                    MediaRoute2ProviderService.this, requestId, packageName, routeId,
+                    requestCreateSession));
+        }
+
+        @Override
+        public void selectRoute(long requestId, String sessionId, String routeId) {
+            if (!checkCallerIsSystem()) {
+                return;
+            }
+            if (!checkSessionIdIsValid(sessionId, "selectRoute")
+                    || !checkRouteIdIsValid(routeId, "selectRoute")) {
+                return;
+            }
+            addRequestId(requestId);
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSelectRoute,
+                    MediaRoute2ProviderService.this, requestId, sessionId, routeId));
+        }
+
+        @Override
+        public void deselectRoute(long requestId, String sessionId, String routeId) {
+            if (!checkCallerIsSystem()) {
+                return;
+            }
+            if (!checkSessionIdIsValid(sessionId, "deselectRoute")
+                    || !checkRouteIdIsValid(routeId, "deselectRoute")) {
+                return;
+            }
+            addRequestId(requestId);
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onDeselectRoute,
+                    MediaRoute2ProviderService.this, requestId, sessionId, routeId));
+        }
+
+        @Override
+        public void transferToRoute(long requestId, String sessionId, String routeId) {
+            if (!checkCallerIsSystem()) {
+                return;
+            }
+            if (!checkSessionIdIsValid(sessionId, "transferToRoute")
+                    || !checkRouteIdIsValid(routeId, "transferToRoute")) {
+                return;
+            }
+            addRequestId(requestId);
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onTransferToRoute,
+                    MediaRoute2ProviderService.this, requestId, sessionId, routeId));
+        }
+
+        @Override
+        public void setSessionVolume(long requestId, String sessionId, int volume) {
+            if (!checkCallerIsSystem()) {
+                return;
+            }
+            if (!checkSessionIdIsValid(sessionId, "setSessionVolume")) {
+                return;
+            }
+            addRequestId(requestId);
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onSetSessionVolume,
+                    MediaRoute2ProviderService.this, requestId, sessionId, volume));
+        }
+
+        @Override
+        public void releaseSession(long requestId, String sessionId) {
+            if (!checkCallerIsSystem()) {
+                return;
+            }
+            if (!checkSessionIdIsValid(sessionId, "releaseSession")) {
+                return;
+            }
+            addRequestId(requestId);
+            mHandler.sendMessage(obtainMessage(MediaRoute2ProviderService::onReleaseSession,
+                    MediaRoute2ProviderService.this, requestId, sessionId));
+        }
+    }
+}
diff --git a/android/media/MediaRouter.java b/android/media/MediaRouter.java
new file mode 100644
index 0000000..345d9b2
--- /dev/null
+++ b/android/media/MediaRouter.java
@@ -0,0 +1,3205 @@
+/*
+ * Copyright (C) 2012 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.Manifest;
+import android.annotation.DrawableRes;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemService;
+import android.app.ActivityThread;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.content.res.Resources;
+import android.graphics.drawable.Drawable;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.WifiDisplay;
+import android.hardware.display.WifiDisplayStatus;
+import android.media.session.MediaSession;
+import android.os.Build;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.UserHandle;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.SparseIntArray;
+import android.view.Display;
+import android.view.DisplayAddress;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * MediaRouter allows applications to control the routing of media channels
+ * and streams from the current device to external speakers and destination devices.
+ *
+ * <p>A MediaRouter is retrieved through {@link Context#getSystemService(String)
+ * Context.getSystemService()} of a {@link Context#MEDIA_ROUTER_SERVICE
+ * Context.MEDIA_ROUTER_SERVICE}.
+ *
+ * <p>The media router API is not thread-safe; all interactions with it must be
+ * done from the main thread of the process.</p>
+ *
+ * <p>
+ * We recommend using {@link android.media.MediaRouter2} APIs for new applications.
+ * </p>
+ */
+//TODO: Link androidx.media2.MediaRouter when we are ready.
+@SystemService(Context.MEDIA_ROUTER_SERVICE)
+public class MediaRouter {
+    private static final String TAG = "MediaRouter";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final boolean DEBUG_RESTORE_ROUTE = true;
+
+    static class Static implements DisplayManager.DisplayListener {
+        final String mPackageName;
+        final Resources mResources;
+        final IAudioService mAudioService;
+        final DisplayManager mDisplayService;
+        final IMediaRouterService mMediaRouterService;
+        final Handler mHandler;
+        final CopyOnWriteArrayList<CallbackInfo> mCallbacks =
+                new CopyOnWriteArrayList<CallbackInfo>();
+
+        final ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
+        final ArrayList<RouteCategory> mCategories = new ArrayList<RouteCategory>();
+
+        final RouteCategory mSystemCategory;
+
+        final AudioRoutesInfo mCurAudioRoutesInfo = new AudioRoutesInfo();
+
+        RouteInfo mDefaultAudioVideo;
+        RouteInfo mBluetoothA2dpRoute;
+        boolean mIsBluetoothA2dpOn;
+
+        RouteInfo mSelectedRoute;
+
+        final boolean mCanConfigureWifiDisplays;
+        boolean mActivelyScanningWifiDisplays;
+        String mPreviousActiveWifiDisplayAddress;
+
+        int mDiscoveryRequestRouteTypes;
+        boolean mDiscoverRequestActiveScan;
+
+        int mCurrentUserId = -1;
+        IMediaRouterClient mClient;
+        MediaRouterClientState mClientState;
+
+        SparseIntArray mStreamVolume = new SparseIntArray();
+
+        final IAudioRoutesObserver.Stub mAudioRoutesObserver = new IAudioRoutesObserver.Stub() {
+            @Override
+            public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) {
+                try {
+                    mIsBluetoothA2dpOn = mAudioService.isBluetoothA2dpOn();
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error querying Bluetooth A2DP state", e);
+                    //TODO: When we reach here, mIsBluetoothA2dpOn may not be synced with
+                    // mBluetoothA2dpRoute.
+                }
+                mHandler.post(new Runnable() {
+                    @Override public void run() {
+                        updateAudioRoutes(newRoutes);
+                    }
+                });
+            }
+        };
+
+        Static(Context appContext) {
+            mPackageName = appContext.getPackageName();
+            mResources = appContext.getResources();
+            mHandler = new Handler(appContext.getMainLooper());
+
+            IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
+            mAudioService = IAudioService.Stub.asInterface(b);
+
+            mDisplayService = (DisplayManager) appContext.getSystemService(Context.DISPLAY_SERVICE);
+
+            mMediaRouterService = IMediaRouterService.Stub.asInterface(
+                    ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
+
+            mSystemCategory = new RouteCategory(
+                    com.android.internal.R.string.default_audio_route_category_name,
+                    ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO, false);
+            mSystemCategory.mIsSystem = true;
+
+            // Only the system can configure wifi displays.  The display manager
+            // enforces this with a permission check.  Set a flag here so that we
+            // know whether this process is actually allowed to scan and connect.
+            mCanConfigureWifiDisplays = appContext.checkPermission(
+                    Manifest.permission.CONFIGURE_WIFI_DISPLAY,
+                    Process.myPid(), Process.myUid()) == PackageManager.PERMISSION_GRANTED;
+        }
+
+        // Called after sStatic is initialized
+        void startMonitoringRoutes(Context appContext) {
+            mDefaultAudioVideo = new RouteInfo(mSystemCategory);
+            mDefaultAudioVideo.mNameResId = com.android.internal.R.string.default_audio_route_name;
+            mDefaultAudioVideo.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO;
+            mDefaultAudioVideo.updatePresentationDisplay();
+            if (((AudioManager) appContext.getSystemService(Context.AUDIO_SERVICE))
+                    .isVolumeFixed()) {
+                mDefaultAudioVideo.mVolumeHandling = RouteInfo.PLAYBACK_VOLUME_FIXED;
+            }
+
+            addRouteStatic(mDefaultAudioVideo);
+
+            // This will select the active wifi display route if there is one.
+            updateWifiDisplayStatus(mDisplayService.getWifiDisplayStatus());
+
+            appContext.registerReceiver(new WifiDisplayStatusChangedReceiver(),
+                    new IntentFilter(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED));
+            appContext.registerReceiver(new VolumeChangeReceiver(),
+                    new IntentFilter(AudioManager.VOLUME_CHANGED_ACTION));
+
+            mDisplayService.registerDisplayListener(this, mHandler);
+
+            AudioRoutesInfo newAudioRoutes = null;
+            try {
+                mIsBluetoothA2dpOn = mAudioService.isBluetoothA2dpOn();
+                newAudioRoutes = mAudioService.startWatchingRoutes(mAudioRoutesObserver);
+            } catch (RemoteException e) {
+            }
+            if (newAudioRoutes != null) {
+                // This will select the active BT route if there is one and the current
+                // selected route is the default system route, or if there is no selected
+                // route yet.
+                updateAudioRoutes(newAudioRoutes);
+            }
+
+            // Bind to the media router service.
+            rebindAsUser(UserHandle.myUserId());
+
+            // Select the default route if the above didn't sync us up
+            // appropriately with relevant system state.
+            if (mSelectedRoute == null) {
+                selectDefaultRouteStatic();
+            }
+        }
+
+        void updateAudioRoutes(AudioRoutesInfo newRoutes) {
+            boolean audioRoutesChanged = false;
+            boolean forceUseDefaultRoute = false;
+
+            if (newRoutes.mainType != mCurAudioRoutesInfo.mainType) {
+                mCurAudioRoutesInfo.mainType = newRoutes.mainType;
+                int name;
+                if ((newRoutes.mainType & AudioRoutesInfo.MAIN_HEADPHONES) != 0
+                        || (newRoutes.mainType & AudioRoutesInfo.MAIN_HEADSET) != 0) {
+                    name = com.android.internal.R.string.default_audio_route_name_headphones;
+                } else if ((newRoutes.mainType & AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) {
+                    name = com.android.internal.R.string.default_audio_route_name_dock_speakers;
+                } else if ((newRoutes.mainType&AudioRoutesInfo.MAIN_HDMI) != 0) {
+                    name = com.android.internal.R.string.default_audio_route_name_hdmi;
+                } else if ((newRoutes.mainType&AudioRoutesInfo.MAIN_USB) != 0) {
+                    name = com.android.internal.R.string.default_audio_route_name_usb;
+                } else {
+                    name = com.android.internal.R.string.default_audio_route_name;
+                }
+                mDefaultAudioVideo.mNameResId = name;
+                dispatchRouteChanged(mDefaultAudioVideo);
+
+                if ((newRoutes.mainType & (AudioRoutesInfo.MAIN_HEADSET
+                        | AudioRoutesInfo.MAIN_HEADPHONES | AudioRoutesInfo.MAIN_USB)) != 0) {
+                    forceUseDefaultRoute = true;
+                }
+                audioRoutesChanged = true;
+            }
+
+            if (!TextUtils.equals(newRoutes.bluetoothName, mCurAudioRoutesInfo.bluetoothName)) {
+                forceUseDefaultRoute = false;
+                if (newRoutes.bluetoothName != null) {
+                    if (mBluetoothA2dpRoute == null) {
+                        // BT connected
+                        final RouteInfo info = new RouteInfo(mSystemCategory);
+                        info.mName = newRoutes.bluetoothName;
+                        info.mDescription = mResources.getText(
+                                com.android.internal.R.string.bluetooth_a2dp_audio_route_name);
+                        info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO;
+                        info.mDeviceType = RouteInfo.DEVICE_TYPE_BLUETOOTH;
+                        mBluetoothA2dpRoute = info;
+                        addRouteStatic(mBluetoothA2dpRoute);
+                    } else {
+                        mBluetoothA2dpRoute.mName = newRoutes.bluetoothName;
+                        dispatchRouteChanged(mBluetoothA2dpRoute);
+                    }
+                } else if (mBluetoothA2dpRoute != null) {
+                    // BT disconnected
+                    RouteInfo btRoute = mBluetoothA2dpRoute;
+                    mBluetoothA2dpRoute = null;
+                    removeRouteStatic(btRoute);
+                }
+                audioRoutesChanged = true;
+            }
+
+            if (audioRoutesChanged) {
+                Log.v(TAG, "Audio routes updated: " + newRoutes + ", a2dp=" + isBluetoothA2dpOn());
+                if (mSelectedRoute == null || mSelectedRoute.isDefault()
+                        || mSelectedRoute.isBluetooth()) {
+                    if (forceUseDefaultRoute || mBluetoothA2dpRoute == null) {
+                        selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo, false);
+                    } else {
+                        selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute, false);
+                    }
+                }
+            }
+            mCurAudioRoutesInfo.bluetoothName = newRoutes.bluetoothName;
+        }
+
+        int getStreamVolume(int streamType) {
+            int idx = mStreamVolume.indexOfKey(streamType);
+            if (idx < 0) {
+                int volume = 0;
+                try {
+                    volume = mAudioService.getStreamVolume(streamType);
+                    mStreamVolume.put(streamType, volume);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error getting local stream volume", e);
+                } finally {
+                    return volume;
+                }
+            }
+            return mStreamVolume.valueAt(idx);
+        }
+
+        boolean isBluetoothA2dpOn() {
+            return mBluetoothA2dpRoute != null && mIsBluetoothA2dpOn;
+        }
+
+        void updateDiscoveryRequest() {
+            // What are we looking for today?
+            int routeTypes = 0;
+            int passiveRouteTypes = 0;
+            boolean activeScan = false;
+            boolean activeScanWifiDisplay = false;
+            final int count = mCallbacks.size();
+            for (int i = 0; i < count; i++) {
+                CallbackInfo cbi = mCallbacks.get(i);
+                if ((cbi.flags & (CALLBACK_FLAG_PERFORM_ACTIVE_SCAN
+                        | CALLBACK_FLAG_REQUEST_DISCOVERY)) != 0) {
+                    // Discovery explicitly requested.
+                    routeTypes |= cbi.type;
+                } else if ((cbi.flags & CALLBACK_FLAG_PASSIVE_DISCOVERY) != 0) {
+                    // Discovery only passively requested.
+                    passiveRouteTypes |= cbi.type;
+                } else {
+                    // Legacy case since applications don't specify the discovery flag.
+                    // Unfortunately we just have to assume they always need discovery
+                    // whenever they have a callback registered.
+                    routeTypes |= cbi.type;
+                }
+                if ((cbi.flags & CALLBACK_FLAG_PERFORM_ACTIVE_SCAN) != 0) {
+                    activeScan = true;
+                    if ((cbi.type & ROUTE_TYPE_REMOTE_DISPLAY) != 0) {
+                        activeScanWifiDisplay = true;
+                    }
+                }
+            }
+            if (routeTypes != 0 || activeScan) {
+                // If someone else requests discovery then enable the passive listeners.
+                // This is used by the MediaRouteButton and MediaRouteActionProvider since
+                // they don't receive lifecycle callbacks from the Activity.
+                routeTypes |= passiveRouteTypes;
+            }
+
+            // Update wifi display scanning.
+            // TODO: All of this should be managed by the media router service.
+            if (mCanConfigureWifiDisplays) {
+                if (mSelectedRoute != null
+                        && mSelectedRoute.matchesTypes(ROUTE_TYPE_REMOTE_DISPLAY)) {
+                    // Don't scan while already connected to a remote display since
+                    // it may interfere with the ongoing transmission.
+                    activeScanWifiDisplay = false;
+                }
+                if (activeScanWifiDisplay) {
+                    if (!mActivelyScanningWifiDisplays) {
+                        mActivelyScanningWifiDisplays = true;
+                        mDisplayService.startWifiDisplayScan();
+                    }
+                } else {
+                    if (mActivelyScanningWifiDisplays) {
+                        mActivelyScanningWifiDisplays = false;
+                        mDisplayService.stopWifiDisplayScan();
+                    }
+                }
+            }
+
+            // Tell the media router service all about it.
+            if (routeTypes != mDiscoveryRequestRouteTypes
+                    || activeScan != mDiscoverRequestActiveScan) {
+                mDiscoveryRequestRouteTypes = routeTypes;
+                mDiscoverRequestActiveScan = activeScan;
+                publishClientDiscoveryRequest();
+            }
+        }
+
+        @Override
+        public void onDisplayAdded(int displayId) {
+            updatePresentationDisplays(displayId);
+        }
+
+        @Override
+        public void onDisplayChanged(int displayId) {
+            updatePresentationDisplays(displayId);
+        }
+
+        @Override
+        public void onDisplayRemoved(int displayId) {
+            updatePresentationDisplays(displayId);
+        }
+
+        public void setRouterGroupId(String groupId) {
+            if (mClient != null) {
+                try {
+                    mMediaRouterService.registerClientGroupId(mClient, groupId);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to register group ID of the client.", ex);
+                }
+            }
+        }
+
+        public Display[] getAllPresentationDisplays() {
+            try {
+                return mDisplayService.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
+            } catch (RuntimeException ex) {
+                Log.e(TAG, "Unable to get displays.", ex);
+                return null;
+            }
+        }
+
+        private void updatePresentationDisplays(int changedDisplayId) {
+            final int count = mRoutes.size();
+            for (int i = 0; i < count; i++) {
+                final RouteInfo route = mRoutes.get(i);
+                if (route.updatePresentationDisplay() || (route.mPresentationDisplay != null
+                        && route.mPresentationDisplay.getDisplayId() == changedDisplayId)) {
+                    dispatchRoutePresentationDisplayChanged(route);
+                }
+            }
+        }
+
+        void handleGroupRouteSelected(String routeId) {
+            RouteInfo routeToSelect = isBluetoothA2dpOn()
+                    ? mBluetoothA2dpRoute : mDefaultAudioVideo;
+            final int count = mRoutes.size();
+            for (int i = 0; i < count; i++) {
+                final RouteInfo route = mRoutes.get(i);
+                if (TextUtils.equals(route.mGlobalRouteId, routeId)) {
+                    routeToSelect = route;
+                }
+            }
+            if (routeToSelect != mSelectedRoute) {
+                selectRouteStatic(routeToSelect.mSupportedTypes, routeToSelect, /*explicit=*/false);
+            }
+        }
+
+        void setSelectedRoute(RouteInfo info, boolean explicit) {
+            // Must be non-reentrant.
+            mSelectedRoute = info;
+            publishClientSelectedRoute(explicit);
+        }
+
+        void rebindAsUser(int userId) {
+            if (mCurrentUserId != userId || userId < 0 || mClient == null) {
+                if (mClient != null) {
+                    try {
+                        mMediaRouterService.unregisterClient(mClient);
+                    } catch (RemoteException ex) {
+                        Log.e(TAG, "Unable to unregister media router client.", ex);
+                    }
+                    mClient = null;
+                }
+
+                mCurrentUserId = userId;
+
+                try {
+                    Client client = new Client();
+                    mMediaRouterService.registerClientAsUser(client, mPackageName, userId);
+                    mClient = client;
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to register media router client.", ex);
+                }
+
+                publishClientDiscoveryRequest();
+                publishClientSelectedRoute(false);
+                updateClientState();
+            }
+        }
+
+        void publishClientDiscoveryRequest() {
+            if (mClient != null) {
+                try {
+                    mMediaRouterService.setDiscoveryRequest(mClient,
+                            mDiscoveryRequestRouteTypes, mDiscoverRequestActiveScan);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to publish media router client discovery request.", ex);
+                }
+            }
+        }
+
+        void publishClientSelectedRoute(boolean explicit) {
+            if (mClient != null) {
+                try {
+                    mMediaRouterService.setSelectedRoute(mClient,
+                            mSelectedRoute != null ? mSelectedRoute.mGlobalRouteId : null,
+                            explicit);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to publish media router client selected route.", ex);
+                }
+            }
+        }
+
+        void updateClientState() {
+            // Update the client state.
+            mClientState = null;
+            if (mClient != null) {
+                try {
+                    mClientState = mMediaRouterService.getState(mClient);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to retrieve media router client state.", ex);
+                }
+            }
+            final ArrayList<MediaRouterClientState.RouteInfo> globalRoutes =
+                    mClientState != null ? mClientState.routes : null;
+
+            // Add or update routes.
+            final int globalRouteCount = globalRoutes != null ? globalRoutes.size() : 0;
+            for (int i = 0; i < globalRouteCount; i++) {
+                final MediaRouterClientState.RouteInfo globalRoute = globalRoutes.get(i);
+                RouteInfo route = findGlobalRoute(globalRoute.id);
+                if (route == null) {
+                    route = makeGlobalRoute(globalRoute);
+                    addRouteStatic(route);
+                } else {
+                    updateGlobalRoute(route, globalRoute);
+                }
+            }
+
+            // Remove defunct routes.
+            outer: for (int i = mRoutes.size(); i-- > 0; ) {
+                final RouteInfo route = mRoutes.get(i);
+                final String globalRouteId = route.mGlobalRouteId;
+                if (globalRouteId != null) {
+                    for (int j = 0; j < globalRouteCount; j++) {
+                        MediaRouterClientState.RouteInfo globalRoute = globalRoutes.get(j);
+                        if (globalRouteId.equals(globalRoute.id)) {
+                            continue outer; // found
+                        }
+                    }
+                    // not found
+                    removeRouteStatic(route);
+                }
+            }
+        }
+
+        void requestSetVolume(RouteInfo route, int volume) {
+            if (route.mGlobalRouteId != null && mClient != null) {
+                try {
+                    mMediaRouterService.requestSetVolume(mClient,
+                            route.mGlobalRouteId, volume);
+                } catch (RemoteException ex) {
+                    Log.w(TAG, "Unable to request volume change.", ex);
+                }
+            }
+        }
+
+        void requestUpdateVolume(RouteInfo route, int direction) {
+            if (route.mGlobalRouteId != null && mClient != null) {
+                try {
+                    mMediaRouterService.requestUpdateVolume(mClient,
+                            route.mGlobalRouteId, direction);
+                } catch (RemoteException ex) {
+                    Log.w(TAG, "Unable to request volume change.", ex);
+                }
+            }
+        }
+
+        RouteInfo makeGlobalRoute(MediaRouterClientState.RouteInfo globalRoute) {
+            RouteInfo route = new RouteInfo(mSystemCategory);
+            route.mGlobalRouteId = globalRoute.id;
+            route.mName = globalRoute.name;
+            route.mDescription = globalRoute.description;
+            route.mSupportedTypes = globalRoute.supportedTypes;
+            route.mDeviceType = globalRoute.deviceType;
+            route.mEnabled = globalRoute.enabled;
+            route.setRealStatusCode(globalRoute.statusCode);
+            route.mPlaybackType = globalRoute.playbackType;
+            route.mPlaybackStream = globalRoute.playbackStream;
+            route.mVolume = globalRoute.volume;
+            route.mVolumeMax = globalRoute.volumeMax;
+            route.mVolumeHandling = globalRoute.volumeHandling;
+            route.mPresentationDisplayId = globalRoute.presentationDisplayId;
+            route.updatePresentationDisplay();
+            return route;
+        }
+
+        void updateGlobalRoute(RouteInfo route, MediaRouterClientState.RouteInfo globalRoute) {
+            boolean changed = false;
+            boolean volumeChanged = false;
+            boolean presentationDisplayChanged = false;
+
+            if (!Objects.equals(route.mName, globalRoute.name)) {
+                route.mName = globalRoute.name;
+                changed = true;
+            }
+            if (!Objects.equals(route.mDescription, globalRoute.description)) {
+                route.mDescription = globalRoute.description;
+                changed = true;
+            }
+            final int oldSupportedTypes = route.mSupportedTypes;
+            if (oldSupportedTypes != globalRoute.supportedTypes) {
+                route.mSupportedTypes = globalRoute.supportedTypes;
+                changed = true;
+            }
+            if (route.mEnabled != globalRoute.enabled) {
+                route.mEnabled = globalRoute.enabled;
+                changed = true;
+            }
+            if (route.mRealStatusCode != globalRoute.statusCode) {
+                route.setRealStatusCode(globalRoute.statusCode);
+                changed = true;
+            }
+            if (route.mPlaybackType != globalRoute.playbackType) {
+                route.mPlaybackType = globalRoute.playbackType;
+                changed = true;
+            }
+            if (route.mPlaybackStream != globalRoute.playbackStream) {
+                route.mPlaybackStream = globalRoute.playbackStream;
+                changed = true;
+            }
+            if (route.mVolume != globalRoute.volume) {
+                route.mVolume = globalRoute.volume;
+                changed = true;
+                volumeChanged = true;
+            }
+            if (route.mVolumeMax != globalRoute.volumeMax) {
+                route.mVolumeMax = globalRoute.volumeMax;
+                changed = true;
+                volumeChanged = true;
+            }
+            if (route.mVolumeHandling != globalRoute.volumeHandling) {
+                route.mVolumeHandling = globalRoute.volumeHandling;
+                changed = true;
+                volumeChanged = true;
+            }
+            if (route.mPresentationDisplayId != globalRoute.presentationDisplayId) {
+                route.mPresentationDisplayId = globalRoute.presentationDisplayId;
+                route.updatePresentationDisplay();
+                changed = true;
+                presentationDisplayChanged = true;
+            }
+
+            if (changed) {
+                dispatchRouteChanged(route, oldSupportedTypes);
+            }
+            if (volumeChanged) {
+                dispatchRouteVolumeChanged(route);
+            }
+            if (presentationDisplayChanged) {
+                dispatchRoutePresentationDisplayChanged(route);
+            }
+        }
+
+        RouteInfo findGlobalRoute(String globalRouteId) {
+            final int count = mRoutes.size();
+            for (int i = 0; i < count; i++) {
+                final RouteInfo route = mRoutes.get(i);
+                if (globalRouteId.equals(route.mGlobalRouteId)) {
+                    return route;
+                }
+            }
+            return null;
+        }
+
+        boolean isPlaybackActive() {
+            if (mClient != null) {
+                try {
+                    return mMediaRouterService.isPlaybackActive(mClient);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to retrieve playback active state.", ex);
+                }
+            }
+            return false;
+        }
+
+        final class Client extends IMediaRouterClient.Stub {
+            @Override
+            public void onStateChanged() {
+                mHandler.post(() -> {
+                    if (Client.this == mClient) {
+                        updateClientState();
+                    }
+                });
+            }
+
+            @Override
+            public void onRestoreRoute() {
+                mHandler.post(() -> {
+                    // Skip restoring route if the selected route is not a system audio route,
+                    // MediaRouter is initializing, or mClient was changed.
+                    if (Client.this != mClient || mSelectedRoute == null
+                            || (!mSelectedRoute.isDefault() && !mSelectedRoute.isBluetooth())) {
+                        return;
+                    }
+                    if (DEBUG_RESTORE_ROUTE) {
+                        if (mSelectedRoute.isDefault() && mBluetoothA2dpRoute != null) {
+                            Log.d(TAG, "onRestoreRoute() : selectedRoute=" + mSelectedRoute
+                                    + ", a2dpRoute=" + mBluetoothA2dpRoute);
+                        } else {
+                            Log.d(TAG, "onRestoreRoute() : route=" + mSelectedRoute);
+                        }
+                    }
+                    mSelectedRoute.select();
+                });
+            }
+
+            @Override
+            public void onGroupRouteSelected(String groupRouteId) {
+                mHandler.post(() -> {
+                    if (Client.this == mClient) {
+                        handleGroupRouteSelected(groupRouteId);
+                    }
+                });
+            }
+
+            // Called when the selection of a connected device (phone speaker or BT devices)
+            // is changed.
+            @Override
+            public void onGlobalA2dpChanged(boolean a2dpOn) {
+                mHandler.post(() -> {
+                    if (mSelectedRoute == null || mBluetoothA2dpRoute == null) {
+                        return;
+                    }
+                    if (mSelectedRoute.isDefault() && a2dpOn) {
+                        setSelectedRoute(mBluetoothA2dpRoute, /*explicit=*/ false);
+                        dispatchRouteUnselected(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo);
+                        dispatchRouteSelected(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute);
+                    } else if (mSelectedRoute.isBluetooth() && !a2dpOn) {
+                        setSelectedRoute(mDefaultAudioVideo, /*explicit=*/ false);
+                        dispatchRouteUnselected(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute);
+                        dispatchRouteSelected(ROUTE_TYPE_LIVE_AUDIO, mDefaultAudioVideo);
+                    }
+                });
+            }
+        }
+    }
+
+    static Static sStatic;
+
+    /**
+     * Route type flag for live audio.
+     *
+     * <p>A device that supports live audio routing will allow the media audio stream
+     * to be routed to supported destinations. This can include internal speakers or
+     * audio jacks on the device itself, A2DP devices, and more.</p>
+     *
+     * <p>Once initiated this routing is transparent to the application. All audio
+     * played on the media stream will be routed to the selected destination.</p>
+     */
+    public static final int ROUTE_TYPE_LIVE_AUDIO = 1 << 0;
+
+    /**
+     * Route type flag for live video.
+     *
+     * <p>A device that supports live video routing will allow a mirrored version
+     * of the device's primary display or a customized
+     * {@link android.app.Presentation Presentation} to be routed to supported destinations.</p>
+     *
+     * <p>Once initiated, display mirroring is transparent to the application.
+     * While remote routing is active the application may use a
+     * {@link android.app.Presentation Presentation} to replace the mirrored view
+     * on the external display with different content.</p>
+     *
+     * @see RouteInfo#getPresentationDisplay()
+     * @see android.app.Presentation
+     */
+    public static final int ROUTE_TYPE_LIVE_VIDEO = 1 << 1;
+
+    /**
+     * Temporary interop constant to identify remote displays.
+     * @hide To be removed when media router API is updated.
+     */
+    public static final int ROUTE_TYPE_REMOTE_DISPLAY = 1 << 2;
+
+    /**
+     * Route type flag for application-specific usage.
+     *
+     * <p>Unlike other media route types, user routes are managed by the application.
+     * The MediaRouter will manage and dispatch events for user routes, but the application
+     * is expected to interpret the meaning of these events and perform the requested
+     * routing tasks.</p>
+     */
+    public static final int ROUTE_TYPE_USER = 1 << 23;
+
+    static final int ROUTE_TYPE_ANY = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO
+            | ROUTE_TYPE_REMOTE_DISPLAY | ROUTE_TYPE_USER;
+
+    /**
+     * Flag for {@link #addCallback}: Actively scan for routes while this callback
+     * is registered.
+     * <p>
+     * When this flag is specified, the media router will actively scan for new
+     * routes.  Certain routes, such as wifi display routes, may not be discoverable
+     * except when actively scanning.  This flag is typically used when the route picker
+     * dialog has been opened by the user to ensure that the route information is
+     * up to date.
+     * </p><p>
+     * Active scanning may consume a significant amount of power and may have intrusive
+     * effects on wireless connectivity.  Therefore it is important that active scanning
+     * only be requested when it is actually needed to satisfy a user request to
+     * discover and select a new route.
+     * </p>
+     */
+    public static final int CALLBACK_FLAG_PERFORM_ACTIVE_SCAN = 1 << 0;
+
+    /**
+     * Flag for {@link #addCallback}: Do not filter route events.
+     * <p>
+     * When this flag is specified, the callback will be invoked for event that affect any
+     * route even if they do not match the callback's filter.
+     * </p>
+     */
+    public static final int CALLBACK_FLAG_UNFILTERED_EVENTS = 1 << 1;
+
+    /**
+     * Explicitly requests discovery.
+     *
+     * @hide Future API ported from support library.  Revisit this later.
+     */
+    public static final int CALLBACK_FLAG_REQUEST_DISCOVERY = 1 << 2;
+
+    /**
+     * Requests that discovery be performed but only if there is some other active
+     * callback already registered.
+     *
+     * @hide Compatibility workaround for the fact that applications do not currently
+     * request discovery explicitly (except when using the support library API).
+     */
+    public static final int CALLBACK_FLAG_PASSIVE_DISCOVERY = 1 << 3;
+
+    /**
+     * Flag for {@link #isRouteAvailable}: Ignore the default route.
+     * <p>
+     * This flag is used to determine whether a matching non-default route is available.
+     * This constraint may be used to decide whether to offer the route chooser dialog
+     * to the user.  There is no point offering the chooser if there are no
+     * non-default choices.
+     * </p>
+     *
+     * @hide Future API ported from support library.  Revisit this later.
+     */
+    public static final int AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE = 1 << 0;
+
+    /**
+     * The route group id used for sharing the selected mirroring device.
+     * System UI and Settings use this to synchronize their mirroring status.
+     * @hide
+     */
+    public static final String MIRRORING_GROUP_ID = "android.media.mirroring_group";
+
+    // Maps application contexts
+    static final HashMap<Context, MediaRouter> sRouters = new HashMap<Context, MediaRouter>();
+
+    static String typesToString(int types) {
+        final StringBuilder result = new StringBuilder();
+        if ((types & ROUTE_TYPE_LIVE_AUDIO) != 0) {
+            result.append("ROUTE_TYPE_LIVE_AUDIO ");
+        }
+        if ((types & ROUTE_TYPE_LIVE_VIDEO) != 0) {
+            result.append("ROUTE_TYPE_LIVE_VIDEO ");
+        }
+        if ((types & ROUTE_TYPE_REMOTE_DISPLAY) != 0) {
+            result.append("ROUTE_TYPE_REMOTE_DISPLAY ");
+        }
+        if ((types & ROUTE_TYPE_USER) != 0) {
+            result.append("ROUTE_TYPE_USER ");
+        }
+        return result.toString();
+    }
+
+    /** @hide */
+    public MediaRouter(Context context) {
+        synchronized (Static.class) {
+            if (sStatic == null) {
+                final Context appContext = context.getApplicationContext();
+                sStatic = new Static(appContext);
+                sStatic.startMonitoringRoutes(appContext);
+            }
+        }
+    }
+
+    /**
+     * Gets the default route for playing media content on the system.
+     * <p>
+     * The system always provides a default route.
+     * </p>
+     *
+     * @return The default route, which is guaranteed to never be null.
+     */
+    public RouteInfo getDefaultRoute() {
+        return sStatic.mDefaultAudioVideo;
+    }
+
+    /**
+     * Returns a Bluetooth route if available, otherwise the default route.
+     * @hide
+     */
+    public RouteInfo getFallbackRoute() {
+        return (sStatic.mBluetoothA2dpRoute != null)
+                ? sStatic.mBluetoothA2dpRoute : sStatic.mDefaultAudioVideo;
+    }
+
+    /**
+     * @hide for use by framework routing UI
+     */
+    public RouteCategory getSystemCategory() {
+        return sStatic.mSystemCategory;
+    }
+
+    /** @hide */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public RouteInfo getSelectedRoute() {
+        return getSelectedRoute(ROUTE_TYPE_ANY);
+    }
+
+    /**
+     * Return the currently selected route for any of the given types
+     *
+     * @param type route types
+     * @return the selected route
+     */
+    public RouteInfo getSelectedRoute(int type) {
+        if (sStatic.mSelectedRoute != null &&
+                (sStatic.mSelectedRoute.mSupportedTypes & type) != 0) {
+            // If the selected route supports any of the types supplied, it's still considered
+            // 'selected' for that type.
+            return sStatic.mSelectedRoute;
+        } else if (type == ROUTE_TYPE_USER) {
+            // The caller specifically asked for a user route and the currently selected route
+            // doesn't qualify.
+            return null;
+        }
+        // If the above didn't match and we're not specifically asking for a user route,
+        // consider the default selected.
+        return sStatic.mDefaultAudioVideo;
+    }
+
+    /**
+     * Returns true if there is a route that matches the specified types.
+     * <p>
+     * This method returns true if there are any available routes that match the types
+     * regardless of whether they are enabled or disabled.  If the
+     * {@link #AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE} flag is specified, then
+     * the method will only consider non-default routes.
+     * </p>
+     *
+     * @param types The types to match.
+     * @param flags Flags to control the determination of whether a route may be available.
+     * May be zero or {@link #AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE}.
+     * @return True if a matching route may be available.
+     *
+     * @hide Future API ported from support library.  Revisit this later.
+     */
+    public boolean isRouteAvailable(int types, int flags) {
+        final int count = sStatic.mRoutes.size();
+        for (int i = 0; i < count; i++) {
+            RouteInfo route = sStatic.mRoutes.get(i);
+            if (route.matchesTypes(types)) {
+                if ((flags & AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE) == 0
+                        || route != sStatic.mDefaultAudioVideo) {
+                    return true;
+                }
+            }
+        }
+
+        // It doesn't look like we can find a matching route right now.
+        return false;
+    }
+
+    /**
+     * Sets the group ID of the router.
+     * Media routers with the same ID acts as if they were a single media router.
+     * For example, if a media router selects a route, the selected route of routers
+     * with the same group ID will be changed automatically.
+     *
+     * Two routers in a group are supposed to use the same route types.
+     *
+     * System UI and Settings use this to synchronize their mirroring status.
+     * Do not set the router group id unless it's necessary.
+     *
+     * {@link android.Manifest.permission#CONFIGURE_WIFI_DISPLAY} permission is required to
+     * call this method.
+     * @hide
+     */
+    public void setRouterGroupId(@Nullable String groupId) {
+        sStatic.setRouterGroupId(groupId);
+    }
+
+    /**
+     * Add a callback to listen to events about specific kinds of media routes.
+     * If the specified callback is already registered, its registration will be updated for any
+     * additional route types specified.
+     * <p>
+     * This is a convenience method that has the same effect as calling
+     * {@link #addCallback(int, Callback, int)} without flags.
+     * </p>
+     *
+     * @param types Types of routes this callback is interested in
+     * @param cb Callback to add
+     */
+    public void addCallback(int types, Callback cb) {
+        addCallback(types, cb, 0);
+    }
+
+    /**
+     * Add a callback to listen to events about specific kinds of media routes.
+     * If the specified callback is already registered, its registration will be updated for any
+     * additional route types specified.
+     * <p>
+     * By default, the callback will only be invoked for events that affect routes
+     * that match the specified selector.  The filtering may be disabled by specifying
+     * the {@link #CALLBACK_FLAG_UNFILTERED_EVENTS} flag.
+     * </p>
+     *
+     * @param types Types of routes this callback is interested in
+     * @param cb Callback to add
+     * @param flags Flags to control the behavior of the callback.
+     * May be zero or a combination of {@link #CALLBACK_FLAG_PERFORM_ACTIVE_SCAN} and
+     * {@link #CALLBACK_FLAG_UNFILTERED_EVENTS}.
+     */
+    public void addCallback(int types, Callback cb, int flags) {
+        CallbackInfo info;
+        int index = findCallbackInfo(cb);
+        if (index >= 0) {
+            info = sStatic.mCallbacks.get(index);
+            info.type |= types;
+            info.flags |= flags;
+        } else {
+            info = new CallbackInfo(cb, types, flags, this);
+            sStatic.mCallbacks.add(info);
+        }
+        sStatic.updateDiscoveryRequest();
+    }
+
+    /**
+     * Remove the specified callback. It will no longer receive events about media routing.
+     *
+     * @param cb Callback to remove
+     */
+    public void removeCallback(Callback cb) {
+        int index = findCallbackInfo(cb);
+        if (index >= 0) {
+            sStatic.mCallbacks.remove(index);
+            sStatic.updateDiscoveryRequest();
+        } else {
+            Log.w(TAG, "removeCallback(" + cb + "): callback not registered");
+        }
+    }
+
+    private int findCallbackInfo(Callback cb) {
+        final int count = sStatic.mCallbacks.size();
+        for (int i = 0; i < count; i++) {
+            final CallbackInfo info = sStatic.mCallbacks.get(i);
+            if (info.cb == cb) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Select the specified route to use for output of the given media types.
+     * <p class="note">
+     * As API version 18, this function may be used to select any route.
+     * In prior versions, this function could only be used to select user
+     * routes and would ignore any attempt to select a system route.
+     * </p>
+     *
+     * @param types type flags indicating which types this route should be used for.
+     *              The route must support at least a subset.
+     * @param route Route to select
+     * @throws IllegalArgumentException if the given route is {@code null}
+     */
+    public void selectRoute(int types, @NonNull RouteInfo route) {
+        if (route == null) {
+            throw new IllegalArgumentException("Route cannot be null.");
+        }
+        selectRouteStatic(types, route, true);
+    }
+
+    /**
+     * @hide internal use
+     */
+    @UnsupportedAppUsage
+    public void selectRouteInt(int types, RouteInfo route, boolean explicit) {
+        selectRouteStatic(types, route, explicit);
+    }
+
+    static void selectRouteStatic(int types, @NonNull RouteInfo route, boolean explicit) {
+        Log.v(TAG, "Selecting route: " + route);
+        assert(route != null);
+        final RouteInfo oldRoute = sStatic.mSelectedRoute;
+        final RouteInfo currentSystemRoute = sStatic.isBluetoothA2dpOn()
+                ? sStatic.mBluetoothA2dpRoute : sStatic.mDefaultAudioVideo;
+        boolean wasDefaultOrBluetoothRoute = (oldRoute != null)
+                && (oldRoute.isDefault() || oldRoute.isBluetooth());
+        if (oldRoute == route
+                && (!wasDefaultOrBluetoothRoute || route == currentSystemRoute)) {
+            return;
+        }
+        if (!route.matchesTypes(types)) {
+            Log.w(TAG, "selectRoute ignored; cannot select route with supported types " +
+                    typesToString(route.getSupportedTypes()) + " into route types " +
+                    typesToString(types));
+            return;
+        }
+
+        if (sStatic.isPlaybackActive() && sStatic.mBluetoothA2dpRoute != null
+                && (types & ROUTE_TYPE_LIVE_AUDIO) != 0
+                && (route.isBluetooth() || route.isDefault())) {
+            try {
+                sStatic.mAudioService.setBluetoothA2dpOn(route.isBluetooth());
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error changing Bluetooth A2DP state", e);
+            }
+        } else if (DEBUG_RESTORE_ROUTE) {
+            Log.i(TAG, "Skip setBluetoothA2dpOn(): types=" + types + ", isPlaybackActive()="
+                    + sStatic.isPlaybackActive() + ", BT route=" + sStatic.mBluetoothA2dpRoute);
+        }
+
+        final WifiDisplay activeDisplay =
+                sStatic.mDisplayService.getWifiDisplayStatus().getActiveDisplay();
+        final boolean oldRouteHasAddress = oldRoute != null && oldRoute.mDeviceAddress != null;
+        final boolean newRouteHasAddress = route.mDeviceAddress != null;
+        if (activeDisplay != null || oldRouteHasAddress || newRouteHasAddress) {
+            if (newRouteHasAddress && !matchesDeviceAddress(activeDisplay, route)) {
+                if (sStatic.mCanConfigureWifiDisplays) {
+                    sStatic.mDisplayService.connectWifiDisplay(route.mDeviceAddress);
+                } else {
+                    Log.e(TAG, "Cannot connect to wifi displays because this process "
+                            + "is not allowed to do so.");
+                }
+            } else if (activeDisplay != null && !newRouteHasAddress) {
+                sStatic.mDisplayService.disconnectWifiDisplay();
+            }
+        }
+
+        sStatic.setSelectedRoute(route, explicit);
+
+        if (oldRoute != null) {
+            dispatchRouteUnselected(types & oldRoute.getSupportedTypes(), oldRoute);
+            if (oldRoute.resolveStatusCode()) {
+                dispatchRouteChanged(oldRoute);
+            }
+        }
+        if (route != null) {
+            if (route.resolveStatusCode()) {
+                dispatchRouteChanged(route);
+            }
+            dispatchRouteSelected(types & route.getSupportedTypes(), route);
+        }
+
+        // The behavior of active scans may depend on the currently selected route.
+        sStatic.updateDiscoveryRequest();
+    }
+
+    static void selectDefaultRouteStatic() {
+        // TODO: Be smarter about the route types here; this selects for all valid.
+        if (sStatic.isBluetoothA2dpOn() && sStatic.mSelectedRoute != null
+                && !sStatic.mSelectedRoute.isBluetooth()) {
+            selectRouteStatic(ROUTE_TYPE_ANY, sStatic.mBluetoothA2dpRoute, false);
+        } else {
+            selectRouteStatic(ROUTE_TYPE_ANY, sStatic.mDefaultAudioVideo, false);
+        }
+    }
+
+    /**
+     * Compare the device address of a display and a route.
+     * Nulls/no device address will match another null/no address.
+     */
+    static boolean matchesDeviceAddress(WifiDisplay display, RouteInfo info) {
+        final boolean routeHasAddress = info != null && info.mDeviceAddress != null;
+        if (display == null && !routeHasAddress) {
+            return true;
+        }
+
+        if (display != null && routeHasAddress) {
+            return display.getDeviceAddress().equals(info.mDeviceAddress);
+        }
+        return false;
+    }
+
+    /**
+     * Add an app-specified route for media to the MediaRouter.
+     * App-specified route definitions are created using {@link #createUserRoute(RouteCategory)}
+     *
+     * @param info Definition of the route to add
+     * @see #createUserRoute(RouteCategory)
+     * @see #removeUserRoute(UserRouteInfo)
+     */
+    public void addUserRoute(UserRouteInfo info) {
+        addRouteStatic(info);
+    }
+
+    /**
+     * @hide Framework use only
+     */
+    public void addRouteInt(RouteInfo info) {
+        addRouteStatic(info);
+    }
+
+    static void addRouteStatic(RouteInfo info) {
+        if (DEBUG) {
+            Log.d(TAG, "Adding route: " + info);
+        }
+        final RouteCategory cat = info.getCategory();
+        if (!sStatic.mCategories.contains(cat)) {
+            sStatic.mCategories.add(cat);
+        }
+        if (cat.isGroupable() && !(info instanceof RouteGroup)) {
+            // Enforce that any added route in a groupable category must be in a group.
+            final RouteGroup group = new RouteGroup(info.getCategory());
+            group.mSupportedTypes = info.mSupportedTypes;
+            sStatic.mRoutes.add(group);
+            dispatchRouteAdded(group);
+            group.addRoute(info);
+
+            info = group;
+        } else {
+            sStatic.mRoutes.add(info);
+            dispatchRouteAdded(info);
+        }
+    }
+
+    /**
+     * Remove an app-specified route for media from the MediaRouter.
+     *
+     * @param info Definition of the route to remove
+     * @see #addUserRoute(UserRouteInfo)
+     */
+    public void removeUserRoute(UserRouteInfo info) {
+        removeRouteStatic(info);
+    }
+
+    /**
+     * Remove all app-specified routes from the MediaRouter.
+     *
+     * @see #removeUserRoute(UserRouteInfo)
+     */
+    public void clearUserRoutes() {
+        for (int i = 0; i < sStatic.mRoutes.size(); i++) {
+            final RouteInfo info = sStatic.mRoutes.get(i);
+            // TODO Right now, RouteGroups only ever contain user routes.
+            // The code below will need to change if this assumption does.
+            if (info instanceof UserRouteInfo || info instanceof RouteGroup) {
+                removeRouteStatic(info);
+                i--;
+            }
+        }
+    }
+
+    /**
+     * @hide internal use only
+     */
+    public void removeRouteInt(RouteInfo info) {
+        removeRouteStatic(info);
+    }
+
+    static void removeRouteStatic(RouteInfo info) {
+        if (DEBUG) {
+            Log.d(TAG, "Removing route: " + info);
+        }
+        if (sStatic.mRoutes.remove(info)) {
+            final RouteCategory removingCat = info.getCategory();
+            final int count = sStatic.mRoutes.size();
+            boolean found = false;
+            for (int i = 0; i < count; i++) {
+                final RouteCategory cat = sStatic.mRoutes.get(i).getCategory();
+                if (removingCat == cat) {
+                    found = true;
+                    break;
+                }
+            }
+            if (info.isSelected()) {
+                // Removing the currently selected route? Select the default before we remove it.
+                selectDefaultRouteStatic();
+            }
+            if (!found) {
+                sStatic.mCategories.remove(removingCat);
+            }
+            dispatchRouteRemoved(info);
+        }
+    }
+
+    /**
+     * Return the number of {@link MediaRouter.RouteCategory categories} currently
+     * represented by routes known to this MediaRouter.
+     *
+     * @return the number of unique categories represented by this MediaRouter's known routes
+     */
+    public int getCategoryCount() {
+        return sStatic.mCategories.size();
+    }
+
+    /**
+     * Return the {@link MediaRouter.RouteCategory category} at the given index.
+     * Valid indices are in the range [0-getCategoryCount).
+     *
+     * @param index which category to return
+     * @return the category at index
+     */
+    public RouteCategory getCategoryAt(int index) {
+        return sStatic.mCategories.get(index);
+    }
+
+    /**
+     * Return the number of {@link MediaRouter.RouteInfo routes} currently known
+     * to this MediaRouter.
+     *
+     * @return the number of routes tracked by this router
+     */
+    public int getRouteCount() {
+        return sStatic.mRoutes.size();
+    }
+
+    /**
+     * Return the route at the specified index.
+     *
+     * @param index index of the route to return
+     * @return the route at index
+     */
+    public RouteInfo getRouteAt(int index) {
+        return sStatic.mRoutes.get(index);
+    }
+
+    static int getRouteCountStatic() {
+        return sStatic.mRoutes.size();
+    }
+
+    static RouteInfo getRouteAtStatic(int index) {
+        return sStatic.mRoutes.get(index);
+    }
+
+    /**
+     * Create a new user route that may be modified and registered for use by the application.
+     *
+     * @param category The category the new route will belong to
+     * @return A new UserRouteInfo for use by the application
+     *
+     * @see #addUserRoute(UserRouteInfo)
+     * @see #removeUserRoute(UserRouteInfo)
+     * @see #createRouteCategory(CharSequence, boolean)
+     */
+    public UserRouteInfo createUserRoute(RouteCategory category) {
+        return new UserRouteInfo(category);
+    }
+
+    /**
+     * Create a new route category. Each route must belong to a category.
+     *
+     * @param name Name of the new category
+     * @param isGroupable true if routes in this category may be grouped with one another
+     * @return the new RouteCategory
+     */
+    public RouteCategory createRouteCategory(CharSequence name, boolean isGroupable) {
+        return new RouteCategory(name, ROUTE_TYPE_USER, isGroupable);
+    }
+
+    /**
+     * Create a new route category. Each route must belong to a category.
+     *
+     * @param nameResId Resource ID of the name of the new category
+     * @param isGroupable true if routes in this category may be grouped with one another
+     * @return the new RouteCategory
+     */
+    public RouteCategory createRouteCategory(int nameResId, boolean isGroupable) {
+        return new RouteCategory(nameResId, ROUTE_TYPE_USER, isGroupable);
+    }
+
+    /**
+     * Rebinds the media router to handle routes that belong to the specified user.
+     * Requires the interact across users permission to access the routes of another user.
+     * <p>
+     * This method is a complete hack to work around the singleton nature of the
+     * media router when running inside of singleton processes like QuickSettings.
+     * This mechanism should be burned to the ground when MediaRouter is redesigned.
+     * Ideally the current user would be pulled from the Context but we need to break
+     * down MediaRouter.Static before we can get there.
+     * </p>
+     *
+     * @hide
+     */
+    public void rebindAsUser(int userId) {
+        sStatic.rebindAsUser(userId);
+    }
+
+    static void updateRoute(final RouteInfo info) {
+        dispatchRouteChanged(info);
+    }
+
+    static void dispatchRouteSelected(int type, RouteInfo info) {
+        if (DEBUG) {
+            Log.d(TAG, "Dispatching route selected: " + info);
+        }
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
+            if (cbi.filterRouteEvent(info)) {
+                cbi.cb.onRouteSelected(cbi.router, type, info);
+            }
+        }
+    }
+
+    static void dispatchRouteUnselected(int type, RouteInfo info) {
+        if (DEBUG) {
+            Log.d(TAG, "Dispatching route unselected: " + info);
+        }
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
+            if (cbi.filterRouteEvent(info)) {
+                cbi.cb.onRouteUnselected(cbi.router, type, info);
+            }
+        }
+    }
+
+    static void dispatchRouteChanged(RouteInfo info) {
+        dispatchRouteChanged(info, info.mSupportedTypes);
+    }
+
+    static void dispatchRouteChanged(RouteInfo info, int oldSupportedTypes) {
+        if (DEBUG) {
+            Log.d(TAG, "Dispatching route change: " + info);
+        }
+        final int newSupportedTypes = info.mSupportedTypes;
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
+            // Reconstruct some of the history for callbacks that may not have observed
+            // all of the events needed to correctly interpret the current state.
+            // FIXME: This is a strong signal that we should deprecate route type filtering
+            // completely in the future because it can lead to inconsistencies in
+            // applications.
+            final boolean oldVisibility = cbi.filterRouteEvent(oldSupportedTypes);
+            final boolean newVisibility = cbi.filterRouteEvent(newSupportedTypes);
+            if (!oldVisibility && newVisibility) {
+                cbi.cb.onRouteAdded(cbi.router, info);
+                if (info.isSelected()) {
+                    cbi.cb.onRouteSelected(cbi.router, newSupportedTypes, info);
+                }
+            }
+            if (oldVisibility || newVisibility) {
+                cbi.cb.onRouteChanged(cbi.router, info);
+            }
+            if (oldVisibility && !newVisibility) {
+                if (info.isSelected()) {
+                    cbi.cb.onRouteUnselected(cbi.router, oldSupportedTypes, info);
+                }
+                cbi.cb.onRouteRemoved(cbi.router, info);
+            }
+        }
+    }
+
+    static void dispatchRouteAdded(RouteInfo info) {
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
+            if (cbi.filterRouteEvent(info)) {
+                cbi.cb.onRouteAdded(cbi.router, info);
+            }
+        }
+    }
+
+    static void dispatchRouteRemoved(RouteInfo info) {
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
+            if (cbi.filterRouteEvent(info)) {
+                cbi.cb.onRouteRemoved(cbi.router, info);
+            }
+        }
+    }
+
+    static void dispatchRouteGrouped(RouteInfo info, RouteGroup group, int index) {
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
+            if (cbi.filterRouteEvent(group)) {
+                cbi.cb.onRouteGrouped(cbi.router, info, group, index);
+            }
+        }
+    }
+
+    static void dispatchRouteUngrouped(RouteInfo info, RouteGroup group) {
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
+            if (cbi.filterRouteEvent(group)) {
+                cbi.cb.onRouteUngrouped(cbi.router, info, group);
+            }
+        }
+    }
+
+    static void dispatchRouteVolumeChanged(RouteInfo info) {
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
+            if (cbi.filterRouteEvent(info)) {
+                cbi.cb.onRouteVolumeChanged(cbi.router, info);
+            }
+        }
+    }
+
+    static void dispatchRoutePresentationDisplayChanged(RouteInfo info) {
+        for (CallbackInfo cbi : sStatic.mCallbacks) {
+            if (cbi.filterRouteEvent(info)) {
+                cbi.cb.onRoutePresentationDisplayChanged(cbi.router, info);
+            }
+        }
+    }
+
+    static void systemVolumeChanged(int newValue) {
+        final RouteInfo selectedRoute = sStatic.mSelectedRoute;
+        if (selectedRoute == null) return;
+
+        if (selectedRoute.isBluetooth() || selectedRoute.isDefault()) {
+            dispatchRouteVolumeChanged(selectedRoute);
+        } else if (sStatic.mBluetoothA2dpRoute != null) {
+            dispatchRouteVolumeChanged(sStatic.mIsBluetoothA2dpOn
+                    ? sStatic.mBluetoothA2dpRoute : sStatic.mDefaultAudioVideo);
+        } else {
+            dispatchRouteVolumeChanged(sStatic.mDefaultAudioVideo);
+        }
+    }
+
+    static void updateWifiDisplayStatus(WifiDisplayStatus status) {
+        WifiDisplay[] displays;
+        WifiDisplay activeDisplay;
+        if (status.getFeatureState() == WifiDisplayStatus.FEATURE_STATE_ON) {
+            displays = status.getDisplays();
+            activeDisplay = status.getActiveDisplay();
+
+            // Only the system is able to connect to wifi display routes.
+            // The display manager will enforce this with a permission check but it
+            // still publishes information about all available displays.
+            // Filter the list down to just the active display.
+            if (!sStatic.mCanConfigureWifiDisplays) {
+                if (activeDisplay != null) {
+                    displays = new WifiDisplay[] { activeDisplay };
+                } else {
+                    displays = WifiDisplay.EMPTY_ARRAY;
+                }
+            }
+        } else {
+            displays = WifiDisplay.EMPTY_ARRAY;
+            activeDisplay = null;
+        }
+        String activeDisplayAddress = activeDisplay != null ?
+                activeDisplay.getDeviceAddress() : null;
+
+        // Add or update routes.
+        for (int i = 0; i < displays.length; i++) {
+            final WifiDisplay d = displays[i];
+            if (shouldShowWifiDisplay(d, activeDisplay)) {
+                RouteInfo route = findWifiDisplayRoute(d);
+                if (route == null) {
+                    route = makeWifiDisplayRoute(d, status);
+                    addRouteStatic(route);
+                } else {
+                    String address = d.getDeviceAddress();
+                    boolean disconnected = !address.equals(activeDisplayAddress)
+                            && address.equals(sStatic.mPreviousActiveWifiDisplayAddress);
+                    updateWifiDisplayRoute(route, d, status, disconnected);
+                }
+                if (d.equals(activeDisplay)) {
+                    selectRouteStatic(route.getSupportedTypes(), route, false);
+                }
+            }
+        }
+
+        // Remove stale routes.
+        for (int i = sStatic.mRoutes.size(); i-- > 0; ) {
+            RouteInfo route = sStatic.mRoutes.get(i);
+            if (route.mDeviceAddress != null) {
+                WifiDisplay d = findWifiDisplay(displays, route.mDeviceAddress);
+                if (d == null || !shouldShowWifiDisplay(d, activeDisplay)) {
+                    removeRouteStatic(route);
+                }
+            }
+        }
+
+        // Remember the current active wifi display address so that we can infer disconnections.
+        // TODO: This hack will go away once all of this is moved into the media router service.
+        sStatic.mPreviousActiveWifiDisplayAddress = activeDisplayAddress;
+    }
+
+    private static boolean shouldShowWifiDisplay(WifiDisplay d, WifiDisplay activeDisplay) {
+        return d.isRemembered() || d.equals(activeDisplay);
+    }
+
+    static int getWifiDisplayStatusCode(WifiDisplay d, WifiDisplayStatus wfdStatus) {
+        int newStatus;
+        if (wfdStatus.getScanState() == WifiDisplayStatus.SCAN_STATE_SCANNING) {
+            newStatus = RouteInfo.STATUS_SCANNING;
+        } else if (d.isAvailable()) {
+            newStatus = d.canConnect() ?
+                    RouteInfo.STATUS_AVAILABLE: RouteInfo.STATUS_IN_USE;
+        } else {
+            newStatus = RouteInfo.STATUS_NOT_AVAILABLE;
+        }
+
+        if (d.equals(wfdStatus.getActiveDisplay())) {
+            final int activeState = wfdStatus.getActiveDisplayState();
+            switch (activeState) {
+                case WifiDisplayStatus.DISPLAY_STATE_CONNECTED:
+                    newStatus = RouteInfo.STATUS_CONNECTED;
+                    break;
+                case WifiDisplayStatus.DISPLAY_STATE_CONNECTING:
+                    newStatus = RouteInfo.STATUS_CONNECTING;
+                    break;
+                case WifiDisplayStatus.DISPLAY_STATE_NOT_CONNECTED:
+                    Log.e(TAG, "Active display is not connected!");
+                    break;
+            }
+        }
+
+        return newStatus;
+    }
+
+    static boolean isWifiDisplayEnabled(WifiDisplay d, WifiDisplayStatus wfdStatus) {
+        return d.isAvailable() && (d.canConnect() || d.equals(wfdStatus.getActiveDisplay()));
+    }
+
+    static RouteInfo makeWifiDisplayRoute(WifiDisplay display, WifiDisplayStatus wfdStatus) {
+        final RouteInfo newRoute = new RouteInfo(sStatic.mSystemCategory);
+        newRoute.mDeviceAddress = display.getDeviceAddress();
+        newRoute.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_LIVE_VIDEO
+                | ROUTE_TYPE_REMOTE_DISPLAY;
+        newRoute.mVolumeHandling = RouteInfo.PLAYBACK_VOLUME_FIXED;
+        newRoute.mPlaybackType = RouteInfo.PLAYBACK_TYPE_REMOTE;
+
+        newRoute.setRealStatusCode(getWifiDisplayStatusCode(display, wfdStatus));
+        newRoute.mEnabled = isWifiDisplayEnabled(display, wfdStatus);
+        newRoute.mName = display.getFriendlyDisplayName();
+        newRoute.mDescription = sStatic.mResources.getText(
+                com.android.internal.R.string.wireless_display_route_description);
+        newRoute.updatePresentationDisplay();
+        newRoute.mDeviceType = RouteInfo.DEVICE_TYPE_TV;
+        return newRoute;
+    }
+
+    private static void updateWifiDisplayRoute(
+            RouteInfo route, WifiDisplay display, WifiDisplayStatus wfdStatus,
+            boolean disconnected) {
+        boolean changed = false;
+        final String newName = display.getFriendlyDisplayName();
+        if (!route.getName().equals(newName)) {
+            route.mName = newName;
+            changed = true;
+        }
+
+        boolean enabled = isWifiDisplayEnabled(display, wfdStatus);
+        changed |= route.mEnabled != enabled;
+        route.mEnabled = enabled;
+
+        changed |= route.setRealStatusCode(getWifiDisplayStatusCode(display, wfdStatus));
+
+        if (changed) {
+            dispatchRouteChanged(route);
+        }
+
+        if ((!enabled || disconnected) && route.isSelected()) {
+            // Oops, no longer available. Reselect the default.
+            selectDefaultRouteStatic();
+        }
+    }
+
+    private static WifiDisplay findWifiDisplay(WifiDisplay[] displays, String deviceAddress) {
+        for (int i = 0; i < displays.length; i++) {
+            final WifiDisplay d = displays[i];
+            if (d.getDeviceAddress().equals(deviceAddress)) {
+                return d;
+            }
+        }
+        return null;
+    }
+
+    private static RouteInfo findWifiDisplayRoute(WifiDisplay d) {
+        final int count = sStatic.mRoutes.size();
+        for (int i = 0; i < count; i++) {
+            final RouteInfo info = sStatic.mRoutes.get(i);
+            if (d.getDeviceAddress().equals(info.mDeviceAddress)) {
+                return info;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Information about a media route.
+     */
+    public static class RouteInfo {
+        CharSequence mName;
+        @UnsupportedAppUsage
+        int mNameResId;
+        CharSequence mDescription;
+        private CharSequence mStatus;
+        int mSupportedTypes;
+        int mDeviceType;
+        RouteGroup mGroup;
+        final RouteCategory mCategory;
+        Drawable mIcon;
+        // playback information
+        int mPlaybackType = PLAYBACK_TYPE_LOCAL;
+        int mVolumeMax = DEFAULT_PLAYBACK_MAX_VOLUME;
+        int mVolume = DEFAULT_PLAYBACK_VOLUME;
+        int mVolumeHandling = PLAYBACK_VOLUME_VARIABLE;
+        int mPlaybackStream = AudioManager.STREAM_MUSIC;
+        VolumeCallbackInfo mVcb;
+        Display mPresentationDisplay;
+        int mPresentationDisplayId = -1;
+
+        String mDeviceAddress;
+        boolean mEnabled = true;
+
+        // An id by which the route is known to the media router service.
+        // Null if this route only exists as an artifact within this process.
+        String mGlobalRouteId;
+
+        // A predetermined connection status that can override mStatus
+        private int mRealStatusCode;
+        private int mResolvedStatusCode;
+
+        /** @hide */ public static final int STATUS_NONE = 0;
+        /** @hide */ public static final int STATUS_SCANNING = 1;
+        /** @hide */
+        @UnsupportedAppUsage
+        public static final int STATUS_CONNECTING = 2;
+        /** @hide */ public static final int STATUS_AVAILABLE = 3;
+        /** @hide */ public static final int STATUS_NOT_AVAILABLE = 4;
+        /** @hide */ public static final int STATUS_IN_USE = 5;
+        /** @hide */ public static final int STATUS_CONNECTED = 6;
+
+        /** @hide */
+        @IntDef({DEVICE_TYPE_UNKNOWN, DEVICE_TYPE_TV, DEVICE_TYPE_SPEAKER, DEVICE_TYPE_BLUETOOTH})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface DeviceType {}
+
+        /**
+         * The default receiver device type of the route indicating the type is unknown.
+         *
+         * @see #getDeviceType
+         */
+        public static final int DEVICE_TYPE_UNKNOWN = 0;
+
+        /**
+         * A receiver device type of the route indicating the presentation of the media is happening
+         * on a TV.
+         *
+         * @see #getDeviceType
+         */
+        public static final int DEVICE_TYPE_TV = 1;
+
+        /**
+         * A receiver device type of the route indicating the presentation of the media is happening
+         * on a speaker.
+         *
+         * @see #getDeviceType
+         */
+        public static final int DEVICE_TYPE_SPEAKER = 2;
+
+        /**
+         * A receiver device type of the route indicating the presentation of the media is happening
+         * on a bluetooth device such as a bluetooth speaker.
+         *
+         * @see #getDeviceType
+         */
+        public static final int DEVICE_TYPE_BLUETOOTH = 3;
+
+        private Object mTag;
+
+        /** @hide */
+        @IntDef({PLAYBACK_TYPE_LOCAL, PLAYBACK_TYPE_REMOTE})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface PlaybackType {}
+
+        /**
+         * The default playback type, "local", indicating the presentation of the media is happening
+         * on the same device (e&#46;g&#46; a phone, a tablet) as where it is controlled from.
+         * @see #getPlaybackType()
+         */
+        public final static int PLAYBACK_TYPE_LOCAL = 0;
+
+        /**
+         * A playback type indicating the presentation of the media is happening on
+         * a different device (i&#46;e&#46; the remote device) than where it is controlled from.
+         * @see #getPlaybackType()
+         */
+        public final static int PLAYBACK_TYPE_REMOTE = 1;
+
+        /** @hide */
+         @IntDef({PLAYBACK_VOLUME_FIXED,PLAYBACK_VOLUME_VARIABLE})
+         @Retention(RetentionPolicy.SOURCE)
+         private @interface PlaybackVolume {}
+
+        /**
+         * Playback information indicating the playback volume is fixed, i&#46;e&#46; it cannot be
+         * controlled from this object. An example of fixed playback volume is a remote player,
+         * playing over HDMI where the user prefers to control the volume on the HDMI sink, rather
+         * than attenuate at the source.
+         * @see #getVolumeHandling()
+         */
+        public final static int PLAYBACK_VOLUME_FIXED = 0;
+        /**
+         * Playback information indicating the playback volume is variable and can be controlled
+         * from this object.
+         * @see #getVolumeHandling()
+         */
+        public final static int PLAYBACK_VOLUME_VARIABLE = 1;
+
+        /**
+         * Default playback max volume if not set.
+         * Hard-coded to the same number of steps as AudioService.MAX_STREAM_VOLUME[STREAM_MUSIC]
+         *
+         * @see #getVolumeMax()
+         */
+        private static final int DEFAULT_PLAYBACK_MAX_VOLUME = 15;
+
+        /**
+         * Default playback volume if not set.
+         *
+         * @see #getVolume()
+         */
+        private static final int DEFAULT_PLAYBACK_VOLUME = DEFAULT_PLAYBACK_MAX_VOLUME;
+
+        /** @hide */
+        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+        public RouteInfo(RouteCategory category) {
+            mCategory = category;
+            mDeviceType = DEVICE_TYPE_UNKNOWN;
+        }
+
+        /**
+         * Gets the user-visible name of the route.
+         * <p>
+         * The route name identifies the destination represented by the route.
+         * It may be a user-supplied name, an alias, or device serial number.
+         * </p>
+         *
+         * @return The user-visible name of a media route.  This is the string presented
+         * to users who may select this as the active route.
+         */
+        public CharSequence getName() {
+            return getName(sStatic.mResources);
+        }
+
+        /**
+         * Return the properly localized/resource user-visible name of this route.
+         * <p>
+         * The route name identifies the destination represented by the route.
+         * It may be a user-supplied name, an alias, or device serial number.
+         * </p>
+         *
+         * @param context Context used to resolve the correct configuration to load
+         * @return The user-visible name of a media route.  This is the string presented
+         * to users who may select this as the active route.
+         */
+        public CharSequence getName(Context context) {
+            return getName(context.getResources());
+        }
+
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        CharSequence getName(Resources res) {
+            if (mNameResId != 0) {
+                return res.getText(mNameResId);
+            }
+            return mName;
+        }
+
+        /**
+         * Gets the user-visible description of the route.
+         * <p>
+         * The route description describes the kind of destination represented by the route.
+         * It may be a user-supplied string, a model number or brand of device.
+         * </p>
+         *
+         * @return The description of the route, or null if none.
+         */
+        public CharSequence getDescription() {
+            return mDescription;
+        }
+
+        /**
+         * @return The user-visible status for a media route. This may include a description
+         * of the currently playing media, if available.
+         */
+        public CharSequence getStatus() {
+            return mStatus;
+        }
+
+        /**
+         * Set this route's status by predetermined status code. If the caller
+         * should dispatch a route changed event this call will return true;
+         */
+        boolean setRealStatusCode(int statusCode) {
+            if (mRealStatusCode != statusCode) {
+                mRealStatusCode = statusCode;
+                return resolveStatusCode();
+            }
+            return false;
+        }
+
+        /**
+         * Resolves the status code whenever the real status code or selection state
+         * changes.
+         */
+        boolean resolveStatusCode() {
+            int statusCode = mRealStatusCode;
+            if (isSelected()) {
+                switch (statusCode) {
+                    // If the route is selected and its status appears to be between states
+                    // then report it as connecting even though it has not yet had a chance
+                    // to officially move into the CONNECTING state.  Note that routes in
+                    // the NONE state are assumed to not require an explicit connection
+                    // lifecycle whereas those that are AVAILABLE are assumed to have
+                    // to eventually proceed to CONNECTED.
+                    case STATUS_AVAILABLE:
+                    case STATUS_SCANNING:
+                        statusCode = STATUS_CONNECTING;
+                        break;
+                }
+            }
+            if (mResolvedStatusCode == statusCode) {
+                return false;
+            }
+
+            mResolvedStatusCode = statusCode;
+            int resId;
+            switch (statusCode) {
+                case STATUS_SCANNING:
+                    resId = com.android.internal.R.string.media_route_status_scanning;
+                    break;
+                case STATUS_CONNECTING:
+                    resId = com.android.internal.R.string.media_route_status_connecting;
+                    break;
+                case STATUS_AVAILABLE:
+                    resId = com.android.internal.R.string.media_route_status_available;
+                    break;
+                case STATUS_NOT_AVAILABLE:
+                    resId = com.android.internal.R.string.media_route_status_not_available;
+                    break;
+                case STATUS_IN_USE:
+                    resId = com.android.internal.R.string.media_route_status_in_use;
+                    break;
+                case STATUS_CONNECTED:
+                case STATUS_NONE:
+                default:
+                    resId = 0;
+                    break;
+            }
+            mStatus = resId != 0 ? sStatic.mResources.getText(resId) : null;
+            return true;
+        }
+
+        /**
+         * @hide
+         */
+        @UnsupportedAppUsage
+        public int getStatusCode() {
+            return mResolvedStatusCode;
+        }
+
+        /**
+         * @return A media type flag set describing which types this route supports.
+         */
+        public int getSupportedTypes() {
+            return mSupportedTypes;
+        }
+
+        /**
+         * Gets the type of the receiver device associated with this route.
+         *
+         * @return The type of the receiver device associated with this route:
+         * {@link #DEVICE_TYPE_BLUETOOTH}, {@link #DEVICE_TYPE_TV}, {@link #DEVICE_TYPE_SPEAKER},
+         * or {@link #DEVICE_TYPE_UNKNOWN}.
+         */
+        @DeviceType
+        public int getDeviceType() {
+            return mDeviceType;
+        }
+
+        /** @hide */
+        @UnsupportedAppUsage
+        public boolean matchesTypes(int types) {
+            return (mSupportedTypes & types) != 0;
+        }
+
+        /**
+         * @return The group that this route belongs to.
+         */
+        public RouteGroup getGroup() {
+            return mGroup;
+        }
+
+        /**
+         * @return the category this route belongs to.
+         */
+        public RouteCategory getCategory() {
+            return mCategory;
+        }
+
+        /**
+         * Get the icon representing this route.
+         * This icon will be used in picker UIs if available.
+         *
+         * @return the icon representing this route or null if no icon is available
+         */
+        public Drawable getIconDrawable() {
+            return mIcon;
+        }
+
+        /**
+         * Set an application-specific tag object for this route.
+         * The application may use this to store arbitrary data associated with the
+         * route for internal tracking.
+         *
+         * <p>Note that the lifespan of a route may be well past the lifespan of
+         * an Activity or other Context; take care that objects you store here
+         * will not keep more data in memory alive than you intend.</p>
+         *
+         * @param tag Arbitrary, app-specific data for this route to hold for later use
+         */
+        public void setTag(Object tag) {
+            mTag = tag;
+            routeUpdated();
+        }
+
+        /**
+         * @return The tag object previously set by the application
+         * @see #setTag(Object)
+         */
+        public Object getTag() {
+            return mTag;
+        }
+
+        /**
+         * @return the type of playback associated with this route
+         * @see UserRouteInfo#setPlaybackType(int)
+         */
+        @PlaybackType
+        public int getPlaybackType() {
+            return mPlaybackType;
+        }
+
+        /**
+         * @return the stream over which the playback associated with this route is performed
+         * @see UserRouteInfo#setPlaybackStream(int)
+         */
+        public int getPlaybackStream() {
+            return mPlaybackStream;
+        }
+
+        /**
+         * Return the current volume for this route. Depending on the route, this may only
+         * be valid if the route is currently selected.
+         *
+         * @return the volume at which the playback associated with this route is performed
+         * @see UserRouteInfo#setVolume(int)
+         */
+        public int getVolume() {
+            if (mPlaybackType == PLAYBACK_TYPE_LOCAL) {
+                return sStatic.getStreamVolume(mPlaybackStream);
+            } else {
+                return mVolume;
+            }
+        }
+
+        /**
+         * Request a volume change for this route.
+         * @param volume value between 0 and getVolumeMax
+         */
+        public void requestSetVolume(int volume) {
+            if (mPlaybackType == PLAYBACK_TYPE_LOCAL) {
+                try {
+                    sStatic.mAudioService.setStreamVolume(mPlaybackStream, volume, 0,
+                            ActivityThread.currentPackageName());
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error setting local stream volume", e);
+                }
+            } else {
+                sStatic.requestSetVolume(this, volume);
+            }
+        }
+
+        /**
+         * Request an incremental volume update for this route.
+         * @param direction Delta to apply to the current volume
+         */
+        public void requestUpdateVolume(int direction) {
+            if (mPlaybackType == PLAYBACK_TYPE_LOCAL) {
+                try {
+                    final int volume =
+                            Math.max(0, Math.min(getVolume() + direction, getVolumeMax()));
+                    sStatic.mAudioService.setStreamVolume(mPlaybackStream, volume, 0,
+                            ActivityThread.currentPackageName());
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error setting local stream volume", e);
+                }
+            } else {
+                sStatic.requestUpdateVolume(this, direction);
+            }
+        }
+
+        /**
+         * @return the maximum volume at which the playback associated with this route is performed
+         * @see UserRouteInfo#setVolumeMax(int)
+         */
+        public int getVolumeMax() {
+            if (mPlaybackType == PLAYBACK_TYPE_LOCAL) {
+                int volMax = 0;
+                try {
+                    volMax = sStatic.mAudioService.getStreamMaxVolume(mPlaybackStream);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error getting local stream volume", e);
+                }
+                return volMax;
+            } else {
+                return mVolumeMax;
+            }
+        }
+
+        /**
+         * @return how volume is handling on the route
+         * @see UserRouteInfo#setVolumeHandling(int)
+         */
+        @PlaybackVolume
+        public int getVolumeHandling() {
+            return mVolumeHandling;
+        }
+
+        /**
+         * Gets the {@link Display} that should be used by the application to show
+         * a {@link android.app.Presentation} on an external display when this route is selected.
+         * Depending on the route, this may only be valid if the route is currently
+         * selected.
+         * <p>
+         * The preferred presentation display may change independently of the route
+         * being selected or unselected.  For example, the presentation display
+         * of the default system route may change when an external HDMI display is connected
+         * or disconnected even though the route itself has not changed.
+         * </p><p>
+         * This method may return null if there is no external display associated with
+         * the route or if the display is not ready to show UI yet.
+         * </p><p>
+         * The application should listen for changes to the presentation display
+         * using the {@link Callback#onRoutePresentationDisplayChanged} callback and
+         * show or dismiss its {@link android.app.Presentation} accordingly when the display
+         * becomes available or is removed.
+         * </p><p>
+         * This method only makes sense for {@link #ROUTE_TYPE_LIVE_VIDEO live video} routes.
+         * </p>
+         *
+         * @return The preferred presentation display to use when this route is
+         * selected or null if none.
+         *
+         * @see #ROUTE_TYPE_LIVE_VIDEO
+         * @see android.app.Presentation
+         */
+        public Display getPresentationDisplay() {
+            return mPresentationDisplay;
+        }
+
+        /** @hide */
+        @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
+        public boolean updatePresentationDisplay() {
+            Display display = choosePresentationDisplay();
+            if (mPresentationDisplay != display) {
+                mPresentationDisplay = display;
+                return true;
+            }
+            return false;
+        }
+
+        private Display choosePresentationDisplay() {
+            if ((getSupportedTypes() & ROUTE_TYPE_LIVE_VIDEO) == 0) {
+                return null;
+            }
+            final Display[] displays = getAllPresentationDisplays();
+            if (displays == null || displays.length == 0) {
+                return null;
+            }
+
+            // Ensure that the specified display is valid for presentations.
+            // This check will normally disallow the default display unless it was
+            // configured as a presentation display for some reason.
+            if (mPresentationDisplayId >= 0) {
+                for (Display display : displays) {
+                    if (display.getDisplayId() == mPresentationDisplayId) {
+                        return display;
+                    }
+                }
+                return null;
+            }
+
+            // Find the indicated Wifi display by its address.
+            if (getDeviceAddress() != null) {
+                for (Display display : displays) {
+                    if (display.getType() == Display.TYPE_WIFI
+                            && displayAddressEquals(display)) {
+                        return display;
+                    }
+                }
+            }
+
+            // Returns the first hard-wired display.
+            for (Display display : displays) {
+                if (display.getType() == Display.TYPE_EXTERNAL) {
+                    return display;
+                }
+            }
+
+            // Returns the first non-default built-in display.
+            for (Display display : displays) {
+                if (display.getType() == Display.TYPE_INTERNAL) {
+                    return display;
+                }
+            }
+
+            // For the default route, choose the first presentation display from the list.
+            if (this == getDefaultAudioVideo()) {
+                return displays[0];
+            }
+            return null;
+        }
+
+        /** @hide */
+        @VisibleForTesting
+        public Display[] getAllPresentationDisplays() {
+            return sStatic.getAllPresentationDisplays();
+        }
+
+        /** @hide */
+        @VisibleForTesting
+        public RouteInfo getDefaultAudioVideo() {
+            return sStatic.mDefaultAudioVideo;
+        }
+
+        private boolean displayAddressEquals(Display display) {
+            final DisplayAddress displayAddress = display.getAddress();
+            // mDeviceAddress recorded mac address. If displayAddress is not a kind of Network,
+            // return false early.
+            if (!(displayAddress instanceof DisplayAddress.Network)) {
+                return false;
+            }
+            final DisplayAddress.Network networkAddress = (DisplayAddress.Network) displayAddress;
+            return getDeviceAddress().equals(networkAddress.toString());
+        }
+
+        /** @hide */
+        @UnsupportedAppUsage
+        public String getDeviceAddress() {
+            return mDeviceAddress;
+        }
+
+        /**
+         * Returns true if this route is enabled and may be selected.
+         *
+         * @return True if this route is enabled.
+         */
+        public boolean isEnabled() {
+            return mEnabled;
+        }
+
+        /**
+         * Returns true if the route is in the process of connecting and is not
+         * yet ready for use.
+         *
+         * @return True if this route is in the process of connecting.
+         */
+        public boolean isConnecting() {
+            return mResolvedStatusCode == STATUS_CONNECTING;
+        }
+
+        /** @hide */
+        @UnsupportedAppUsage
+        public boolean isSelected() {
+            return this == sStatic.mSelectedRoute;
+        }
+
+        /** @hide */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+        public boolean isDefault() {
+            return this == sStatic.mDefaultAudioVideo;
+        }
+
+        /** @hide */
+        public boolean isBluetooth() {
+            return mDeviceType == RouteInfo.DEVICE_TYPE_BLUETOOTH;
+        }
+
+        /** @hide */
+        @UnsupportedAppUsage
+        public void select() {
+            selectRouteStatic(mSupportedTypes, this, true);
+        }
+
+        void setStatusInt(CharSequence status) {
+            if (!status.equals(mStatus)) {
+                mStatus = status;
+                if (mGroup != null) {
+                    mGroup.memberStatusChanged(this, status);
+                }
+                routeUpdated();
+            }
+        }
+
+        final IRemoteVolumeObserver.Stub mRemoteVolObserver = new IRemoteVolumeObserver.Stub() {
+            @Override
+            public void dispatchRemoteVolumeUpdate(final int direction, final int value) {
+                sStatic.mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        if (mVcb != null) {
+                            if (direction != 0) {
+                                mVcb.vcb.onVolumeUpdateRequest(mVcb.route, direction);
+                            } else {
+                                mVcb.vcb.onVolumeSetRequest(mVcb.route, value);
+                            }
+                        }
+                    }
+                });
+            }
+        };
+
+        void routeUpdated() {
+            updateRoute(this);
+        }
+
+        @Override
+        public String toString() {
+            String supportedTypes = typesToString(getSupportedTypes());
+            return getClass().getSimpleName() + "{ name=" + getName() +
+                    ", description=" + getDescription() +
+                    ", status=" + getStatus() +
+                    ", category=" + getCategory() +
+                    ", supportedTypes=" + supportedTypes +
+                    ", presentationDisplay=" + mPresentationDisplay + " }";
+        }
+    }
+
+    /**
+     * Information about a route that the application may define and modify.
+     * A user route defaults to {@link RouteInfo#PLAYBACK_TYPE_REMOTE} and
+     * {@link RouteInfo#PLAYBACK_VOLUME_FIXED}.
+     *
+     * @see MediaRouter.RouteInfo
+     */
+    public static class UserRouteInfo extends RouteInfo {
+        RemoteControlClient mRcc;
+        SessionVolumeProvider mSvp;
+
+        UserRouteInfo(RouteCategory category) {
+            super(category);
+            mSupportedTypes = ROUTE_TYPE_USER;
+            mPlaybackType = PLAYBACK_TYPE_REMOTE;
+            mVolumeHandling = PLAYBACK_VOLUME_FIXED;
+        }
+
+        /**
+         * Set the user-visible name of this route.
+         * @param name Name to display to the user to describe this route
+         */
+        public void setName(CharSequence name) {
+            mNameResId = 0;
+            mName = name;
+            routeUpdated();
+        }
+
+        /**
+         * Set the user-visible name of this route.
+         * <p>
+         * The route name identifies the destination represented by the route.
+         * It may be a user-supplied name, an alias, or device serial number.
+         * </p>
+         *
+         * @param resId Resource ID of the name to display to the user to describe this route
+         */
+        public void setName(int resId) {
+            mNameResId = resId;
+            mName = null;
+            routeUpdated();
+        }
+
+        /**
+         * Set the user-visible description of this route.
+         * <p>
+         * The route description describes the kind of destination represented by the route.
+         * It may be a user-supplied string, a model number or brand of device.
+         * </p>
+         *
+         * @param description The description of the route, or null if none.
+         */
+        public void setDescription(CharSequence description) {
+            mDescription = description;
+            routeUpdated();
+        }
+
+        /**
+         * Set the current user-visible status for this route.
+         * @param status Status to display to the user to describe what the endpoint
+         * of this route is currently doing
+         */
+        public void setStatus(CharSequence status) {
+            setStatusInt(status);
+        }
+
+        /**
+         * Set the RemoteControlClient responsible for reporting playback info for this
+         * user route.
+         *
+         * <p>If this route manages remote playback, the data exposed by this
+         * RemoteControlClient will be used to reflect and update information
+         * such as route volume info in related UIs.</p>
+         *
+         * <p>The RemoteControlClient must have been previously registered with
+         * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.</p>
+         *
+         * @param rcc RemoteControlClient associated with this route
+         */
+        public void setRemoteControlClient(RemoteControlClient rcc) {
+            mRcc = rcc;
+            updatePlaybackInfoOnRcc();
+        }
+
+        /**
+         * Retrieve the RemoteControlClient associated with this route, if one has been set.
+         *
+         * @return the RemoteControlClient associated with this route
+         * @see #setRemoteControlClient(RemoteControlClient)
+         */
+        public RemoteControlClient getRemoteControlClient() {
+            return mRcc;
+        }
+
+        /**
+         * Set an icon that will be used to represent this route.
+         * The system may use this icon in picker UIs or similar.
+         *
+         * @param icon icon drawable to use to represent this route
+         */
+        public void setIconDrawable(Drawable icon) {
+            mIcon = icon;
+        }
+
+        /**
+         * Set an icon that will be used to represent this route.
+         * The system may use this icon in picker UIs or similar.
+         *
+         * @param resId Resource ID of an icon drawable to use to represent this route
+         */
+        public void setIconResource(@DrawableRes int resId) {
+            setIconDrawable(sStatic.mResources.getDrawable(resId));
+        }
+
+        /**
+         * Set a callback to be notified of volume update requests
+         * @param vcb
+         */
+        public void setVolumeCallback(VolumeCallback vcb) {
+            mVcb = new VolumeCallbackInfo(vcb, this);
+        }
+
+        /**
+         * Defines whether playback associated with this route is "local"
+         *    ({@link RouteInfo#PLAYBACK_TYPE_LOCAL}) or "remote"
+         *    ({@link RouteInfo#PLAYBACK_TYPE_REMOTE}).
+         * @param type
+         */
+        public void setPlaybackType(@RouteInfo.PlaybackType int type) {
+            if (mPlaybackType != type) {
+                mPlaybackType = type;
+                configureSessionVolume();
+            }
+        }
+
+        /**
+         * Defines whether volume for the playback associated with this route is fixed
+         * ({@link RouteInfo#PLAYBACK_VOLUME_FIXED}) or can modified
+         * ({@link RouteInfo#PLAYBACK_VOLUME_VARIABLE}).
+         * @param volumeHandling
+         */
+        public void setVolumeHandling(@RouteInfo.PlaybackVolume int volumeHandling) {
+            if (mVolumeHandling != volumeHandling) {
+                mVolumeHandling = volumeHandling;
+                configureSessionVolume();
+            }
+        }
+
+        /**
+         * Defines at what volume the playback associated with this route is performed (for user
+         * feedback purposes). This information is only used when the playback is not local.
+         * @param volume
+         */
+        public void setVolume(int volume) {
+            volume = Math.max(0, Math.min(volume, getVolumeMax()));
+            if (mVolume != volume) {
+                mVolume = volume;
+                if (mSvp != null) {
+                    mSvp.setCurrentVolume(mVolume);
+                }
+                dispatchRouteVolumeChanged(this);
+                if (mGroup != null) {
+                    mGroup.memberVolumeChanged(this);
+                }
+            }
+        }
+
+        @Override
+        public void requestSetVolume(int volume) {
+            if (mVolumeHandling == PLAYBACK_VOLUME_VARIABLE) {
+                if (mVcb == null) {
+                    Log.e(TAG, "Cannot requestSetVolume on user route - no volume callback set");
+                    return;
+                }
+                mVcb.vcb.onVolumeSetRequest(this, volume);
+            }
+        }
+
+        @Override
+        public void requestUpdateVolume(int direction) {
+            if (mVolumeHandling == PLAYBACK_VOLUME_VARIABLE) {
+                if (mVcb == null) {
+                    Log.e(TAG, "Cannot requestChangeVolume on user route - no volumec callback set");
+                    return;
+                }
+                mVcb.vcb.onVolumeUpdateRequest(this, direction);
+            }
+        }
+
+        /**
+         * Defines the maximum volume at which the playback associated with this route is performed
+         * (for user feedback purposes). This information is only used when the playback is not
+         * local.
+         * @param volumeMax
+         */
+        public void setVolumeMax(int volumeMax) {
+            if (mVolumeMax != volumeMax) {
+                mVolumeMax = volumeMax;
+                configureSessionVolume();
+            }
+        }
+
+        /**
+         * Defines over what stream type the media is presented.
+         * @param stream
+         */
+        public void setPlaybackStream(int stream) {
+            if (mPlaybackStream != stream) {
+                mPlaybackStream = stream;
+                configureSessionVolume();
+            }
+        }
+
+        private void updatePlaybackInfoOnRcc() {
+            configureSessionVolume();
+        }
+
+        private void configureSessionVolume() {
+            if (mRcc == null) {
+                if (DEBUG) {
+                    Log.d(TAG, "No Rcc to configure volume for route " + getName());
+                }
+                return;
+            }
+            MediaSession session = mRcc.getMediaSession();
+            if (session == null) {
+                if (DEBUG) {
+                    Log.d(TAG, "Rcc has no session to configure volume");
+                }
+                return;
+            }
+            if (mPlaybackType == PLAYBACK_TYPE_REMOTE) {
+                int volumeControl = VolumeProvider.VOLUME_CONTROL_FIXED;
+                switch (mVolumeHandling) {
+                    case PLAYBACK_VOLUME_VARIABLE:
+                        volumeControl = VolumeProvider.VOLUME_CONTROL_ABSOLUTE;
+                        break;
+                    case PLAYBACK_VOLUME_FIXED:
+                    default:
+                        break;
+                }
+                // Only register a new listener if necessary
+                if (mSvp == null || mSvp.getVolumeControl() != volumeControl
+                        || mSvp.getMaxVolume() != mVolumeMax) {
+                    mSvp = new SessionVolumeProvider(volumeControl, mVolumeMax, mVolume);
+                    session.setPlaybackToRemote(mSvp);
+                }
+            } else {
+                // We only know how to handle local and remote, fall back to local if not remote.
+                AudioAttributes.Builder bob = new AudioAttributes.Builder();
+                bob.setLegacyStreamType(mPlaybackStream);
+                session.setPlaybackToLocal(bob.build());
+                mSvp = null;
+            }
+        }
+
+        class SessionVolumeProvider extends VolumeProvider {
+
+            SessionVolumeProvider(int volumeControl, int maxVolume, int currentVolume) {
+                super(volumeControl, maxVolume, currentVolume);
+            }
+
+            @Override
+            public void onSetVolumeTo(final int volume) {
+                sStatic.mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        if (mVcb != null) {
+                            mVcb.vcb.onVolumeSetRequest(mVcb.route, volume);
+                        }
+                    }
+                });
+            }
+
+            @Override
+            public void onAdjustVolume(final int direction) {
+                sStatic.mHandler.post(new Runnable() {
+                    @Override
+                    public void run() {
+                        if (mVcb != null) {
+                            mVcb.vcb.onVolumeUpdateRequest(mVcb.route, direction);
+                        }
+                    }
+                });
+            }
+        }
+    }
+
+    /**
+     * Information about a route that consists of multiple other routes in a group.
+     */
+    public static class RouteGroup extends RouteInfo {
+        final ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>();
+        private boolean mUpdateName;
+
+        RouteGroup(RouteCategory category) {
+            super(category);
+            mGroup = this;
+            mVolumeHandling = PLAYBACK_VOLUME_FIXED;
+        }
+
+        @Override
+        CharSequence getName(Resources res) {
+            if (mUpdateName) updateName();
+            return super.getName(res);
+        }
+
+        /**
+         * Add a route to this group. The route must not currently belong to another group.
+         *
+         * @param route route to add to this group
+         */
+        public void addRoute(RouteInfo route) {
+            if (route.getGroup() != null) {
+                throw new IllegalStateException("Route " + route + " is already part of a group.");
+            }
+            if (route.getCategory() != mCategory) {
+                throw new IllegalArgumentException(
+                        "Route cannot be added to a group with a different category. " +
+                            "(Route category=" + route.getCategory() +
+                            " group category=" + mCategory + ")");
+            }
+            final int at = mRoutes.size();
+            mRoutes.add(route);
+            route.mGroup = this;
+            mUpdateName = true;
+            updateVolume();
+            routeUpdated();
+            dispatchRouteGrouped(route, this, at);
+        }
+
+        /**
+         * Add a route to this group before the specified index.
+         *
+         * @param route route to add
+         * @param insertAt insert the new route before this index
+         */
+        public void addRoute(RouteInfo route, int insertAt) {
+            if (route.getGroup() != null) {
+                throw new IllegalStateException("Route " + route + " is already part of a group.");
+            }
+            if (route.getCategory() != mCategory) {
+                throw new IllegalArgumentException(
+                        "Route cannot be added to a group with a different category. " +
+                            "(Route category=" + route.getCategory() +
+                            " group category=" + mCategory + ")");
+            }
+            mRoutes.add(insertAt, route);
+            route.mGroup = this;
+            mUpdateName = true;
+            updateVolume();
+            routeUpdated();
+            dispatchRouteGrouped(route, this, insertAt);
+        }
+
+        /**
+         * Remove a route from this group.
+         *
+         * @param route route to remove
+         */
+        public void removeRoute(RouteInfo route) {
+            if (route.getGroup() != this) {
+                throw new IllegalArgumentException("Route " + route +
+                        " is not a member of this group.");
+            }
+            mRoutes.remove(route);
+            route.mGroup = null;
+            mUpdateName = true;
+            updateVolume();
+            dispatchRouteUngrouped(route, this);
+            routeUpdated();
+        }
+
+        /**
+         * Remove the route at the specified index from this group.
+         *
+         * @param index index of the route to remove
+         */
+        public void removeRoute(int index) {
+            RouteInfo route = mRoutes.remove(index);
+            route.mGroup = null;
+            mUpdateName = true;
+            updateVolume();
+            dispatchRouteUngrouped(route, this);
+            routeUpdated();
+        }
+
+        /**
+         * @return The number of routes in this group
+         */
+        public int getRouteCount() {
+            return mRoutes.size();
+        }
+
+        /**
+         * Return the route in this group at the specified index
+         *
+         * @param index Index to fetch
+         * @return The route at index
+         */
+        public RouteInfo getRouteAt(int index) {
+            return mRoutes.get(index);
+        }
+
+        /**
+         * Set an icon that will be used to represent this group.
+         * The system may use this icon in picker UIs or similar.
+         *
+         * @param icon icon drawable to use to represent this group
+         */
+        public void setIconDrawable(Drawable icon) {
+            mIcon = icon;
+        }
+
+        /**
+         * Set an icon that will be used to represent this group.
+         * The system may use this icon in picker UIs or similar.
+         *
+         * @param resId Resource ID of an icon drawable to use to represent this group
+         */
+        public void setIconResource(@DrawableRes int resId) {
+            setIconDrawable(sStatic.mResources.getDrawable(resId));
+        }
+
+        @Override
+        public void requestSetVolume(int volume) {
+            final int maxVol = getVolumeMax();
+            if (maxVol == 0) {
+                return;
+            }
+
+            final float scaledVolume = (float) volume / maxVol;
+            final int routeCount = getRouteCount();
+            for (int i = 0; i < routeCount; i++) {
+                final RouteInfo route = getRouteAt(i);
+                final int routeVol = (int) (scaledVolume * route.getVolumeMax());
+                route.requestSetVolume(routeVol);
+            }
+            if (volume != mVolume) {
+                mVolume = volume;
+                dispatchRouteVolumeChanged(this);
+            }
+        }
+
+        @Override
+        public void requestUpdateVolume(int direction) {
+            final int maxVol = getVolumeMax();
+            if (maxVol == 0) {
+                return;
+            }
+
+            final int routeCount = getRouteCount();
+            int volume = 0;
+            for (int i = 0; i < routeCount; i++) {
+                final RouteInfo route = getRouteAt(i);
+                route.requestUpdateVolume(direction);
+                final int routeVol = route.getVolume();
+                if (routeVol > volume) {
+                    volume = routeVol;
+                }
+            }
+            if (volume != mVolume) {
+                mVolume = volume;
+                dispatchRouteVolumeChanged(this);
+            }
+        }
+
+        void memberNameChanged(RouteInfo info, CharSequence name) {
+            mUpdateName = true;
+            routeUpdated();
+        }
+
+        void memberStatusChanged(RouteInfo info, CharSequence status) {
+            setStatusInt(status);
+        }
+
+        void memberVolumeChanged(RouteInfo info) {
+            updateVolume();
+        }
+
+        void updateVolume() {
+            // A group always represents the highest component volume value.
+            final int routeCount = getRouteCount();
+            int volume = 0;
+            for (int i = 0; i < routeCount; i++) {
+                final int routeVol = getRouteAt(i).getVolume();
+                if (routeVol > volume) {
+                    volume = routeVol;
+                }
+            }
+            if (volume != mVolume) {
+                mVolume = volume;
+                dispatchRouteVolumeChanged(this);
+            }
+        }
+
+        @Override
+        void routeUpdated() {
+            int types = 0;
+            final int count = mRoutes.size();
+            if (count == 0) {
+                // Don't keep empty groups in the router.
+                MediaRouter.removeRouteStatic(this);
+                return;
+            }
+
+            int maxVolume = 0;
+            boolean isLocal = true;
+            boolean isFixedVolume = true;
+            for (int i = 0; i < count; i++) {
+                final RouteInfo route = mRoutes.get(i);
+                types |= route.mSupportedTypes;
+                final int routeMaxVolume = route.getVolumeMax();
+                if (routeMaxVolume > maxVolume) {
+                    maxVolume = routeMaxVolume;
+                }
+                isLocal &= route.getPlaybackType() == PLAYBACK_TYPE_LOCAL;
+                isFixedVolume &= route.getVolumeHandling() == PLAYBACK_VOLUME_FIXED;
+            }
+            mPlaybackType = isLocal ? PLAYBACK_TYPE_LOCAL : PLAYBACK_TYPE_REMOTE;
+            mVolumeHandling = isFixedVolume ? PLAYBACK_VOLUME_FIXED : PLAYBACK_VOLUME_VARIABLE;
+            mSupportedTypes = types;
+            mVolumeMax = maxVolume;
+            mIcon = count == 1 ? mRoutes.get(0).getIconDrawable() : null;
+            super.routeUpdated();
+        }
+
+        void updateName() {
+            final StringBuilder sb = new StringBuilder();
+            final int count = mRoutes.size();
+            for (int i = 0; i < count; i++) {
+                final RouteInfo info = mRoutes.get(i);
+                // TODO: There's probably a much more correct way to localize this.
+                if (i > 0) {
+                    sb.append(", ");
+                }
+                sb.append(info.getName());
+            }
+            mName = sb.toString();
+            mUpdateName = false;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder(super.toString());
+            sb.append('[');
+            final int count = mRoutes.size();
+            for (int i = 0; i < count; i++) {
+                if (i > 0) sb.append(", ");
+                sb.append(mRoutes.get(i));
+            }
+            sb.append(']');
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Definition of a category of routes. All routes belong to a category.
+     */
+    public static class RouteCategory {
+        CharSequence mName;
+        int mNameResId;
+        int mTypes;
+        final boolean mGroupable;
+        boolean mIsSystem;
+
+        RouteCategory(CharSequence name, int types, boolean groupable) {
+            mName = name;
+            mTypes = types;
+            mGroupable = groupable;
+        }
+
+        RouteCategory(int nameResId, int types, boolean groupable) {
+            mNameResId = nameResId;
+            mTypes = types;
+            mGroupable = groupable;
+        }
+
+        /**
+         * @return the name of this route category
+         */
+        public CharSequence getName() {
+            return getName(sStatic.mResources);
+        }
+
+        /**
+         * Return the properly localized/configuration dependent name of this RouteCategory.
+         *
+         * @param context Context to resolve name resources
+         * @return the name of this route category
+         */
+        public CharSequence getName(Context context) {
+            return getName(context.getResources());
+        }
+
+        CharSequence getName(Resources res) {
+            if (mNameResId != 0) {
+                return res.getText(mNameResId);
+            }
+            return mName;
+        }
+
+        /**
+         * Return the current list of routes in this category that have been added
+         * to the MediaRouter.
+         *
+         * <p>This list will not include routes that are nested within RouteGroups.
+         * A RouteGroup is treated as a single route within its category.</p>
+         *
+         * @param out a List to fill with the routes in this category. If this parameter is
+         *            non-null, it will be cleared, filled with the current routes with this
+         *            category, and returned. If this parameter is null, a new List will be
+         *            allocated to report the category's current routes.
+         * @return A list with the routes in this category that have been added to the MediaRouter.
+         */
+        public List<RouteInfo> getRoutes(List<RouteInfo> out) {
+            if (out == null) {
+                out = new ArrayList<RouteInfo>();
+            } else {
+                out.clear();
+            }
+
+            final int count = getRouteCountStatic();
+            for (int i = 0; i < count; i++) {
+                final RouteInfo route = getRouteAtStatic(i);
+                if (route.mCategory == this) {
+                    out.add(route);
+                }
+            }
+            return out;
+        }
+
+        /**
+         * @return Flag set describing the route types supported by this category
+         */
+        public int getSupportedTypes() {
+            return mTypes;
+        }
+
+        /**
+         * Return whether or not this category supports grouping.
+         *
+         * <p>If this method returns true, all routes obtained from this category
+         * via calls to {@link #getRouteAt(int)} will be {@link MediaRouter.RouteGroup}s.</p>
+         *
+         * @return true if this category supports
+         */
+        public boolean isGroupable() {
+            return mGroupable;
+        }
+
+        /**
+         * @return true if this is the category reserved for system routes.
+         * @hide
+         */
+        public boolean isSystem() {
+            return mIsSystem;
+        }
+
+        @Override
+        public String toString() {
+            return "RouteCategory{ name=" + getName() + " types=" + typesToString(mTypes) +
+                    " groupable=" + mGroupable + " }";
+        }
+    }
+
+    static class CallbackInfo {
+        public int type;
+        public int flags;
+        public final Callback cb;
+        public final MediaRouter router;
+
+        public CallbackInfo(Callback cb, int type, int flags, MediaRouter router) {
+            this.cb = cb;
+            this.type = type;
+            this.flags = flags;
+            this.router = router;
+        }
+
+        public boolean filterRouteEvent(RouteInfo route) {
+            return filterRouteEvent(route.mSupportedTypes);
+        }
+
+        public boolean filterRouteEvent(int supportedTypes) {
+            return (flags & CALLBACK_FLAG_UNFILTERED_EVENTS) != 0
+                    || (type & supportedTypes) != 0;
+        }
+    }
+
+    /**
+     * Interface for receiving events about media routing changes.
+     * All methods of this interface will be called from the application's main thread.
+     * <p>
+     * A Callback will only receive events relevant to routes that the callback
+     * was registered for unless the {@link MediaRouter#CALLBACK_FLAG_UNFILTERED_EVENTS}
+     * flag was specified in {@link MediaRouter#addCallback(int, Callback, int)}.
+     * </p>
+     *
+     * @see MediaRouter#addCallback(int, Callback, int)
+     * @see MediaRouter#removeCallback(Callback)
+     */
+    public static abstract class Callback {
+        /**
+         * Called when the supplied route becomes selected as the active route
+         * for the given route type.
+         *
+         * @param router the MediaRouter reporting the event
+         * @param type Type flag set indicating the routes that have been selected
+         * @param info Route that has been selected for the given route types
+         */
+        public abstract void onRouteSelected(MediaRouter router, int type, RouteInfo info);
+
+        /**
+         * Called when the supplied route becomes unselected as the active route
+         * for the given route type.
+         *
+         * @param router the MediaRouter reporting the event
+         * @param type Type flag set indicating the routes that have been unselected
+         * @param info Route that has been unselected for the given route types
+         */
+        public abstract void onRouteUnselected(MediaRouter router, int type, RouteInfo info);
+
+        /**
+         * Called when a route for the specified type was added.
+         *
+         * @param router the MediaRouter reporting the event
+         * @param info Route that has become available for use
+         */
+        public abstract void onRouteAdded(MediaRouter router, RouteInfo info);
+
+        /**
+         * Called when a route for the specified type was removed.
+         *
+         * @param router the MediaRouter reporting the event
+         * @param info Route that has been removed from availability
+         */
+        public abstract void onRouteRemoved(MediaRouter router, RouteInfo info);
+
+        /**
+         * Called when an aspect of the indicated route has changed.
+         *
+         * <p>This will not indicate that the types supported by this route have
+         * changed, only that cosmetic info such as name or status have been updated.</p>
+         *
+         * @param router the MediaRouter reporting the event
+         * @param info The route that was changed
+         */
+        public abstract void onRouteChanged(MediaRouter router, RouteInfo info);
+
+        /**
+         * Called when a route is added to a group.
+         *
+         * @param router the MediaRouter reporting the event
+         * @param info The route that was added
+         * @param group The group the route was added to
+         * @param index The route index within group that info was added at
+         */
+        public abstract void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group,
+                int index);
+
+        /**
+         * Called when a route is removed from a group.
+         *
+         * @param router the MediaRouter reporting the event
+         * @param info The route that was removed
+         * @param group The group the route was removed from
+         */
+        public abstract void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group);
+
+        /**
+         * Called when a route's volume changes.
+         *
+         * @param router the MediaRouter reporting the event
+         * @param info The route with altered volume
+         */
+        public abstract void onRouteVolumeChanged(MediaRouter router, RouteInfo info);
+
+        /**
+         * Called when a route's presentation display changes.
+         * <p>
+         * This method is called whenever the route's presentation display becomes
+         * available, is removes or has changes to some of its properties (such as its size).
+         * </p>
+         *
+         * @param router the MediaRouter reporting the event
+         * @param info The route whose presentation display changed
+         *
+         * @see RouteInfo#getPresentationDisplay()
+         */
+        public void onRoutePresentationDisplayChanged(MediaRouter router, RouteInfo info) {
+        }
+    }
+
+    /**
+     * Stub implementation of {@link MediaRouter.Callback}.
+     * Each abstract method is defined as a no-op. Override just the ones
+     * you need.
+     */
+    public static class SimpleCallback extends Callback {
+
+        @Override
+        public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
+        }
+
+        @Override
+        public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
+        }
+
+        @Override
+        public void onRouteAdded(MediaRouter router, RouteInfo info) {
+        }
+
+        @Override
+        public void onRouteRemoved(MediaRouter router, RouteInfo info) {
+        }
+
+        @Override
+        public void onRouteChanged(MediaRouter router, RouteInfo info) {
+        }
+
+        @Override
+        public void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group,
+                int index) {
+        }
+
+        @Override
+        public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) {
+        }
+
+        @Override
+        public void onRouteVolumeChanged(MediaRouter router, RouteInfo info) {
+        }
+    }
+
+    static class VolumeCallbackInfo {
+        public final VolumeCallback vcb;
+        public final RouteInfo route;
+
+        public VolumeCallbackInfo(VolumeCallback vcb, RouteInfo route) {
+            this.vcb = vcb;
+            this.route = route;
+        }
+    }
+
+    /**
+     * Interface for receiving events about volume changes.
+     * All methods of this interface will be called from the application's main thread.
+     *
+     * <p>A VolumeCallback will only receive events relevant to routes that the callback
+     * was registered for.</p>
+     *
+     * @see UserRouteInfo#setVolumeCallback(VolumeCallback)
+     */
+    public static abstract class VolumeCallback {
+        /**
+         * Called when the volume for the route should be increased or decreased.
+         * @param info the route affected by this event
+         * @param direction an integer indicating whether the volume is to be increased
+         *     (positive value) or decreased (negative value).
+         *     For bundled changes, the absolute value indicates the number of changes
+         *     in the same direction, e.g. +3 corresponds to three "volume up" changes.
+         */
+        public abstract void onVolumeUpdateRequest(RouteInfo info, int direction);
+        /**
+         * Called when the volume for the route should be set to the given value
+         * @param info the route affected by this event
+         * @param volume an integer indicating the new volume value that should be used, always
+         *     between 0 and the value set by {@link UserRouteInfo#setVolumeMax(int)}.
+         */
+        public abstract void onVolumeSetRequest(RouteInfo info, int volume);
+    }
+
+    static class VolumeChangeReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(AudioManager.VOLUME_CHANGED_ACTION)) {
+                final int streamType = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_TYPE,
+                        -1);
+                final int newVolume = intent.getIntExtra(AudioManager.EXTRA_VOLUME_STREAM_VALUE, 0);
+                sStatic.mStreamVolume.put(streamType, newVolume);
+                if (streamType != AudioManager.STREAM_MUSIC) {
+                    return;
+                }
+
+                final int oldVolume = intent.getIntExtra(
+                        AudioManager.EXTRA_PREV_VOLUME_STREAM_VALUE, 0);
+                if (newVolume != oldVolume) {
+                    systemVolumeChanged(newVolume);
+                }
+            }
+        }
+    }
+
+    static class WifiDisplayStatusChangedReceiver extends BroadcastReceiver {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(DisplayManager.ACTION_WIFI_DISPLAY_STATUS_CHANGED)) {
+                updateWifiDisplayStatus((WifiDisplayStatus) intent.getParcelableExtra(
+                        DisplayManager.EXTRA_WIFI_DISPLAY_STATUS));
+            }
+        }
+    }
+}
diff --git a/android/media/MediaRouter2.java b/android/media/MediaRouter2.java
new file mode 100644
index 0000000..fbf7def
--- /dev/null
+++ b/android/media/MediaRouter2.java
@@ -0,0 +1,2070 @@
+/*
+ * Copyright 2019 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 com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.Manifest;
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+/**
+ * This API is not generally intended for third party application developers.
+ * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+  <a href="{@docRoot}reference/androidx/mediarouter/media/package-summary.html">Media Router
+ * Library</a> for consistent behavior across all devices.
+ *
+ * Media Router 2 allows applications to control the routing of media channels
+ * and streams from the current device to remote speakers and devices.
+ */
+// TODO(b/157873330): Add method names at the beginning of log messages. (e.g. selectRoute)
+//       Not only MediaRouter2, but also to service / manager / provider.
+// TODO: ensure thread-safe and document it
+public final class MediaRouter2 {
+    private static final String TAG = "MR2";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+    private static final Object sSystemRouterLock = new Object();
+    private static final Object sRouterLock = new Object();
+
+    // The maximum time for the old routing controller available after transfer.
+    private static final int TRANSFER_TIMEOUT_MS = 30_000;
+    // The manager request ID representing that no manager is involved.
+    private static final long MANAGER_REQUEST_ID_NONE = MediaRoute2ProviderService.REQUEST_ID_NONE;
+
+    @GuardedBy("sSystemRouterLock")
+    private static Map<String, MediaRouter2> sSystemMediaRouter2Map = new ArrayMap<>();
+    private static MediaRouter2Manager sManager;
+
+    @GuardedBy("sRouterLock")
+    private static MediaRouter2 sInstance;
+
+    private final Context mContext;
+    private final IMediaRouterService mMediaRouterService;
+    private final Object mLock = new Object();
+
+    private final CopyOnWriteArrayList<RouteCallbackRecord> mRouteCallbackRecords =
+            new CopyOnWriteArrayList<>();
+    private final CopyOnWriteArrayList<TransferCallbackRecord> mTransferCallbackRecords =
+            new CopyOnWriteArrayList<>();
+    private final CopyOnWriteArrayList<ControllerCallbackRecord> mControllerCallbackRecords =
+            new CopyOnWriteArrayList<>();
+
+    private final CopyOnWriteArrayList<ControllerCreationRequest> mControllerCreationRequests =
+            new CopyOnWriteArrayList<>();
+
+    // TODO: Specify the fields that are only used (or not used) by system media router.
+    private final String mClientPackageName;
+    final ManagerCallback mManagerCallback;
+
+    private final String mPackageName;
+
+    @GuardedBy("mLock")
+    final Map<String, MediaRoute2Info> mRoutes = new ArrayMap<>();
+
+    final RoutingController mSystemController;
+
+    @GuardedBy("mLock")
+    private RouteDiscoveryPreference mDiscoveryPreference = RouteDiscoveryPreference.EMPTY;
+
+    // TODO: Make MediaRouter2 is always connected to the MediaRouterService.
+    @GuardedBy("mLock")
+    MediaRouter2Stub mStub;
+
+    @GuardedBy("mLock")
+    private final Map<String, RoutingController> mNonSystemRoutingControllers = new ArrayMap<>();
+
+    private final AtomicInteger mNextRequestId = new AtomicInteger(1);
+
+    final Handler mHandler;
+    @GuardedBy("mLock")
+    private boolean mShouldUpdateRoutes = true;
+    private volatile List<MediaRoute2Info> mFilteredRoutes = Collections.emptyList();
+    private volatile OnGetControllerHintsListener mOnGetControllerHintsListener;
+
+    /**
+     * Gets an instance of the media router associated with the context.
+     */
+    @NonNull
+    public static MediaRouter2 getInstance(@NonNull Context context) {
+        Objects.requireNonNull(context, "context must not be null");
+        synchronized (sRouterLock) {
+            if (sInstance == null) {
+                sInstance = new MediaRouter2(context.getApplicationContext());
+            }
+            return sInstance;
+        }
+    }
+
+    /**
+     * Gets an instance of the system media router which controls the app's media routing.
+     * Returns {@code null} if the given package name is invalid.
+     * There are several things to note when using the media routers created with this method.
+     * <p>
+     * First of all, the discovery preference passed to {@link #registerRouteCallback}
+     * will have no effect. The callback will be called accordingly with the client app's
+     * discovery preference. Therefore, it is recommended to pass
+     * {@link RouteDiscoveryPreference#EMPTY} there.
+     * <p>
+     * Also, do not keep/compare the instances of the {@link RoutingController}, since they are
+     * always newly created with the latest session information whenever below methods are called:
+     * <ul>
+     * <li> {@link #getControllers()} </li>
+     * <li> {@link #getController(String)}} </li>
+     * <li> {@link TransferCallback#onTransfer(RoutingController, RoutingController)} </li>
+     * <li> {@link TransferCallback#onStop(RoutingController)} </li>
+     * <li> {@link ControllerCallback#onControllerUpdated(RoutingController)} </li>
+     * </ul>
+     * Therefore, in order to track the current routing status, keep the controller's ID instead,
+     * and use {@link #getController(String)} and {@link #getSystemController()} for
+     * getting controllers.
+     * <p>
+     * Finally, it will have no effect to call {@link #setOnGetControllerHintsListener}.
+     *
+     * @param clientPackageName the package name of the app to control
+     * @throws SecurityException if the caller doesn't have MODIFY_AUDIO_ROUTING permission.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
+    @Nullable
+    public static MediaRouter2 getInstance(@NonNull Context context,
+            @NonNull String clientPackageName) {
+        Objects.requireNonNull(context, "context must not be null");
+        Objects.requireNonNull(clientPackageName, "clientPackageName must not be null");
+
+        // Note: Even though this check could be somehow bypassed, the other permission checks
+        // in system server will not allow MediaRouter2Manager to be registered.
+        IMediaRouterService serviceBinder = IMediaRouterService.Stub.asInterface(
+                ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
+        try {
+            // SecurityException will be thrown if there's no permission.
+            serviceBinder.enforceMediaContentControlPermission();
+        } catch (RemoteException e) {
+            e.rethrowFromSystemServer();
+        }
+
+        PackageManager pm = context.getPackageManager();
+        try {
+            pm.getPackageInfo(clientPackageName, 0);
+        } catch (PackageManager.NameNotFoundException ex) {
+            Log.e(TAG, "Package " + clientPackageName + " not found. Ignoring.");
+            return null;
+        }
+
+        synchronized (sSystemRouterLock) {
+            MediaRouter2 instance = sSystemMediaRouter2Map.get(clientPackageName);
+            if (instance == null) {
+                if (sManager == null) {
+                    sManager = MediaRouter2Manager.getInstance(context.getApplicationContext());
+                }
+                instance = new MediaRouter2(context, clientPackageName);
+                sSystemMediaRouter2Map.put(clientPackageName, instance);
+                // Using direct executor here, since MediaRouter2Manager also posts
+                // to the main handler.
+                sManager.registerCallback(Runnable::run, instance.mManagerCallback);
+            }
+            return instance;
+        }
+    }
+
+    /**
+     * Starts scanning remote routes.
+     * <p>
+     * Route discovery can happen even when the {@link #startScan()} is not called.
+     * This is because the scanning could be started before by other apps.
+     * Therefore, calling this method after calling {@link #stopScan()} does not necessarily mean
+     * that the routes found before are removed and added again.
+     * <p>
+     * Use {@link RouteCallback} to get the route related events.
+     * <p>
+     * Note that calling start/stopScan is applied to all system routers in the same process.
+     * <p>
+     * This will be no-op for non-system media routers.
+     *
+     * @see #stopScan()
+     * @see #getInstance(Context, String)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
+    public void startScan() {
+        if (isSystemRouter()) {
+            sManager.startScan();
+        }
+    }
+
+    /**
+     * Stops scanning remote routes to reduce resource consumption.
+     * <p>
+     * Route discovery can be continued even after this method is called.
+     * This is because the scanning is only turned off when all the apps stop scanning.
+     * Therefore, calling this method does not necessarily mean the routes are removed.
+     * Also, for the same reason it does not mean that {@link RouteCallback#onRoutesAdded(List)}
+     * is not called afterwards.
+     * <p>
+     * Use {@link RouteCallback} to get the route related events.
+     * <p>
+     * Note that calling start/stopScan is applied to all system routers in the same process.
+     * <p>
+     * This will be no-op for non-system media routers.
+     *
+     * @see #startScan()
+     * @see #getInstance(Context, String)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
+    public void stopScan() {
+        if (isSystemRouter()) {
+            sManager.stopScan();
+        }
+    }
+
+    private MediaRouter2(Context appContext) {
+        mContext = appContext;
+        mMediaRouterService = IMediaRouterService.Stub.asInterface(
+                ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
+        mPackageName = mContext.getPackageName();
+        mHandler = new Handler(Looper.getMainLooper());
+
+        List<MediaRoute2Info> currentSystemRoutes = null;
+        RoutingSessionInfo currentSystemSessionInfo = null;
+        try {
+            currentSystemRoutes = mMediaRouterService.getSystemRoutes();
+            currentSystemSessionInfo = mMediaRouterService.getSystemSessionInfo();
+        } catch (RemoteException ex) {
+            Log.e(TAG, "Unable to get current system's routes / session info", ex);
+        }
+
+        if (currentSystemRoutes == null || currentSystemRoutes.isEmpty()) {
+            throw new RuntimeException("Null or empty currentSystemRoutes. Something is wrong.");
+        }
+
+        if (currentSystemSessionInfo == null) {
+            throw new RuntimeException("Null currentSystemSessionInfo. Something is wrong.");
+        }
+
+        for (MediaRoute2Info route : currentSystemRoutes) {
+            mRoutes.put(route.getId(), route);
+        }
+        mSystemController = new SystemRoutingController(currentSystemSessionInfo);
+
+        // Only used by system MediaRouter2.
+        mClientPackageName = null;
+        mManagerCallback = null;
+    }
+
+    private MediaRouter2(Context context, String clientPackageName) {
+        mContext = context;
+        mClientPackageName = clientPackageName;
+        mManagerCallback = new ManagerCallback();
+        mHandler = new Handler(Looper.getMainLooper());
+        mSystemController = new SystemRoutingController(
+                ensureClientPackageNameForSystemSession(sManager.getSystemRoutingSession()));
+        mDiscoveryPreference = new RouteDiscoveryPreference.Builder(
+                sManager.getPreferredFeatures(clientPackageName), true).build();
+        updateAllRoutesFromManager();
+
+        // Only used by non-system MediaRouter2.
+        mMediaRouterService = null;
+        mPackageName = null;
+    }
+
+    /**
+     * Returns whether any route in {@code routeList} has a same unique ID with given route.
+     *
+     * @hide
+     */
+    static boolean checkRouteListContainsRouteId(@NonNull List<MediaRoute2Info> routeList,
+            @NonNull String routeId) {
+        for (MediaRoute2Info info : routeList) {
+            if (TextUtils.equals(routeId, info.getId())) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Gets the client package name of the app which this media router controls.
+     * <p>
+     * This will return null for non-system media routers.
+     *
+     * @see #getInstance(Context, String)
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    public String getClientPackageName() {
+        return mClientPackageName;
+    }
+
+    /**
+     * Registers a callback to discover routes and to receive events when they change.
+     * <p>
+     * If the specified callback is already registered, its registration will be updated for the
+     * given {@link Executor executor} and {@link RouteDiscoveryPreference discovery preference}.
+     * </p>
+     */
+    public void registerRouteCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull RouteCallback routeCallback,
+            @NonNull RouteDiscoveryPreference preference) {
+        Objects.requireNonNull(executor, "executor must not be null");
+        Objects.requireNonNull(routeCallback, "callback must not be null");
+        Objects.requireNonNull(preference, "preference must not be null");
+        if (isSystemRouter()) {
+            preference = RouteDiscoveryPreference.EMPTY;
+        }
+
+        RouteCallbackRecord record = new RouteCallbackRecord(executor, routeCallback, preference);
+
+        mRouteCallbackRecords.remove(record);
+        // It can fail to add the callback record if another registration with the same callback
+        // is happening but it's okay because either this or the other registration should be done.
+        mRouteCallbackRecords.addIfAbsent(record);
+
+        if (isSystemRouter()) {
+            return;
+        }
+
+        synchronized (mLock) {
+            if (mStub == null) {
+                MediaRouter2Stub stub = new MediaRouter2Stub();
+                try {
+                    mMediaRouterService.registerRouter2(stub, mPackageName);
+                    mStub = stub;
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "registerRouteCallback: Unable to register MediaRouter2.", ex);
+                }
+            }
+            if (mStub != null && updateDiscoveryPreferenceIfNeededLocked()) {
+                try {
+                    mMediaRouterService.setDiscoveryRequestWithRouter2(mStub, mDiscoveryPreference);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "registerRouteCallback: Unable to set discovery request.", ex);
+                }
+            }
+        }
+    }
+
+    /**
+     * Unregisters the given callback. The callback will no longer receive events.
+     * If the callback has not been added or been removed already, it is ignored.
+     *
+     * @param routeCallback the callback to unregister
+     * @see #registerRouteCallback
+     */
+    public void unregisterRouteCallback(@NonNull RouteCallback routeCallback) {
+        Objects.requireNonNull(routeCallback, "callback must not be null");
+
+        if (!mRouteCallbackRecords.remove(
+                new RouteCallbackRecord(null, routeCallback, null))) {
+            Log.w(TAG, "unregisterRouteCallback: Ignoring unknown callback");
+            return;
+        }
+
+        if (isSystemRouter()) {
+            return;
+        }
+
+        synchronized (mLock) {
+            if (mStub == null) {
+                return;
+            }
+            if (updateDiscoveryPreferenceIfNeededLocked()) {
+                try {
+                    mMediaRouterService.setDiscoveryRequestWithRouter2(
+                            mStub, mDiscoveryPreference);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "unregisterRouteCallback: Unable to set discovery request.", ex);
+                }
+            }
+            if (mRouteCallbackRecords.isEmpty() && mNonSystemRoutingControllers.isEmpty()) {
+                try {
+                    mMediaRouterService.unregisterRouter2(mStub);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to unregister media router.", ex);
+                }
+                mStub = null;
+            }
+            mShouldUpdateRoutes = true;
+        }
+    }
+
+    private boolean updateDiscoveryPreferenceIfNeededLocked() {
+        RouteDiscoveryPreference newDiscoveryPreference = new RouteDiscoveryPreference.Builder(
+                mRouteCallbackRecords.stream().map(record -> record.mPreference).collect(
+                        Collectors.toList())).build();
+        if (Objects.equals(mDiscoveryPreference, newDiscoveryPreference)) {
+            return false;
+        }
+        mDiscoveryPreference = newDiscoveryPreference;
+        mShouldUpdateRoutes = true;
+        return true;
+    }
+
+    /**
+     * Gets the list of all discovered routes.
+     * This list includes the routes that are not related to the client app.
+     * <p>
+     * This will return an empty list for non-system media routers.
+     *
+     * @hide
+     */
+    @SystemApi
+    @NonNull
+    public List<MediaRoute2Info> getAllRoutes() {
+        if (isSystemRouter()) {
+            return sManager.getAllRoutes();
+        }
+        return Collections.emptyList();
+    }
+
+    /**
+     * Gets the unmodifiable list of {@link MediaRoute2Info routes} currently
+     * known to the media router.
+     * <p>
+     * Please note that the list can be changed before callbacks are invoked.
+     * </p>
+     * @return the list of routes that contains at least one of the route features in discovery
+     * preferences registered by the application
+     */
+    @NonNull
+    public List<MediaRoute2Info> getRoutes() {
+        synchronized (mLock) {
+            if (mShouldUpdateRoutes) {
+                mShouldUpdateRoutes = false;
+
+                List<MediaRoute2Info> filteredRoutes = new ArrayList<>();
+                for (MediaRoute2Info route : mRoutes.values()) {
+                    if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+                        filteredRoutes.add(route);
+                    }
+                }
+                mFilteredRoutes = Collections.unmodifiableList(filteredRoutes);
+            }
+        }
+        return mFilteredRoutes;
+    }
+
+    /**
+     * Registers a callback to get the result of {@link #transferTo(MediaRoute2Info)}.
+     * If you register the same callback twice or more, it will be ignored.
+     *
+     * @param executor the executor to execute the callback on
+     * @param callback the callback to register
+     * @see #unregisterTransferCallback
+     */
+    public void registerTransferCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull TransferCallback callback) {
+        Objects.requireNonNull(executor, "executor must not be null");
+        Objects.requireNonNull(callback, "callback must not be null");
+
+        TransferCallbackRecord record = new TransferCallbackRecord(executor, callback);
+        if (!mTransferCallbackRecords.addIfAbsent(record)) {
+            Log.w(TAG, "registerTransferCallback: Ignoring the same callback");
+            return;
+        }
+    }
+
+    /**
+     * Unregisters the given callback. The callback will no longer receive events.
+     * If the callback has not been added or been removed already, it is ignored.
+     *
+     * @param callback the callback to unregister
+     * @see #registerTransferCallback
+     */
+    public void unregisterTransferCallback(@NonNull TransferCallback callback) {
+        Objects.requireNonNull(callback, "callback must not be null");
+
+        if (!mTransferCallbackRecords.remove(new TransferCallbackRecord(null, callback))) {
+            Log.w(TAG, "unregisterTransferCallback: Ignoring an unknown callback");
+            return;
+        }
+    }
+
+    /**
+     * Registers a {@link ControllerCallback}.
+     * If you register the same callback twice or more, it will be ignored.
+     * @see #unregisterControllerCallback(ControllerCallback)
+     */
+    public void registerControllerCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull ControllerCallback callback) {
+        Objects.requireNonNull(executor, "executor must not be null");
+        Objects.requireNonNull(callback, "callback must not be null");
+
+        ControllerCallbackRecord record = new ControllerCallbackRecord(executor, callback);
+        if (!mControllerCallbackRecords.addIfAbsent(record)) {
+            Log.w(TAG, "registerControllerCallback: Ignoring the same callback");
+            return;
+        }
+    }
+
+    /**
+     * Unregisters a {@link ControllerCallback}. The callback will no longer receive
+     * events. If the callback has not been added or been removed already, it is ignored.
+     * @see #registerControllerCallback(Executor, ControllerCallback)
+     */
+    public void unregisterControllerCallback(
+            @NonNull ControllerCallback callback) {
+        Objects.requireNonNull(callback, "callback must not be null");
+
+        if (!mControllerCallbackRecords.remove(new ControllerCallbackRecord(null, callback))) {
+            Log.w(TAG, "unregisterControllerCallback: Ignoring an unknown callback");
+            return;
+        }
+    }
+
+    /**
+     * Sets an {@link OnGetControllerHintsListener} to send hints when creating a
+     * {@link RoutingController}. To send the hints, listener should be set <em>BEFORE</em> calling
+     * {@link #transferTo(MediaRoute2Info)}.
+     *
+     * @param listener A listener to send optional app-specific hints when creating a controller.
+     *                 {@code null} for unset.
+     */
+    public void setOnGetControllerHintsListener(@Nullable OnGetControllerHintsListener listener) {
+        if (isSystemRouter()) {
+            return;
+        }
+        mOnGetControllerHintsListener = listener;
+    }
+
+    /**
+     * Transfers the current media to the given route.
+     * If it's necessary a new {@link RoutingController} is created or it is handled within
+     * the current routing controller.
+     *
+     * @param route the route you want to transfer the current media to. Pass {@code null} to
+     *              stop routing of the current media.
+     *
+     * @see TransferCallback#onTransfer
+     * @see TransferCallback#onTransferFailure
+     */
+    public void transferTo(@NonNull MediaRoute2Info route) {
+        if (isSystemRouter()) {
+            sManager.selectRoute(mClientPackageName, route);
+            return;
+        }
+
+        Log.v(TAG, "Transferring to route: " + route);
+
+        boolean routeFound;
+        synchronized (mLock) {
+            // TODO: Check thread-safety
+            routeFound = mRoutes.containsKey(route.getId());
+        }
+        if (!routeFound) {
+            notifyTransferFailure(route);
+            return;
+        }
+
+        RoutingController controller = getCurrentController();
+        if (controller.getRoutingSessionInfo().getTransferableRoutes().contains(route.getId())) {
+            controller.transferToRoute(route);
+            return;
+        }
+
+        requestCreateController(controller, route, MANAGER_REQUEST_ID_NONE);
+    }
+
+    /**
+     * Stops the current media routing. If the {@link #getSystemController() system controller}
+     * controls the media routing, this method is a no-op.
+     */
+    public void stop() {
+        if (isSystemRouter()) {
+            List<RoutingSessionInfo> sessionInfos = sManager.getRoutingSessions(mClientPackageName);
+            RoutingSessionInfo sessionToRelease = sessionInfos.get(sessionInfos.size() - 1);
+            sManager.releaseSession(sessionToRelease);
+            return;
+        }
+        getCurrentController().release();
+    }
+
+    /**
+     * Transfers the media of a routing controller to the given route.
+     * <p>
+     * This will be no-op for non-system media routers.
+     *
+     * @param controller a routing controller controlling media routing.
+     * @param route the route you want to transfer the media to.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
+    public void transfer(@NonNull RoutingController controller, @NonNull MediaRoute2Info route) {
+        if (isSystemRouter()) {
+            sManager.transfer(controller.getRoutingSessionInfo(), route);
+            return;
+        }
+    }
+
+    void requestCreateController(@NonNull RoutingController controller,
+            @NonNull MediaRoute2Info route, long managerRequestId) {
+
+        final int requestId = mNextRequestId.getAndIncrement();
+
+        ControllerCreationRequest request = new ControllerCreationRequest(requestId,
+                managerRequestId, route, controller);
+        mControllerCreationRequests.add(request);
+
+        OnGetControllerHintsListener listener = mOnGetControllerHintsListener;
+        Bundle controllerHints = null;
+        if (listener != null) {
+            controllerHints = listener.onGetControllerHints(route);
+            if (controllerHints != null) {
+                controllerHints = new Bundle(controllerHints);
+            }
+        }
+
+        MediaRouter2Stub stub;
+        synchronized (mLock) {
+            stub = mStub;
+        }
+        if (stub != null) {
+            try {
+                mMediaRouterService.requestCreateSessionWithRouter2(
+                        stub, requestId, managerRequestId,
+                        controller.getRoutingSessionInfo(), route, controllerHints);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "createControllerForTransfer: "
+                        + "Failed to request for creating a controller.", ex);
+                mControllerCreationRequests.remove(request);
+                if (managerRequestId == MANAGER_REQUEST_ID_NONE) {
+                    notifyTransferFailure(route);
+                }
+            }
+        }
+    }
+
+    @NonNull
+    private RoutingController getCurrentController() {
+        List<RoutingController> controllers = getControllers();
+        return controllers.get(controllers.size() - 1);
+    }
+
+    /**
+     * Gets a {@link RoutingController} which can control the routes provided by system.
+     * e.g. Phone speaker, wired headset, Bluetooth, etc.
+     * <p>
+     * Note: The system controller can't be released. Calling {@link RoutingController#release()}
+     * will be ignored.
+     * <p>
+     * This method always returns the same instance.
+     */
+    @NonNull
+    public RoutingController getSystemController() {
+        return mSystemController;
+    }
+
+    /**
+     * Gets a {@link RoutingController} whose ID is equal to the given ID.
+     * Returns {@code null} if there is no matching controller.
+     */
+    @Nullable
+    public RoutingController getController(@NonNull String id) {
+        Objects.requireNonNull(id, "id must not be null");
+        for (RoutingController controller : getControllers()) {
+            if (TextUtils.equals(id, controller.getId())) {
+                return controller;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets the list of currently active {@link RoutingController routing controllers} on which
+     * media can be played.
+     * <p>
+     * Note: The list returned here will never be empty. The first element in the list is
+     * always the {@link #getSystemController() system controller}.
+     */
+    @NonNull
+    public List<RoutingController> getControllers() {
+        List<RoutingController> result = new ArrayList<>();
+
+        if (isSystemRouter()) {
+            // Unlike non-system MediaRouter2, controller instances cannot be kept,
+            // since the transfer events initiated from other apps will not come through manager.
+            List<RoutingSessionInfo> sessions = sManager.getRoutingSessions(mClientPackageName);
+            for (RoutingSessionInfo session : sessions) {
+                RoutingController controller;
+                if (session.isSystemSession()) {
+                    mSystemController.setRoutingSessionInfo(
+                            ensureClientPackageNameForSystemSession(session));
+                    controller = mSystemController;
+                } else {
+                    controller = new RoutingController(session);
+                }
+                result.add(controller);
+            }
+            return result;
+        }
+
+        result.add(0, mSystemController);
+        synchronized (mLock) {
+            result.addAll(mNonSystemRoutingControllers.values());
+        }
+        return result;
+    }
+
+    /**
+     * Requests a volume change for the route asynchronously.
+     * It may have no effect if the route is currently not selected.
+     * <p>
+     * This will be no-op for non-system media routers.
+     *
+     * @param volume The new volume value between 0 and {@link MediaRoute2Info#getVolumeMax}.
+     * @see #getInstance(Context, String)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(Manifest.permission.MEDIA_CONTENT_CONTROL)
+    public void setRouteVolume(@NonNull MediaRoute2Info route, int volume) {
+        Objects.requireNonNull(route, "route must not be null");
+
+        if (isSystemRouter()) {
+            sManager.setRouteVolume(route, volume);
+            return;
+        }
+        // If this API needs to be public, use IMediaRouterService#setRouteVolumeWithRouter2()
+    }
+
+    void syncRoutesOnHandler(List<MediaRoute2Info> currentRoutes,
+            RoutingSessionInfo currentSystemSessionInfo) {
+        if (currentRoutes == null || currentRoutes.isEmpty() || currentSystemSessionInfo == null) {
+            Log.e(TAG, "syncRoutesOnHandler: Received wrong data. currentRoutes=" + currentRoutes
+                    + ", currentSystemSessionInfo=" + currentSystemSessionInfo);
+            return;
+        }
+
+        List<MediaRoute2Info> addedRoutes = new ArrayList<>();
+        List<MediaRoute2Info> removedRoutes = new ArrayList<>();
+        List<MediaRoute2Info> changedRoutes = new ArrayList<>();
+
+        synchronized (mLock) {
+            List<String> currentRoutesIds = currentRoutes.stream().map(MediaRoute2Info::getId)
+                    .collect(Collectors.toList());
+
+            for (String routeId : mRoutes.keySet()) {
+                if (!currentRoutesIds.contains(routeId)) {
+                    // This route is removed while the callback is unregistered.
+                    MediaRoute2Info route = mRoutes.get(routeId);
+                    if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+                        removedRoutes.add(mRoutes.get(routeId));
+                    }
+                }
+            }
+
+            for (MediaRoute2Info route : currentRoutes) {
+                if (mRoutes.containsKey(route.getId())) {
+                    if (!route.equals(mRoutes.get(route.getId()))) {
+                        // This route is changed while the callback is unregistered.
+                        if (route.hasAnyFeatures(
+                                        mDiscoveryPreference.getPreferredFeatures())) {
+                            changedRoutes.add(route);
+                        }
+                    }
+                } else {
+                    // This route is added while the callback is unregistered.
+                    if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+                        addedRoutes.add(route);
+                    }
+                }
+            }
+
+            mRoutes.clear();
+            for (MediaRoute2Info route : currentRoutes) {
+                mRoutes.put(route.getId(), route);
+            }
+
+            mShouldUpdateRoutes = true;
+        }
+
+        if (!addedRoutes.isEmpty()) {
+            notifyRoutesAdded(addedRoutes);
+        }
+        if (!removedRoutes.isEmpty()) {
+            notifyRoutesRemoved(removedRoutes);
+        }
+        if (!changedRoutes.isEmpty()) {
+            notifyRoutesChanged(changedRoutes);
+        }
+
+        RoutingSessionInfo oldInfo = mSystemController.getRoutingSessionInfo();
+        mSystemController.setRoutingSessionInfo(currentSystemSessionInfo);
+        if (!oldInfo.equals(currentSystemSessionInfo)) {
+            notifyControllerUpdated(mSystemController);
+        }
+    }
+
+    void addRoutesOnHandler(List<MediaRoute2Info> routes) {
+        List<MediaRoute2Info> addedRoutes = new ArrayList<>();
+        synchronized (mLock) {
+            for (MediaRoute2Info route : routes) {
+                mRoutes.put(route.getId(), route);
+                if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+                    addedRoutes.add(route);
+                }
+            }
+            mShouldUpdateRoutes = true;
+        }
+        if (!addedRoutes.isEmpty()) {
+            notifyRoutesAdded(addedRoutes);
+        }
+    }
+
+    void removeRoutesOnHandler(List<MediaRoute2Info> routes) {
+        List<MediaRoute2Info> removedRoutes = new ArrayList<>();
+        synchronized (mLock) {
+            for (MediaRoute2Info route : routes) {
+                mRoutes.remove(route.getId());
+                if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+                    removedRoutes.add(route);
+                }
+            }
+            mShouldUpdateRoutes = true;
+        }
+        if (!removedRoutes.isEmpty()) {
+            notifyRoutesRemoved(removedRoutes);
+        }
+    }
+
+    void changeRoutesOnHandler(List<MediaRoute2Info> routes) {
+        List<MediaRoute2Info> changedRoutes = new ArrayList<>();
+        synchronized (mLock) {
+            for (MediaRoute2Info route : routes) {
+                mRoutes.put(route.getId(), route);
+                if (route.hasAnyFeatures(mDiscoveryPreference.getPreferredFeatures())) {
+                    changedRoutes.add(route);
+                }
+            }
+            mShouldUpdateRoutes = true;
+        }
+        if (!changedRoutes.isEmpty()) {
+            notifyRoutesChanged(changedRoutes);
+        }
+    }
+
+    /**
+     * Creates a controller and calls the {@link TransferCallback#onTransfer}.
+     * If the controller creation has failed, then it calls
+     * {@link TransferCallback#onTransferFailure}.
+     * <p>
+     * Pass {@code null} to sessionInfo for the failure case.
+     */
+    void createControllerOnHandler(int requestId, @Nullable RoutingSessionInfo sessionInfo) {
+        ControllerCreationRequest matchingRequest = null;
+        for (ControllerCreationRequest request : mControllerCreationRequests) {
+            if (request.mRequestId == requestId) {
+                matchingRequest = request;
+                break;
+            }
+        }
+
+        if (matchingRequest == null) {
+            Log.w(TAG, "createControllerOnHandler: Ignoring an unknown request.");
+            return;
+        }
+
+        mControllerCreationRequests.remove(matchingRequest);
+        MediaRoute2Info requestedRoute = matchingRequest.mRoute;
+
+        // TODO: Notify the reason for failure.
+        if (sessionInfo == null) {
+            notifyTransferFailure(requestedRoute);
+            return;
+        } else if (!TextUtils.equals(requestedRoute.getProviderId(),
+                sessionInfo.getProviderId())) {
+            Log.w(TAG, "The session's provider ID does not match the requested route's. "
+                    + "(requested route's providerId=" + requestedRoute.getProviderId()
+                    + ", actual providerId=" + sessionInfo.getProviderId()
+                    + ")");
+            notifyTransferFailure(requestedRoute);
+            return;
+        }
+
+        RoutingController oldController = matchingRequest.mOldController;
+        // When the old controller is released before transferred, treat it as a failure.
+        // This could also happen when transfer is requested twice or more.
+        if (!oldController.scheduleRelease()) {
+            Log.w(TAG, "createControllerOnHandler: "
+                    + "Ignoring controller creation for released old controller. "
+                    + "oldController=" + oldController);
+            if (!sessionInfo.isSystemSession()) {
+                new RoutingController(sessionInfo).release();
+            }
+            notifyTransferFailure(requestedRoute);
+            return;
+        }
+
+        RoutingController newController;
+        if (sessionInfo.isSystemSession()) {
+            newController = getSystemController();
+            newController.setRoutingSessionInfo(sessionInfo);
+        } else {
+            newController = new RoutingController(sessionInfo);
+            synchronized (mLock) {
+                mNonSystemRoutingControllers.put(newController.getId(), newController);
+            }
+        }
+
+        notifyTransfer(oldController, newController);
+    }
+
+    void updateControllerOnHandler(RoutingSessionInfo sessionInfo) {
+        if (sessionInfo == null) {
+            Log.w(TAG, "updateControllerOnHandler: Ignoring null sessionInfo.");
+            return;
+        }
+
+        if (sessionInfo.isSystemSession()) {
+            // The session info is sent from SystemMediaRoute2Provider.
+            RoutingController systemController = getSystemController();
+            systemController.setRoutingSessionInfo(sessionInfo);
+            notifyControllerUpdated(systemController);
+            return;
+        }
+
+        RoutingController matchingController;
+        synchronized (mLock) {
+            matchingController = mNonSystemRoutingControllers.get(sessionInfo.getId());
+        }
+
+        if (matchingController == null) {
+            Log.w(TAG, "updateControllerOnHandler: Matching controller not found. uniqueSessionId="
+                    + sessionInfo.getId());
+            return;
+        }
+
+        RoutingSessionInfo oldInfo = matchingController.getRoutingSessionInfo();
+        if (!TextUtils.equals(oldInfo.getProviderId(), sessionInfo.getProviderId())) {
+            Log.w(TAG, "updateControllerOnHandler: Provider IDs are not matched. old="
+                    + oldInfo.getProviderId() + ", new=" + sessionInfo.getProviderId());
+            return;
+        }
+
+        matchingController.setRoutingSessionInfo(sessionInfo);
+        notifyControllerUpdated(matchingController);
+    }
+
+    void releaseControllerOnHandler(RoutingSessionInfo sessionInfo) {
+        if (sessionInfo == null) {
+            Log.w(TAG, "releaseControllerOnHandler: Ignoring null sessionInfo.");
+            return;
+        }
+
+        RoutingController matchingController;
+        synchronized (mLock) {
+            matchingController = mNonSystemRoutingControllers.get(sessionInfo.getId());
+        }
+
+        if (matchingController == null) {
+            if (DEBUG) {
+                Log.d(TAG, "releaseControllerOnHandler: Matching controller not found. "
+                        + "uniqueSessionId=" + sessionInfo.getId());
+            }
+            return;
+        }
+
+        RoutingSessionInfo oldInfo = matchingController.getRoutingSessionInfo();
+        if (!TextUtils.equals(oldInfo.getProviderId(), sessionInfo.getProviderId())) {
+            Log.w(TAG, "releaseControllerOnHandler: Provider IDs are not matched. old="
+                    + oldInfo.getProviderId() + ", new=" + sessionInfo.getProviderId());
+            return;
+        }
+
+        matchingController.releaseInternal(/* shouldReleaseSession= */ false);
+    }
+
+    void onRequestCreateControllerByManagerOnHandler(RoutingSessionInfo oldSession,
+            MediaRoute2Info route, long managerRequestId) {
+        RoutingController controller;
+        if (oldSession.isSystemSession()) {
+            controller = getSystemController();
+        } else {
+            synchronized (mLock) {
+                controller = mNonSystemRoutingControllers.get(oldSession.getId());
+            }
+        }
+        if (controller == null) {
+            return;
+        }
+        requestCreateController(controller, route, managerRequestId);
+    }
+
+    /**
+     * Returns whether this router is created with {@link #getInstance(Context, String)}.
+     * This kind of router can control the target app's media routing.
+     */
+    private boolean isSystemRouter() {
+        return mClientPackageName != null;
+    }
+
+    /**
+     * Returns a {@link RoutingSessionInfo} which has the client package name.
+     * The client package name is set only when the given sessionInfo doesn't have it.
+     * Should only used for system media routers.
+     */
+    private RoutingSessionInfo ensureClientPackageNameForSystemSession(
+            @NonNull RoutingSessionInfo sessionInfo) {
+        if (!sessionInfo.isSystemSession()
+                || !TextUtils.isEmpty(sessionInfo.getClientPackageName())) {
+            return sessionInfo;
+        }
+
+        return new RoutingSessionInfo.Builder(sessionInfo)
+                .setClientPackageName(mClientPackageName)
+                .build();
+    }
+
+    private List<MediaRoute2Info> filterRoutes(List<MediaRoute2Info> routes,
+            RouteDiscoveryPreference discoveryRequest) {
+        return routes.stream()
+                .filter(route -> route.hasAnyFeatures(discoveryRequest.getPreferredFeatures()))
+                .collect(Collectors.toList());
+    }
+
+    private void updateAllRoutesFromManager() {
+        if (!isSystemRouter()) {
+            return;
+        }
+        synchronized (mLock) {
+            mRoutes.clear();
+            for (MediaRoute2Info route : sManager.getAllRoutes()) {
+                mRoutes.put(route.getId(), route);
+            }
+            mShouldUpdateRoutes = true;
+        }
+    }
+
+    private void notifyRoutesAdded(List<MediaRoute2Info> routes) {
+        for (RouteCallbackRecord record: mRouteCallbackRecords) {
+            List<MediaRoute2Info> filteredRoutes = filterRoutes(routes, record.mPreference);
+            if (!filteredRoutes.isEmpty()) {
+                record.mExecutor.execute(
+                        () -> record.mRouteCallback.onRoutesAdded(filteredRoutes));
+            }
+        }
+    }
+
+    private void notifyRoutesRemoved(List<MediaRoute2Info> routes) {
+        for (RouteCallbackRecord record: mRouteCallbackRecords) {
+            List<MediaRoute2Info> filteredRoutes = filterRoutes(routes, record.mPreference);
+            if (!filteredRoutes.isEmpty()) {
+                record.mExecutor.execute(
+                        () -> record.mRouteCallback.onRoutesRemoved(filteredRoutes));
+            }
+        }
+    }
+
+    private void notifyRoutesChanged(List<MediaRoute2Info> routes) {
+        for (RouteCallbackRecord record: mRouteCallbackRecords) {
+            List<MediaRoute2Info> filteredRoutes = filterRoutes(routes, record.mPreference);
+            if (!filteredRoutes.isEmpty()) {
+                record.mExecutor.execute(
+                        () -> record.mRouteCallback.onRoutesChanged(filteredRoutes));
+            }
+        }
+    }
+
+    private void notifyPreferredFeaturesChanged(List<String> features) {
+        for (RouteCallbackRecord record: mRouteCallbackRecords) {
+            record.mExecutor.execute(
+                    () -> record.mRouteCallback.onPreferredFeaturesChanged(features));
+        }
+    }
+
+    private void notifyTransfer(RoutingController oldController, RoutingController newController) {
+        for (TransferCallbackRecord record: mTransferCallbackRecords) {
+            record.mExecutor.execute(
+                    () -> record.mTransferCallback.onTransfer(oldController, newController));
+        }
+    }
+
+    private void notifyTransferFailure(MediaRoute2Info route) {
+        for (TransferCallbackRecord record: mTransferCallbackRecords) {
+            record.mExecutor.execute(
+                    () -> record.mTransferCallback.onTransferFailure(route));
+        }
+    }
+
+    private void notifyStop(RoutingController controller) {
+        for (TransferCallbackRecord record: mTransferCallbackRecords) {
+            record.mExecutor.execute(
+                    () -> record.mTransferCallback.onStop(controller));
+        }
+    }
+
+    private void notifyControllerUpdated(RoutingController controller) {
+        for (ControllerCallbackRecord record: mControllerCallbackRecords) {
+            record.mExecutor.execute(() -> record.mCallback.onControllerUpdated(controller));
+        }
+    }
+
+    /**
+     * Callback for receiving events about media route discovery.
+     */
+    public abstract static class RouteCallback {
+        /**
+         * Called when routes are added. Whenever you registers a callback, this will
+         * be invoked with known routes.
+         *
+         * @param routes the list of routes that have been added. It's never empty.
+         */
+        public void onRoutesAdded(@NonNull List<MediaRoute2Info> routes) {}
+
+        /**
+         * Called when routes are removed.
+         *
+         * @param routes the list of routes that have been removed. It's never empty.
+         */
+        public void onRoutesRemoved(@NonNull List<MediaRoute2Info> routes) {}
+
+        /**
+         * Called when routes are changed. For example, it is called when the route's name
+         * or volume have been changed.
+         *
+         * @param routes the list of routes that have been changed. It's never empty.
+         */
+        public void onRoutesChanged(@NonNull List<MediaRoute2Info> routes) {}
+
+        /**
+         * Called when the client app's preferred features are changed.
+         * When this is called, it is recommended to {@link #getRoutes()} to get the routes
+         * that are currently available to the app.
+         *
+         * @param preferredFeatures the new preferred features set by the application
+         * @hide
+         */
+        @SystemApi
+        public void onPreferredFeaturesChanged(@NonNull List<String> preferredFeatures) {}
+    }
+
+    /**
+     * Callback for receiving events on media transfer.
+     */
+    public abstract static class TransferCallback {
+        /**
+         * Called when a media is transferred between two different routing controllers.
+         * This can happen by calling {@link #transferTo(MediaRoute2Info)}.
+         * <p> Override this to start playback with {@code newController}. You may want to get
+         * the status of the media that is being played with {@code oldController} and resume it
+         * continuously with {@code newController}.
+         * After this is called, any callbacks with {@code oldController} will not be invoked
+         * unless {@code oldController} is the {@link #getSystemController() system controller}.
+         * You need to {@link RoutingController#release() release} {@code oldController} before
+         * playing the media with {@code newController}.
+         *
+         * @param oldController the previous controller that controlled routing
+         * @param newController the new controller to control routing
+         * @see #transferTo(MediaRoute2Info)
+         */
+        public void onTransfer(@NonNull RoutingController oldController,
+                @NonNull RoutingController newController) {}
+
+        /**
+         * Called when {@link #transferTo(MediaRoute2Info)} failed.
+         *
+         * @param requestedRoute the route info which was used for the transfer
+         */
+        public void onTransferFailure(@NonNull MediaRoute2Info requestedRoute) {}
+
+        /**
+         * Called when a media routing stops. It can be stopped by a user or a provider.
+         * App should not continue playing media locally when this method is called.
+         * The {@code controller} is released before this method is called.
+         *
+         * @param controller the controller that controlled the stopped media routing
+         */
+        public void onStop(@NonNull RoutingController controller) { }
+    }
+
+    /**
+     * A listener interface to send optional app-specific hints when creating a
+     * {@link RoutingController}.
+     */
+    public interface OnGetControllerHintsListener {
+        /**
+         * Called when the {@link MediaRouter2} or the system is about to request
+         * a media route provider service to create a controller with the given route.
+         * The {@link Bundle} returned here will be sent to media route provider service as a hint.
+         * <p>
+         * Since controller creation can be requested by the {@link MediaRouter2} and the system,
+         * set the listener as soon as possible after acquiring {@link MediaRouter2} instance.
+         * The method will be called on the same thread that calls
+         * {@link #transferTo(MediaRoute2Info)} or the main thread if it is requested by the system.
+         *
+         * @param route the route to create a controller with
+         * @return An optional bundle of app-specific arguments to send to the provider,
+         *         or {@code null} if none. The contents of this bundle may affect the result of
+         *         controller creation.
+         * @see MediaRoute2ProviderService#onCreateSession(long, String, String, Bundle)
+         */
+        @Nullable
+        Bundle onGetControllerHints(@NonNull MediaRoute2Info route);
+    }
+
+    /**
+     * Callback for receiving {@link RoutingController} updates.
+     */
+    public abstract static class ControllerCallback {
+        /**
+         * Called when a controller is updated. (e.g., when the selected routes of the
+         * controller is changed or when the volume of the controller is changed.)
+         *
+         * @param controller the updated controller. It may be the
+         * {@link #getSystemController() system controller}.
+         * @see #getSystemController()
+         */
+        public void onControllerUpdated(@NonNull RoutingController controller) { }
+    }
+
+    /**
+     * A class to control media routing session in media route provider.
+     * For example, selecting/deselecting/transferring to routes of a session can be done through
+     * this. Instances are created when
+     * {@link TransferCallback#onTransfer(RoutingController, RoutingController)} is called,
+     * which is invoked after {@link #transferTo(MediaRoute2Info)} is called.
+     */
+    public class RoutingController {
+        private final Object mControllerLock = new Object();
+
+        private static final int CONTROLLER_STATE_UNKNOWN = 0;
+        private static final int CONTROLLER_STATE_ACTIVE = 1;
+        private static final int CONTROLLER_STATE_RELEASING = 2;
+        private static final int CONTROLLER_STATE_RELEASED = 3;
+
+        @GuardedBy("mControllerLock")
+        private RoutingSessionInfo mSessionInfo;
+
+        @GuardedBy("mControllerLock")
+        private int mState;
+
+        RoutingController(@NonNull RoutingSessionInfo sessionInfo) {
+            mSessionInfo = sessionInfo;
+            mState = CONTROLLER_STATE_ACTIVE;
+        }
+
+        RoutingController(@NonNull RoutingSessionInfo sessionInfo, int state) {
+            mSessionInfo = sessionInfo;
+            mState = state;
+        }
+
+        /**
+         * @return the ID of the controller. It is globally unique.
+         */
+        @NonNull
+        public String getId() {
+            synchronized (mControllerLock) {
+                return mSessionInfo.getId();
+            }
+        }
+
+        /**
+         * Gets the original session ID set by
+         * {@link RoutingSessionInfo.Builder#Builder(String, String)}.
+         *
+         * @hide
+         */
+        @NonNull
+        @TestApi
+        public String getOriginalId() {
+            synchronized (mControllerLock) {
+                return mSessionInfo.getOriginalId();
+            }
+        }
+
+        /**
+         * Gets the control hints used to control routing session if available.
+         * It is set by the media route provider.
+         */
+        @Nullable
+        public Bundle getControlHints() {
+            synchronized (mControllerLock) {
+                return mSessionInfo.getControlHints();
+            }
+        }
+
+        /**
+         * @return the unmodifiable list of currently selected routes
+         */
+        @NonNull
+        public List<MediaRoute2Info> getSelectedRoutes() {
+            List<String> selectedRouteIds;
+            synchronized (mControllerLock) {
+                selectedRouteIds = mSessionInfo.getSelectedRoutes();
+            }
+            return getRoutesWithIds(selectedRouteIds);
+        }
+
+        /**
+         * @return the unmodifiable list of selectable routes for the session.
+         */
+        @NonNull
+        public List<MediaRoute2Info> getSelectableRoutes() {
+            List<String> selectableRouteIds;
+            synchronized (mControllerLock) {
+                selectableRouteIds = mSessionInfo.getSelectableRoutes();
+            }
+            return getRoutesWithIds(selectableRouteIds);
+        }
+
+        /**
+         * @return the unmodifiable list of deselectable routes for the session.
+         */
+        @NonNull
+        public List<MediaRoute2Info> getDeselectableRoutes() {
+            List<String> deselectableRouteIds;
+            synchronized (mControllerLock) {
+                deselectableRouteIds = mSessionInfo.getDeselectableRoutes();
+            }
+            return getRoutesWithIds(deselectableRouteIds);
+        }
+
+        /**
+         * Gets the information about how volume is handled on the session.
+         * <p>Please note that you may not control the volume of the session even when
+         * you can control the volume of each selected route in the session.
+         *
+         * @return {@link MediaRoute2Info#PLAYBACK_VOLUME_FIXED} or
+         * {@link MediaRoute2Info#PLAYBACK_VOLUME_VARIABLE}
+         */
+        @MediaRoute2Info.PlaybackVolume
+        public int getVolumeHandling() {
+            synchronized (mControllerLock) {
+                return mSessionInfo.getVolumeHandling();
+            }
+        }
+
+        /**
+         * Gets the maximum volume of the session.
+         */
+        public int getVolumeMax() {
+            synchronized (mControllerLock) {
+                return mSessionInfo.getVolumeMax();
+            }
+        }
+
+        /**
+         * Gets the current volume of the session.
+         * <p>
+         * When it's available, it represents the volume of routing session, which is a group
+         * of selected routes. Use {@link MediaRoute2Info#getVolume()}
+         * to get the volume of a route,
+         * </p>
+         * @see MediaRoute2Info#getVolume()
+         */
+        public int getVolume() {
+            synchronized (mControllerLock) {
+                return mSessionInfo.getVolume();
+            }
+        }
+
+        /**
+         * Returns true if this controller is released, false otherwise.
+         * If it is released, then all other getters from this instance may return invalid values.
+         * Also, any operations to this instance will be ignored once released.
+         *
+         * @see #release
+         */
+        public boolean isReleased() {
+            synchronized (mControllerLock) {
+                return mState == CONTROLLER_STATE_RELEASED;
+            }
+        }
+
+        /**
+         * Selects a route for the remote session. After a route is selected, the media is expected
+         * to be played to the all the selected routes. This is different from {@link
+         * MediaRouter2#transferTo(MediaRoute2Info)} transferring to a route},
+         * where the media is expected to 'move' from one route to another.
+         * <p>
+         * The given route must satisfy all of the following conditions:
+         * <ul>
+         * <li>It should not be included in {@link #getSelectedRoutes()}</li>
+         * <li>It should be included in {@link #getSelectableRoutes()}</li>
+         * </ul>
+         * If the route doesn't meet any of above conditions, it will be ignored.
+         *
+         * @see #deselectRoute(MediaRoute2Info)
+         * @see #getSelectedRoutes()
+         * @see #getSelectableRoutes()
+         * @see ControllerCallback#onControllerUpdated
+         */
+        public void selectRoute(@NonNull MediaRoute2Info route) {
+            Objects.requireNonNull(route, "route must not be null");
+            if (isReleased()) {
+                Log.w(TAG, "selectRoute: Called on released controller. Ignoring.");
+                return;
+            }
+
+            List<MediaRoute2Info> selectedRoutes = getSelectedRoutes();
+            if (checkRouteListContainsRouteId(selectedRoutes, route.getId())) {
+                Log.w(TAG, "Ignoring selecting a route that is already selected. route=" + route);
+                return;
+            }
+
+            List<MediaRoute2Info> selectableRoutes = getSelectableRoutes();
+            if (!checkRouteListContainsRouteId(selectableRoutes, route.getId())) {
+                Log.w(TAG, "Ignoring selecting a non-selectable route=" + route);
+                return;
+            }
+
+            if (isSystemRouter()) {
+                sManager.selectRoute(getRoutingSessionInfo(), route);
+                return;
+            }
+
+            MediaRouter2Stub stub;
+            synchronized (mLock) {
+                stub = mStub;
+            }
+            if (stub != null) {
+                try {
+                    mMediaRouterService.selectRouteWithRouter2(stub, getId(), route);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to select route for session.", ex);
+                }
+            }
+        }
+
+        /**
+         * Deselects a route from the remote session. After a route is deselected, the media is
+         * expected to be stopped on the deselected route.
+         * <p>
+         * The given route must satisfy all of the following conditions:
+         * <ul>
+         * <li>It should be included in {@link #getSelectedRoutes()}</li>
+         * <li>It should be included in {@link #getDeselectableRoutes()}</li>
+         * </ul>
+         * If the route doesn't meet any of above conditions, it will be ignored.
+         *
+         * @see #getSelectedRoutes()
+         * @see #getDeselectableRoutes()
+         * @see ControllerCallback#onControllerUpdated
+         */
+        public void deselectRoute(@NonNull MediaRoute2Info route) {
+            Objects.requireNonNull(route, "route must not be null");
+            if (isReleased()) {
+                Log.w(TAG, "deselectRoute: called on released controller. Ignoring.");
+                return;
+            }
+
+            List<MediaRoute2Info> selectedRoutes = getSelectedRoutes();
+            if (!checkRouteListContainsRouteId(selectedRoutes, route.getId())) {
+                Log.w(TAG, "Ignoring deselecting a route that is not selected. route=" + route);
+                return;
+            }
+
+            List<MediaRoute2Info> deselectableRoutes = getDeselectableRoutes();
+            if (!checkRouteListContainsRouteId(deselectableRoutes, route.getId())) {
+                Log.w(TAG, "Ignoring deselecting a non-deselectable route=" + route);
+                return;
+            }
+
+            if (isSystemRouter()) {
+                sManager.deselectRoute(getRoutingSessionInfo(), route);
+                return;
+            }
+
+            MediaRouter2Stub stub;
+            synchronized (mLock) {
+                stub = mStub;
+            }
+            if (stub != null) {
+                try {
+                    mMediaRouterService.deselectRouteWithRouter2(stub, getId(), route);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to deselect route from session.", ex);
+                }
+            }
+        }
+
+        /**
+         * Transfers to a given route for the remote session. The given route must be included
+         * in {@link RoutingSessionInfo#getTransferableRoutes()}.
+         *
+         * @see RoutingSessionInfo#getSelectedRoutes()
+         * @see RoutingSessionInfo#getTransferableRoutes()
+         * @see ControllerCallback#onControllerUpdated
+         */
+        void transferToRoute(@NonNull MediaRoute2Info route) {
+            Objects.requireNonNull(route, "route must not be null");
+            synchronized (mControllerLock) {
+                if (isReleased()) {
+                    Log.w(TAG, "transferToRoute: Called on released controller. Ignoring.");
+                    return;
+                }
+
+                if (!mSessionInfo.getTransferableRoutes().contains(route.getId())) {
+                    Log.w(TAG, "Ignoring transferring to a non-transferable route=" + route);
+                    return;
+                }
+            }
+
+            MediaRouter2Stub stub;
+            synchronized (mLock) {
+                stub = mStub;
+            }
+            if (stub != null) {
+                try {
+                    mMediaRouterService.transferToRouteWithRouter2(stub, getId(), route);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "Unable to transfer to route for session.", ex);
+                }
+            }
+        }
+
+        /**
+         * Requests a volume change for the remote session asynchronously.
+         *
+         * @param volume The new volume value between 0 and {@link RoutingController#getVolumeMax}
+         *               (inclusive).
+         * @see #getVolume()
+         */
+        public void setVolume(int volume) {
+            if (getVolumeHandling() == MediaRoute2Info.PLAYBACK_VOLUME_FIXED) {
+                Log.w(TAG, "setVolume: The routing session has fixed volume. Ignoring.");
+                return;
+            }
+            if (volume < 0 || volume > getVolumeMax()) {
+                Log.w(TAG, "setVolume: The target volume is out of range. Ignoring");
+                return;
+            }
+
+            if (isReleased()) {
+                Log.w(TAG, "setVolume: Called on released controller. Ignoring.");
+                return;
+            }
+
+            if (isSystemRouter()) {
+                sManager.setSessionVolume(getRoutingSessionInfo(), volume);
+                return;
+            }
+
+            MediaRouter2Stub stub;
+            synchronized (mLock) {
+                stub = mStub;
+            }
+            if (stub != null) {
+                try {
+                    mMediaRouterService.setSessionVolumeWithRouter2(stub, getId(), volume);
+                } catch (RemoteException ex) {
+                    Log.e(TAG, "setVolume: Failed to deliver request.", ex);
+                }
+            }
+        }
+
+        /**
+         * Releases this controller and the corresponding session.
+         * Any operations on this controller after calling this method will be ignored.
+         * The devices that are playing media will stop playing it.
+         */
+        public void release() {
+            releaseInternal(/* shouldReleaseSession= */ true);
+        }
+
+        /**
+         * Schedules release of the controller.
+         * @return {@code true} if it's successfully scheduled, {@code false} if it's already
+         * scheduled to be released or released.
+         */
+        boolean scheduleRelease() {
+            synchronized (mControllerLock) {
+                if (mState != CONTROLLER_STATE_ACTIVE) {
+                    return false;
+                }
+                mState = CONTROLLER_STATE_RELEASING;
+            }
+
+            synchronized (mLock) {
+                // It could happen if the controller is released by the another thread
+                // in between two locks
+                if (!mNonSystemRoutingControllers.remove(getId(), this)) {
+                    // In that case, onStop isn't called so we return true to call onTransfer.
+                    // It's also consistent with that the another thread acquires the lock later.
+                    return true;
+                }
+            }
+
+            mHandler.postDelayed(this::release, TRANSFER_TIMEOUT_MS);
+
+            return true;
+        }
+
+        void releaseInternal(boolean shouldReleaseSession) {
+            boolean shouldNotifyStop;
+
+            synchronized (mControllerLock) {
+                if (mState == CONTROLLER_STATE_RELEASED) {
+                    if (DEBUG) {
+                        Log.d(TAG, "releaseInternal: Called on released controller. Ignoring.");
+                    }
+                    return;
+                }
+                shouldNotifyStop = (mState == CONTROLLER_STATE_ACTIVE);
+                mState = CONTROLLER_STATE_RELEASED;
+            }
+
+            if (isSystemRouter()) {
+                sManager.releaseSession(getRoutingSessionInfo());
+                return;
+            }
+
+            synchronized (mLock) {
+                mNonSystemRoutingControllers.remove(getId(), this);
+
+                if (shouldReleaseSession && mStub != null) {
+                    try {
+                        mMediaRouterService.releaseSessionWithRouter2(mStub, getId());
+                    } catch (RemoteException ex) {
+                        Log.e(TAG, "Unable to release session", ex);
+                    }
+                }
+
+                if (shouldNotifyStop) {
+                    mHandler.sendMessage(obtainMessage(MediaRouter2::notifyStop, MediaRouter2.this,
+                            RoutingController.this));
+                }
+
+                if (mRouteCallbackRecords.isEmpty() && mNonSystemRoutingControllers.isEmpty()
+                        && mStub != null) {
+                    try {
+                        mMediaRouterService.unregisterRouter2(mStub);
+                    } catch (RemoteException ex) {
+                        Log.e(TAG, "releaseInternal: Unable to unregister media router.", ex);
+                    }
+                    mStub = null;
+                }
+            }
+        }
+
+        @Override
+        public String toString() {
+            // To prevent logging spam, we only print the ID of each route.
+            List<String> selectedRoutes = getSelectedRoutes().stream()
+                    .map(MediaRoute2Info::getId).collect(Collectors.toList());
+            List<String> selectableRoutes = getSelectableRoutes().stream()
+                    .map(MediaRoute2Info::getId).collect(Collectors.toList());
+            List<String> deselectableRoutes = getDeselectableRoutes().stream()
+                    .map(MediaRoute2Info::getId).collect(Collectors.toList());
+
+            StringBuilder result = new StringBuilder()
+                    .append("RoutingController{ ")
+                    .append("id=").append(getId())
+                    .append(", selectedRoutes={")
+                    .append(selectedRoutes)
+                    .append("}")
+                    .append(", selectableRoutes={")
+                    .append(selectableRoutes)
+                    .append("}")
+                    .append(", deselectableRoutes={")
+                    .append(deselectableRoutes)
+                    .append("}")
+                    .append(" }");
+            return result.toString();
+        }
+
+        @NonNull
+        RoutingSessionInfo getRoutingSessionInfo() {
+            synchronized (mControllerLock) {
+                return mSessionInfo;
+            }
+        }
+
+        void setRoutingSessionInfo(@NonNull RoutingSessionInfo info) {
+            synchronized (mControllerLock) {
+                mSessionInfo = info;
+            }
+        }
+
+        private List<MediaRoute2Info> getRoutesWithIds(List<String> routeIds) {
+            if (isSystemRouter()) {
+                return getRoutes().stream()
+                        .filter(r -> routeIds.contains(r.getId()))
+                        .collect(Collectors.toList());
+            }
+
+            synchronized (mLock) {
+                return routeIds.stream().map(mRoutes::get)
+                        .filter(Objects::nonNull)
+                        .collect(Collectors.toList());
+            }
+        }
+    }
+
+    class SystemRoutingController extends RoutingController {
+        SystemRoutingController(@NonNull RoutingSessionInfo sessionInfo) {
+            super(sessionInfo);
+        }
+
+        @Override
+        public boolean isReleased() {
+            // SystemRoutingController will never be released
+            return false;
+        }
+
+        @Override
+        boolean scheduleRelease() {
+            // SystemRoutingController can be always transferred
+            return true;
+        }
+
+        @Override
+        void releaseInternal(boolean shouldReleaseSession) {
+            // Do nothing. SystemRoutingController will never be released
+        }
+    }
+
+    static final class RouteCallbackRecord {
+        public final Executor mExecutor;
+        public final RouteCallback mRouteCallback;
+        public final RouteDiscoveryPreference mPreference;
+
+        RouteCallbackRecord(@Nullable Executor executor, @NonNull RouteCallback routeCallback,
+                @Nullable RouteDiscoveryPreference preference) {
+            mRouteCallback = routeCallback;
+            mExecutor = executor;
+            mPreference = preference;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (!(obj instanceof RouteCallbackRecord)) {
+                return false;
+            }
+            return mRouteCallback == ((RouteCallbackRecord) obj).mRouteCallback;
+        }
+
+        @Override
+        public int hashCode() {
+            return mRouteCallback.hashCode();
+        }
+    }
+
+    static final class TransferCallbackRecord {
+        public final Executor mExecutor;
+        public final TransferCallback mTransferCallback;
+
+        TransferCallbackRecord(@NonNull Executor executor,
+                @NonNull TransferCallback transferCallback) {
+            mTransferCallback = transferCallback;
+            mExecutor = executor;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (!(obj instanceof TransferCallbackRecord)) {
+                return false;
+            }
+            return mTransferCallback == ((TransferCallbackRecord) obj).mTransferCallback;
+        }
+
+        @Override
+        public int hashCode() {
+            return mTransferCallback.hashCode();
+        }
+    }
+
+    static final class ControllerCallbackRecord {
+        public final Executor mExecutor;
+        public final ControllerCallback mCallback;
+
+        ControllerCallbackRecord(@Nullable Executor executor,
+                @NonNull ControllerCallback callback) {
+            mCallback = callback;
+            mExecutor = executor;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (!(obj instanceof ControllerCallbackRecord)) {
+                return false;
+            }
+            return mCallback == ((ControllerCallbackRecord) obj).mCallback;
+        }
+
+        @Override
+        public int hashCode() {
+            return mCallback.hashCode();
+        }
+    }
+
+    static final class ControllerCreationRequest {
+        public final int mRequestId;
+        public final long mManagerRequestId;
+        public final MediaRoute2Info mRoute;
+        public final RoutingController mOldController;
+
+        ControllerCreationRequest(int requestId, long managerRequestId,
+                @NonNull MediaRoute2Info route, @NonNull RoutingController oldController) {
+            mRequestId = requestId;
+            mManagerRequestId = managerRequestId;
+            mRoute = Objects.requireNonNull(route, "route must not be null");
+            mOldController = Objects.requireNonNull(oldController,
+                    "oldController must not be null");
+        }
+    }
+
+    class MediaRouter2Stub extends IMediaRouter2.Stub {
+        @Override
+        public void notifyRouterRegistered(List<MediaRoute2Info> currentRoutes,
+                RoutingSessionInfo currentSystemSessionInfo) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2::syncRoutesOnHandler,
+                    MediaRouter2.this, currentRoutes, currentSystemSessionInfo));
+        }
+
+        @Override
+        public void notifyRoutesAdded(List<MediaRoute2Info> routes) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2::addRoutesOnHandler,
+                    MediaRouter2.this, routes));
+        }
+
+        @Override
+        public void notifyRoutesRemoved(List<MediaRoute2Info> routes) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2::removeRoutesOnHandler,
+                    MediaRouter2.this, routes));
+        }
+
+        @Override
+        public void notifyRoutesChanged(List<MediaRoute2Info> routes) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2::changeRoutesOnHandler,
+                    MediaRouter2.this, routes));
+        }
+
+        @Override
+        public void notifySessionCreated(int requestId, @Nullable RoutingSessionInfo sessionInfo) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2::createControllerOnHandler,
+                    MediaRouter2.this, requestId, sessionInfo));
+        }
+
+        @Override
+        public void notifySessionInfoChanged(@Nullable RoutingSessionInfo sessionInfo) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2::updateControllerOnHandler,
+                    MediaRouter2.this, sessionInfo));
+        }
+
+        @Override
+        public void notifySessionReleased(RoutingSessionInfo sessionInfo) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2::releaseControllerOnHandler,
+                    MediaRouter2.this, sessionInfo));
+        }
+
+        @Override
+        public void requestCreateSessionByManager(long managerRequestId,
+                RoutingSessionInfo oldSession, MediaRoute2Info route) {
+            mHandler.sendMessage(obtainMessage(
+                    MediaRouter2::onRequestCreateControllerByManagerOnHandler,
+                    MediaRouter2.this, oldSession, route, managerRequestId));
+        }
+    }
+
+    // Note: All methods are run on main thread.
+    class ManagerCallback implements MediaRouter2Manager.Callback {
+
+        @Override
+        public void onRoutesAdded(@NonNull List<MediaRoute2Info> routes) {
+            updateAllRoutesFromManager();
+
+            List<MediaRoute2Info> filteredRoutes;
+            synchronized (mLock) {
+                filteredRoutes = filterRoutes(routes, mDiscoveryPreference);
+            }
+            if (filteredRoutes.isEmpty()) {
+                return;
+            }
+            for (RouteCallbackRecord record: mRouteCallbackRecords) {
+                record.mExecutor.execute(
+                        () -> record.mRouteCallback.onRoutesAdded(filteredRoutes));
+            }
+        }
+
+        @Override
+        public void onRoutesRemoved(@NonNull List<MediaRoute2Info> routes) {
+            updateAllRoutesFromManager();
+
+            List<MediaRoute2Info> filteredRoutes;
+            synchronized (mLock) {
+                filteredRoutes = filterRoutes(routes, mDiscoveryPreference);
+            }
+            if (filteredRoutes.isEmpty()) {
+                return;
+            }
+            for (RouteCallbackRecord record: mRouteCallbackRecords) {
+                record.mExecutor.execute(
+                        () -> record.mRouteCallback.onRoutesRemoved(filteredRoutes));
+            }
+        }
+
+        @Override
+        public void onRoutesChanged(@NonNull List<MediaRoute2Info> routes) {
+            updateAllRoutesFromManager();
+
+            List<MediaRoute2Info> filteredRoutes;
+            synchronized (mLock) {
+                filteredRoutes = filterRoutes(routes, mDiscoveryPreference);
+            }
+            if (filteredRoutes.isEmpty()) {
+                return;
+            }
+            for (RouteCallbackRecord record: mRouteCallbackRecords) {
+                record.mExecutor.execute(
+                        () -> record.mRouteCallback.onRoutesChanged(filteredRoutes));
+            }
+        }
+
+        @Override
+        public void onTransferred(@NonNull RoutingSessionInfo oldSession,
+                @NonNull RoutingSessionInfo newSession) {
+            if (!oldSession.isSystemSession()
+                    && !TextUtils.equals(mClientPackageName, oldSession.getClientPackageName())) {
+                return;
+            }
+
+            if (!newSession.isSystemSession()
+                    && !TextUtils.equals(mClientPackageName, newSession.getClientPackageName())) {
+                return;
+            }
+
+            // For successful in-session transfer, onControllerUpdated() handles it.
+            if (TextUtils.equals(oldSession.getId(), newSession.getId())) {
+                return;
+            }
+
+
+            RoutingController oldController;
+            if (oldSession.isSystemSession()) {
+                mSystemController.setRoutingSessionInfo(
+                        ensureClientPackageNameForSystemSession(oldSession));
+                oldController = mSystemController;
+            } else {
+                oldController = new RoutingController(oldSession);
+            }
+
+            RoutingController newController;
+            if (newSession.isSystemSession()) {
+                mSystemController.setRoutingSessionInfo(
+                        ensureClientPackageNameForSystemSession(newSession));
+                newController = mSystemController;
+            } else {
+                newController = new RoutingController(newSession);
+            }
+
+            notifyTransfer(oldController, newController);
+        }
+
+        @Override
+        public void onTransferFailed(@NonNull RoutingSessionInfo session,
+                @NonNull MediaRoute2Info route) {
+            if (!session.isSystemSession()
+                    && !TextUtils.equals(mClientPackageName, session.getClientPackageName())) {
+                return;
+            }
+            notifyTransferFailure(route);
+        }
+
+        @Override
+        public void onSessionUpdated(@NonNull RoutingSessionInfo session) {
+            if (!session.isSystemSession()
+                    && !TextUtils.equals(mClientPackageName, session.getClientPackageName())) {
+                return;
+            }
+
+            RoutingController controller;
+            if (session.isSystemSession()) {
+                mSystemController.setRoutingSessionInfo(
+                        ensureClientPackageNameForSystemSession(session));
+                controller = mSystemController;
+            } else {
+                controller = new RoutingController(session);
+            }
+            notifyControllerUpdated(controller);
+        }
+
+        @Override
+        public void onSessionReleased(@NonNull RoutingSessionInfo session) {
+            if (session.isSystemSession()) {
+                Log.e(TAG, "onSessionReleased: Called on system session. Ignoring.");
+                return;
+            }
+
+            if (!TextUtils.equals(mClientPackageName, session.getClientPackageName())) {
+                return;
+            }
+
+            notifyStop(new RoutingController(session, RoutingController.CONTROLLER_STATE_RELEASED));
+        }
+
+        @Override
+        public void onPreferredFeaturesChanged(@NonNull String packageName,
+                @NonNull List<String> preferredFeatures) {
+            if (!TextUtils.equals(mClientPackageName, packageName)) {
+                return;
+            }
+
+            synchronized (mLock) {
+                mDiscoveryPreference = new RouteDiscoveryPreference.Builder(
+                        preferredFeatures, true).build();
+            }
+
+            updateAllRoutesFromManager();
+            notifyPreferredFeaturesChanged(preferredFeatures);
+        }
+
+        @Override
+        public void onRequestFailed(int reason) {
+            // Does nothing.
+        }
+    }
+}
diff --git a/android/media/MediaRouter2Manager.java b/android/media/MediaRouter2Manager.java
new file mode 100644
index 0000000..7f7fb60
--- /dev/null
+++ b/android/media/MediaRouter2Manager.java
@@ -0,0 +1,1154 @@
+/*
+ * Copyright 2019 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 com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.media.session.MediaController;
+import android.media.session.MediaSessionManager;
+import android.os.Handler;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.Executor;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.stream.Collectors;
+
+/**
+ * A class that monitors and controls media routing of other apps.
+ * {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL} is required to use this class,
+ * or {@link SecurityException} will be thrown.
+ * @hide
+ */
+public final class MediaRouter2Manager {
+    private static final String TAG = "MR2Manager";
+    private static final Object sLock = new Object();
+    /**
+     * The request ID for requests not asked by this instance.
+     * Shouldn't be used for a valid request.
+     * @hide
+     */
+    public static final int REQUEST_ID_NONE = 0;
+    /** @hide */
+    @VisibleForTesting
+    public static final int TRANSFER_TIMEOUT_MS = 30_000;
+
+    @GuardedBy("sLock")
+    private static MediaRouter2Manager sInstance;
+
+    private final MediaSessionManager mMediaSessionManager;
+
+    final String mPackageName;
+
+    private final Context mContext;
+    @GuardedBy("sLock")
+    private Client mClient;
+    private final IMediaRouterService mMediaRouterService;
+    final Handler mHandler;
+    final CopyOnWriteArrayList<CallbackRecord> mCallbackRecords = new CopyOnWriteArrayList<>();
+
+    private final Object mRoutesLock = new Object();
+    @GuardedBy("mRoutesLock")
+    private final Map<String, MediaRoute2Info> mRoutes = new HashMap<>();
+    @NonNull
+    final ConcurrentMap<String, List<String>> mPreferredFeaturesMap = new ConcurrentHashMap<>();
+
+    private final AtomicInteger mNextRequestId = new AtomicInteger(1);
+    private final CopyOnWriteArrayList<TransferRequest> mTransferRequests =
+            new CopyOnWriteArrayList<>();
+
+    /**
+     * Gets an instance of media router manager that controls media route of other applications.
+     *
+     * @return The media router manager instance for the context.
+     */
+    public static MediaRouter2Manager getInstance(@NonNull Context context) {
+        Objects.requireNonNull(context, "context must not be null");
+        synchronized (sLock) {
+            if (sInstance == null) {
+                sInstance = new MediaRouter2Manager(context);
+            }
+            return sInstance;
+        }
+    }
+
+    private MediaRouter2Manager(Context context) {
+        mContext = context.getApplicationContext();
+        mMediaRouterService = IMediaRouterService.Stub.asInterface(
+                ServiceManager.getService(Context.MEDIA_ROUTER_SERVICE));
+        mMediaSessionManager = (MediaSessionManager) context
+                .getSystemService(Context.MEDIA_SESSION_SERVICE);
+        mPackageName = mContext.getPackageName();
+        mHandler = new Handler(context.getMainLooper());
+        mHandler.post(this::getOrCreateClient);
+    }
+
+    /**
+     * Registers a callback to listen route info.
+     *
+     * @param executor the executor that runs the callback
+     * @param callback the callback to add
+     */
+    public void registerCallback(@NonNull @CallbackExecutor Executor executor,
+            @NonNull Callback callback) {
+        Objects.requireNonNull(executor, "executor must not be null");
+        Objects.requireNonNull(callback, "callback must not be null");
+
+        CallbackRecord callbackRecord = new CallbackRecord(executor, callback);
+        if (!mCallbackRecords.addIfAbsent(callbackRecord)) {
+            Log.w(TAG, "Ignoring to register the same callback twice.");
+            return;
+        }
+    }
+
+    /**
+     * Unregisters the specified callback.
+     *
+     * @param callback the callback to unregister
+     */
+    public void unregisterCallback(@NonNull Callback callback) {
+        Objects.requireNonNull(callback, "callback must not be null");
+
+        if (!mCallbackRecords.remove(new CallbackRecord(null, callback))) {
+            Log.w(TAG, "unregisterCallback: Ignore unknown callback. " + callback);
+            return;
+        }
+    }
+
+    /**
+     * Starts scanning remote routes.
+     * <p>
+     * Route discovery can happen even when the {@link #startScan()} is not called.
+     * This is because the scanning could be started before by other apps.
+     * Therefore, calling this method after calling {@link #stopScan()} does not necessarily mean
+     * that the routes found before are removed and added again.
+     * <p>
+     * Use {@link Callback} to get the route related events.
+     * <p>
+     * @see #stopScan()
+     */
+    public void startScan() {
+        Client client = getOrCreateClient();
+        if (client != null) {
+            try {
+                mMediaRouterService.startScan(client);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "Unable to get sessions. Service probably died.", ex);
+            }
+        }
+    }
+
+    /**
+     * Stops scanning remote routes to reduce resource consumption.
+     * <p>
+     * Route discovery can be continued even after this method is called.
+     * This is because the scanning is only turned off when all the apps stop scanning.
+     * Therefore, calling this method does not necessarily mean the routes are removed.
+     * Also, for the same reason it does not mean that {@link Callback#onRoutesAdded(List)}
+     * is not called afterwards.
+     * <p>
+     * Use {@link Callback} to get the route related events.
+     *
+     * @see #startScan()
+     */
+    public void stopScan() {
+        Client client = getOrCreateClient();
+        if (client != null) {
+            try {
+                mMediaRouterService.stopScan(client);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "Unable to get sessions. Service probably died.", ex);
+            }
+        }
+    }
+
+    /**
+     * Gets a {@link android.media.session.MediaController} associated with the
+     * given routing session.
+     * If there is no matching media session, {@code null} is returned.
+     */
+    @Nullable
+    public MediaController getMediaControllerForRoutingSession(
+            @NonNull RoutingSessionInfo sessionInfo) {
+        for (MediaController controller : mMediaSessionManager.getActiveSessions(null)) {
+            if (areSessionsMatched(controller, sessionInfo)) {
+                return controller;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets available routes for an application.
+     *
+     * @param packageName the package name of the application
+     */
+    @NonNull
+    public List<MediaRoute2Info> getAvailableRoutes(@NonNull String packageName) {
+        Objects.requireNonNull(packageName, "packageName must not be null");
+
+        List<RoutingSessionInfo> sessions = getRoutingSessions(packageName);
+        return getAvailableRoutes(sessions.get(sessions.size() - 1));
+    }
+
+    /**
+     * Gets routes that can be transferable seamlessly for an application.
+     *
+     * @param packageName the package name of the application
+     */
+    @NonNull
+    public List<MediaRoute2Info> getTransferableRoutes(@NonNull String packageName) {
+        Objects.requireNonNull(packageName, "packageName must not be null");
+
+        List<RoutingSessionInfo> sessions = getRoutingSessions(packageName);
+        return getTransferableRoutes(sessions.get(sessions.size() - 1));
+    }
+
+
+    /**
+     * Gets available routes for the given routing session.
+     * The returned routes can be passed to
+     * {@link #transfer(RoutingSessionInfo, MediaRoute2Info)} for transferring the routing session.
+     *
+     * @param sessionInfo the routing session that would be transferred
+     */
+    @NonNull
+    public List<MediaRoute2Info> getAvailableRoutes(@NonNull RoutingSessionInfo sessionInfo) {
+        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+
+        List<MediaRoute2Info> routes = new ArrayList<>();
+
+        String packageName = sessionInfo.getClientPackageName();
+        List<String> preferredFeatures = mPreferredFeaturesMap.get(packageName);
+        if (preferredFeatures == null) {
+            preferredFeatures = Collections.emptyList();
+        }
+        synchronized (mRoutesLock) {
+            for (MediaRoute2Info route : mRoutes.values()) {
+                if (route.hasAnyFeatures(preferredFeatures)
+                        || sessionInfo.getSelectedRoutes().contains(route.getId())
+                        || sessionInfo.getTransferableRoutes().contains(route.getId())) {
+                    routes.add(route);
+                }
+            }
+        }
+        return routes;
+    }
+
+    /**
+     * Gets routes that can be transferable seamlessly for the given routing session.
+     * The returned routes can be passed to
+     * {@link #transfer(RoutingSessionInfo, MediaRoute2Info)} for transferring the routing session.
+     * <p>
+     * This includes routes that are {@link RoutingSessionInfo#getTransferableRoutes() transferable}
+     * by provider itself and routes that are different playback type (e.g. local/remote)
+     * from the given routing session.
+     *
+     * @param sessionInfo the routing session that would be transferred
+     */
+    @NonNull
+    public List<MediaRoute2Info> getTransferableRoutes(@NonNull RoutingSessionInfo sessionInfo) {
+        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+
+        List<MediaRoute2Info> routes = new ArrayList<>();
+
+        String packageName = sessionInfo.getClientPackageName();
+        List<String> preferredFeatures = mPreferredFeaturesMap.get(packageName);
+        if (preferredFeatures == null) {
+            preferredFeatures = Collections.emptyList();
+        }
+        synchronized (mRoutesLock) {
+            for (MediaRoute2Info route : mRoutes.values()) {
+                if (sessionInfo.getTransferableRoutes().contains(route.getId())) {
+                    routes.add(route);
+                    continue;
+                }
+                // Add Phone -> Cast and Cast -> Phone
+                if (route.hasAnyFeatures(preferredFeatures)
+                        && (sessionInfo.isSystemSession() ^ route.isSystemRoute())) {
+                    routes.add(route);
+                }
+            }
+        }
+        return routes;
+    }
+
+    /**
+     * Returns the preferred features of the specified package name.
+     */
+    @NonNull
+    public List<String> getPreferredFeatures(@NonNull String packageName) {
+        Objects.requireNonNull(packageName, "packageName must not be null");
+
+        List<String> preferredFeatures = mPreferredFeaturesMap.get(packageName);
+        if (preferredFeatures == null) {
+            preferredFeatures = Collections.emptyList();
+        }
+        return preferredFeatures;
+    }
+
+    /**
+     * Returns a list of routes which are related to the given package name in the given route list.
+     */
+    @NonNull
+    public List<MediaRoute2Info> filterRoutesForPackage(@NonNull List<MediaRoute2Info> routes,
+            @NonNull String packageName) {
+        Objects.requireNonNull(routes, "routes must not be null");
+        Objects.requireNonNull(packageName, "packageName must not be null");
+
+        List<RoutingSessionInfo> sessions = getRoutingSessions(packageName);
+        RoutingSessionInfo sessionInfo = sessions.get(sessions.size() - 1);
+
+        List<MediaRoute2Info> result = new ArrayList<>();
+        List<String> preferredFeatures = mPreferredFeaturesMap.get(packageName);
+        if (preferredFeatures == null) {
+            preferredFeatures = Collections.emptyList();
+        }
+
+        synchronized (mRoutesLock) {
+            for (MediaRoute2Info route : routes) {
+                if (route.hasAnyFeatures(preferredFeatures)
+                        || sessionInfo.getSelectedRoutes().contains(route.getId())
+                        || sessionInfo.getTransferableRoutes().contains(route.getId())) {
+                    result.add(route);
+                }
+            }
+        }
+        return result;
+    }
+
+    /**
+     * Gets the system routing session associated with no specific application.
+     */
+    @NonNull
+    public RoutingSessionInfo getSystemRoutingSession() {
+        for (RoutingSessionInfo sessionInfo : getActiveSessions()) {
+            if (sessionInfo.isSystemSession()) {
+                return sessionInfo;
+            }
+        }
+        throw new IllegalStateException("No system routing session");
+    }
+
+    /**
+     * Gets the routing session of a media session.
+     * If the session is using {#link PlaybackInfo#PLAYBACK_TYPE_LOCAL local playback},
+     * the system routing session is returned.
+     * If the session is using {#link PlaybackInfo#PLAYBACK_TYPE_REMOTE remote playback},
+     * it returns the corresponding routing session or {@code null} if it's unavailable.
+     */
+    @Nullable
+    public RoutingSessionInfo getRoutingSessionForMediaController(MediaController mediaController) {
+        MediaController.PlaybackInfo playbackInfo = mediaController.getPlaybackInfo();
+        if (playbackInfo == null) {
+            return null;
+        }
+        if (playbackInfo.getPlaybackType() == MediaController.PlaybackInfo.PLAYBACK_TYPE_LOCAL) {
+            return new RoutingSessionInfo.Builder(getSystemRoutingSession())
+                    .setClientPackageName(mediaController.getPackageName())
+                    .build();
+        }
+        for (RoutingSessionInfo sessionInfo : getActiveSessions()) {
+            if (!sessionInfo.isSystemSession()
+                    && areSessionsMatched(mediaController, sessionInfo)) {
+                return sessionInfo;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets routing sessions of an application with the given package name.
+     * The first element of the returned list is the system routing session.
+     *
+     * @param packageName the package name of the application that is routing.
+     * @see #getSystemRoutingSession()
+     */
+    @NonNull
+    public List<RoutingSessionInfo> getRoutingSessions(@NonNull String packageName) {
+        Objects.requireNonNull(packageName, "packageName must not be null");
+
+        List<RoutingSessionInfo> sessions = new ArrayList<>();
+
+        for (RoutingSessionInfo sessionInfo : getActiveSessions()) {
+            if (sessionInfo.isSystemSession()) {
+                sessions.add(new RoutingSessionInfo.Builder(sessionInfo)
+                        .setClientPackageName(packageName)
+                        .build());
+            } else if (TextUtils.equals(sessionInfo.getClientPackageName(), packageName)) {
+                sessions.add(sessionInfo);
+            }
+        }
+        return sessions;
+    }
+
+    /**
+     * Gets the list of all active routing sessions.
+     * <p>
+     * The first element of the list is the system routing session containing
+     * phone speakers, wired headset, Bluetooth devices.
+     * The system routing session is shared by apps such that controlling it will affect
+     * all apps.
+     * If you want to transfer media of an application, use {@link #getRoutingSessions(String)}.
+     *
+     * @see #getRoutingSessions(String)
+     * @see #getSystemRoutingSession()
+     */
+    @NonNull
+    public List<RoutingSessionInfo> getActiveSessions() {
+        Client client = getOrCreateClient();
+        if (client != null) {
+            try {
+                return mMediaRouterService.getActiveSessions(client);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "Unable to get sessions. Service probably died.", ex);
+            }
+        }
+        return Collections.emptyList();
+    }
+
+    /**
+     * Gets the list of all discovered routes.
+     */
+    @NonNull
+    public List<MediaRoute2Info> getAllRoutes() {
+        List<MediaRoute2Info> routes = new ArrayList<>();
+        synchronized (mRoutesLock) {
+            routes.addAll(mRoutes.values());
+        }
+        return routes;
+    }
+
+    /**
+     * Selects media route for the specified package name.
+     */
+    public void selectRoute(@NonNull String packageName, @NonNull MediaRoute2Info route) {
+        Objects.requireNonNull(packageName, "packageName must not be null");
+        Objects.requireNonNull(route, "route must not be null");
+
+        Log.v(TAG, "Selecting route. packageName= " + packageName + ", route=" + route);
+
+        List<RoutingSessionInfo> sessionInfos = getRoutingSessions(packageName);
+        RoutingSessionInfo targetSession = sessionInfos.get(sessionInfos.size() - 1);
+        transfer(targetSession, route);
+    }
+
+    /**
+     * Transfers a routing session to a media route.
+     * <p>{@link Callback#onTransferred} or {@link Callback#onTransferFailed} will be called
+     * depending on the result.
+     *
+     * @param sessionInfo the routing session info to transfer
+     * @param route the route transfer to
+     *
+     * @see Callback#onTransferred(RoutingSessionInfo, RoutingSessionInfo)
+     * @see Callback#onTransferFailed(RoutingSessionInfo, MediaRoute2Info)
+     */
+    public void transfer(@NonNull RoutingSessionInfo sessionInfo,
+            @NonNull MediaRoute2Info route) {
+        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+        Objects.requireNonNull(route, "route must not be null");
+
+        Log.v(TAG, "Transferring routing session. session= " + sessionInfo + ", route=" + route);
+
+        synchronized (mRoutesLock) {
+            if (!mRoutes.containsKey(route.getId())) {
+                Log.w(TAG, "transfer: Ignoring an unknown route id=" + route.getId());
+                notifyTransferFailed(sessionInfo, route);
+                return;
+            }
+        }
+
+        if (sessionInfo.getTransferableRoutes().contains(route.getId())) {
+            transferToRoute(sessionInfo, route);
+        } else {
+            requestCreateSession(sessionInfo, route);
+        }
+    }
+
+    /**
+     * Requests a volume change for a route asynchronously.
+     * <p>
+     * It may have no effect if the route is currently not selected.
+     * </p>
+     *
+     * @param volume The new volume value between 0 and {@link MediaRoute2Info#getVolumeMax}
+     *               (inclusive).
+     */
+    public void setRouteVolume(@NonNull MediaRoute2Info route, int volume) {
+        Objects.requireNonNull(route, "route must not be null");
+
+        if (route.getVolumeHandling() == MediaRoute2Info.PLAYBACK_VOLUME_FIXED) {
+            Log.w(TAG, "setRouteVolume: the route has fixed volume. Ignoring.");
+            return;
+        }
+        if (volume < 0 || volume > route.getVolumeMax()) {
+            Log.w(TAG, "setRouteVolume: the target volume is out of range. Ignoring");
+            return;
+        }
+
+        Client client = getOrCreateClient();
+        if (client != null) {
+            try {
+                int requestId = mNextRequestId.getAndIncrement();
+                mMediaRouterService.setRouteVolumeWithManager(client, requestId, route, volume);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "Unable to set route volume.", ex);
+            }
+        }
+    }
+
+    /**
+     * Requests a volume change for a routing session asynchronously.
+     *
+     * @param volume The new volume value between 0 and {@link RoutingSessionInfo#getVolumeMax}
+     *               (inclusive).
+     */
+    public void setSessionVolume(@NonNull RoutingSessionInfo sessionInfo, int volume) {
+        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+
+        if (sessionInfo.getVolumeHandling() == MediaRoute2Info.PLAYBACK_VOLUME_FIXED) {
+            Log.w(TAG, "setSessionVolume: the route has fixed volume. Ignoring.");
+            return;
+        }
+        if (volume < 0 || volume > sessionInfo.getVolumeMax()) {
+            Log.w(TAG, "setSessionVolume: the target volume is out of range. Ignoring");
+            return;
+        }
+
+        Client client = getOrCreateClient();
+        if (client != null) {
+            try {
+                int requestId = mNextRequestId.getAndIncrement();
+                mMediaRouterService.setSessionVolumeWithManager(
+                        client, requestId, sessionInfo.getId(), volume);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "Unable to set session volume.", ex);
+            }
+        }
+    }
+
+    void addRoutesOnHandler(List<MediaRoute2Info> routes) {
+        synchronized (mRoutesLock) {
+            for (MediaRoute2Info route : routes) {
+                mRoutes.put(route.getId(), route);
+            }
+        }
+        if (routes.size() > 0) {
+            notifyRoutesAdded(routes);
+        }
+    }
+
+    void removeRoutesOnHandler(List<MediaRoute2Info> routes) {
+        synchronized (mRoutesLock) {
+            for (MediaRoute2Info route : routes) {
+                mRoutes.remove(route.getId());
+            }
+        }
+        if (routes.size() > 0) {
+            notifyRoutesRemoved(routes);
+        }
+    }
+
+    void changeRoutesOnHandler(List<MediaRoute2Info> routes) {
+        synchronized (mRoutesLock) {
+            for (MediaRoute2Info route : routes) {
+                mRoutes.put(route.getId(), route);
+            }
+        }
+        if (routes.size() > 0) {
+            notifyRoutesChanged(routes);
+        }
+    }
+
+    void createSessionOnHandler(int requestId, RoutingSessionInfo sessionInfo) {
+        TransferRequest matchingRequest = null;
+        for (TransferRequest request : mTransferRequests) {
+            if (request.mRequestId == requestId) {
+                matchingRequest = request;
+                break;
+            }
+        }
+
+        if (matchingRequest == null) {
+            return;
+        }
+
+        mTransferRequests.remove(matchingRequest);
+
+        MediaRoute2Info requestedRoute = matchingRequest.mTargetRoute;
+
+        if (sessionInfo == null) {
+            notifyTransferFailed(matchingRequest.mOldSessionInfo, requestedRoute);
+            return;
+        } else if (!sessionInfo.getSelectedRoutes().contains(requestedRoute.getId())) {
+            Log.w(TAG, "The session does not contain the requested route. "
+                    + "(requestedRouteId=" + requestedRoute.getId()
+                    + ", actualRoutes=" + sessionInfo.getSelectedRoutes()
+                    + ")");
+            notifyTransferFailed(matchingRequest.mOldSessionInfo, requestedRoute);
+            return;
+        } else if (!TextUtils.equals(requestedRoute.getProviderId(),
+                sessionInfo.getProviderId())) {
+            Log.w(TAG, "The session's provider ID does not match the requested route's. "
+                    + "(requested route's providerId=" + requestedRoute.getProviderId()
+                    + ", actual providerId=" + sessionInfo.getProviderId()
+                    + ")");
+            notifyTransferFailed(matchingRequest.mOldSessionInfo, requestedRoute);
+            return;
+        }
+        notifyTransferred(matchingRequest.mOldSessionInfo, sessionInfo);
+    }
+
+    void handleFailureOnHandler(int requestId, int reason) {
+        TransferRequest matchingRequest = null;
+        for (TransferRequest request : mTransferRequests) {
+            if (request.mRequestId == requestId) {
+                matchingRequest = request;
+                break;
+            }
+        }
+
+        if (matchingRequest != null) {
+            mTransferRequests.remove(matchingRequest);
+            notifyTransferFailed(matchingRequest.mOldSessionInfo, matchingRequest.mTargetRoute);
+            return;
+        }
+        notifyRequestFailed(reason);
+    }
+
+    void handleSessionsUpdatedOnHandler(RoutingSessionInfo sessionInfo) {
+        for (TransferRequest request : mTransferRequests) {
+            String sessionId = request.mOldSessionInfo.getId();
+            if (!TextUtils.equals(sessionId, sessionInfo.getId())) {
+                continue;
+            }
+            if (sessionInfo.getSelectedRoutes().contains(request.mTargetRoute.getId())) {
+                mTransferRequests.remove(request);
+                notifyTransferred(request.mOldSessionInfo, sessionInfo);
+                break;
+            }
+        }
+        notifySessionUpdated(sessionInfo);
+    }
+
+    private void notifyRoutesAdded(List<MediaRoute2Info> routes) {
+        for (CallbackRecord record: mCallbackRecords) {
+            record.mExecutor.execute(
+                    () -> record.mCallback.onRoutesAdded(routes));
+        }
+    }
+
+    private void notifyRoutesRemoved(List<MediaRoute2Info> routes) {
+        for (CallbackRecord record: mCallbackRecords) {
+            record.mExecutor.execute(
+                    () -> record.mCallback.onRoutesRemoved(routes));
+        }
+    }
+
+    private void notifyRoutesChanged(List<MediaRoute2Info> routes) {
+        for (CallbackRecord record: mCallbackRecords) {
+            record.mExecutor.execute(
+                    () -> record.mCallback.onRoutesChanged(routes));
+        }
+    }
+
+    void notifySessionUpdated(RoutingSessionInfo sessionInfo) {
+        for (CallbackRecord record : mCallbackRecords) {
+            record.mExecutor.execute(() -> record.mCallback.onSessionUpdated(sessionInfo));
+        }
+    }
+
+    void notifySessionReleased(RoutingSessionInfo session) {
+        for (CallbackRecord record : mCallbackRecords) {
+            record.mExecutor.execute(() -> record.mCallback.onSessionReleased(session));
+        }
+    }
+
+    void notifyRequestFailed(int reason) {
+        for (CallbackRecord record : mCallbackRecords) {
+            record.mExecutor.execute(() -> record.mCallback.onRequestFailed(reason));
+        }
+    }
+
+    void notifyTransferred(RoutingSessionInfo oldSession, RoutingSessionInfo newSession) {
+        for (CallbackRecord record : mCallbackRecords) {
+            record.mExecutor.execute(() -> record.mCallback.onTransferred(oldSession, newSession));
+        }
+    }
+
+    void notifyTransferFailed(RoutingSessionInfo sessionInfo, MediaRoute2Info route) {
+        for (CallbackRecord record : mCallbackRecords) {
+            record.mExecutor.execute(() -> record.mCallback.onTransferFailed(sessionInfo, route));
+        }
+    }
+
+    void updatePreferredFeatures(String packageName, List<String> preferredFeatures) {
+        if (preferredFeatures == null) {
+            mPreferredFeaturesMap.remove(packageName);
+            return;
+        }
+        List<String> prevFeatures = mPreferredFeaturesMap.put(packageName, preferredFeatures);
+        if ((prevFeatures == null && preferredFeatures.size() == 0)
+                || Objects.equals(preferredFeatures, prevFeatures)) {
+            return;
+        }
+        for (CallbackRecord record : mCallbackRecords) {
+            record.mExecutor.execute(() -> record.mCallback
+                    .onPreferredFeaturesChanged(packageName, preferredFeatures));
+        }
+    }
+
+    /**
+     * Gets the unmodifiable list of selected routes for the session.
+     */
+    @NonNull
+    public List<MediaRoute2Info> getSelectedRoutes(@NonNull RoutingSessionInfo sessionInfo) {
+        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+
+        synchronized (mRoutesLock) {
+            return sessionInfo.getSelectedRoutes().stream().map(mRoutes::get)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toList());
+        }
+    }
+
+    /**
+     * Gets the unmodifiable list of selectable routes for the session.
+     */
+    @NonNull
+    public List<MediaRoute2Info> getSelectableRoutes(@NonNull RoutingSessionInfo sessionInfo) {
+        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+
+        List<String> selectedRouteIds = sessionInfo.getSelectedRoutes();
+
+        synchronized (mRoutesLock) {
+            return sessionInfo.getSelectableRoutes().stream()
+                    .filter(routeId -> !selectedRouteIds.contains(routeId))
+                    .map(mRoutes::get)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toList());
+        }
+    }
+
+    /**
+     * Gets the unmodifiable list of deselectable routes for the session.
+     */
+    @NonNull
+    public List<MediaRoute2Info> getDeselectableRoutes(@NonNull RoutingSessionInfo sessionInfo) {
+        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+
+        List<String> selectedRouteIds = sessionInfo.getSelectedRoutes();
+
+        synchronized (mRoutesLock) {
+            return sessionInfo.getDeselectableRoutes().stream()
+                    .filter(routeId -> selectedRouteIds.contains(routeId))
+                    .map(mRoutes::get)
+                    .filter(Objects::nonNull)
+                    .collect(Collectors.toList());
+        }
+    }
+
+    /**
+     * Selects a route for the remote session. After a route is selected, the media is expected
+     * to be played to the all the selected routes. This is different from {@link
+     * #transfer(RoutingSessionInfo, MediaRoute2Info)} transferring to a route},
+     * where the media is expected to 'move' from one route to another.
+     * <p>
+     * The given route must satisfy all of the following conditions:
+     * <ul>
+     * <li>it should not be included in {@link #getSelectedRoutes(RoutingSessionInfo)}</li>
+     * <li>it should be included in {@link #getSelectableRoutes(RoutingSessionInfo)}</li>
+     * </ul>
+     * If the route doesn't meet any of above conditions, it will be ignored.
+     *
+     * @see #getSelectedRoutes(RoutingSessionInfo)
+     * @see #getSelectableRoutes(RoutingSessionInfo)
+     * @see Callback#onSessionUpdated(RoutingSessionInfo)
+     */
+    public void selectRoute(@NonNull RoutingSessionInfo sessionInfo,
+            @NonNull MediaRoute2Info route) {
+        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+        Objects.requireNonNull(route, "route must not be null");
+
+        if (sessionInfo.getSelectedRoutes().contains(route.getId())) {
+            Log.w(TAG, "Ignoring selecting a route that is already selected. route=" + route);
+            return;
+        }
+
+        if (!sessionInfo.getSelectableRoutes().contains(route.getId())) {
+            Log.w(TAG, "Ignoring selecting a non-selectable route=" + route);
+            return;
+        }
+
+        Client client = getOrCreateClient();
+        if (client != null) {
+            try {
+                int requestId = mNextRequestId.getAndIncrement();
+                mMediaRouterService.selectRouteWithManager(
+                        client, requestId, sessionInfo.getId(), route);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "selectRoute: Failed to send a request.", ex);
+            }
+        }
+    }
+
+    /**
+     * Deselects a route from the remote session. After a route is deselected, the media is
+     * expected to be stopped on the deselected routes.
+     * <p>
+     * The given route must satisfy all of the following conditions:
+     * <ul>
+     * <li>it should be included in {@link #getSelectedRoutes(RoutingSessionInfo)}</li>
+     * <li>it should be included in {@link #getDeselectableRoutes(RoutingSessionInfo)}</li>
+     * </ul>
+     * If the route doesn't meet any of above conditions, it will be ignored.
+     *
+     * @see #getSelectedRoutes(RoutingSessionInfo)
+     * @see #getDeselectableRoutes(RoutingSessionInfo)
+     * @see Callback#onSessionUpdated(RoutingSessionInfo)
+     */
+    public void deselectRoute(@NonNull RoutingSessionInfo sessionInfo,
+            @NonNull MediaRoute2Info route) {
+        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+        Objects.requireNonNull(route, "route must not be null");
+
+        if (!sessionInfo.getSelectedRoutes().contains(route.getId())) {
+            Log.w(TAG, "Ignoring deselecting a route that is not selected. route=" + route);
+            return;
+        }
+
+        if (!sessionInfo.getDeselectableRoutes().contains(route.getId())) {
+            Log.w(TAG, "Ignoring deselecting a non-deselectable route=" + route);
+            return;
+        }
+
+        Client client = getOrCreateClient();
+        if (client != null) {
+            try {
+                int requestId = mNextRequestId.getAndIncrement();
+                mMediaRouterService.deselectRouteWithManager(
+                        client, requestId, sessionInfo.getId(), route);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "deselectRoute: Failed to send a request.", ex);
+            }
+        }
+    }
+
+    /**
+     * Requests releasing a session.
+     * <p>
+     * If a session is released, any operation on the session will be ignored.
+     * {@link Callback#onSessionReleased(RoutingSessionInfo)} will be called
+     * when the session is released.
+     * </p>
+     *
+     * @see Callback#onTransferred(RoutingSessionInfo, RoutingSessionInfo)
+     */
+    public void releaseSession(@NonNull RoutingSessionInfo sessionInfo) {
+        Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+
+        Client client = getOrCreateClient();
+        if (client != null) {
+            try {
+                int requestId = mNextRequestId.getAndIncrement();
+                mMediaRouterService.releaseSessionWithManager(
+                        client, requestId, sessionInfo.getId());
+            } catch (RemoteException ex) {
+                Log.e(TAG, "releaseSession: Failed to send a request", ex);
+            }
+        }
+    }
+
+    /**
+     * Transfers the remote session to the given route.
+     *
+     * @hide
+     */
+    private void transferToRoute(@NonNull RoutingSessionInfo session,
+            @NonNull MediaRoute2Info route) {
+        int requestId = createTransferRequest(session, route);
+
+        Client client = getOrCreateClient();
+        if (client != null) {
+            try {
+                mMediaRouterService.transferToRouteWithManager(
+                        client, requestId, session.getId(), route);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "transferToRoute: Failed to send a request.", ex);
+            }
+        }
+    }
+
+    private void requestCreateSession(RoutingSessionInfo oldSession, MediaRoute2Info route) {
+        if (TextUtils.isEmpty(oldSession.getClientPackageName())) {
+            Log.w(TAG, "requestCreateSession: Can't create a session without package name.");
+            notifyTransferFailed(oldSession, route);
+            return;
+        }
+
+        int requestId = createTransferRequest(oldSession, route);
+
+        Client client = getOrCreateClient();
+        if (client != null) {
+            try {
+                mMediaRouterService.requestCreateSessionWithManager(
+                        client, requestId, oldSession, route);
+            } catch (RemoteException ex) {
+                Log.e(TAG, "requestCreateSession: Failed to send a request", ex);
+            }
+        }
+    }
+
+    private int createTransferRequest(RoutingSessionInfo session, MediaRoute2Info route) {
+        int requestId = mNextRequestId.getAndIncrement();
+        TransferRequest transferRequest = new TransferRequest(requestId, session, route);
+        mTransferRequests.add(transferRequest);
+
+        Message timeoutMessage =
+                obtainMessage(MediaRouter2Manager::handleTransferTimeout, this, transferRequest);
+        mHandler.sendMessageDelayed(timeoutMessage, TRANSFER_TIMEOUT_MS);
+        return requestId;
+    }
+
+    private void handleTransferTimeout(TransferRequest request) {
+        boolean removed = mTransferRequests.remove(request);
+        if (removed) {
+            notifyTransferFailed(request.mOldSessionInfo, request.mTargetRoute);
+        }
+    }
+
+
+    private boolean areSessionsMatched(MediaController mediaController,
+            RoutingSessionInfo sessionInfo) {
+        MediaController.PlaybackInfo playbackInfo = mediaController.getPlaybackInfo();
+        if (playbackInfo == null) {
+            return false;
+        }
+
+        String volumeControlId = playbackInfo.getVolumeControlId();
+        if (volumeControlId == null) {
+            return false;
+        }
+
+        if (TextUtils.equals(volumeControlId, sessionInfo.getId())) {
+            return true;
+        }
+        // Workaround for provider not being able to know the unique session ID.
+        return TextUtils.equals(volumeControlId, sessionInfo.getOriginalId())
+                && TextUtils.equals(mediaController.getPackageName(),
+                sessionInfo.getOwnerPackageName());
+    }
+
+    private Client getOrCreateClient() {
+        synchronized (sLock) {
+            if (mClient != null) {
+                return mClient;
+            }
+            Client client = new Client();
+            try {
+                mMediaRouterService.registerManager(client, mPackageName);
+                mClient = client;
+                return client;
+            } catch (RemoteException ex) {
+                Log.e(TAG, "Unable to register media router manager.", ex);
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Interface for receiving events about media routing changes.
+     */
+    public interface Callback {
+        /**
+         * Called when routes are added.
+         * @param routes the list of routes that have been added. It's never empty.
+         */
+        default void onRoutesAdded(@NonNull List<MediaRoute2Info> routes) {}
+
+        /**
+         * Called when routes are removed.
+         * @param routes the list of routes that have been removed. It's never empty.
+         */
+        default void onRoutesRemoved(@NonNull List<MediaRoute2Info> routes) {}
+
+        /**
+         * Called when routes are changed.
+         * @param routes the list of routes that have been changed. It's never empty.
+         */
+        default void onRoutesChanged(@NonNull List<MediaRoute2Info> routes) {}
+
+        /**
+         * Called when a session is changed.
+         * @param session the updated session
+         */
+        default void onSessionUpdated(@NonNull RoutingSessionInfo session) {}
+
+        /**
+         * Called when a session is released.
+         * @param session the released session.
+         * @see #releaseSession(RoutingSessionInfo)
+         */
+        default void onSessionReleased(@NonNull RoutingSessionInfo session) {}
+
+        /**
+         * Called when media is transferred.
+         *
+         * @param oldSession the previous session
+         * @param newSession the new session
+         */
+        default void onTransferred(@NonNull RoutingSessionInfo oldSession,
+                @NonNull RoutingSessionInfo newSession) { }
+
+        /**
+         * Called when {@link #transfer(RoutingSessionInfo, MediaRoute2Info)} fails.
+         */
+        default void onTransferFailed(@NonNull RoutingSessionInfo session,
+                @NonNull MediaRoute2Info route) { }
+
+        /**
+         * Called when the preferred route features of an app is changed.
+         *
+         * @param packageName the package name of the application
+         * @param preferredFeatures the list of preferred route features set by an application.
+         */
+        default void onPreferredFeaturesChanged(@NonNull String packageName,
+                @NonNull List<String> preferredFeatures) {}
+
+        /**
+         * Called when a previous request has failed.
+         *
+         * @param reason the reason that the request has failed. Can be one of followings:
+         *               {@link MediaRoute2ProviderService#REASON_UNKNOWN_ERROR},
+         *               {@link MediaRoute2ProviderService#REASON_REJECTED},
+         *               {@link MediaRoute2ProviderService#REASON_NETWORK_ERROR},
+         *               {@link MediaRoute2ProviderService#REASON_ROUTE_NOT_AVAILABLE},
+         *               {@link MediaRoute2ProviderService#REASON_INVALID_COMMAND},
+         */
+        default void onRequestFailed(int reason) {}
+    }
+
+    final class CallbackRecord {
+        public final Executor mExecutor;
+        public final Callback mCallback;
+
+        CallbackRecord(Executor executor, Callback callback) {
+            mExecutor = executor;
+            mCallback = callback;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (!(obj instanceof CallbackRecord)) {
+                return false;
+            }
+            return mCallback == ((CallbackRecord) obj).mCallback;
+        }
+
+        @Override
+        public int hashCode() {
+            return mCallback.hashCode();
+        }
+    }
+
+    static final class TransferRequest {
+        public final int mRequestId;
+        public final RoutingSessionInfo mOldSessionInfo;
+        public final MediaRoute2Info mTargetRoute;
+
+        TransferRequest(int requestId, @NonNull RoutingSessionInfo oldSessionInfo,
+                @NonNull MediaRoute2Info targetRoute) {
+            mRequestId = requestId;
+            mOldSessionInfo = oldSessionInfo;
+            mTargetRoute = targetRoute;
+        }
+    }
+
+    class Client extends IMediaRouter2Manager.Stub {
+        @Override
+        public void notifySessionCreated(int requestId, RoutingSessionInfo session) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::createSessionOnHandler,
+                    MediaRouter2Manager.this, requestId, session));
+        }
+
+        @Override
+        public void notifySessionUpdated(RoutingSessionInfo session) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::handleSessionsUpdatedOnHandler,
+                    MediaRouter2Manager.this, session));
+        }
+
+        @Override
+        public void notifySessionReleased(RoutingSessionInfo session) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::notifySessionReleased,
+                    MediaRouter2Manager.this, session));
+        }
+
+        @Override
+        public void notifyRequestFailed(int requestId, int reason) {
+            // Note: requestId is not used.
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::handleFailureOnHandler,
+                    MediaRouter2Manager.this, requestId, reason));
+        }
+
+        @Override
+        public void notifyPreferredFeaturesChanged(String packageName, List<String> features) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::updatePreferredFeatures,
+                    MediaRouter2Manager.this, packageName, features));
+        }
+
+        @Override
+        public void notifyRoutesAdded(List<MediaRoute2Info> routes) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::addRoutesOnHandler,
+                    MediaRouter2Manager.this, routes));
+        }
+
+        @Override
+        public void notifyRoutesRemoved(List<MediaRoute2Info> routes) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::removeRoutesOnHandler,
+                    MediaRouter2Manager.this, routes));
+        }
+
+        @Override
+        public void notifyRoutesChanged(List<MediaRoute2Info> routes) {
+            mHandler.sendMessage(obtainMessage(MediaRouter2Manager::changeRoutesOnHandler,
+                    MediaRouter2Manager.this, routes));
+        }
+    }
+}
diff --git a/android/media/MediaRouter2Utils.java b/android/media/MediaRouter2Utils.java
new file mode 100644
index 0000000..c15972d
--- /dev/null
+++ b/android/media/MediaRouter2Utils.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2020 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.text.TextUtils;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+public class MediaRouter2Utils {
+
+    static final String TAG = "MR2Utils";
+    static final String SEPARATOR = ":";
+
+    @NonNull
+    public static String toUniqueId(@NonNull String providerId, @NonNull String id) {
+        if (TextUtils.isEmpty(providerId)) {
+            Log.w(TAG, "toUniqueId: providerId shouldn't be empty");
+            return null;
+        }
+        if (TextUtils.isEmpty(id)) {
+            Log.w(TAG, "toUniqueId: id shouldn't be null");
+            return null;
+        }
+
+        return providerId + SEPARATOR + id;
+    }
+
+    /**
+     * Gets provider ID from unique ID.
+     * If the corresponding provider ID could not be generated, it will return null.
+     */
+    @Nullable
+    public static String getProviderId(@NonNull String uniqueId) {
+        if (TextUtils.isEmpty(uniqueId)) {
+            Log.w(TAG, "getProviderId: uniqueId shouldn't be empty");
+            return null;
+        }
+
+        int firstIndexOfSeparator = uniqueId.indexOf(SEPARATOR);
+        if (firstIndexOfSeparator == -1) {
+            return null;
+        }
+
+        String providerId = uniqueId.substring(0, firstIndexOfSeparator);
+        if (TextUtils.isEmpty(providerId)) {
+            return null;
+        }
+
+        return providerId;
+    }
+
+    /**
+     * Gets the original ID (i.e. non-unique route/session ID) from unique ID.
+     * If the corresponding ID could not be generated, it will return null.
+     */
+    @Nullable
+    public static String getOriginalId(@NonNull String uniqueId) {
+        if (TextUtils.isEmpty(uniqueId)) {
+            Log.w(TAG, "getOriginalId: uniqueId shouldn't be empty");
+            return null;
+        }
+
+        int firstIndexOfSeparator = uniqueId.indexOf(SEPARATOR);
+        if (firstIndexOfSeparator == -1 || firstIndexOfSeparator + 1 >= uniqueId.length()) {
+            return null;
+        }
+
+        String providerId = uniqueId.substring(firstIndexOfSeparator + 1);
+        if (TextUtils.isEmpty(providerId)) {
+            return null;
+        }
+
+        return providerId;
+    }
+}
diff --git a/android/media/MediaRouterClientState.java b/android/media/MediaRouterClientState.java
new file mode 100644
index 0000000..1fe4eef
--- /dev/null
+++ b/android/media/MediaRouterClientState.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2013 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.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+
+/**
+ * Information available from MediaRouterService about the state perceived by
+ * a particular client and the routes that are available to it.
+ *
+ * Clients must not modify the contents of this object.
+ * @hide
+ */
+public final class MediaRouterClientState implements Parcelable {
+    /**
+     * A list of all known routes.
+     */
+    public final ArrayList<RouteInfo> routes;
+
+    public MediaRouterClientState() {
+        routes = new ArrayList<RouteInfo>();
+    }
+
+    MediaRouterClientState(Parcel src) {
+        routes = src.createTypedArrayList(RouteInfo.CREATOR);
+    }
+
+    public RouteInfo getRoute(String id) {
+        final int count = routes.size();
+        for (int i = 0; i < count; i++) {
+            final RouteInfo route = routes.get(i);
+            if (route.id.equals(id)) {
+                return route;
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeTypedList(routes);
+    }
+
+    @Override
+    public String toString() {
+        return "MediaRouterClientState{ routes=" + routes.toString() + " }";
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<MediaRouterClientState> CREATOR =
+            new Parcelable.Creator<MediaRouterClientState>() {
+        @Override
+        public MediaRouterClientState createFromParcel(Parcel in) {
+            return new MediaRouterClientState(in);
+        }
+
+        @Override
+        public MediaRouterClientState[] newArray(int size) {
+            return new MediaRouterClientState[size];
+        }
+    };
+
+    public static final class RouteInfo implements Parcelable {
+        public String id;
+        public String name;
+        public String description;
+        public int supportedTypes;
+        public boolean enabled;
+        public int statusCode;
+        public int playbackType;
+        public int playbackStream;
+        public int volume;
+        public int volumeMax;
+        public int volumeHandling;
+        public int presentationDisplayId;
+        public @MediaRouter.RouteInfo.DeviceType int deviceType;
+
+        public RouteInfo(String id) {
+            this.id = id;
+            enabled = true;
+            statusCode = MediaRouter.RouteInfo.STATUS_NONE;
+            playbackType = MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE;
+            playbackStream = -1;
+            volumeHandling = MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED;
+            presentationDisplayId = -1;
+            deviceType = MediaRouter.RouteInfo.DEVICE_TYPE_UNKNOWN;
+        }
+
+        public RouteInfo(RouteInfo other) {
+            id = other.id;
+            name = other.name;
+            description = other.description;
+            supportedTypes = other.supportedTypes;
+            enabled = other.enabled;
+            statusCode = other.statusCode;
+            playbackType = other.playbackType;
+            playbackStream = other.playbackStream;
+            volume = other.volume;
+            volumeMax = other.volumeMax;
+            volumeHandling = other.volumeHandling;
+            presentationDisplayId = other.presentationDisplayId;
+            deviceType = other.deviceType;
+        }
+
+        RouteInfo(Parcel in) {
+            id = in.readString();
+            name = in.readString();
+            description = in.readString();
+            supportedTypes = in.readInt();
+            enabled = in.readInt() != 0;
+            statusCode = in.readInt();
+            playbackType = in.readInt();
+            playbackStream = in.readInt();
+            volume = in.readInt();
+            volumeMax = in.readInt();
+            volumeHandling = in.readInt();
+            presentationDisplayId = in.readInt();
+            deviceType = in.readInt();
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(id);
+            dest.writeString(name);
+            dest.writeString(description);
+            dest.writeInt(supportedTypes);
+            dest.writeInt(enabled ? 1 : 0);
+            dest.writeInt(statusCode);
+            dest.writeInt(playbackType);
+            dest.writeInt(playbackStream);
+            dest.writeInt(volume);
+            dest.writeInt(volumeMax);
+            dest.writeInt(volumeHandling);
+            dest.writeInt(presentationDisplayId);
+            dest.writeInt(deviceType);
+        }
+
+        @Override
+        public String toString() {
+            return "RouteInfo{ id=" + id
+                    + ", name=" + name
+                    + ", description=" + description
+                    + ", supportedTypes=0x" + Integer.toHexString(supportedTypes)
+                    + ", enabled=" + enabled
+                    + ", statusCode=" + statusCode
+                    + ", playbackType=" + playbackType
+                    + ", playbackStream=" + playbackStream
+                    + ", volume=" + volume
+                    + ", volumeMax=" + volumeMax
+                    + ", volumeHandling=" + volumeHandling
+                    + ", presentationDisplayId=" + presentationDisplayId
+                    + ", deviceType=" + deviceType
+                    + " }";
+        }
+
+        @SuppressWarnings("hiding")
+        public static final @android.annotation.NonNull Parcelable.Creator<RouteInfo> CREATOR =
+                new Parcelable.Creator<RouteInfo>() {
+            @Override
+            public RouteInfo createFromParcel(Parcel in) {
+                return new RouteInfo(in);
+            }
+
+            @Override
+            public RouteInfo[] newArray(int size) {
+                return new RouteInfo[size];
+            }
+        };
+    }
+}
diff --git a/android/media/MediaScanner.java b/android/media/MediaScanner.java
new file mode 100644
index 0000000..aae2606
--- /dev/null
+++ b/android/media/MediaScanner.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 2007 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.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentValues;
+import android.content.Context;
+import android.net.Uri;
+import android.os.Build;
+import android.os.RemoteException;
+
+/**
+ * @hide
+ * @deprecated this media scanner has served faithfully for many years, but it's
+ *             become tedious to test and maintain, mainly due to the way it
+ *             weaves obscurely between managed and native code. It's been
+ *             replaced by {@code ModernMediaScanner} in the
+ *             {@code MediaProvider} package.
+ */
+@Deprecated
+public class MediaScanner implements AutoCloseable {
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private static final String[] FILES_PRESCAN_PROJECTION = new String[] {
+    };
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private final Context mContext;
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private final String mPackageName;
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private final Uri mAudioUri;
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private final Uri mFilesUri;
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private String mDefaultRingtoneFilename;
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private String mDefaultNotificationFilename;
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private String mDefaultAlarmAlertFilename;
+
+    private static class FileEntry {
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        long mRowId;
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        boolean mLastModifiedChanged;
+
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        FileEntry(long rowId, String path, long lastModified, int format) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private MediaInserter mMediaInserter;
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    public MediaScanner(Context c, String volumeName) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private final MyMediaScannerClient mClient = new MyMediaScannerClient();
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private boolean isDrmEnabled() {
+        throw new UnsupportedOperationException();
+    }
+
+    private class MyMediaScannerClient implements MediaScannerClient {
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        private String mMimeType;
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        private int mFileType;
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        private String mPath;
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        private boolean mIsDrm;
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        private boolean mNoMedia;
+
+        public MyMediaScannerClient() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        public FileEntry beginFile(String path, String mimeType, long lastModified,
+                long fileSize, boolean isDirectory, boolean noMedia) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        public void scanFile(String path, long lastModified, long fileSize,
+                boolean isDirectory, boolean noMedia) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        public Uri doScanFile(String path, String mimeType, long lastModified,
+                long fileSize, boolean isDirectory, boolean scanAlways, boolean noMedia) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        public void handleStringTag(String name, String value) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        public void setMimeType(String mimeType) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        private ContentValues toValues() {
+            throw new UnsupportedOperationException();
+        }
+
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        private Uri endFile(FileEntry entry, boolean ringtones, boolean notifications,
+                boolean alarms, boolean podcasts, boolean audiobooks, boolean music)
+                throws RemoteException {
+            throw new UnsupportedOperationException();
+        }
+
+        @Deprecated
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+        private int getFileTypeFromDrm(String path) {
+            throw new UnsupportedOperationException();
+        }
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private void prescan(String filePath, boolean prescanFiles) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private void postscan(final String[] directories) throws RemoteException {
+        throw new UnsupportedOperationException();
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    public Uri scanSingleFile(String path, String mimeType) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    public static boolean isNoMediaPath(String path) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    FileEntry makeEntryFor(String path) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.Q, publicAlternatives = "All scanning requests should be performed through {@link android.media.MediaScannerConnection}")
+    private void setLocale(String locale) {
+        throw new UnsupportedOperationException();
+    }
+
+    @Override
+    public void close() {
+        throw new UnsupportedOperationException();
+    }
+}
diff --git a/android/media/MediaScannerClient.java b/android/media/MediaScannerClient.java
new file mode 100644
index 0000000..b326671
--- /dev/null
+++ b/android/media/MediaScannerClient.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2007 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;
+
+/**
+ * {@hide}
+ */
+public interface MediaScannerClient
+{    
+    public void scanFile(String path, long lastModified, long fileSize,
+            boolean isDirectory, boolean noMedia);
+
+    /**
+     * Called by native code to return metadata extracted from media files.
+     */
+    public void handleStringTag(String name, String value);
+
+    /**
+     * Called by native code to return mime type extracted from DRM content.
+     */
+    public void setMimeType(String mimeType);
+}
diff --git a/android/media/MediaScannerConnection.java b/android/media/MediaScannerConnection.java
new file mode 100644
index 0000000..2bffe8a
--- /dev/null
+++ b/android/media/MediaScannerConnection.java
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2008 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.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
+import android.content.ContentProviderClient;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.ServiceConnection;
+import android.net.Uri;
+import android.os.Build;
+import android.os.IBinder;
+import android.provider.MediaStore;
+import android.util.Log;
+
+import com.android.internal.os.BackgroundThread;
+
+import java.io.File;
+
+/**
+ * MediaScannerConnection provides a way for applications to pass a
+ * newly created or downloaded media file to the media scanner service.
+ * The media scanner service will read metadata from the file and add
+ * the file to the media content provider.
+ * The MediaScannerConnectionClient provides an interface for the
+ * media scanner service to return the Uri for a newly scanned file
+ * to the client of the MediaScannerConnection class.
+ */
+public class MediaScannerConnection implements ServiceConnection {
+    private static final String TAG = "MediaScannerConnection";
+
+    private final Context mContext;
+    private final MediaScannerConnectionClient mClient;
+
+    private ContentProviderClient mProvider;
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
+    private IMediaScannerService mService;
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
+    private boolean mConnected;
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
+    private final IMediaScannerListener.Stub mListener = new IMediaScannerListener.Stub() {
+        @Override
+        public void scanCompleted(String path, Uri uri) {
+        }
+    };
+
+    /**
+     * Interface for notifying clients of the result of scanning a
+     * requested media file.
+     */
+    public interface OnScanCompletedListener {
+        /**
+         * Called to notify the client when the media scanner has finished
+         * scanning a file.
+         * @param path the path to the file that has been scanned.
+         * @param uri the Uri for the file if the scanning operation succeeded
+         * and the file was added to the media database, or null if scanning failed.
+         */
+        public void onScanCompleted(String path, Uri uri);
+    }
+
+    /**
+     * An interface for notifying clients of MediaScannerConnection
+     * when a connection to the MediaScanner service has been established
+     * and when the scanning of a file has completed.
+     */
+    public interface MediaScannerConnectionClient extends OnScanCompletedListener {
+        /**
+         * Called to notify the client when a connection to the
+         * MediaScanner service has been established.
+         */
+        public void onMediaScannerConnected();
+    }
+
+    /**
+     * Constructs a new MediaScannerConnection object.
+     * @param context the Context object, required for establishing a connection to
+     * the media scanner service.
+     * @param client an optional object implementing the MediaScannerConnectionClient
+     * interface, for receiving notifications from the media scanner.
+     */
+    public MediaScannerConnection(Context context, MediaScannerConnectionClient client) {
+        mContext = context;
+        mClient = client;
+    }
+
+    /**
+     * Initiates a connection to the media scanner service.
+     * {@link MediaScannerConnectionClient#onMediaScannerConnected()}
+     * will be called when the connection is established.
+     */
+    public void connect() {
+        synchronized (this) {
+            if (mProvider == null) {
+                mProvider = mContext.getContentResolver()
+                        .acquireContentProviderClient(MediaStore.AUTHORITY);
+                if (mClient != null) {
+                    mClient.onMediaScannerConnected();
+                }
+            }
+        }
+    }
+
+    /**
+     * Releases the connection to the media scanner service.
+     */
+    public void disconnect() {
+        synchronized (this) {
+            if (mProvider != null) {
+                mProvider.close();
+                mProvider = null;
+            }
+        }
+    }
+
+    /**
+     * Returns whether we are connected to the media scanner service
+     * @return true if we are connected, false otherwise
+     */
+    public synchronized boolean isConnected() {
+        return (mProvider != null);
+    }
+
+    /**
+     * Requests the media scanner to scan a file.
+     * Success or failure of the scanning operation cannot be determined until
+     * {@link MediaScannerConnectionClient#onScanCompleted(String, Uri)} is called.
+     *
+     * @param path the path to the file to be scanned.
+     * @param mimeType  an optional mimeType for the file.
+     * If mimeType is null, then the mimeType will be inferred from the file extension.
+     */
+     public void scanFile(String path, String mimeType) {
+        synchronized (this) {
+            if (mProvider == null) {
+                throw new IllegalStateException("not connected to MediaScannerService");
+            }
+            BackgroundThread.getExecutor().execute(() -> {
+                final Uri uri = scanFileQuietly(mProvider, new File(path));
+                runCallBack(mContext, mClient, path, uri);
+            });
+        }
+    }
+
+    /**
+     * Convenience for constructing a {@link MediaScannerConnection}, calling
+     * {@link #connect} on it, and calling {@link #scanFile(String, String)} with the given
+     * <var>path</var> and <var>mimeType</var> when the connection is
+     * established.
+     * @param context The caller's Context, required for establishing a connection to
+     * the media scanner service.
+     * Success or failure of the scanning operation cannot be determined until
+     * {@link MediaScannerConnectionClient#onScanCompleted(String, Uri)} is called.
+     * @param paths Array of paths to be scanned.
+     * @param mimeTypes Optional array of MIME types for each path.
+     * If mimeType is null, then the mimeType will be inferred from the file extension.
+     * @param callback Optional callback through which you can receive the
+     * scanned URI and MIME type; If null, the file will be scanned but
+     * you will not get a result back.
+     * @see #scanFile(String, String)
+     */
+    public static void scanFile(Context context, String[] paths, String[] mimeTypes,
+            OnScanCompletedListener callback) {
+        BackgroundThread.getExecutor().execute(() -> {
+            try (ContentProviderClient client = context.getContentResolver()
+                    .acquireContentProviderClient(MediaStore.AUTHORITY)) {
+                for (String path : paths) {
+                    final Uri uri = scanFileQuietly(client, new File(path));
+                    runCallBack(context, callback, path, uri);
+                }
+            }
+        });
+    }
+
+    private static Uri scanFileQuietly(ContentProviderClient client, File file) {
+        Uri uri = null;
+        try {
+            uri = MediaStore.scanFile(ContentResolver.wrap(client), file.getCanonicalFile());
+            Log.d(TAG, "Scanned " + file + " to " + uri);
+        } catch (Exception e) {
+            Log.w(TAG, "Failed to scan " + file + ": " + e);
+        }
+        return uri;
+    }
+
+    private static void runCallBack(Context context, OnScanCompletedListener callback,
+            String path, Uri uri) {
+        if (callback != null) {
+            // Ignore exceptions from callback to avoid calling app from crashing.
+            // Don't ignore exceptions for apps targeting 'R' or higher.
+            try {
+                callback.onScanCompleted(path, uri);
+            } catch (Throwable e) {
+                if (context.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) {
+                    throw e;
+                } else {
+                    Log.w(TAG, "Ignoring exception from callback for backward compatibility", e);
+                }
+            }
+        }
+    }
+
+    @Deprecated
+    static class ClientProxy implements MediaScannerConnectionClient {
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
+        final String[] mPaths;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
+        final String[] mMimeTypes;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
+        final OnScanCompletedListener mClient;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
+        MediaScannerConnection mConnection;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
+        int mNextPath;
+
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
+        ClientProxy(String[] paths, String[] mimeTypes, OnScanCompletedListener client) {
+            mPaths = paths;
+            mMimeTypes = mimeTypes;
+            mClient = client;
+        }
+
+        @Override
+        public void onMediaScannerConnected() {
+        }
+
+        @Override
+        public void onScanCompleted(String path, Uri uri) {
+        }
+
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.O)
+        void scanNextPath() {
+        }
+    }
+
+    /**
+     * Part of the ServiceConnection interface.  Do not call.
+     */
+    @Override
+    public void onServiceConnected(ComponentName className, IBinder service) {
+        // No longer needed
+    }
+
+    /**
+     * Part of the ServiceConnection interface.  Do not call.
+     */
+    @Override
+    public void onServiceDisconnected(ComponentName className) {
+        // No longer needed
+    }
+}
diff --git a/android/media/MediaServiceManager.java b/android/media/MediaServiceManager.java
new file mode 100644
index 0000000..fd89c0c
--- /dev/null
+++ b/android/media/MediaServiceManager.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2020 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.SystemApi.Client;
+import android.os.IBinder;
+import android.os.ServiceManager;
+
+/**
+ * Provides a way to register and obtain the system service binder objects managed by the media
+ * service.
+ *
+ * <p> Only the media mainline module will be able to access an instance of this class.
+ * @hide
+ */
+@SystemApi(client = Client.MODULE_LIBRARIES)
+public class MediaServiceManager {
+    private static final String MEDIA_SESSION_SERVICE = "media_session";
+    private static final String MEDIA_TRANSCODING_SERVICE = "media.transcoding";
+    private static final String MEDIA_COMMUNICATION_SERVICE = "media_communication";
+
+    /**
+     * @hide
+     */
+    public MediaServiceManager() {}
+
+    /**
+     * A class that exposes the methods to register and obtain each system service.
+     */
+    public static final class ServiceRegisterer {
+        private final String mServiceName;
+        private final boolean mLazyStart;
+
+        /**
+         * @hide
+         */
+        public ServiceRegisterer(String serviceName, boolean lazyStart) {
+            mServiceName = serviceName;
+            mLazyStart = lazyStart;
+        }
+
+        /**
+         * @hide
+         */
+        public ServiceRegisterer(String serviceName) {
+            this(serviceName, false /*lazyStart*/);
+        }
+
+        /**
+         * Get the system server binding object for MediaServiceManager.
+         *
+         * <p> This blocks until the service instance is ready.
+         * or a timeout happens, in which case it returns null.
+         */
+        @Nullable
+        public IBinder get() {
+            if (mLazyStart) {
+                return ServiceManager.waitForService(mServiceName);
+            }
+            return ServiceManager.getService(mServiceName);
+        }
+    }
+
+    /**
+     * Returns {@link ServiceRegisterer} for MEDIA_SESSION_SERVICE.
+     */
+    @NonNull
+    public ServiceRegisterer getMediaSessionServiceRegisterer() {
+        return new ServiceRegisterer(MEDIA_SESSION_SERVICE);
+    }
+
+    /**
+     * Returns {@link ServiceRegisterer} for MEDIA_TRANSCODING_SERVICE.
+     */
+    @NonNull
+    public ServiceRegisterer getMediaTranscodingServiceRegisterer() {
+        return new ServiceRegisterer(MEDIA_TRANSCODING_SERVICE, true /*lazyStart*/);
+    }
+
+    /**
+     * Returns {@link ServiceRegisterer} for MEDIA_COMMUNICATION_SERVICE.
+     */
+    @NonNull
+    public ServiceRegisterer getMediaCommunicationServiceRegisterer() {
+        return new ServiceRegisterer(MEDIA_COMMUNICATION_SERVICE);
+    }
+}
diff --git a/android/media/MediaSession2.java b/android/media/MediaSession2.java
new file mode 100644
index 0000000..e76d61c
--- /dev/null
+++ b/android/media/MediaSession2.java
@@ -0,0 +1,931 @@
+/*
+ * 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.MediaConstants.KEY_ALLOWED_COMMANDS;
+import static android.media.MediaConstants.KEY_CONNECTION_HINTS;
+import static android.media.MediaConstants.KEY_PACKAGE_NAME;
+import static android.media.MediaConstants.KEY_PID;
+import static android.media.MediaConstants.KEY_PLAYBACK_ACTIVE;
+import static android.media.MediaConstants.KEY_SESSION2LINK;
+import static android.media.MediaConstants.KEY_TOKEN_EXTRAS;
+import static android.media.Session2Command.Result.RESULT_ERROR_UNKNOWN_ERROR;
+import static android.media.Session2Command.Result.RESULT_INFO_SKIPPED;
+import static android.media.Session2Token.TYPE_SESSION;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.media.session.MediaSessionManager;
+import android.media.session.MediaSessionManager.RemoteUserInfo;
+import android.os.BadParcelableException;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Parcel;
+import android.os.Process;
+import android.os.ResultReceiver;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.Log;
+
+import com.android.modules.utils.build.SdkLevel;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * This API is not generally intended for third party application developers.
+ * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+ * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+ * Library</a> for consistent behavior across all devices.
+ * <p>
+ * Allows a media app to expose its transport controls and playback information in a process to
+ * other processes including the Android framework and other apps.
+ */
+public class MediaSession2 implements AutoCloseable {
+    static final String TAG = "MediaSession2";
+    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    // Note: This checks the uniqueness of a session ID only in a single process.
+    // When the framework becomes able to check the uniqueness, this logic should be removed.
+    //@GuardedBy("MediaSession.class")
+    private static final List<String> SESSION_ID_LIST = new ArrayList<>();
+
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final Object mLock = new Object();
+    //@GuardedBy("mLock")
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final Map<Controller2Link, ControllerInfo> mConnectedControllers = new HashMap<>();
+
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final Context mContext;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final Executor mCallbackExecutor;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final SessionCallback mCallback;
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    final Session2Link mSessionStub;
+
+    private final String mSessionId;
+    private final PendingIntent mSessionActivity;
+    private final Session2Token mSessionToken;
+    private final MediaSessionManager mMediaSessionManager;
+    private final MediaCommunicationManager mCommunicationManager;
+    private final Handler mResultHandler;
+
+    //@GuardedBy("mLock")
+    private boolean mClosed;
+    //@GuardedBy("mLock")
+    private boolean mPlaybackActive;
+    //@GuardedBy("mLock")
+    private ForegroundServiceEventCallback mForegroundServiceEventCallback;
+
+    MediaSession2(@NonNull Context context, @NonNull String id, PendingIntent sessionActivity,
+            @NonNull Executor callbackExecutor, @NonNull SessionCallback callback,
+            @NonNull Bundle tokenExtras) {
+        synchronized (MediaSession2.class) {
+            if (SESSION_ID_LIST.contains(id)) {
+                throw new IllegalStateException("Session ID must be unique. ID=" + id);
+            }
+            SESSION_ID_LIST.add(id);
+        }
+
+        mContext = context;
+        mSessionId = id;
+        mSessionActivity = sessionActivity;
+        mCallbackExecutor = callbackExecutor;
+        mCallback = callback;
+        mSessionStub = new Session2Link(this);
+        mSessionToken = new Session2Token(Process.myUid(), TYPE_SESSION, context.getPackageName(),
+                mSessionStub, tokenExtras);
+        if (SdkLevel.isAtLeastS()) {
+            mCommunicationManager = mContext.getSystemService(MediaCommunicationManager.class);
+            mMediaSessionManager = null;
+        } else {
+            mMediaSessionManager = mContext.getSystemService(MediaSessionManager.class);
+            mCommunicationManager = null;
+        }
+        // NOTE: mResultHandler uses main looper, so this MUST NOT be blocked.
+        mResultHandler = new Handler(context.getMainLooper());
+        mClosed = false;
+    }
+
+    @Override
+    public void close() {
+        try {
+            List<ControllerInfo> controllerInfos;
+            ForegroundServiceEventCallback callback;
+            synchronized (mLock) {
+                if (mClosed) {
+                    return;
+                }
+                mClosed = true;
+                controllerInfos = getConnectedControllers();
+                mConnectedControllers.clear();
+                callback = mForegroundServiceEventCallback;
+                mForegroundServiceEventCallback = null;
+            }
+            synchronized (MediaSession2.class) {
+                SESSION_ID_LIST.remove(mSessionId);
+            }
+            if (callback != null) {
+                callback.onSessionClosed(this);
+            }
+            for (ControllerInfo info : controllerInfos) {
+                info.notifyDisconnected();
+            }
+        } catch (Exception e) {
+            // Should not be here.
+        }
+    }
+
+    /**
+     * Returns the session ID
+     */
+    @NonNull
+    public String getId() {
+        return mSessionId;
+    }
+
+    /**
+     * Returns the {@link Session2Token} for creating {@link MediaController2}.
+     */
+    @NonNull
+    public Session2Token getToken() {
+        return mSessionToken;
+    }
+
+    /**
+     * Broadcasts a session command to all the connected controllers
+     * <p>
+     * @param command the session command
+     * @param args optional arguments
+     */
+    public void broadcastSessionCommand(@NonNull Session2Command command, @Nullable Bundle args) {
+        if (command == null) {
+            throw new IllegalArgumentException("command shouldn't be null");
+        }
+        List<ControllerInfo> controllerInfos = getConnectedControllers();
+        for (ControllerInfo controller : controllerInfos) {
+            controller.sendSessionCommand(command, args, null);
+        }
+    }
+
+    /**
+     * Sends a session command to a specific controller
+     * <p>
+     * @param controller the controller to get the session command
+     * @param command the session command
+     * @param args optional arguments
+     * @return a token which will be sent together in {@link SessionCallback#onCommandResult}
+     *     when its result is received.
+     */
+    @NonNull
+    public Object sendSessionCommand(@NonNull ControllerInfo controller,
+            @NonNull Session2Command command, @Nullable Bundle args) {
+        if (controller == null) {
+            throw new IllegalArgumentException("controller shouldn't be null");
+        }
+        if (command == null) {
+            throw new IllegalArgumentException("command shouldn't be null");
+        }
+        ResultReceiver resultReceiver = new ResultReceiver(mResultHandler) {
+            protected void onReceiveResult(int resultCode, Bundle resultData) {
+                controller.receiveCommandResult(this);
+                mCallbackExecutor.execute(() -> {
+                    mCallback.onCommandResult(MediaSession2.this, controller, this,
+                            command, new Session2Command.Result(resultCode, resultData));
+                });
+            }
+        };
+        controller.sendSessionCommand(command, args, resultReceiver);
+        return resultReceiver;
+    }
+
+    /**
+     * Cancels the session command previously sent.
+     *
+     * @param controller the controller to get the session command
+     * @param token the token which is returned from {@link #sendSessionCommand}.
+     */
+    public void cancelSessionCommand(@NonNull ControllerInfo controller, @NonNull Object token) {
+        if (controller == null) {
+            throw new IllegalArgumentException("controller shouldn't be null");
+        }
+        if (token == null) {
+            throw new IllegalArgumentException("token shouldn't be null");
+        }
+        controller.cancelSessionCommand(token);
+    }
+
+    /**
+     * Sets whether the playback is active (i.e. playing something)
+     *
+     * @param playbackActive {@code true} if the playback active, {@code false} otherwise.
+     **/
+    public void setPlaybackActive(boolean playbackActive) {
+        final ForegroundServiceEventCallback serviceCallback;
+        synchronized (mLock) {
+            if (mPlaybackActive == playbackActive) {
+                return;
+            }
+            mPlaybackActive = playbackActive;
+            serviceCallback = mForegroundServiceEventCallback;
+        }
+        if (serviceCallback != null) {
+            serviceCallback.onPlaybackActiveChanged(this, playbackActive);
+        }
+        List<ControllerInfo> controllerInfos = getConnectedControllers();
+        for (ControllerInfo controller : controllerInfos) {
+            controller.notifyPlaybackActiveChanged(playbackActive);
+        }
+    }
+
+    /**
+     * Returns whehther the playback is active (i.e. playing something)
+     *
+     * @return {@code true} if the playback active, {@code false} otherwise.
+     */
+    public boolean isPlaybackActive() {
+        synchronized (mLock) {
+            return mPlaybackActive;
+        }
+    }
+
+    /**
+     * Gets the list of the connected controllers
+     *
+     * @return list of the connected controllers.
+     */
+    @NonNull
+    public List<ControllerInfo> getConnectedControllers() {
+        List<ControllerInfo> controllers = new ArrayList<>();
+        synchronized (mLock) {
+            controllers.addAll(mConnectedControllers.values());
+        }
+        return controllers;
+    }
+
+    /**
+     * Returns whether the given bundle includes non-framework Parcelables.
+     */
+    static boolean hasCustomParcelable(@Nullable Bundle bundle) {
+        if (bundle == null) {
+            return false;
+        }
+
+        // Try writing the bundle to parcel, and read it with framework classloader.
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            parcel.writeBundle(bundle);
+            parcel.setDataPosition(0);
+            Bundle out = parcel.readBundle(null);
+
+            // Calling Bundle#size() will trigger Bundle#unparcel().
+            out.size();
+        } catch (BadParcelableException e) {
+            Log.d(TAG, "Custom parcelable in bundle.", e);
+            return true;
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+            }
+        }
+        return false;
+    }
+
+    boolean isClosed() {
+        synchronized (mLock) {
+            return mClosed;
+        }
+    }
+
+    SessionCallback getCallback() {
+        return mCallback;
+    }
+
+    boolean isTrustedForMediaControl(RemoteUserInfo remoteUserInfo) {
+        if (SdkLevel.isAtLeastS()) {
+            return mCommunicationManager.isTrustedForMediaControl(remoteUserInfo);
+        } else {
+            return mMediaSessionManager.isTrustedForMediaControl(remoteUserInfo);
+        }
+    }
+
+    void setForegroundServiceEventCallback(ForegroundServiceEventCallback callback) {
+        synchronized (mLock) {
+            if (mForegroundServiceEventCallback == callback) {
+                return;
+            }
+            if (mForegroundServiceEventCallback != null && callback != null) {
+                throw new IllegalStateException("A session cannot be added to multiple services");
+            }
+            mForegroundServiceEventCallback = callback;
+        }
+    }
+
+    // Called by Session2Link.onConnect and MediaSession2Service.MediaSession2ServiceStub.connect
+    void onConnect(final Controller2Link controller, int callingPid, int callingUid, int seq,
+            Bundle connectionRequest) {
+        if (callingPid == 0) {
+            // The pid here is from Binder.getCallingPid(), which can be 0 for an oneway call from
+            // the remote process. If it's the case, use PID from the connectionRequest.
+            callingPid = connectionRequest.getInt(KEY_PID);
+        }
+        String callingPkg = connectionRequest.getString(KEY_PACKAGE_NAME);
+
+        RemoteUserInfo remoteUserInfo = new RemoteUserInfo(callingPkg, callingPid, callingUid);
+
+        Bundle connectionHints = connectionRequest.getBundle(KEY_CONNECTION_HINTS);
+        if (connectionHints == null) {
+            Log.w(TAG, "connectionHints shouldn't be null.");
+            connectionHints = Bundle.EMPTY;
+        } else if (hasCustomParcelable(connectionHints)) {
+            Log.w(TAG, "connectionHints contain custom parcelable. Ignoring.");
+            connectionHints = Bundle.EMPTY;
+        }
+
+        final ControllerInfo controllerInfo = new ControllerInfo(
+                remoteUserInfo,
+                isTrustedForMediaControl(remoteUserInfo),
+                controller,
+                connectionHints);
+        mCallbackExecutor.execute(() -> {
+            boolean connected = false;
+            try {
+                if (isClosed()) {
+                    return;
+                }
+                controllerInfo.mAllowedCommands =
+                        mCallback.onConnect(MediaSession2.this, controllerInfo);
+                // Don't reject connection for the request from trusted app.
+                // Otherwise server will fail to retrieve session's information to dispatch
+                // media keys to.
+                if (controllerInfo.mAllowedCommands == null && !controllerInfo.isTrusted()) {
+                    return;
+                }
+                if (controllerInfo.mAllowedCommands == null) {
+                    // For trusted apps, send non-null allowed commands to keep
+                    // connection.
+                    controllerInfo.mAllowedCommands =
+                            new Session2CommandGroup.Builder().build();
+                }
+                if (DEBUG) {
+                    Log.d(TAG, "Accepting connection: " + controllerInfo);
+                }
+                // If connection is accepted, notify the current state to the controller.
+                // It's needed because we cannot call synchronous calls between
+                // session/controller.
+                Bundle connectionResult = new Bundle();
+                connectionResult.putParcelable(KEY_SESSION2LINK, mSessionStub);
+                connectionResult.putParcelable(KEY_ALLOWED_COMMANDS,
+                        controllerInfo.mAllowedCommands);
+                connectionResult.putBoolean(KEY_PLAYBACK_ACTIVE, isPlaybackActive());
+                connectionResult.putBundle(KEY_TOKEN_EXTRAS, mSessionToken.getExtras());
+
+                // Double check if session is still there, because close() can be called in
+                // another thread.
+                if (isClosed()) {
+                    return;
+                }
+                controllerInfo.notifyConnected(connectionResult);
+                synchronized (mLock) {
+                    if (mConnectedControllers.containsKey(controller)) {
+                        Log.w(TAG, "Controller " + controllerInfo + " has sent connection"
+                                + " request multiple times");
+                    }
+                    mConnectedControllers.put(controller, controllerInfo);
+                }
+                mCallback.onPostConnect(MediaSession2.this, controllerInfo);
+                connected = true;
+            } finally {
+                if (!connected || isClosed()) {
+                    if (DEBUG) {
+                        Log.d(TAG, "Rejecting connection or notifying that session is closed"
+                                + ", controllerInfo=" + controllerInfo);
+                    }
+                    synchronized (mLock) {
+                        mConnectedControllers.remove(controller);
+                    }
+                    controllerInfo.notifyDisconnected();
+                }
+            }
+        });
+    }
+
+    // Called by Session2Link.onDisconnect
+    void onDisconnect(@NonNull final Controller2Link controller, int seq) {
+        final ControllerInfo controllerInfo;
+        synchronized (mLock) {
+            controllerInfo = mConnectedControllers.remove(controller);
+        }
+        if (controllerInfo == null) {
+            return;
+        }
+        mCallbackExecutor.execute(() -> {
+            mCallback.onDisconnected(MediaSession2.this, controllerInfo);
+        });
+    }
+
+    // Called by Session2Link.onSessionCommand
+    void onSessionCommand(@NonNull final Controller2Link controller, final int seq,
+            final Session2Command command, final Bundle args,
+            @Nullable ResultReceiver resultReceiver) {
+        if (controller == null) {
+            return;
+        }
+        final ControllerInfo controllerInfo;
+        synchronized (mLock) {
+            controllerInfo = mConnectedControllers.get(controller);
+        }
+        if (controllerInfo == null) {
+            return;
+        }
+
+        // TODO: check allowed commands.
+        synchronized (mLock) {
+            controllerInfo.addRequestedCommandSeqNumber(seq);
+        }
+        mCallbackExecutor.execute(() -> {
+            if (!controllerInfo.removeRequestedCommandSeqNumber(seq)) {
+                if (resultReceiver != null) {
+                    resultReceiver.send(RESULT_INFO_SKIPPED, null);
+                }
+                return;
+            }
+            Session2Command.Result result = mCallback.onSessionCommand(
+                    MediaSession2.this, controllerInfo, command, args);
+            if (resultReceiver != null) {
+                if (result == null) {
+                    resultReceiver.send(RESULT_INFO_SKIPPED, null);
+                } else {
+                    resultReceiver.send(result.getResultCode(), result.getResultData());
+                }
+            }
+        });
+    }
+
+    // Called by Session2Link.onCancelCommand
+    void onCancelCommand(@NonNull final Controller2Link controller, final int seq) {
+        final ControllerInfo controllerInfo;
+        synchronized (mLock) {
+            controllerInfo = mConnectedControllers.get(controller);
+        }
+        if (controllerInfo == null) {
+            return;
+        }
+        controllerInfo.removeRequestedCommandSeqNumber(seq);
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Builder for {@link MediaSession2}.
+     * <p>
+     * Any incoming event from the {@link MediaController2} will be handled on the callback
+     * executor. If it's not set, {@link Context#getMainExecutor()} will be used by default.
+     */
+    public static final class Builder {
+        private Context mContext;
+        private String mId;
+        private PendingIntent mSessionActivity;
+        private Executor mCallbackExecutor;
+        private SessionCallback mCallback;
+        private Bundle mExtras;
+
+        /**
+         * Creates a builder for {@link MediaSession2}.
+         *
+         * @param context Context
+         * @throws IllegalArgumentException if context is {@code null}.
+         */
+        public Builder(@NonNull Context context) {
+            if (context == null) {
+                throw new IllegalArgumentException("context shouldn't be null");
+            }
+            mContext = context;
+        }
+
+        /**
+         * Set an intent for launching UI for this Session. This can be used as a
+         * quick link to an ongoing media screen. The intent should be for an
+         * activity that may be started using {@link Context#startActivity(Intent)}.
+         *
+         * @param pi The intent to launch to show UI for this session.
+         * @return The Builder to allow chaining
+         */
+        @NonNull
+        public Builder setSessionActivity(@Nullable PendingIntent pi) {
+            mSessionActivity = pi;
+            return this;
+        }
+
+        /**
+         * Set ID of the session. If it's not set, an empty string will be used to create a session.
+         * <p>
+         * Use this if and only if your app supports multiple playback at the same time and also
+         * wants to provide external apps to have finer controls of them.
+         *
+         * @param id id of the session. Must be unique per package.
+         * @throws IllegalArgumentException if id is {@code null}.
+         * @return The Builder to allow chaining
+         */
+        @NonNull
+        public Builder setId(@NonNull String id) {
+            if (id == null) {
+                throw new IllegalArgumentException("id shouldn't be null");
+            }
+            mId = id;
+            return this;
+        }
+
+        /**
+         * Set callback for the session and its executor.
+         *
+         * @param executor callback executor
+         * @param callback session callback.
+         * @return The Builder to allow chaining
+         */
+        @NonNull
+        public Builder setSessionCallback(@NonNull Executor executor,
+                @NonNull SessionCallback callback) {
+            mCallbackExecutor = executor;
+            mCallback = callback;
+            return this;
+        }
+
+        /**
+         * Set extras for the session token. If null or not set, {@link Session2Token#getExtras()}
+         * will return an empty {@link Bundle}. An {@link IllegalArgumentException} will be thrown
+         * if the bundle contains any non-framework Parcelable objects.
+         *
+         * @return The Builder to allow chaining
+         * @see Session2Token#getExtras()
+         */
+        @NonNull
+        public Builder setExtras(@NonNull Bundle extras) {
+            if (extras == null) {
+                throw new NullPointerException("extras shouldn't be null");
+            }
+            if (hasCustomParcelable(extras)) {
+                throw new IllegalArgumentException(
+                        "extras shouldn't contain any custom parcelables");
+            }
+            mExtras = new Bundle(extras);
+            return this;
+        }
+
+        /**
+         * Build {@link MediaSession2}.
+         *
+         * @return a new session
+         * @throws IllegalStateException if the session with the same id is already exists for the
+         *      package.
+         */
+        @NonNull
+        public MediaSession2 build() {
+            if (mCallbackExecutor == null) {
+                mCallbackExecutor = mContext.getMainExecutor();
+            }
+            if (mCallback == null) {
+                mCallback = new SessionCallback() {};
+            }
+            if (mId == null) {
+                mId = "";
+            }
+            if (mExtras == null) {
+                mExtras = Bundle.EMPTY;
+            }
+            MediaSession2 session2 = new MediaSession2(mContext, mId, mSessionActivity,
+                    mCallbackExecutor, mCallback, mExtras);
+
+            // Notify framework about the newly create session after the constructor is finished.
+            // Otherwise, framework may access the session before the initialization is finished.
+            try {
+                if (SdkLevel.isAtLeastS()) {
+                    MediaCommunicationManager manager =
+                            mContext.getSystemService(MediaCommunicationManager.class);
+                    manager.notifySession2Created(session2.getToken());
+                } else {
+                    MediaSessionManager manager =
+                            mContext.getSystemService(MediaSessionManager.class);
+                    manager.notifySession2Created(session2.getToken());
+                }
+            } catch (Exception e) {
+                session2.close();
+                throw e;
+            }
+
+            return session2;
+        }
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Information of a controller.
+     */
+    public static final class ControllerInfo {
+        private final RemoteUserInfo mRemoteUserInfo;
+        private final boolean mIsTrusted;
+        private final Controller2Link mControllerBinder;
+        private final Bundle mConnectionHints;
+        private final Object mLock = new Object();
+        //@GuardedBy("mLock")
+        private int mNextSeqNumber;
+        //@GuardedBy("mLock")
+        private ArrayMap<ResultReceiver, Integer> mPendingCommands;
+        //@GuardedBy("mLock")
+        private ArraySet<Integer> mRequestedCommandSeqNumbers;
+
+        @SuppressWarnings("WeakerAccess") /* synthetic access */
+        Session2CommandGroup mAllowedCommands;
+
+        /**
+         * @param remoteUserInfo remote user info
+         * @param trusted {@code true} if trusted, {@code false} otherwise
+         * @param controllerBinder Controller2Link for the connected controller.
+         * @param connectionHints a session-specific argument sent from the controller for the
+         *                        connection. The contents of this bundle may affect the
+         *                        connection result.
+         */
+        ControllerInfo(@NonNull RemoteUserInfo remoteUserInfo, boolean trusted,
+                @Nullable Controller2Link controllerBinder, @NonNull Bundle connectionHints) {
+            mRemoteUserInfo = remoteUserInfo;
+            mIsTrusted = trusted;
+            mControllerBinder = controllerBinder;
+            mConnectionHints = connectionHints;
+            mPendingCommands = new ArrayMap<>();
+            mRequestedCommandSeqNumbers = new ArraySet<>();
+        }
+
+        /**
+         * @return remote user info of the controller.
+         */
+        @NonNull
+        public RemoteUserInfo getRemoteUserInfo() {
+            return mRemoteUserInfo;
+        }
+
+        /**
+         * @return package name of the controller.
+         */
+        @NonNull
+        public String getPackageName() {
+            return mRemoteUserInfo.getPackageName();
+        }
+
+        /**
+         * @return uid of the controller. Can be a negative value if the uid cannot be obtained.
+         */
+        public int getUid() {
+            return mRemoteUserInfo.getUid();
+        }
+
+        /**
+         * @return connection hints sent from controller.
+         */
+        @NonNull
+        public Bundle getConnectionHints() {
+            return new Bundle(mConnectionHints);
+        }
+
+        /**
+         * Return if the controller has granted {@code android.permission.MEDIA_CONTENT_CONTROL} or
+         * has a enabled notification listener so can be trusted to accept connection and incoming
+         * command request.
+         *
+         * @return {@code true} if the controller is trusted.
+         * @hide
+         */
+        public boolean isTrusted() {
+            return mIsTrusted;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mControllerBinder, mRemoteUserInfo);
+        }
+
+        @Override
+        public boolean equals(@Nullable Object obj) {
+            if (!(obj instanceof ControllerInfo)) return false;
+            if (this == obj) return true;
+
+            ControllerInfo other = (ControllerInfo) obj;
+            if (mControllerBinder != null || other.mControllerBinder != null) {
+                return Objects.equals(mControllerBinder, other.mControllerBinder);
+            }
+            return mRemoteUserInfo.equals(other.mRemoteUserInfo);
+        }
+
+        @Override
+        @NonNull
+        public String toString() {
+            return "ControllerInfo {pkg=" + mRemoteUserInfo.getPackageName() + ", uid="
+                    + mRemoteUserInfo.getUid() + ", allowedCommands=" + mAllowedCommands + "})";
+        }
+
+        void notifyConnected(Bundle connectionResult) {
+            if (mControllerBinder == null) return;
+
+            try {
+                mControllerBinder.notifyConnected(getNextSeqNumber(), connectionResult);
+            } catch (RuntimeException e) {
+                // Controller may be died prematurely.
+            }
+        }
+
+        void notifyDisconnected() {
+            if (mControllerBinder == null) return;
+
+            try {
+                mControllerBinder.notifyDisconnected(getNextSeqNumber());
+            } catch (RuntimeException e) {
+                // Controller may be died prematurely.
+            }
+        }
+
+        void notifyPlaybackActiveChanged(boolean playbackActive) {
+            if (mControllerBinder == null) return;
+
+            try {
+                mControllerBinder.notifyPlaybackActiveChanged(getNextSeqNumber(), playbackActive);
+            } catch (RuntimeException e) {
+                // Controller may be died prematurely.
+            }
+        }
+
+        void sendSessionCommand(Session2Command command, Bundle args,
+                ResultReceiver resultReceiver) {
+            if (mControllerBinder == null) return;
+
+            try {
+                int seq = getNextSeqNumber();
+                synchronized (mLock) {
+                    mPendingCommands.put(resultReceiver, seq);
+                }
+                mControllerBinder.sendSessionCommand(seq, command, args, resultReceiver);
+            } catch (RuntimeException e) {
+                // Controller may be died prematurely.
+                synchronized (mLock) {
+                    mPendingCommands.remove(resultReceiver);
+                }
+                resultReceiver.send(RESULT_ERROR_UNKNOWN_ERROR, null);
+            }
+        }
+
+        void cancelSessionCommand(@NonNull Object token) {
+            if (mControllerBinder == null) return;
+            Integer seq;
+            synchronized (mLock) {
+                seq = mPendingCommands.remove(token);
+            }
+            if (seq != null) {
+                mControllerBinder.cancelSessionCommand(seq);
+            }
+        }
+
+        void receiveCommandResult(ResultReceiver resultReceiver) {
+            synchronized (mLock) {
+                mPendingCommands.remove(resultReceiver);
+            }
+        }
+
+        void addRequestedCommandSeqNumber(int seq) {
+            synchronized (mLock) {
+                mRequestedCommandSeqNumbers.add(seq);
+            }
+        }
+
+        boolean removeRequestedCommandSeqNumber(int seq) {
+            synchronized (mLock) {
+                return mRequestedCommandSeqNumbers.remove(seq);
+            }
+        }
+
+        private int getNextSeqNumber() {
+            synchronized (mLock) {
+                return mNextSeqNumber++;
+            }
+        }
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Callback to be called for all incoming commands from {@link MediaController2}s.
+     */
+    public abstract static class SessionCallback {
+        /**
+         * Called when a controller is created for this session. Return allowed commands for
+         * controller. By default it returns {@code null}.
+         * <p>
+         * You can reject the connection by returning {@code null}. In that case, controller
+         * receives {@link MediaController2.ControllerCallback#onDisconnected(MediaController2)}
+         * and cannot be used.
+         * <p>
+         * The controller hasn't connected yet in this method, so calls to the controller
+         * (e.g. {@link #sendSessionCommand}) would be ignored. Override {@link #onPostConnect} for
+         * the custom initialization for the controller instead.
+         *
+         * @param session the session for this event
+         * @param controller controller information.
+         * @return allowed commands. Can be {@code null} to reject connection.
+         */
+        @Nullable
+        public Session2CommandGroup onConnect(@NonNull MediaSession2 session,
+                @NonNull ControllerInfo controller) {
+            return null;
+        }
+
+        /**
+         * Called immediately after a controller is connected. This is a convenient method to add
+         * custom initialization between the session and a controller.
+         * <p>
+         * Note that calls to the controller (e.g. {@link #sendSessionCommand}) work here but don't
+         * work in {@link #onConnect} because the controller hasn't connected yet in
+         * {@link #onConnect}.
+         *
+         * @param session the session for this event
+         * @param controller controller information.
+         */
+        public void onPostConnect(@NonNull MediaSession2 session,
+                @NonNull ControllerInfo controller) {
+        }
+
+        /**
+         * Called when a controller is disconnected
+         *
+         * @param session the session for this event
+         * @param controller controller information
+         */
+        public void onDisconnected(@NonNull MediaSession2 session,
+                @NonNull ControllerInfo controller) {}
+
+        /**
+         * Called when a controller sent a session command.
+         *
+         * @param session the session for this event
+         * @param controller controller information
+         * @param command the session command
+         * @param args optional arguments
+         * @return the result for the session command. If {@code null}, RESULT_INFO_SKIPPED
+         *         will be sent to the session.
+         */
+        @Nullable
+        public Session2Command.Result onSessionCommand(@NonNull MediaSession2 session,
+                @NonNull ControllerInfo controller, @NonNull Session2Command command,
+                @Nullable Bundle args) {
+            return null;
+        }
+
+        /**
+         * Called when the command sent to the controller is finished.
+         *
+         * @param session the session for this event
+         * @param controller controller information
+         * @param token the token got from {@link MediaSession2#sendSessionCommand}
+         * @param command the session command
+         * @param result the result of the session command
+         */
+        public void onCommandResult(@NonNull MediaSession2 session,
+                @NonNull ControllerInfo controller, @NonNull Object token,
+                @NonNull Session2Command command, @NonNull Session2Command.Result result) {}
+    }
+
+    abstract static class ForegroundServiceEventCallback {
+        public void onPlaybackActiveChanged(MediaSession2 session, boolean playbackActive) {}
+        public void onSessionClosed(MediaSession2 session) {}
+    }
+}
diff --git a/android/media/MediaSession2Service.java b/android/media/MediaSession2Service.java
new file mode 100644
index 0000000..f6fd509
--- /dev/null
+++ b/android/media/MediaSession2Service.java
@@ -0,0 +1,452 @@
+/*
+ * Copyright 2019 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.MediaConstants.KEY_CONNECTION_HINTS;
+import static android.media.MediaConstants.KEY_PACKAGE_NAME;
+import static android.media.MediaConstants.KEY_PID;
+
+import android.annotation.CallSuper;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.Notification;
+import android.app.NotificationManager;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.media.MediaSession2.ControllerInfo;
+import android.media.session.MediaSessionManager;
+import android.media.session.MediaSessionManager.RemoteUserInfo;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * This API is not generally intended for third party application developers.
+ * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+ * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+ * Library</a> for consistent behavior across all devices.
+ * <p>
+ * Service containing {@link MediaSession2}.
+ */
+public abstract class MediaSession2Service extends Service {
+    /**
+     * The {@link Intent} that must be declared as handled by the service.
+     */
+    public static final String SERVICE_INTERFACE = "android.media.MediaSession2Service";
+
+    private static final String TAG = "MediaSession2Service";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final MediaSession2.ForegroundServiceEventCallback mForegroundServiceEventCallback =
+            new MediaSession2.ForegroundServiceEventCallback() {
+                @Override
+                public void onPlaybackActiveChanged(MediaSession2 session, boolean playbackActive) {
+                    MediaSession2Service.this.onPlaybackActiveChanged(session, playbackActive);
+                }
+
+                @Override
+                public void onSessionClosed(MediaSession2 session) {
+                    removeSession(session);
+                }
+            };
+
+    private final Object mLock = new Object();
+    //@GuardedBy("mLock")
+    private NotificationManager mNotificationManager;
+    //@GuardedBy("mLock")
+    private MediaSessionManager mMediaSessionManager;
+    //@GuardedBy("mLock")
+    private Intent mStartSelfIntent;
+    //@GuardedBy("mLock")
+    private Map<String, MediaSession2> mSessions = new ArrayMap<>();
+    //@GuardedBy("mLock")
+    private Map<MediaSession2, MediaNotification> mNotifications = new ArrayMap<>();
+    //@GuardedBy("mLock")
+    private MediaSession2ServiceStub mStub;
+
+    /**
+     * Called by the system when the service is first created. Do not call this method directly.
+     * <p>
+     * Override this method if you need your own initialization. Derived classes MUST call through
+     * to the super class's implementation of this method.
+     */
+    @CallSuper
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        synchronized (mLock) {
+            mStub = new MediaSession2ServiceStub(this);
+            mStartSelfIntent = new Intent(this, this.getClass());
+            mNotificationManager =
+                    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+            mMediaSessionManager =
+                    (MediaSessionManager) getSystemService(Context.MEDIA_SESSION_SERVICE);
+        }
+    }
+
+    @CallSuper
+    @Override
+    @Nullable
+    public IBinder onBind(@NonNull Intent intent) {
+        if (SERVICE_INTERFACE.equals(intent.getAction())) {
+            synchronized (mLock) {
+                return mStub;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Called by the system to notify that it is no longer used and is being removed. Do not call
+     * this method directly.
+     * <p>
+     * Override this method if you need your own clean up. Derived classes MUST call through
+     * to the super class's implementation of this method.
+     */
+    @CallSuper
+    @Override
+    public void onDestroy() {
+        super.onDestroy();
+        synchronized (mLock) {
+            List<MediaSession2> sessions = getSessions();
+            for (MediaSession2 session : sessions) {
+                removeSession(session);
+            }
+            mSessions.clear();
+            mNotifications.clear();
+        }
+        mStub.close();
+    }
+
+    /**
+     * Called when a {@link MediaController2} is created with the this service's
+     * {@link Session2Token}. Return the session for telling the controller which session to
+     * connect. Return {@code null} to reject the connection from this controller.
+     * <p>
+     * Session returned here will be added to this service automatically. You don't need to call
+     * {@link #addSession(MediaSession2)} for that.
+     * <p>
+     * This method is always called on the main thread.
+     *
+     * @param controllerInfo information of the controller which is trying to connect.
+     * @return a {@link MediaSession2} instance for the controller to connect to, or {@code null}
+     *         to reject connection
+     * @see MediaSession2.Builder
+     * @see #getSessions()
+     */
+    @Nullable
+    public abstract MediaSession2 onGetSession(@NonNull ControllerInfo controllerInfo);
+
+    /**
+     * Called when notification UI needs update. Override this method to show or cancel your own
+     * notification UI.
+     * <p>
+     * This would be called on {@link MediaSession2}'s callback executor when playback state is
+     * changed.
+     * <p>
+     * With the notification returned here, the service becomes foreground service when the playback
+     * is started. Apps must request the permission
+     * {@link android.Manifest.permission#FOREGROUND_SERVICE} in order to use this API. It becomes
+     * background service after the playback is stopped.
+     *
+     * @param session a session that needs notification update.
+     * @return a {@link MediaNotification}. Can be {@code null}.
+     */
+    @Nullable
+    public abstract MediaNotification onUpdateNotification(@NonNull MediaSession2 session);
+
+    /**
+     * Adds a session to this service.
+     * <p>
+     * Added session will be removed automatically when it's closed, or removed when
+     * {@link #removeSession} is called.
+     *
+     * @param session a session to be added.
+     * @see #removeSession(MediaSession2)
+     */
+    public final void addSession(@NonNull MediaSession2 session) {
+        if (session == null) {
+            throw new IllegalArgumentException("session shouldn't be null");
+        }
+        if (session.isClosed()) {
+            throw new IllegalArgumentException("session is already closed");
+        }
+        synchronized (mLock) {
+            MediaSession2 previousSession = mSessions.get(session.getId());
+            if (previousSession != null) {
+                if (previousSession != session) {
+                    Log.w(TAG, "Session ID should be unique, ID=" + session.getId()
+                            + ", previous=" + previousSession + ", session=" + session);
+                }
+                return;
+            }
+            mSessions.put(session.getId(), session);
+            session.setForegroundServiceEventCallback(mForegroundServiceEventCallback);
+        }
+    }
+
+    /**
+     * Removes a session from this service.
+     *
+     * @param session a session to be removed.
+     * @see #addSession(MediaSession2)
+     */
+    public final void removeSession(@NonNull MediaSession2 session) {
+        if (session == null) {
+            throw new IllegalArgumentException("session shouldn't be null");
+        }
+        MediaNotification notification;
+        synchronized (mLock) {
+            if (mSessions.get(session.getId()) != session) {
+                // Session isn't added or removed already.
+                return;
+            }
+            mSessions.remove(session.getId());
+            notification = mNotifications.remove(session);
+        }
+        session.setForegroundServiceEventCallback(null);
+        if (notification != null) {
+            mNotificationManager.cancel(notification.getNotificationId());
+        }
+        if (getSessions().isEmpty()) {
+            stopForeground(false);
+        }
+    }
+
+    /**
+     * Gets the list of {@link MediaSession2}s that you've added to this service.
+     *
+     * @return sessions
+     */
+    public final @NonNull List<MediaSession2> getSessions() {
+        List<MediaSession2> list = new ArrayList<>();
+        synchronized (mLock) {
+            list.addAll(mSessions.values());
+        }
+        return list;
+    }
+
+    /**
+     * Returns the {@link MediaSessionManager}.
+     */
+    @NonNull
+    MediaSessionManager getMediaSessionManager() {
+        synchronized (mLock) {
+            return mMediaSessionManager;
+        }
+    }
+
+    /**
+     * Called by registered {@link MediaSession2.ForegroundServiceEventCallback}
+     *
+     * @param session session with change
+     * @param playbackActive {@code true} if playback is active.
+     */
+    void onPlaybackActiveChanged(MediaSession2 session, boolean playbackActive) {
+        MediaNotification mediaNotification = onUpdateNotification(session);
+        if (mediaNotification == null) {
+            // The service implementation doesn't want to use the automatic start/stopForeground
+            // feature.
+            return;
+        }
+        synchronized (mLock) {
+            mNotifications.put(session, mediaNotification);
+        }
+        int id = mediaNotification.getNotificationId();
+        Notification notification = mediaNotification.getNotification();
+        if (!playbackActive) {
+            mNotificationManager.notify(id, notification);
+            return;
+        }
+        // playbackActive == true
+        startForegroundService(mStartSelfIntent);
+        startForeground(id, notification);
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Returned by {@link #onUpdateNotification(MediaSession2)} for making session service
+     * foreground service to keep playback running in the background. It's highly recommended to
+     * show media style notification here.
+     */
+    public static class MediaNotification {
+        private final int mNotificationId;
+        private final Notification mNotification;
+
+        /**
+         * Default constructor
+         *
+         * @param notificationId notification id to be used for
+         *        {@link NotificationManager#notify(int, Notification)}.
+         * @param notification a notification to make session service run in the foreground. Media
+         *        style notification is recommended here.
+         */
+        public MediaNotification(int notificationId, @NonNull Notification notification) {
+            if (notification == null) {
+                throw new IllegalArgumentException("notification shouldn't be null");
+            }
+            mNotificationId = notificationId;
+            mNotification = notification;
+        }
+
+        /**
+         * Gets the id of the notification.
+         *
+         * @return the notification id
+         */
+        public int getNotificationId() {
+            return mNotificationId;
+        }
+
+        /**
+         * Gets the notification.
+         *
+         * @return the notification
+         */
+        @NonNull
+        public Notification getNotification() {
+            return mNotification;
+        }
+    }
+
+    private static final class MediaSession2ServiceStub extends IMediaSession2Service.Stub
+            implements AutoCloseable {
+        final WeakReference<MediaSession2Service> mService;
+        final Handler mHandler;
+
+        MediaSession2ServiceStub(MediaSession2Service service) {
+            mService = new WeakReference<>(service);
+            mHandler = new Handler(service.getMainLooper());
+        }
+
+        @Override
+        public void connect(Controller2Link caller, int seq, Bundle connectionRequest) {
+            if (mService.get() == null) {
+                if (DEBUG) {
+                    Log.d(TAG, "Service is already destroyed");
+                }
+                return;
+            }
+            if (caller == null || connectionRequest == null) {
+                if (DEBUG) {
+                    Log.d(TAG, "Ignoring calls with illegal arguments, caller=" + caller
+                            + ", connectionRequest=" + connectionRequest);
+                }
+                return;
+            }
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                mHandler.post(() -> {
+                    boolean shouldNotifyDisconnected = true;
+                    try {
+                        final MediaSession2Service service = mService.get();
+                        if (service == null) {
+                            if (DEBUG) {
+                                Log.d(TAG, "Service isn't available");
+                            }
+                            return;
+                        }
+
+                        String callingPkg = connectionRequest.getString(KEY_PACKAGE_NAME);
+                        // The Binder.getCallingPid() can be 0 for an oneway call from the
+                        // remote process. If it's the case, use PID from the connectionRequest.
+                        RemoteUserInfo remoteUserInfo = new RemoteUserInfo(
+                                callingPkg,
+                                pid == 0 ? connectionRequest.getInt(KEY_PID) : pid,
+                                uid);
+
+                        Bundle connectionHints = connectionRequest.getBundle(KEY_CONNECTION_HINTS);
+                        if (connectionHints == null) {
+                            Log.w(TAG, "connectionHints shouldn't be null.");
+                            connectionHints = Bundle.EMPTY;
+                        } else if (MediaSession2.hasCustomParcelable(connectionHints)) {
+                            Log.w(TAG, "connectionHints contain custom parcelable. Ignoring.");
+                            connectionHints = Bundle.EMPTY;
+                        }
+
+                        final ControllerInfo controllerInfo = new ControllerInfo(
+                                remoteUserInfo,
+                                service.getMediaSessionManager()
+                                        .isTrustedForMediaControl(remoteUserInfo),
+                                caller,
+                                connectionHints);
+
+                        if (DEBUG) {
+                            Log.d(TAG, "Handling incoming connection request from the"
+                                    + " controller=" + controllerInfo);
+                        }
+
+                        final MediaSession2 session;
+                        session = service.onGetSession(controllerInfo);
+
+                        if (session == null) {
+                            if (DEBUG) {
+                                Log.d(TAG, "Rejecting incoming connection request from the"
+                                        + " controller=" + controllerInfo);
+                            }
+                            // Note: Trusted controllers also can be rejected according to the
+                            // service implementation.
+                            return;
+                        }
+                        service.addSession(session);
+                        shouldNotifyDisconnected = false;
+                        session.onConnect(caller, pid, uid, seq, connectionRequest);
+                    } catch (Exception e) {
+                        // Don't propagate exception in service to the controller.
+                        Log.w(TAG, "Failed to add a session to session service", e);
+                    } finally {
+                        // Trick to call onDisconnected() in one place.
+                        if (shouldNotifyDisconnected) {
+                            if (DEBUG) {
+                                Log.d(TAG, "Notifying the controller of its disconnection");
+                            }
+                            try {
+                                caller.notifyDisconnected(0);
+                            } catch (RuntimeException e) {
+                                // Controller may be died prematurely.
+                                // Not an issue because we'll ignore it anyway.
+                            }
+                        }
+                    }
+                });
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void close() {
+            mHandler.removeCallbacksAndMessages(null);
+            mService.clear();
+        }
+    }
+}
diff --git a/android/media/MediaSync.java b/android/media/MediaSync.java
new file mode 100644
index 0000000..799f4bf
--- /dev/null
+++ b/android/media/MediaSync.java
@@ -0,0 +1,643 @@
+/*
+ * Copyright (C) 2015 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.media.AudioTrack;
+import android.media.PlaybackParams;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+import android.view.Surface;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.util.concurrent.TimeUnit;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * MediaSync class can be used to synchronously play audio and video streams.
+ * It can be used to play audio-only or video-only stream, too.
+ *
+ * <p>MediaSync is generally used like this:
+ * <pre>
+ * MediaSync sync = new MediaSync();
+ * sync.setSurface(surface);
+ * Surface inputSurface = sync.createInputSurface();
+ * ...
+ * // MediaCodec videoDecoder = ...;
+ * videoDecoder.configure(format, inputSurface, ...);
+ * ...
+ * sync.setAudioTrack(audioTrack);
+ * sync.setCallback(new MediaSync.Callback() {
+ *     {@literal @Override}
+ *     public void onAudioBufferConsumed(MediaSync sync, ByteBuffer audioBuffer, int bufferId) {
+ *         ...
+ *     }
+ * }, null);
+ * // This needs to be done since sync is paused on creation.
+ * sync.setPlaybackParams(new PlaybackParams().setSpeed(1.f));
+ *
+ * for (;;) {
+ *   ...
+ *   // send video frames to surface for rendering, e.g., call
+ *   // videoDecoder.releaseOutputBuffer(videoOutputBufferIx, videoPresentationTimeNs);
+ *   // More details are available as below.
+ *   ...
+ *   sync.queueAudio(audioByteBuffer, bufferId, audioPresentationTimeUs); // non-blocking.
+ *   // The audioByteBuffer and bufferId will be returned via callback.
+ *   // More details are available as below.
+ *   ...
+ *     ...
+ * }
+ * sync.setPlaybackParams(new PlaybackParams().setSpeed(0.f));
+ * sync.release();
+ * sync = null;
+ *
+ * // The following code snippet illustrates how video/audio raw frames are created by
+ * // MediaCodec's, how they are fed to MediaSync and how they are returned by MediaSync.
+ * // This is the callback from MediaCodec.
+ * onOutputBufferAvailable(MediaCodec codec, int bufferId, BufferInfo info) {
+ *     // ...
+ *     if (codec == videoDecoder) {
+ *         // surface timestamp must contain media presentation time in nanoseconds.
+ *         codec.releaseOutputBuffer(bufferId, 1000 * info.presentationTime);
+ *     } else {
+ *         ByteBuffer audioByteBuffer = codec.getOutputBuffer(bufferId);
+ *         sync.queueAudio(audioByteBuffer, bufferId, info.presentationTime);
+ *     }
+ *     // ...
+ * }
+ *
+ * // This is the callback from MediaSync.
+ * onAudioBufferConsumed(MediaSync sync, ByteBuffer buffer, int bufferId) {
+ *     // ...
+ *     audioDecoder.releaseBuffer(bufferId, false);
+ *     // ...
+ * }
+ *
+ * </pre>
+ *
+ * The client needs to configure corresponding sink by setting the Surface and/or AudioTrack
+ * based on the stream type it will play.
+ * <p>
+ * For video, the client needs to call {@link #createInputSurface} to obtain a surface on
+ * which it will render video frames.
+ * <p>
+ * For audio, the client needs to set up audio track correctly, e.g., using {@link
+ * AudioTrack#MODE_STREAM}. The audio buffers are sent to MediaSync directly via {@link
+ * #queueAudio}, and are returned to the client via {@link Callback#onAudioBufferConsumed}
+ * asynchronously. The client should not modify an audio buffer till it's returned.
+ * <p>
+ * The client can optionally pre-fill audio/video buffers by setting playback rate to 0.0,
+ * and then feed audio/video buffers to corresponding components. This can reduce possible
+ * initial underrun.
+ * <p>
+ */
+public final class MediaSync {
+    /**
+     * MediaSync callback interface. Used to notify the user asynchronously
+     * of various MediaSync events.
+     */
+    public static abstract class Callback {
+        /**
+         * Called when returning an audio buffer which has been consumed.
+         *
+         * @param sync The MediaSync object.
+         * @param audioBuffer The returned audio buffer.
+         * @param bufferId The ID associated with audioBuffer as passed into
+         *     {@link MediaSync#queueAudio}.
+         */
+        public abstract void onAudioBufferConsumed(
+                @NonNull MediaSync sync, @NonNull ByteBuffer audioBuffer, int bufferId);
+    }
+
+    /** Audio track failed.
+     * @see android.media.MediaSync.OnErrorListener
+     */
+    public static final int MEDIASYNC_ERROR_AUDIOTRACK_FAIL = 1;
+
+    /** The surface failed to handle video buffers.
+     * @see android.media.MediaSync.OnErrorListener
+     */
+    public static final int MEDIASYNC_ERROR_SURFACE_FAIL = 2;
+
+    /**
+     * Interface definition of a callback to be invoked when there
+     * has been an error during an asynchronous operation (other errors
+     * will throw exceptions at method call time).
+     */
+    public interface OnErrorListener {
+        /**
+         * Called to indicate an error.
+         *
+         * @param sync The MediaSync the error pertains to
+         * @param what The type of error that has occurred:
+         * <ul>
+         * <li>{@link #MEDIASYNC_ERROR_AUDIOTRACK_FAIL}
+         * <li>{@link #MEDIASYNC_ERROR_SURFACE_FAIL}
+         * </ul>
+         * @param extra an extra code, specific to the error. Typically
+         * implementation dependent.
+         */
+        void onError(@NonNull MediaSync sync, int what, int extra);
+    }
+
+    private static final String TAG = "MediaSync";
+
+    private static final int EVENT_CALLBACK = 1;
+    private static final int EVENT_SET_CALLBACK = 2;
+
+    private static final int CB_RETURN_AUDIO_BUFFER = 1;
+
+    private static class AudioBuffer {
+        public ByteBuffer mByteBuffer;
+        public int mBufferIndex;
+        long mPresentationTimeUs;
+
+        public AudioBuffer(@NonNull ByteBuffer byteBuffer, int bufferId,
+                           long presentationTimeUs) {
+            mByteBuffer = byteBuffer;
+            mBufferIndex = bufferId;
+            mPresentationTimeUs = presentationTimeUs;
+        }
+    }
+
+    private final Object mCallbackLock = new Object();
+    private Handler mCallbackHandler = null;
+    private MediaSync.Callback mCallback = null;
+
+    private final Object mOnErrorListenerLock = new Object();
+    private Handler mOnErrorListenerHandler = null;
+    private MediaSync.OnErrorListener mOnErrorListener = null;
+
+    private Thread mAudioThread = null;
+    // Created on mAudioThread when mAudioThread is started. When used on user thread, they should
+    // be guarded by checking mAudioThread.
+    private Handler mAudioHandler = null;
+    private Looper mAudioLooper = null;
+
+    private final Object mAudioLock = new Object();
+    private AudioTrack mAudioTrack = null;
+    private List<AudioBuffer> mAudioBuffers = new LinkedList<AudioBuffer>();
+    // this is only used for paused/running decisions, so it is not affected by clock drift
+    private float mPlaybackRate = 0.0f;
+
+    private long mNativeContext;
+
+    /**
+     * Class constructor. On creation, MediaSync is paused, i.e., playback rate is 0.0f.
+     */
+    public MediaSync() {
+        native_setup();
+    }
+
+    private native final void native_setup();
+
+    @Override
+    protected void finalize() {
+        native_finalize();
+    }
+
+    private native final void native_finalize();
+
+    /**
+     * Make sure you call this when you're done to free up any opened
+     * component instance instead of relying on the garbage collector
+     * to do this for you at some point in the future.
+     */
+    public final void release() {
+        returnAudioBuffers();
+        if (mAudioThread != null) {
+            if (mAudioLooper != null) {
+                mAudioLooper.quit();
+            }
+        }
+        setCallback(null, null);
+        native_release();
+    }
+
+    private native final void native_release();
+
+    /**
+     * Sets an asynchronous callback for actionable MediaSync events.
+     * <p>
+     * This method can be called multiple times to update a previously set callback. If the
+     * handler is changed, undelivered notifications scheduled for the old handler may be dropped.
+     * <p>
+     * <b>Do not call this inside callback.</b>
+     *
+     * @param cb The callback that will run. Use {@code null} to stop receiving callbacks.
+     * @param handler The Handler that will run the callback. Use {@code null} to use MediaSync's
+     *     internal handler if it exists.
+     */
+    public void setCallback(@Nullable /* MediaSync. */ Callback cb, @Nullable Handler handler) {
+        synchronized(mCallbackLock) {
+            if (handler != null) {
+                mCallbackHandler = handler;
+            } else {
+                Looper looper;
+                if ((looper = Looper.myLooper()) == null) {
+                    looper = Looper.getMainLooper();
+                }
+                if (looper == null) {
+                    mCallbackHandler = null;
+                } else {
+                    mCallbackHandler = new Handler(looper);
+                }
+            }
+
+            mCallback = cb;
+        }
+    }
+
+    /**
+     * Sets an asynchronous callback for error events.
+     * <p>
+     * This method can be called multiple times to update a previously set listener. If the
+     * handler is changed, undelivered notifications scheduled for the old handler may be dropped.
+     * <p>
+     * <b>Do not call this inside callback.</b>
+     *
+     * @param listener The callback that will run. Use {@code null} to stop receiving callbacks.
+     * @param handler The Handler that will run the callback. Use {@code null} to use MediaSync's
+     *     internal handler if it exists.
+     */
+    public void setOnErrorListener(@Nullable /* MediaSync. */ OnErrorListener listener,
+            @Nullable Handler handler) {
+        synchronized(mOnErrorListenerLock) {
+            if (handler != null) {
+                mOnErrorListenerHandler = handler;
+            } else {
+                Looper looper;
+                if ((looper = Looper.myLooper()) == null) {
+                    looper = Looper.getMainLooper();
+                }
+                if (looper == null) {
+                    mOnErrorListenerHandler = null;
+                } else {
+                    mOnErrorListenerHandler = new Handler(looper);
+                }
+            }
+
+            mOnErrorListener = listener;
+        }
+    }
+
+    /**
+     * Sets the output surface for MediaSync.
+     * <p>
+     * Currently, this is only supported in the Initialized state.
+     *
+     * @param surface Specify a surface on which to render the video data.
+     * @throws IllegalArgumentException if the surface has been released, is invalid,
+     *     or can not be connected.
+     * @throws IllegalStateException if setting the surface is not supported, e.g.
+     *     not in the Initialized state, or another surface has already been set.
+     */
+    public void setSurface(@Nullable Surface surface) {
+        native_setSurface(surface);
+    }
+
+    private native final void native_setSurface(@Nullable Surface surface);
+
+    /**
+     * Sets the audio track for MediaSync.
+     * <p>
+     * Currently, this is only supported in the Initialized state.
+     *
+     * @param audioTrack Specify an AudioTrack through which to render the audio data.
+     * @throws IllegalArgumentException if the audioTrack has been released, or is invalid.
+     * @throws IllegalStateException if setting the audio track is not supported, e.g.
+     *     not in the Initialized state, or another audio track has already been set.
+     */
+    public void setAudioTrack(@Nullable AudioTrack audioTrack) {
+        native_setAudioTrack(audioTrack);
+        mAudioTrack = audioTrack;
+        if (audioTrack != null && mAudioThread == null) {
+            createAudioThread();
+        }
+    }
+
+    private native final void native_setAudioTrack(@Nullable AudioTrack audioTrack);
+
+    /**
+     * Requests a Surface to use as the input. This may only be called after
+     * {@link #setSurface}.
+     * <p>
+     * The application is responsible for calling release() on the Surface when
+     * done.
+     * @throws IllegalStateException if not set, or another input surface has
+     *     already been created.
+     */
+    @NonNull
+    public native final Surface createInputSurface();
+
+    /**
+     * Sets playback rate using {@link PlaybackParams}.
+     * <p>
+     * When using MediaSync with {@link AudioTrack}, set playback params using this
+     * call instead of calling it directly on the track, so that the sync is aware of
+     * the params change.
+     * <p>
+     * This call also works if there is no audio track.
+     *
+     * @param params the playback params to use. {@link PlaybackParams#getSpeed
+     *     Speed} is the ratio between desired playback rate and normal one. 1.0 means
+     *     normal playback speed. 0.0 means pause. Value larger than 1.0 means faster playback,
+     *     while value between 0.0 and 1.0 for slower playback. <b>Note:</b> the normal rate
+     *     does not change as a result of this call. To restore the original rate at any time,
+     *     use speed of 1.0.
+     *
+     * @throws IllegalStateException if the internal sync engine or the audio track has not
+     *     been initialized.
+     * @throws IllegalArgumentException if the params are not supported.
+     */
+    public void setPlaybackParams(@NonNull PlaybackParams params) {
+        synchronized(mAudioLock) {
+            mPlaybackRate = native_setPlaybackParams(params);;
+        }
+        if (mPlaybackRate != 0.0 && mAudioThread != null) {
+            postRenderAudio(0);
+        }
+    }
+
+    /**
+     * Gets the playback rate using {@link PlaybackParams}.
+     *
+     * @return the playback rate being used.
+     *
+     * @throws IllegalStateException if the internal sync engine or the audio track has not
+     *     been initialized.
+     */
+    @NonNull
+    public native PlaybackParams getPlaybackParams();
+
+    private native float native_setPlaybackParams(@NonNull PlaybackParams params);
+
+    /**
+     * Sets A/V sync mode.
+     *
+     * @param params the A/V sync params to apply
+     *
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized.
+     * @throws IllegalArgumentException if params are not supported.
+     */
+    public void setSyncParams(@NonNull SyncParams params) {
+        synchronized(mAudioLock) {
+            mPlaybackRate = native_setSyncParams(params);;
+        }
+        if (mPlaybackRate != 0.0 && mAudioThread != null) {
+            postRenderAudio(0);
+        }
+    }
+
+    private native float native_setSyncParams(@NonNull SyncParams params);
+
+    /**
+     * Gets the A/V sync mode.
+     *
+     * @return the A/V sync params
+     *
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized.
+     */
+    @NonNull
+    public native SyncParams getSyncParams();
+
+    /**
+     * Flushes all buffers from the sync object.
+     * <p>
+     * All pending unprocessed audio and video buffers are discarded. If an audio track was
+     * configured, it is flushed and stopped. If a video output surface was configured, the
+     * last frame queued to it is left on the frame. Queue a blank video frame to clear the
+     * surface,
+     * <p>
+     * No callbacks are received for the flushed buffers.
+     *
+     * @throws IllegalStateException if the internal player engine has not been
+     * initialized.
+     */
+    public void flush() {
+        synchronized(mAudioLock) {
+            mAudioBuffers.clear();
+            mCallbackHandler.removeCallbacksAndMessages(null);
+        }
+        if (mAudioTrack != null) {
+            mAudioTrack.pause();
+            mAudioTrack.flush();
+            // Call stop() to signal to the AudioSink to completely fill the
+            // internal buffer before resuming playback.
+            mAudioTrack.stop();
+        }
+        native_flush();
+    }
+
+    private native final void native_flush();
+
+    /**
+     * Get current playback position.
+     * <p>
+     * The MediaTimestamp represents how the media time correlates to the system time in
+     * a linear fashion using an anchor and a clock rate. During regular playback, the media
+     * time moves fairly constantly (though the anchor frame may be rebased to a current
+     * system time, the linear correlation stays steady). Therefore, this method does not
+     * need to be called often.
+     * <p>
+     * To help users get current playback position, this method always anchors the timestamp
+     * to the current {@link System#nanoTime system time}, so
+     * {@link MediaTimestamp#getAnchorMediaTimeUs} can be used as current playback position.
+     *
+     * @return a MediaTimestamp object if a timestamp is available, or {@code null} if no timestamp
+     *         is available, e.g. because the media player has not been initialized.
+     *
+     * @see MediaTimestamp
+     */
+    @Nullable
+    public MediaTimestamp getTimestamp()
+    {
+        try {
+            // TODO: create the timestamp in native
+            MediaTimestamp timestamp = new MediaTimestamp();
+            if (native_getTimestamp(timestamp)) {
+                return timestamp;
+            } else {
+                return null;
+            }
+        } catch (IllegalStateException e) {
+            return null;
+        }
+    }
+
+    private native final boolean native_getTimestamp(@NonNull MediaTimestamp timestamp);
+
+    /**
+     * Queues the audio data asynchronously for playback (AudioTrack must be in streaming mode).
+     * If the audio track was flushed as a result of {@link #flush}, it will be restarted.
+     * @param audioData the buffer that holds the data to play. This buffer will be returned
+     *     to the client via registered callback.
+     * @param bufferId an integer used to identify audioData. It will be returned to
+     *     the client along with audioData. This helps applications to keep track of audioData,
+     *     e.g., it can be used to store the output buffer index used by the audio codec.
+     * @param presentationTimeUs the presentation timestamp in microseconds for the first frame
+     *     in the buffer.
+     * @throws IllegalStateException if audio track is not set or internal configureation
+     *     has not been done correctly.
+     */
+    public void queueAudio(
+            @NonNull ByteBuffer audioData, int bufferId, long presentationTimeUs) {
+        if (mAudioTrack == null || mAudioThread == null) {
+            throw new IllegalStateException(
+                    "AudioTrack is NOT set or audio thread is not created");
+        }
+
+        synchronized(mAudioLock) {
+            mAudioBuffers.add(new AudioBuffer(audioData, bufferId, presentationTimeUs));
+        }
+
+        if (mPlaybackRate != 0.0) {
+            postRenderAudio(0);
+        }
+    }
+
+    // When called on user thread, make sure to check mAudioThread != null.
+    private void postRenderAudio(long delayMillis) {
+        mAudioHandler.postDelayed(new Runnable() {
+            public void run() {
+                synchronized(mAudioLock) {
+                    if (mPlaybackRate == 0.0) {
+                        return;
+                    }
+
+                    if (mAudioBuffers.isEmpty()) {
+                        return;
+                    }
+
+                    AudioBuffer audioBuffer = mAudioBuffers.get(0);
+                    int size = audioBuffer.mByteBuffer.remaining();
+                    // restart audio track after flush
+                    if (size > 0 && mAudioTrack.getPlayState() != AudioTrack.PLAYSTATE_PLAYING) {
+                        try {
+                            mAudioTrack.play();
+                        } catch (IllegalStateException e) {
+                            Log.w(TAG, "could not start audio track");
+                        }
+                    }
+                    int sizeWritten = mAudioTrack.write(
+                            audioBuffer.mByteBuffer,
+                            size,
+                            AudioTrack.WRITE_NON_BLOCKING);
+                    if (sizeWritten > 0) {
+                        if (audioBuffer.mPresentationTimeUs != -1) {
+                            native_updateQueuedAudioData(
+                                    size, audioBuffer.mPresentationTimeUs);
+                            audioBuffer.mPresentationTimeUs = -1;
+                        }
+
+                        if (sizeWritten == size) {
+                            postReturnByteBuffer(audioBuffer);
+                            mAudioBuffers.remove(0);
+                            if (!mAudioBuffers.isEmpty()) {
+                                postRenderAudio(0);
+                            }
+                            return;
+                        }
+                    }
+                    long pendingTimeMs = TimeUnit.MICROSECONDS.toMillis(
+                            native_getPlayTimeForPendingAudioFrames());
+                    postRenderAudio(pendingTimeMs / 2);
+                }
+            }
+        }, delayMillis);
+    }
+
+    private native final void native_updateQueuedAudioData(
+            int sizeInBytes, long presentationTimeUs);
+
+    private native final long native_getPlayTimeForPendingAudioFrames();
+
+    private final void postReturnByteBuffer(@NonNull final AudioBuffer audioBuffer) {
+        synchronized(mCallbackLock) {
+            if (mCallbackHandler != null) {
+                final MediaSync sync = this;
+                mCallbackHandler.post(new Runnable() {
+                    public void run() {
+                        Callback callback;
+                        synchronized(mCallbackLock) {
+                            callback = mCallback;
+                            if (mCallbackHandler == null
+                                    || mCallbackHandler.getLooper().getThread()
+                                            != Thread.currentThread()) {
+                                // callback handler has been changed.
+                                return;
+                            }
+                        }
+                        if (callback != null) {
+                            callback.onAudioBufferConsumed(sync, audioBuffer.mByteBuffer,
+                                    audioBuffer.mBufferIndex);
+                        }
+                    }
+                });
+            }
+        }
+    }
+
+    private final void returnAudioBuffers() {
+        synchronized(mAudioLock) {
+            for (AudioBuffer audioBuffer: mAudioBuffers) {
+                postReturnByteBuffer(audioBuffer);
+            }
+            mAudioBuffers.clear();
+        }
+    }
+
+    private void createAudioThread() {
+        mAudioThread = new Thread() {
+            @Override
+            public void run() {
+                Looper.prepare();
+                synchronized(mAudioLock) {
+                    mAudioLooper = Looper.myLooper();
+                    mAudioHandler = new Handler();
+                    mAudioLock.notify();
+                }
+                Looper.loop();
+            }
+        };
+        mAudioThread.start();
+
+        synchronized(mAudioLock) {
+            try {
+                mAudioLock.wait();
+            } catch(InterruptedException e) {
+            }
+        }
+    }
+
+    static {
+        System.loadLibrary("media_jni");
+        native_init();
+    }
+
+    private static native final void native_init();
+}
diff --git a/android/media/MediaSyncEvent.java b/android/media/MediaSyncEvent.java
new file mode 100644
index 0000000..fa7d5b8
--- /dev/null
+++ b/android/media/MediaSyncEvent.java
@@ -0,0 +1,212 @@
+/*
+ * Copyright (C) 2012 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.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/**
+ * The MediaSyncEvent class defines events that can be used to synchronize playback or capture
+ * actions between different players and recorders.
+ * <p>For instance, {@link AudioRecord#startRecording(MediaSyncEvent)} is used to start capture
+ * only when the playback on a particular audio session is complete.
+ * The audio session ID is retrieved from a player (e.g {@link MediaPlayer}, {@link AudioTrack} or
+ * {@link ToneGenerator}) by use of the getAudioSessionId() method.
+ */
+public class MediaSyncEvent implements Parcelable {
+
+    /**
+     * No sync event specified. When used with a synchronized playback or capture method, the
+     * behavior is equivalent to calling the corresponding non synchronized method.
+     */
+    public static final int SYNC_EVENT_NONE = AudioSystem.SYNC_EVENT_NONE;
+
+    /**
+     * The corresponding action is triggered only when the presentation is completed
+     * (meaning the media has been presented to the user) on the specified session.
+     * A synchronization of this type requires a source audio session ID to be set via
+     * {@link #setAudioSessionId(int)} method.
+     */
+    public static final int SYNC_EVENT_PRESENTATION_COMPLETE =
+            AudioSystem.SYNC_EVENT_PRESENTATION_COMPLETE;
+
+    /**
+     * @hide
+     * Used when sharing audio history between AudioRecord instances.
+     * See {@link AudioRecord.Builder#setSharedAudioEvent(MediaSyncEvent).
+     */
+    @SystemApi
+    public static final int SYNC_EVENT_SHARE_AUDIO_HISTORY =
+            AudioSystem.SYNC_EVENT_SHARE_AUDIO_HISTORY;
+
+    /**
+     * Creates a synchronization event of the sepcified type.
+     *
+     * <p>The type specifies which kind of event is monitored.
+     * For instance, event {@link #SYNC_EVENT_PRESENTATION_COMPLETE} corresponds to the audio being
+     * presented to the user on a particular audio session.
+     * @param eventType the synchronization event type.
+     * @return the MediaSyncEvent created.
+     * @throws java.lang.IllegalArgumentException
+     */
+    public static MediaSyncEvent createEvent(int eventType)
+                            throws IllegalArgumentException {
+        if (!isValidType(eventType)) {
+            throw (new IllegalArgumentException(eventType
+                    + "is not a valid MediaSyncEvent type."));
+        } else {
+            return new MediaSyncEvent(eventType);
+        }
+    }
+
+    private final int mType;
+    private int mAudioSession = 0;
+
+    private MediaSyncEvent(int eventType) {
+        mType = eventType;
+    }
+
+    /**
+     * Sets the event source audio session ID.
+     *
+     * <p>The audio session ID specifies on which audio session the synchronization event should be
+     * monitored.
+     * It is mandatory for certain event types (e.g. {@link #SYNC_EVENT_PRESENTATION_COMPLETE}).
+     * For instance, the audio session ID can be retrieved via
+     * {@link MediaPlayer#getAudioSessionId()} when monitoring an event on a particular MediaPlayer.
+     * @param audioSessionId the audio session ID of the event source being monitored.
+     * @return the MediaSyncEvent the method is called on.
+     * @throws java.lang.IllegalArgumentException
+     */
+    public MediaSyncEvent setAudioSessionId(int audioSessionId)
+            throws IllegalArgumentException {
+        if (audioSessionId > 0) {
+            mAudioSession = audioSessionId;
+        } else {
+            throw (new IllegalArgumentException(audioSessionId + " is not a valid session ID."));
+        }
+        return this;
+    }
+
+    /**
+     * Gets the synchronization event type.
+     *
+     * @return the synchronization event type.
+     */
+    public int getType() {
+        return mType;
+    }
+
+    /**
+     * Gets the synchronization event audio session ID.
+     *
+     * @return the synchronization audio session ID. The returned audio session ID is 0 if it has
+     * not been set.
+     */
+    public int getAudioSessionId() {
+        return mAudioSession;
+    }
+
+    private static boolean isValidType(int type) {
+        switch (type) {
+            case SYNC_EVENT_NONE:
+            case SYNC_EVENT_PRESENTATION_COMPLETE:
+            case SYNC_EVENT_SHARE_AUDIO_HISTORY:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    // Parcelable implementation
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        Objects.requireNonNull(dest);
+        dest.writeInt(mType);
+        dest.writeInt(mAudioSession);
+    }
+
+    private MediaSyncEvent(Parcel in) {
+        mType = in.readInt();
+        mAudioSession = in.readInt();
+    }
+
+    public static final @NonNull Parcelable.Creator<MediaSyncEvent> CREATOR =
+            new Parcelable.Creator<MediaSyncEvent>() {
+        /**
+         * Rebuilds an MediaSyncEvent previously stored with writeToParcel().
+         * @param p Parcel object to read the MediaSyncEvent from
+         * @return a new MediaSyncEvent created from the data in the parcel
+         */
+        public MediaSyncEvent createFromParcel(Parcel p) {
+            return new MediaSyncEvent(p);
+        }
+        public MediaSyncEvent[] newArray(int size) {
+            return new MediaSyncEvent[size];
+        }
+    };
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        MediaSyncEvent that = (MediaSyncEvent) o;
+        return ((mType == that.mType)
+                && (mAudioSession == that.mAudioSession));
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mType, mAudioSession);
+    }
+
+    @Override
+    public String toString() {
+        return new String("MediaSyncEvent:"
+                + " type=" + typeToString(mType)
+                + " session=" + mAudioSession);
+    }
+
+    /**
+     * Returns the string representation for the type.
+     * @param type one of the {@link MediaSyncEvent} type constants
+     * @hide
+     */
+    public static @NonNull String typeToString(int type) {
+        switch (type) {
+            case SYNC_EVENT_NONE:
+                return "SYNC_EVENT_NONE";
+            case SYNC_EVENT_PRESENTATION_COMPLETE:
+                return "SYNC_EVENT_PRESENTATION_COMPLETE";
+            case SYNC_EVENT_SHARE_AUDIO_HISTORY:
+                return "SYNC_EVENT_SHARE_AUDIO_HISTORY";
+            default:
+                return "unknown event type " + type;
+        }
+    }
+
+}
diff --git a/android/media/MediaTimeProvider.java b/android/media/MediaTimeProvider.java
new file mode 100644
index 0000000..fe37712
--- /dev/null
+++ b/android/media/MediaTimeProvider.java
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2013 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;
+
+/** @hide */
+public interface MediaTimeProvider {
+    // we do not allow negative media time
+    /**
+     * Presentation time value if no timed event notification is requested.
+     */
+    public final static long NO_TIME = -1;
+
+    /**
+     * Cancels all previous notification request from this listener if any.  It
+     * registers the listener to get seek and stop notifications.  If timeUs is
+     * not negative, it also registers the listener for a timed event
+     * notification when the presentation time reaches (becomes greater) than
+     * the value specified.  This happens immediately if the current media time
+     * is larger than or equal to timeUs.
+     *
+     * @param timeUs presentation time to get timed event callback at (or
+     *               {@link #NO_TIME})
+     */
+    public void notifyAt(long timeUs, OnMediaTimeListener listener);
+
+    /**
+     * Cancels all previous notification request from this listener if any.  It
+     * registers the listener to get seek and stop notifications.  If the media
+     * is stopped, the listener will immediately receive a stop notification.
+     * Otherwise, it will receive a timed event notificaton.
+     */
+    public void scheduleUpdate(OnMediaTimeListener listener);
+
+    /**
+     * Cancels all previous notification request from this listener if any.
+     */
+    public void cancelNotifications(OnMediaTimeListener listener);
+
+    /**
+     * Get the current presentation time.
+     *
+     * @param precise   Whether getting a precise time is important. This is
+     *                  more costly.
+     * @param monotonic Whether returned time should be monotonic: that is,
+     *                  greater than or equal to the last returned time.  Don't
+     *                  always set this to true.  E.g. this has undesired
+     *                  consequences if the media is seeked between calls.
+     * @throws IllegalStateException if the media is not initialized
+     */
+    public long getCurrentTimeUs(boolean precise, boolean monotonic)
+            throws IllegalStateException;
+
+    /** @hide */
+    public static interface OnMediaTimeListener {
+        /**
+         * Called when the registered time was reached naturally.
+         *
+         * @param timeUs current media time
+         */
+        void onTimedEvent(long timeUs);
+
+        /**
+         * Called when the media time changed due to seeking.
+         *
+         * @param timeUs current media time
+         */
+        void onSeek(long timeUs);
+
+        /**
+         * Called when the playback stopped.  This is not called on pause, only
+         * on full stop, at which point there is no further current media time.
+         */
+        void onStop();
+    }
+}
+
diff --git a/android/media/MediaTimestamp.java b/android/media/MediaTimestamp.java
new file mode 100644
index 0000000..0777ba3
--- /dev/null
+++ b/android/media/MediaTimestamp.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2015 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.annotation.FloatRange;
+
+/**
+ * An immutable object that represents the linear correlation between the media time
+ * and the system time. It contains the media clock rate, together with the media timestamp
+ * of an anchor frame and the system time when that frame was presented or is committed
+ * to be presented.
+ * <p>
+ * The phrase "present" means that audio/video produced on device is detectable by an external
+ * observer off device.
+ * The time is based on the implementation's best effort, using whatever knowledge
+ * is available to the system, but cannot account for any delay unknown to the implementation.
+ * The anchor frame could be any frame, including a just-rendered frame, or even a theoretical
+ * or in-between frame, based on the source of the MediaTimestamp.
+ * When the anchor frame is a just-rendered one, the media time stands for
+ * current position of the playback or recording.
+ *
+ * @see MediaSync#getTimestamp
+ * @see MediaPlayer#getTimestamp
+ */
+public final class MediaTimestamp
+{
+    /**
+     * An unknown media timestamp value
+     */
+    public static final MediaTimestamp TIMESTAMP_UNKNOWN = new MediaTimestamp(-1, -1, 0.0f);
+
+    /**
+     * Get the media time of the anchor in microseconds.
+     */
+    public long getAnchorMediaTimeUs() {
+        return mediaTimeUs;
+    }
+
+    /**
+     * Get the {@link java.lang.System#nanoTime system time} corresponding to the media time
+     * in nanoseconds.
+     * @deprecated use {@link #getAnchorSystemNanoTime} instead.
+     */
+    @Deprecated
+    public long getAnchorSytemNanoTime() {
+        return getAnchorSystemNanoTime();
+    }
+
+    /**
+     * Get the {@link java.lang.System#nanoTime system time} corresponding to the media time
+     * in nanoseconds.
+     */
+    public long getAnchorSystemNanoTime() {
+        return nanoTime;
+    }
+
+    /**
+     * Get the rate of the media clock in relation to the system time.
+     * <p>
+     * It is 1.0 if media clock advances in sync with the system clock;
+     * greater than 1.0 if media clock is faster than the system clock;
+     * less than 1.0 if media clock is slower than the system clock.
+     */
+    @FloatRange(from = 0.0f, to = Float.MAX_VALUE)
+    public float getMediaClockRate() {
+        return clockRate;
+    }
+
+    /** @hide - accessor shorthand */
+    public final long mediaTimeUs;
+    /** @hide - accessor shorthand */
+    public final long nanoTime;
+    /** @hide - accessor shorthand */
+    public final float clockRate;
+
+    /**
+     * Constructor.
+     *
+     * @param mediaTimeUs the media time of the anchor in microseconds
+     * @param nanoTimeNs the {@link java.lang.System#nanoTime system time} corresponding to the
+     *                  media time in nanoseconds.
+     * @param clockRate the rate of the media clock in relation to the system time.
+     */
+    public MediaTimestamp(long mediaTimeUs, long nanoTimeNs,
+            @FloatRange(from = 0.0f, to = Float.MAX_VALUE) float clockRate) {
+        this.mediaTimeUs = mediaTimeUs;
+        this.nanoTime = nanoTimeNs;
+        this.clockRate = clockRate;
+    }
+
+    /** @hide */
+    MediaTimestamp() {
+        mediaTimeUs = 0;
+        nanoTime = 0;
+        clockRate = 1.0f;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) return true;
+        if (obj == null || getClass() != obj.getClass()) return false;
+
+        final MediaTimestamp that = (MediaTimestamp) obj;
+        return (this.mediaTimeUs == that.mediaTimeUs)
+                && (this.nanoTime == that.nanoTime)
+                && (this.clockRate == that.clockRate);
+    }
+
+    @Override
+    public String toString() {
+        return getClass().getName()
+                + "{AnchorMediaTimeUs=" + mediaTimeUs
+                + " AnchorSystemNanoTime=" + nanoTime
+                + " clockRate=" + clockRate
+                + "}";
+    }
+}
diff --git a/android/media/MediaTranscodingManager.java b/android/media/MediaTranscodingManager.java
new file mode 100644
index 0000000..93d58d0
--- /dev/null
+++ b/android/media/MediaTranscodingManager.java
@@ -0,0 +1,1751 @@
+/*
+ * Copyright (C) 2019 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.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.ActivityManager;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.net.Uri;
+import android.os.Build;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.system.Os;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.modules.annotation.MinSdk;
+import com.android.modules.utils.build.SdkLevel;
+
+import java.io.FileNotFoundException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+/**
+ Android 12 introduces Compatible media transcoding feature.  See
+ <a href="https://developer.android.com/about/versions/12/features#compatible_media_transcoding">
+ Compatible media transcoding</a>. MediaTranscodingManager provides an interface to the system's media
+ transcoding service and can be used to transcode media files, e.g. transcoding a video from HEVC to
+ AVC.
+
+ <h3>Transcoding Types</h3>
+ <h4>Video Transcoding</h4>
+ When transcoding a video file, the video track will be transcoded based on the desired track format
+ and the audio track will be pass through without any modification.
+ <p class=note>
+ Note that currently only support transcoding video file in mp4 format and with single video track.
+
+ <h3>Transcoding Request</h3>
+ <p>
+ To transcode a media file, first create a {@link TranscodingRequest} through its builder class
+ {@link VideoTranscodingRequest.Builder}. Transcode requests are then enqueue to the manager through
+ {@link MediaTranscodingManager#enqueueRequest(
+         TranscodingRequest, Executor, OnTranscodingFinishedListener)}
+ TranscodeRequest are processed based on client process's priority and request priority. When a
+ transcode operation is completed the caller is notified via its
+ {@link OnTranscodingFinishedListener}.
+ In the meantime the caller may use the returned TranscodingSession object to cancel or check the
+ status of a specific transcode operation.
+ <p>
+ Here is an example where <code>Builder</code> is used to specify all parameters
+
+ <pre class=prettyprint>
+ VideoTranscodingRequest request =
+    new VideoTranscodingRequest.Builder(srcUri, dstUri, videoFormat).build();
+ }</pre>
+ @hide
+ */
+@MinSdk(Build.VERSION_CODES.S)
+@SystemApi
+public final class MediaTranscodingManager {
+    private static final String TAG = "MediaTranscodingManager";
+
+    /** Maximum number of retry to connect to the service. */
+    private static final int CONNECT_SERVICE_RETRY_COUNT = 100;
+
+    /** Interval between trying to reconnect to the service. */
+    private static final int INTERVAL_CONNECT_SERVICE_RETRY_MS = 40;
+
+    /** Default bpp(bits-per-pixel) to use for calculating default bitrate. */
+    private static final float BPP = 0.25f;
+
+    /**
+     * Listener that gets notified when a transcoding operation has finished.
+     * This listener gets notified regardless of how the operation finished. It is up to the
+     * listener implementation to check the result and take appropriate action.
+     */
+    @FunctionalInterface
+    public interface OnTranscodingFinishedListener {
+        /**
+         * Called when the transcoding operation has finished. The receiver may use the
+         * TranscodingSession to check the result, i.e. whether the operation succeeded, was
+         * canceled or if an error occurred.
+         *
+         * @param session The TranscodingSession instance for the finished transcoding operation.
+         */
+        void onTranscodingFinished(@NonNull TranscodingSession session);
+    }
+
+    private final Context mContext;
+    private ContentResolver mContentResolver;
+    private final String mPackageName;
+    private final int mPid;
+    private final int mUid;
+    private final boolean mIsLowRamDevice;
+    private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
+    private final HashMap<Integer, TranscodingSession> mPendingTranscodingSessions = new HashMap();
+    private final Object mLock = new Object();
+    @GuardedBy("mLock")
+    @NonNull private ITranscodingClient mTranscodingClient = null;
+    private static MediaTranscodingManager sMediaTranscodingManager;
+
+    private void handleTranscodingFinished(int sessionId, TranscodingResultParcel result) {
+        synchronized (mPendingTranscodingSessions) {
+            // Gets the session associated with the sessionId and removes it from
+            // mPendingTranscodingSessions.
+            final TranscodingSession session = mPendingTranscodingSessions.remove(sessionId);
+
+            if (session == null) {
+                // This should not happen in reality.
+                Log.e(TAG, "Session " + sessionId + " is not in Pendingsessions");
+                return;
+            }
+
+            // Updates the session status and result.
+            session.updateStatusAndResult(TranscodingSession.STATUS_FINISHED,
+                    TranscodingSession.RESULT_SUCCESS,
+                    TranscodingSession.ERROR_NONE);
+
+            // Notifies client the session is done.
+            if (session.mListener != null && session.mListenerExecutor != null) {
+                session.mListenerExecutor.execute(
+                        () -> session.mListener.onTranscodingFinished(session));
+            }
+        }
+    }
+
+    private void handleTranscodingFailed(int sessionId, int errorCode) {
+        synchronized (mPendingTranscodingSessions) {
+            // Gets the session associated with the sessionId and removes it from
+            // mPendingTranscodingSessions.
+            final TranscodingSession session = mPendingTranscodingSessions.remove(sessionId);
+
+            if (session == null) {
+                // This should not happen in reality.
+                Log.e(TAG, "Session " + sessionId + " is not in Pendingsessions");
+                return;
+            }
+
+            // Updates the session status and result.
+            session.updateStatusAndResult(TranscodingSession.STATUS_FINISHED,
+                    TranscodingSession.RESULT_ERROR, errorCode);
+
+            // Notifies client the session failed.
+            if (session.mListener != null && session.mListenerExecutor != null) {
+                session.mListenerExecutor.execute(
+                        () -> session.mListener.onTranscodingFinished(session));
+            }
+        }
+    }
+
+    private void handleTranscodingProgressUpdate(int sessionId, int newProgress) {
+        synchronized (mPendingTranscodingSessions) {
+            // Gets the session associated with the sessionId.
+            final TranscodingSession session = mPendingTranscodingSessions.get(sessionId);
+
+            if (session == null) {
+                // This should not happen in reality.
+                Log.e(TAG, "Session " + sessionId + " is not in Pendingsessions");
+                return;
+            }
+
+            // Updates the session progress.
+            session.updateProgress(newProgress);
+
+            // Notifies client the progress update.
+            if (session.mProgressUpdateExecutor != null
+                    && session.mProgressUpdateListener != null) {
+                session.mProgressUpdateExecutor.execute(
+                        () -> session.mProgressUpdateListener.onProgressUpdate(session,
+                                newProgress));
+            }
+        }
+    }
+
+    private IMediaTranscodingService getService(boolean retry) {
+        // Do not try to get the service on pre-S. The service is lazy-start and getting the
+        // service could block.
+        if (!SdkLevel.isAtLeastS()) {
+            return null;
+        }
+        // Do not try to get the service on AndroidGo (low-ram) devices.
+        if (mIsLowRamDevice) {
+            return null;
+        }
+        int retryCount = !retry ? 1 :  CONNECT_SERVICE_RETRY_COUNT;
+        Log.i(TAG, "get service with retry " + retryCount);
+        for (int count = 1;  count <= retryCount; count++) {
+            Log.d(TAG, "Trying to connect to service. Try count: " + count);
+            IMediaTranscodingService service = IMediaTranscodingService.Stub.asInterface(
+                    MediaFrameworkInitializer
+                    .getMediaServiceManager()
+                    .getMediaTranscodingServiceRegisterer()
+                    .get());
+            if (service != null) {
+                return service;
+            }
+            try {
+                // Sleep a bit before retry.
+                Thread.sleep(INTERVAL_CONNECT_SERVICE_RETRY_MS);
+            } catch (InterruptedException ie) {
+                /* ignore */
+            }
+        }
+        Log.w(TAG, "Failed to get service");
+        return null;
+    }
+
+    /*
+     * Handle client binder died event.
+     * Upon receiving a binder died event of the client, we will do the following:
+     * 1) For the session that is running, notify the client that the session is failed with
+     *    error code,  so client could choose to retry the session or not.
+     *    TODO(hkuang): Add a new error code to signal service died error.
+     * 2) For the sessions that is still pending or paused, we will resubmit the session
+     *    once we successfully reconnect to the service and register a new client.
+     * 3) When trying to connect to the service and register a new client. The service may need time
+     *    to reboot or never boot up again. So we will retry for a number of times. If we still
+     *    could not connect, we will notify client session failure for the pending and paused
+     *    sessions.
+     */
+    private void onClientDied() {
+        synchronized (mLock) {
+            mTranscodingClient = null;
+        }
+
+        // Delegates the session notification and retry to the executor as it may take some time.
+        mExecutor.execute(() -> {
+            // List to track the sessions that we want to retry.
+            List<TranscodingSession> retrySessions = new ArrayList<TranscodingSession>();
+
+            // First notify the client of session failure for all the running sessions.
+            synchronized (mPendingTranscodingSessions) {
+                for (Map.Entry<Integer, TranscodingSession> entry :
+                        mPendingTranscodingSessions.entrySet()) {
+                    TranscodingSession session = entry.getValue();
+
+                    if (session.getStatus() == TranscodingSession.STATUS_RUNNING) {
+                        session.updateStatusAndResult(TranscodingSession.STATUS_FINISHED,
+                                TranscodingSession.RESULT_ERROR,
+                                TranscodingSession.ERROR_SERVICE_DIED);
+
+                        // Remove the session from pending sessions.
+                        mPendingTranscodingSessions.remove(entry.getKey());
+
+                        if (session.mListener != null && session.mListenerExecutor != null) {
+                            Log.i(TAG, "Notify client session failed");
+                            session.mListenerExecutor.execute(
+                                    () -> session.mListener.onTranscodingFinished(session));
+                        }
+                    } else if (session.getStatus() == TranscodingSession.STATUS_PENDING
+                            || session.getStatus() == TranscodingSession.STATUS_PAUSED) {
+                        // Add the session to retrySessions to handle them later.
+                        retrySessions.add(session);
+                    }
+                }
+            }
+
+            // Try to register with the service once it boots up.
+            IMediaTranscodingService service = getService(true /*retry*/);
+            boolean haveTranscodingClient = false;
+            if (service != null) {
+                synchronized (mLock) {
+                    mTranscodingClient = registerClient(service);
+                    if (mTranscodingClient != null) {
+                        haveTranscodingClient = true;
+                    }
+                }
+            }
+
+            for (TranscodingSession session : retrySessions) {
+                // Notify the session failure if we fails to connect to the service or fail
+                // to retry the session.
+                if (!haveTranscodingClient) {
+                    // TODO(hkuang): Return correct error code to the client.
+                    handleTranscodingFailed(session.getSessionId(), 0 /*unused */);
+                }
+
+                try {
+                    // Do not set hasRetried for retry initiated by MediaTranscodingManager.
+                    session.retryInternal(false /*setHasRetried*/);
+                } catch (Exception re) {
+                    // TODO(hkuang): Return correct error code to the client.
+                    handleTranscodingFailed(session.getSessionId(), 0 /*unused */);
+                }
+            }
+        });
+    }
+
+    private void updateStatus(int sessionId, int status) {
+        synchronized (mPendingTranscodingSessions) {
+            final TranscodingSession session = mPendingTranscodingSessions.get(sessionId);
+
+            if (session == null) {
+                // This should not happen in reality.
+                Log.e(TAG, "Session " + sessionId + " is not in Pendingsessions");
+                return;
+            }
+
+            // Updates the session status.
+            session.updateStatus(status);
+        }
+    }
+
+    // Just forwards all the events to the event handler.
+    private ITranscodingClientCallback mTranscodingClientCallback =
+            new ITranscodingClientCallback.Stub() {
+                // TODO(hkuang): Add more unit test to test difference file open mode.
+                @Override
+                public ParcelFileDescriptor openFileDescriptor(String fileUri, String mode)
+                        throws RemoteException {
+                    if (!mode.equals("r") && !mode.equals("w") && !mode.equals("rw")) {
+                        Log.e(TAG, "Unsupport mode: " + mode);
+                        return null;
+                    }
+
+                    Uri uri = Uri.parse(fileUri);
+                    try {
+                        AssetFileDescriptor afd = mContentResolver.openAssetFileDescriptor(uri,
+                                mode);
+                        if (afd != null) {
+                            return afd.getParcelFileDescriptor();
+                        }
+                    } catch (FileNotFoundException e) {
+                        Log.w(TAG, "Cannot find content uri: " + uri, e);
+                    } catch (SecurityException e) {
+                        Log.w(TAG, "Cannot open content uri: " + uri, e);
+                    } catch (Exception e) {
+                        Log.w(TAG, "Unknown content uri: " + uri, e);
+                    }
+                    return null;
+                }
+
+                @Override
+                public void onTranscodingStarted(int sessionId) throws RemoteException {
+                    updateStatus(sessionId, TranscodingSession.STATUS_RUNNING);
+                }
+
+                @Override
+                public void onTranscodingPaused(int sessionId) throws RemoteException {
+                    updateStatus(sessionId, TranscodingSession.STATUS_PAUSED);
+                }
+
+                @Override
+                public void onTranscodingResumed(int sessionId) throws RemoteException {
+                    updateStatus(sessionId, TranscodingSession.STATUS_RUNNING);
+                }
+
+                @Override
+                public void onTranscodingFinished(int sessionId, TranscodingResultParcel result)
+                        throws RemoteException {
+                    handleTranscodingFinished(sessionId, result);
+                }
+
+                @Override
+                public void onTranscodingFailed(int sessionId, int errorCode)
+                        throws RemoteException {
+                    handleTranscodingFailed(sessionId, errorCode);
+                }
+
+                @Override
+                public void onAwaitNumberOfSessionsChanged(int sessionId, int oldAwaitNumber,
+                        int newAwaitNumber) throws RemoteException {
+                    //TODO(hkuang): Implement this.
+                }
+
+                @Override
+                public void onProgressUpdate(int sessionId, int newProgress)
+                        throws RemoteException {
+                    handleTranscodingProgressUpdate(sessionId, newProgress);
+                }
+            };
+
+    private ITranscodingClient registerClient(IMediaTranscodingService service) {
+        synchronized (mLock) {
+            try {
+                // Registers the client with MediaTranscoding service.
+                mTranscodingClient = service.registerClient(
+                        mTranscodingClientCallback,
+                        mPackageName,
+                        mPackageName);
+
+                if (mTranscodingClient != null) {
+                    mTranscodingClient.asBinder().linkToDeath(() -> onClientDied(), /* flags */ 0);
+                }
+            } catch (Exception ex) {
+                Log.e(TAG, "Failed to register new client due to exception " + ex);
+                mTranscodingClient = null;
+            }
+        }
+        return mTranscodingClient;
+    }
+
+    /**
+     * @hide
+     */
+    public MediaTranscodingManager(@NonNull Context context) {
+        mContext = context;
+        mContentResolver = mContext.getContentResolver();
+        mPackageName = mContext.getPackageName();
+        mUid = Os.getuid();
+        mPid = Os.getpid();
+        mIsLowRamDevice = mContext.getSystemService(ActivityManager.class).isLowRamDevice();
+    }
+
+    /**
+     * Abstract base class for all the TranscodingRequest.
+     * <p> TranscodingRequest encapsulates the desired configuration for the transcoding.
+     */
+    public abstract static class TranscodingRequest {
+        /**
+         *
+         * Default transcoding type.
+         * @hide
+         */
+        public static final int TRANSCODING_TYPE_UNKNOWN = 0;
+
+        /**
+         * TRANSCODING_TYPE_VIDEO indicates that client wants to perform transcoding on a video.
+         * <p>Note that currently only support transcoding video file in mp4 format.
+         * @hide
+         */
+        public static final int TRANSCODING_TYPE_VIDEO = 1;
+
+        /**
+         * TRANSCODING_TYPE_IMAGE indicates that client wants to perform transcoding on an image.
+         * @hide
+         */
+        public static final int TRANSCODING_TYPE_IMAGE = 2;
+
+        /** @hide */
+        @IntDef(prefix = {"TRANSCODING_TYPE_"}, value = {
+                TRANSCODING_TYPE_UNKNOWN,
+                TRANSCODING_TYPE_VIDEO,
+                TRANSCODING_TYPE_IMAGE,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface TranscodingType {}
+
+        /**
+         * Default value.
+         *
+         * @hide
+         */
+        public static final int PRIORITY_UNKNOWN = 0;
+        /**
+         * PRIORITY_REALTIME indicates that the transcoding request is time-critical and that the
+         * client wants the transcoding result as soon as possible.
+         * <p> Set PRIORITY_REALTIME only if the transcoding is time-critical as it will involve
+         * performance penalty due to resource reallocation to prioritize the sessions with higher
+         * priority.
+         *
+         * @hide
+         */
+        public static final int PRIORITY_REALTIME = 1;
+
+        /**
+         * PRIORITY_OFFLINE indicates the transcoding is not time-critical and the client does not
+         * need the transcoding result as soon as possible.
+         * <p>Sessions with PRIORITY_OFFLINE will be scheduled behind PRIORITY_REALTIME. Always set
+         * to
+         * PRIORITY_OFFLINE if client does not need the result as soon as possible and could accept
+         * delay of the transcoding result.
+         *
+         * @hide
+         *
+         */
+        public static final int PRIORITY_OFFLINE = 2;
+
+        /** @hide */
+        @IntDef(prefix = {"PRIORITY_"}, value = {
+                PRIORITY_UNKNOWN,
+                PRIORITY_REALTIME,
+                PRIORITY_OFFLINE,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface TranscodingPriority {}
+
+        /** Uri of the source media file. */
+        private @NonNull Uri mSourceUri;
+
+        /** Uri of the destination media file. */
+        private @NonNull Uri mDestinationUri;
+
+        /** FileDescriptor of the source media file. */
+        private @Nullable ParcelFileDescriptor mSourceFileDescriptor;
+
+        /** FileDescriptor of the destination media file. */
+        private @Nullable ParcelFileDescriptor mDestinationFileDescriptor;
+
+        /**
+         *  The UID of the client that the TranscodingRequest is for. Only privileged caller could
+         *  set this Uid as only they could do the transcoding on behalf of the client.
+         *  -1 means not available.
+         */
+        private int mClientUid = -1;
+
+        /**
+         *  The Pid of the client that the TranscodingRequest is for. Only privileged caller could
+         *  set this Uid as only they could do the transcoding on behalf of the client.
+         *  -1 means not available.
+         */
+        private int mClientPid = -1;
+
+        /** Type of the transcoding. */
+        private @TranscodingType int mType = TRANSCODING_TYPE_UNKNOWN;
+
+        /** Priority of the transcoding. */
+        private @TranscodingPriority int mPriority = PRIORITY_UNKNOWN;
+
+        /**
+         * Desired image format for the destination file.
+         * <p> If this is null, source file's image track will be passed through and copied to the
+         * destination file.
+         * @hide
+         */
+        private @Nullable MediaFormat mImageFormat = null;
+
+        @VisibleForTesting
+        private TranscodingTestConfig mTestConfig = null;
+
+        /**
+         * Prevent public constructor access.
+         */
+        /* package private */ TranscodingRequest() {
+        }
+
+        private TranscodingRequest(Builder b) {
+            mSourceUri = b.mSourceUri;
+            mSourceFileDescriptor = b.mSourceFileDescriptor;
+            mDestinationUri = b.mDestinationUri;
+            mDestinationFileDescriptor = b.mDestinationFileDescriptor;
+            mClientUid = b.mClientUid;
+            mClientPid = b.mClientPid;
+            mPriority = b.mPriority;
+            mType = b.mType;
+            mTestConfig = b.mTestConfig;
+        }
+
+        /**
+         * Return the type of the transcoding.
+         * @hide
+         */
+        @TranscodingType
+        public int getType() {
+            return mType;
+        }
+
+        /** Return source uri of the transcoding. */
+        @NonNull
+        public Uri getSourceUri() {
+            return mSourceUri;
+        }
+
+        /**
+         * Return source file descriptor of the transcoding.
+         * This will be null if client has not provided it.
+         */
+        @Nullable
+        public ParcelFileDescriptor getSourceFileDescriptor() {
+            return mSourceFileDescriptor;
+        }
+
+        /** Return the UID of the client that this request is for. -1 means not available. */
+        public int getClientUid() {
+            return mClientUid;
+        }
+
+        /** Return the PID of the client that this request is for. -1 means not available. */
+        public int getClientPid() {
+            return mClientPid;
+        }
+
+        /** Return destination uri of the transcoding. */
+        @NonNull
+        public Uri getDestinationUri() {
+            return mDestinationUri;
+        }
+
+        /**
+         * Return destination file descriptor of the transcoding.
+         * This will be null if client has not provided it.
+         */
+        @Nullable
+        public ParcelFileDescriptor getDestinationFileDescriptor() {
+            return mDestinationFileDescriptor;
+        }
+
+        /**
+         * Return priority of the transcoding.
+         * @hide
+         */
+        @TranscodingPriority
+        public int getPriority() {
+            return mPriority;
+        }
+
+        /**
+         * Return TestConfig of the transcoding.
+         * @hide
+         */
+        @Nullable
+        public TranscodingTestConfig getTestConfig() {
+            return mTestConfig;
+        }
+
+        abstract void writeFormatToParcel(TranscodingRequestParcel parcel);
+
+        /* Writes the TranscodingRequest to a parcel. */
+        private TranscodingRequestParcel writeToParcel(@NonNull Context context) {
+            TranscodingRequestParcel parcel = new TranscodingRequestParcel();
+            switch (mPriority) {
+            case PRIORITY_OFFLINE:
+                parcel.priority = TranscodingSessionPriority.kUnspecified;
+                break;
+            case PRIORITY_REALTIME:
+            case PRIORITY_UNKNOWN:
+            default:
+                parcel.priority = TranscodingSessionPriority.kNormal;
+                break;
+            }
+            parcel.transcodingType = mType;
+            parcel.sourceFilePath = mSourceUri.toString();
+            parcel.sourceFd = mSourceFileDescriptor;
+            parcel.destinationFilePath = mDestinationUri.toString();
+            parcel.destinationFd = mDestinationFileDescriptor;
+            parcel.clientUid = mClientUid;
+            parcel.clientPid = mClientPid;
+            if (mClientUid < 0) {
+                parcel.clientPackageName = context.getPackageName();
+            } else {
+                String packageName = context.getPackageManager().getNameForUid(mClientUid);
+                // PackageName is optional as some uid does not have package name. Set to
+                // "Unavailable" string in this case.
+                if (packageName == null) {
+                    Log.w(TAG, "Failed to find package for uid: " + mClientUid);
+                    packageName = "Unavailable";
+                }
+                parcel.clientPackageName = packageName;
+            }
+            writeFormatToParcel(parcel);
+            if (mTestConfig != null) {
+                parcel.isForTesting = true;
+                parcel.testConfig = mTestConfig;
+            }
+            return parcel;
+        }
+
+        /**
+         * Builder to build a {@link TranscodingRequest} object.
+         *
+         * @param <T> The subclass to be built.
+         */
+        abstract static class Builder<T extends Builder<T>> {
+            private @NonNull Uri mSourceUri;
+            private @NonNull Uri mDestinationUri;
+            private @Nullable ParcelFileDescriptor mSourceFileDescriptor = null;
+            private @Nullable ParcelFileDescriptor mDestinationFileDescriptor = null;
+            private int mClientUid = -1;
+            private int mClientPid = -1;
+            private @TranscodingType int mType = TRANSCODING_TYPE_UNKNOWN;
+            private @TranscodingPriority int mPriority = PRIORITY_UNKNOWN;
+            private TranscodingTestConfig mTestConfig;
+
+            abstract T self();
+
+            /**
+             * Creates a builder for building {@link TranscodingRequest}s.
+             *
+             * Client must set the source Uri. If client also provides the source fileDescriptor
+             * through is provided by {@link #setSourceFileDescriptor(ParcelFileDescriptor)},
+             * TranscodingSession will use the fd instead of calling back to the client to open the
+             * sourceUri.
+             *
+             *
+             * @param type The transcoding type.
+             * @param sourceUri Content uri for the source media file.
+             * @param destinationUri Content uri for the destination media file.
+             *
+             */
+            private Builder(@TranscodingType int type, @NonNull Uri sourceUri,
+                    @NonNull Uri destinationUri) {
+                mType = type;
+
+                if (sourceUri == null || Uri.EMPTY.equals(sourceUri)) {
+                    throw new IllegalArgumentException(
+                            "You must specify a non-empty source Uri.");
+                }
+                mSourceUri = sourceUri;
+
+                if (destinationUri == null || Uri.EMPTY.equals(destinationUri)) {
+                    throw new IllegalArgumentException(
+                            "You must specify a non-empty destination Uri.");
+                }
+                mDestinationUri = destinationUri;
+            }
+
+            /**
+             * Specifies the fileDescriptor opened from the source media file.
+             *
+             * This call is optional. If the source fileDescriptor is provided, TranscodingSession
+             * will use it directly instead of opening the uri from {@link #Builder(int, Uri, Uri)}.
+             * It is client's responsibility to make sure the fileDescriptor is opened from the
+             * source uri.
+             * @param fileDescriptor a {@link ParcelFileDescriptor} opened from source media file.
+             * @return The same builder instance.
+             * @throws IllegalArgumentException if fileDescriptor is invalid.
+             */
+            @NonNull
+            public T setSourceFileDescriptor(@NonNull ParcelFileDescriptor fileDescriptor) {
+                if (fileDescriptor == null || fileDescriptor.getFd() < 0) {
+                    throw new IllegalArgumentException(
+                            "Invalid source descriptor.");
+                }
+                mSourceFileDescriptor = fileDescriptor;
+                return self();
+            }
+
+            /**
+             * Specifies the fileDescriptor opened from the destination media file.
+             *
+             * This call is optional. If the destination fileDescriptor is provided,
+             * TranscodingSession will use it directly instead of opening the source uri from
+             * {@link #Builder(int, Uri, Uri)} upon transcoding starts. It is client's
+             * responsibility to make sure the fileDescriptor is opened from the destination uri.
+             * @param fileDescriptor a {@link ParcelFileDescriptor} opened from destination media
+             *                       file.
+             * @return The same builder instance.
+             * @throws IllegalArgumentException if fileDescriptor is invalid.
+             */
+            @NonNull
+            public T setDestinationFileDescriptor(
+                    @NonNull ParcelFileDescriptor fileDescriptor) {
+                if (fileDescriptor == null || fileDescriptor.getFd() < 0) {
+                    throw new IllegalArgumentException(
+                            "Invalid destination descriptor.");
+                }
+                mDestinationFileDescriptor = fileDescriptor;
+                return self();
+            }
+
+            /**
+             * Specify the UID of the client that this request is for.
+             * <p>
+             * Only privilege caller with android.permission.WRITE_MEDIA_STORAGE could forward the
+             * pid. Note that the permission check happens on the service side upon starting the
+             * transcoding. If the client does not have the permission, the transcoding will fail.
+             *
+             * @param uid client Uid.
+             * @return The same builder instance.
+             * @throws IllegalArgumentException if uid is invalid.
+             */
+            @NonNull
+            public T setClientUid(int uid) {
+                if (uid < 0) {
+                    throw new IllegalArgumentException("Invalid Uid");
+                }
+                mClientUid = uid;
+                return self();
+            }
+
+            /**
+             * Specify the pid of the client that this request is for.
+             * <p>
+             * Only privilege caller with android.permission.WRITE_MEDIA_STORAGE could forward the
+             * pid. Note that the permission check happens on the service side upon starting the
+             * transcoding. If the client does not have the permission, the transcoding will fail.
+             *
+             * @param pid client Pid.
+             * @return The same builder instance.
+             * @throws IllegalArgumentException if pid is invalid.
+             */
+            @NonNull
+            public T setClientPid(int pid) {
+                if (pid < 0) {
+                    throw new IllegalArgumentException("Invalid pid");
+                }
+                mClientPid = pid;
+                return self();
+            }
+
+            /**
+             * Specifies the priority of the transcoding.
+             *
+             * @param priority Must be one of the {@code PRIORITY_*}
+             * @return The same builder instance.
+             * @throws IllegalArgumentException if flags is invalid.
+             * @hide
+             */
+            @NonNull
+            public T setPriority(@TranscodingPriority int priority) {
+                if (priority != PRIORITY_OFFLINE && priority != PRIORITY_REALTIME) {
+                    throw new IllegalArgumentException("Invalid priority: " + priority);
+                }
+                mPriority = priority;
+                return self();
+            }
+
+            /**
+             * Sets the delay in processing this request.
+             * @param config test config.
+             * @return The same builder instance.
+             * @hide
+             */
+            @VisibleForTesting
+            @NonNull
+            public T setTestConfig(@NonNull TranscodingTestConfig config) {
+                mTestConfig = config;
+                return self();
+            }
+        }
+
+        /**
+         * Abstract base class for all the format resolvers.
+         */
+        abstract static class MediaFormatResolver {
+            private @NonNull ApplicationMediaCapabilities mClientCaps;
+
+            /**
+             * Prevents public constructor access.
+             */
+            /* package private */ MediaFormatResolver() {
+            }
+
+            /**
+             * Constructs MediaFormatResolver object.
+             *
+             * @param clientCaps An ApplicationMediaCapabilities object containing the client's
+             *                   capabilities.
+             */
+            MediaFormatResolver(@NonNull ApplicationMediaCapabilities clientCaps) {
+                if (clientCaps == null) {
+                    throw new IllegalArgumentException("Client capabilities must not be null");
+                }
+                mClientCaps = clientCaps;
+            }
+
+            /**
+             * Returns the client capabilities.
+             */
+            @NonNull
+            /* package */ ApplicationMediaCapabilities getClientCapabilities() {
+                return mClientCaps;
+            }
+
+            abstract boolean shouldTranscode();
+        }
+
+        /**
+         * VideoFormatResolver for deciding if video transcoding is needed, and if so, the track
+         * formats to use.
+         */
+        public static class VideoFormatResolver extends MediaFormatResolver {
+            private static final int BIT_RATE = 20000000;            // 20Mbps
+
+            private MediaFormat mSrcVideoFormatHint;
+            private MediaFormat mSrcAudioFormatHint;
+
+            /**
+             * Constructs a new VideoFormatResolver object.
+             *
+             * @param clientCaps An ApplicationMediaCapabilities object containing the client's
+             *                   capabilities.
+             * @param srcVideoFormatHint A MediaFormat object containing information about the
+             *                           source's video track format that could affect the
+             *                           transcoding decision. Such information could include video
+             *                           codec types, color spaces, whether special format info (eg.
+             *                           slow-motion markers) are present, etc.. If a particular
+             *                           information is not present, it will not be used to make the
+             *                           decision.
+             */
+            public VideoFormatResolver(@NonNull ApplicationMediaCapabilities clientCaps,
+                    @NonNull MediaFormat srcVideoFormatHint) {
+                super(clientCaps);
+                mSrcVideoFormatHint = srcVideoFormatHint;
+            }
+
+            /**
+             * Constructs a new VideoFormatResolver object.
+             *
+             * @param clientCaps An ApplicationMediaCapabilities object containing the client's
+             *                   capabilities.
+             * @param srcVideoFormatHint A MediaFormat object containing information about the
+             *                           source's video track format that could affect the
+             *                           transcoding decision. Such information could include video
+             *                           codec types, color spaces, whether special format info (eg.
+             *                           slow-motion markers) are present, etc.. If a particular
+             *                           information is not present, it will not be used to make the
+             *                           decision.
+             * @param srcAudioFormatHint A MediaFormat object containing information about the
+             *                           source's audio track format that could affect the
+             *                           transcoding decision.
+             * @hide
+             */
+            VideoFormatResolver(@NonNull ApplicationMediaCapabilities clientCaps,
+                    @NonNull MediaFormat srcVideoFormatHint,
+                    @NonNull MediaFormat srcAudioFormatHint) {
+                super(clientCaps);
+                mSrcVideoFormatHint = srcVideoFormatHint;
+                mSrcAudioFormatHint = srcAudioFormatHint;
+            }
+
+            /**
+             * Returns whether the source content should be transcoded.
+             *
+             * @return true if the source should be transcoded.
+             */
+            public boolean shouldTranscode() {
+                boolean supportHevc = getClientCapabilities().isVideoMimeTypeSupported(
+                        MediaFormat.MIMETYPE_VIDEO_HEVC);
+                if (!supportHevc && MediaFormat.MIMETYPE_VIDEO_HEVC.equals(
+                        mSrcVideoFormatHint.getString(MediaFormat.KEY_MIME))) {
+                    return true;
+                }
+                // TODO: add more checks as needed below.
+                return false;
+            }
+
+            /**
+             * Retrieves the video track format to be used on
+             * {@link VideoTranscodingRequest.Builder#setVideoTrackFormat(MediaFormat)} for this
+             * configuration.
+             *
+             * @return the video track format to be used if transcoding should be performed,
+             *         and null otherwise.
+             */
+            @Nullable
+            public MediaFormat resolveVideoFormat() {
+                if (!shouldTranscode()) {
+                    return null;
+                }
+
+                MediaFormat videoTrackFormat = new MediaFormat(mSrcVideoFormatHint);
+                videoTrackFormat.setString(MediaFormat.KEY_MIME, MediaFormat.MIMETYPE_VIDEO_AVC);
+
+                int width = mSrcVideoFormatHint.getInteger(MediaFormat.KEY_WIDTH);
+                int height = mSrcVideoFormatHint.getInteger(MediaFormat.KEY_HEIGHT);
+                if (width <= 0 || height <= 0) {
+                    throw new IllegalArgumentException(
+                            "Source Width and height must be larger than 0");
+                }
+
+                float frameRate = 30.0f; // default to 30fps.
+                if (mSrcVideoFormatHint.containsKey(MediaFormat.KEY_FRAME_RATE)) {
+                    frameRate = mSrcVideoFormatHint.getFloat(MediaFormat.KEY_FRAME_RATE);
+                    if (frameRate <= 0) {
+                        throw new IllegalArgumentException(
+                                "frameRate must be larger than 0");
+                    }
+                }
+
+                int bitrate = getAVCBitrate(width, height, frameRate);
+                videoTrackFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate);
+                return videoTrackFormat;
+            }
+
+            /**
+             * Generate a default bitrate with the fixed bpp(bits-per-pixel) 0.25.
+             * This maps to:
+             * 1080P@30fps -> 16Mbps
+             * 1080P@60fps-> 32Mbps
+             * 4K@30fps -> 62Mbps
+             */
+            private static int getDefaultBitrate(int width, int height, float frameRate) {
+                return (int) (width * height * frameRate * BPP);
+            }
+
+            /**
+             * Query the bitrate from CamcorderProfile. If there are two profiles that match the
+             * width/height/framerate, we will use the higher one to get better quality.
+             * Return default bitrate if could not find any match profile.
+             */
+            private static int getAVCBitrate(int width, int height, float frameRate) {
+                int bitrate = -1;
+                int[] cameraIds = {0, 1};
+
+                // Profiles ordered in decreasing order of preference.
+                int[] preferQualities = {
+                        CamcorderProfile.QUALITY_2160P,
+                        CamcorderProfile.QUALITY_1080P,
+                        CamcorderProfile.QUALITY_720P,
+                        CamcorderProfile.QUALITY_480P,
+                        CamcorderProfile.QUALITY_LOW,
+                };
+
+                for (int cameraId : cameraIds) {
+                    for (int quality : preferQualities) {
+                        // Check if camera id has profile for the quality level.
+                        if (!CamcorderProfile.hasProfile(cameraId, quality)) {
+                            continue;
+                        }
+                        CamcorderProfile profile = CamcorderProfile.get(cameraId, quality);
+                        // Check the width/height/framerate/codec, also consider portrait case.
+                        if (((width == profile.videoFrameWidth
+                                && height == profile.videoFrameHeight)
+                                || (height == profile.videoFrameWidth
+                                && width == profile.videoFrameHeight))
+                                && (int) frameRate == profile.videoFrameRate
+                                && profile.videoCodec == MediaRecorder.VideoEncoder.H264) {
+                            if (bitrate < profile.videoBitRate) {
+                                bitrate = profile.videoBitRate;
+                            }
+                            break;
+                        }
+                    }
+                }
+
+                if (bitrate == -1) {
+                    Log.w(TAG, "Failed to find CamcorderProfile for w: " + width + "h: " + height
+                            + " fps: "
+                            + frameRate);
+                    bitrate = getDefaultBitrate(width, height, frameRate);
+                }
+                Log.d(TAG, "Using bitrate " + bitrate + " for " + width + " " + height + " "
+                        + frameRate);
+                return bitrate;
+            }
+
+            /**
+             * Retrieves the audio track format to be used for transcoding.
+             *
+             * @return the audio track format to be used if transcoding should be performed, and
+             *         null otherwise.
+             * @hide
+             */
+            @Nullable
+            public MediaFormat resolveAudioFormat() {
+                if (!shouldTranscode()) {
+                    return null;
+                }
+                // Audio transcoding is not supported yet, always return null.
+                return null;
+            }
+        }
+    }
+
+    /**
+     * VideoTranscodingRequest encapsulates the configuration for transcoding a video.
+     */
+    public static final class VideoTranscodingRequest extends TranscodingRequest {
+        /**
+         * Desired output video format of the destination file.
+         * <p> If this is null, source file's video track will be passed through and copied to the
+         * destination file.
+         */
+        private @Nullable MediaFormat mVideoTrackFormat = null;
+
+        /**
+         * Desired output audio format of the destination file.
+         * <p> If this is null, source file's audio track will be passed through and copied to the
+         * destination file.
+         */
+        private @Nullable MediaFormat mAudioTrackFormat = null;
+
+        private VideoTranscodingRequest(VideoTranscodingRequest.Builder builder) {
+            super(builder);
+            mVideoTrackFormat = builder.mVideoTrackFormat;
+            mAudioTrackFormat = builder.mAudioTrackFormat;
+        }
+
+        /**
+         * Return the video track format of the transcoding.
+         * This will be null if client has not specified the video track format.
+         */
+        @NonNull
+        public MediaFormat getVideoTrackFormat() {
+            return mVideoTrackFormat;
+        }
+
+        @Override
+        void writeFormatToParcel(TranscodingRequestParcel parcel) {
+            parcel.requestedVideoTrackFormat = convertToVideoTrackFormat(mVideoTrackFormat);
+        }
+
+        /* Converts the MediaFormat to TranscodingVideoTrackFormat. */
+        private static TranscodingVideoTrackFormat convertToVideoTrackFormat(MediaFormat format) {
+            if (format == null) {
+                throw new IllegalArgumentException("Invalid MediaFormat");
+            }
+
+            TranscodingVideoTrackFormat trackFormat = new TranscodingVideoTrackFormat();
+
+            if (format.containsKey(MediaFormat.KEY_MIME)) {
+                String mime = format.getString(MediaFormat.KEY_MIME);
+                if (MediaFormat.MIMETYPE_VIDEO_AVC.equals(mime)) {
+                    trackFormat.codecType = TranscodingVideoCodecType.kAvc;
+                } else if (MediaFormat.MIMETYPE_VIDEO_HEVC.equals(mime)) {
+                    trackFormat.codecType = TranscodingVideoCodecType.kHevc;
+                } else {
+                    throw new UnsupportedOperationException("Only support transcode to avc/hevc");
+                }
+            }
+
+            if (format.containsKey(MediaFormat.KEY_BIT_RATE)) {
+                int bitrateBps = format.getInteger(MediaFormat.KEY_BIT_RATE);
+                if (bitrateBps <= 0) {
+                    throw new IllegalArgumentException("Bitrate must be larger than 0");
+                }
+                trackFormat.bitrateBps = bitrateBps;
+            }
+
+            if (format.containsKey(MediaFormat.KEY_WIDTH) && format.containsKey(
+                    MediaFormat.KEY_HEIGHT)) {
+                int width = format.getInteger(MediaFormat.KEY_WIDTH);
+                int height = format.getInteger(MediaFormat.KEY_HEIGHT);
+                if (width <= 0 || height <= 0) {
+                    throw new IllegalArgumentException("Width and height must be larger than 0");
+                }
+                // TODO: Validate the aspect ratio after adding scaling.
+                trackFormat.width = width;
+                trackFormat.height = height;
+            }
+
+            if (format.containsKey(MediaFormat.KEY_PROFILE)) {
+                int profile = format.getInteger(MediaFormat.KEY_PROFILE);
+                if (profile <= 0) {
+                    throw new IllegalArgumentException("Invalid codec profile");
+                }
+                // TODO: Validate the profile according to codec type.
+                trackFormat.profile = profile;
+            }
+
+            if (format.containsKey(MediaFormat.KEY_LEVEL)) {
+                int level = format.getInteger(MediaFormat.KEY_LEVEL);
+                if (level <= 0) {
+                    throw new IllegalArgumentException("Invalid codec level");
+                }
+                // TODO: Validate the level according to codec type.
+                trackFormat.level = level;
+            }
+
+            return trackFormat;
+        }
+
+        /**
+         * Builder class for {@link VideoTranscodingRequest}.
+         */
+        public static final class Builder extends
+                TranscodingRequest.Builder<VideoTranscodingRequest.Builder> {
+            /**
+             * Desired output video format of the destination file.
+             * <p> If this is null, source file's video track will be passed through and
+             * copied to the destination file.
+             */
+            private @Nullable MediaFormat mVideoTrackFormat = null;
+
+            /**
+             * Desired output audio format of the destination file.
+             * <p> If this is null, source file's audio track will be passed through and copied
+             * to the destination file.
+             */
+            private @Nullable MediaFormat mAudioTrackFormat = null;
+
+            /**
+             * Creates a builder for building {@link VideoTranscodingRequest}s.
+             *
+             * <p> Client could only specify the settings that matters to them, e.g. codec format or
+             * bitrate. And by default, transcoding will preserve the original video's settings
+             * (bitrate, framerate, resolution) if not provided.
+             * <p>Note that some settings may silently fail to apply if the device does not support
+             * them.
+             * @param sourceUri Content uri for the source media file.
+             * @param destinationUri Content uri for the destination media file.
+             * @param videoFormat MediaFormat containing the settings that client wants override in
+             *                    the original video's video track.
+             * @throws IllegalArgumentException if videoFormat is invalid.
+             */
+            public Builder(@NonNull Uri sourceUri, @NonNull Uri destinationUri,
+                    @NonNull MediaFormat videoFormat) {
+                super(TRANSCODING_TYPE_VIDEO, sourceUri, destinationUri);
+                setVideoTrackFormat(videoFormat);
+            }
+
+            @Override
+            @NonNull
+            public Builder setClientUid(int uid) {
+                super.setClientUid(uid);
+                return self();
+            }
+
+            @Override
+            @NonNull
+            public Builder setClientPid(int pid) {
+                super.setClientPid(pid);
+                return self();
+            }
+
+            @Override
+            @NonNull
+            public Builder setSourceFileDescriptor(@NonNull ParcelFileDescriptor fd) {
+                super.setSourceFileDescriptor(fd);
+                return self();
+            }
+
+            @Override
+            @NonNull
+            public Builder setDestinationFileDescriptor(@NonNull ParcelFileDescriptor fd) {
+                super.setDestinationFileDescriptor(fd);
+                return self();
+            }
+
+            private void setVideoTrackFormat(@NonNull MediaFormat videoFormat) {
+                if (videoFormat == null) {
+                    throw new IllegalArgumentException("videoFormat must not be null");
+                }
+
+                // Check if the MediaFormat is for video by looking at the MIME type.
+                String mime = videoFormat.containsKey(MediaFormat.KEY_MIME)
+                        ? videoFormat.getString(MediaFormat.KEY_MIME) : null;
+                if (mime == null || !mime.startsWith("video/")) {
+                    throw new IllegalArgumentException("Invalid video format: wrong mime type");
+                }
+
+                mVideoTrackFormat = videoFormat;
+            }
+
+            /**
+             * @return a new {@link TranscodingRequest} instance successfully initialized
+             * with all the parameters set on this <code>Builder</code>.
+             * @throws UnsupportedOperationException if the parameters set on the
+             *                                       <code>Builder</code> were incompatible, or
+             *                                       if they are not supported by the
+             *                                       device.
+             */
+            @NonNull
+            public VideoTranscodingRequest build() {
+                return new VideoTranscodingRequest(this);
+            }
+
+            @Override
+            VideoTranscodingRequest.Builder self() {
+                return this;
+            }
+        }
+    }
+
+    /**
+     * Handle to an enqueued transcoding operation. An instance of this class represents a single
+     * enqueued transcoding operation. The caller can use that instance to query the status or
+     * progress, and to get the result once the operation has completed.
+     */
+    public static final class TranscodingSession {
+        /** The session is enqueued but not yet running. */
+        public static final int STATUS_PENDING = 1;
+        /** The session is currently running. */
+        public static final int STATUS_RUNNING = 2;
+        /** The session is finished. */
+        public static final int STATUS_FINISHED = 3;
+        /** The session is paused. */
+        public static final int STATUS_PAUSED = 4;
+
+        /** @hide */
+        @IntDef(prefix = { "STATUS_" }, value = {
+                STATUS_PENDING,
+                STATUS_RUNNING,
+                STATUS_FINISHED,
+                STATUS_PAUSED,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Status {}
+
+        /** The session does not have a result yet. */
+        public static final int RESULT_NONE = 1;
+        /** The session completed successfully. */
+        public static final int RESULT_SUCCESS = 2;
+        /** The session encountered an error while running. */
+        public static final int RESULT_ERROR = 3;
+        /** The session was canceled by the caller. */
+        public static final int RESULT_CANCELED = 4;
+
+        /** @hide */
+        @IntDef(prefix = { "RESULT_" }, value = {
+                RESULT_NONE,
+                RESULT_SUCCESS,
+                RESULT_ERROR,
+                RESULT_CANCELED,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Result {}
+
+
+        // The error code exposed here should be in sync with:
+        // frameworks/av/media/libmediatranscoding/aidl/android/media/TranscodingErrorCode.aidl
+        /** @hide */
+        @IntDef(prefix = { "TRANSCODING_SESSION_ERROR_" }, value = {
+                ERROR_NONE,
+                ERROR_DROPPED_BY_SERVICE,
+                ERROR_SERVICE_DIED})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface TranscodingSessionErrorCode{}
+        /**
+         * Constant indicating that no error occurred.
+         */
+        public static final int ERROR_NONE = 0;
+
+        /**
+         * Constant indicating that the session is dropped by Transcoding service due to hitting
+         * the limit, e.g. too many back to back transcoding happen in a short time frame.
+         */
+        public static final int ERROR_DROPPED_BY_SERVICE = 1;
+
+        /**
+         * Constant indicating the backing transcoding service is died. Client should enqueue the
+         * the request again.
+         */
+        public static final int ERROR_SERVICE_DIED = 2;
+
+        /** Listener that gets notified when the progress changes. */
+        @FunctionalInterface
+        public interface OnProgressUpdateListener {
+            /**
+             * Called when the progress changes. The progress is in percentage between 0 and 1,
+             * where 0 means the session has not yet started and 100 means that it has finished.
+             *
+             * @param session      The session associated with the progress.
+             * @param progress The new progress ranging from 0 ~ 100 inclusive.
+             */
+            void onProgressUpdate(@NonNull TranscodingSession session,
+                    @IntRange(from = 0, to = 100) int progress);
+        }
+
+        private final MediaTranscodingManager mManager;
+        private Executor mListenerExecutor;
+        private OnTranscodingFinishedListener mListener;
+        private int mSessionId = -1;
+        // Lock for internal state.
+        private final Object mLock = new Object();
+        @GuardedBy("mLock")
+        private Executor mProgressUpdateExecutor = null;
+        @GuardedBy("mLock")
+        private OnProgressUpdateListener mProgressUpdateListener = null;
+        @GuardedBy("mLock")
+        private int mProgress = 0;
+        @GuardedBy("mLock")
+        private int mProgressUpdateInterval = 0;
+        @GuardedBy("mLock")
+        private @Status int mStatus = STATUS_PENDING;
+        @GuardedBy("mLock")
+        private @Result int mResult = RESULT_NONE;
+        @GuardedBy("mLock")
+        private @TranscodingSessionErrorCode int mErrorCode = ERROR_NONE;
+        @GuardedBy("mLock")
+        private boolean mHasRetried = false;
+        // The original request that associated with this session.
+        private final TranscodingRequest mRequest;
+
+        private TranscodingSession(
+                @NonNull MediaTranscodingManager manager,
+                @NonNull TranscodingRequest request,
+                @NonNull TranscodingSessionParcel parcel,
+                @NonNull @CallbackExecutor Executor executor,
+                @NonNull OnTranscodingFinishedListener listener) {
+            Objects.requireNonNull(manager, "manager must not be null");
+            Objects.requireNonNull(parcel, "parcel must not be null");
+            Objects.requireNonNull(executor, "listenerExecutor must not be null");
+            Objects.requireNonNull(listener, "listener must not be null");
+            mManager = manager;
+            mSessionId = parcel.sessionId;
+            mListenerExecutor = executor;
+            mListener = listener;
+            mRequest = request;
+        }
+
+        /**
+         * Set a progress listener.
+         * @param executor The executor on which listener will be invoked.
+         * @param listener The progress listener.
+         */
+        public void setOnProgressUpdateListener(
+                @NonNull @CallbackExecutor Executor executor,
+                @Nullable OnProgressUpdateListener listener) {
+            synchronized (mLock) {
+                Objects.requireNonNull(executor, "listenerExecutor must not be null");
+                Objects.requireNonNull(listener, "listener must not be null");
+                mProgressUpdateExecutor = executor;
+                mProgressUpdateListener = listener;
+            }
+        }
+
+        private void updateStatusAndResult(@Status int sessionStatus,
+                @Result int sessionResult, @TranscodingSessionErrorCode int errorCode) {
+            synchronized (mLock) {
+                mStatus = sessionStatus;
+                mResult = sessionResult;
+                mErrorCode = errorCode;
+            }
+        }
+
+        /**
+         * Retrieve the error code associated with the RESULT_ERROR.
+         */
+        public @TranscodingSessionErrorCode int getErrorCode() {
+            synchronized (mLock) {
+                return mErrorCode;
+            }
+        }
+
+        /**
+         * Resubmit the transcoding session to the service.
+         * Note that only the session that fails or gets cancelled could be retried and each session
+         * could be retried only once. After that, Client need to enqueue a new request if they want
+         * to try again.
+         *
+         * @return true if successfully resubmit the job to service. False otherwise.
+         * @throws UnsupportedOperationException if the retry could not be fulfilled.
+         * @hide
+         */
+        public boolean retry() {
+            return retryInternal(true /*setHasRetried*/);
+        }
+
+        // TODO(hkuang): Add more test for it.
+        private boolean retryInternal(boolean setHasRetried) {
+            synchronized (mLock) {
+                if (mStatus == STATUS_PENDING || mStatus == STATUS_RUNNING) {
+                    throw new UnsupportedOperationException(
+                            "Failed to retry as session is in processing");
+                }
+
+                if (mHasRetried) {
+                    throw new UnsupportedOperationException("Session has been retried already");
+                }
+
+                // Get the client interface.
+                ITranscodingClient client = mManager.getTranscodingClient();
+                if (client == null) {
+                    Log.e(TAG, "Service rebooting. Try again later");
+                    return false;
+                }
+
+                synchronized (mManager.mPendingTranscodingSessions) {
+                    try {
+                        // Submits the request to MediaTranscoding service.
+                        TranscodingSessionParcel sessionParcel = new TranscodingSessionParcel();
+                        if (!client.submitRequest(mRequest.writeToParcel(mManager.mContext),
+                                                  sessionParcel)) {
+                            mHasRetried = true;
+                            throw new UnsupportedOperationException("Failed to enqueue request");
+                        }
+
+                        // Replace the old session id wit the new one.
+                        mSessionId = sessionParcel.sessionId;
+                        // Adds the new session back into pending sessions.
+                        mManager.mPendingTranscodingSessions.put(mSessionId, this);
+                    } catch (RemoteException re) {
+                        return false;
+                    }
+                    mStatus = STATUS_PENDING;
+                    mHasRetried = setHasRetried ? true : false;
+                }
+            }
+            return true;
+        }
+
+        /**
+         * Cancels the transcoding session and notify the listener.
+         * If the session happened to finish before being canceled this call is effectively a no-op
+         * and will not update the result in that case.
+         */
+        public void cancel() {
+            synchronized (mLock) {
+                // Check if the session is finished already.
+                if (mStatus != STATUS_FINISHED) {
+                    try {
+                        ITranscodingClient client = mManager.getTranscodingClient();
+                        // The client may be gone.
+                        if (client != null) {
+                            client.cancelSession(mSessionId);
+                        }
+                    } catch (RemoteException re) {
+                        //TODO(hkuang): Find out what to do if failing to cancel the session.
+                        Log.e(TAG, "Failed to cancel the session due to exception:  " + re);
+                    }
+                    mStatus = STATUS_FINISHED;
+                    mResult = RESULT_CANCELED;
+
+                    // Notifies client the session is canceled.
+                    mListenerExecutor.execute(() -> mListener.onTranscodingFinished(this));
+                }
+            }
+        }
+
+        /**
+         * Gets the progress of the transcoding session. The progress is between 0 and 100, where 0
+         * means that the session has not yet started and 100 means that it is finished. For the
+         * cancelled session, the progress will be the last updated progress before it is cancelled.
+         * @return The progress.
+         */
+        @IntRange(from = 0, to = 100)
+        public int getProgress() {
+            synchronized (mLock) {
+                return mProgress;
+            }
+        }
+
+        /**
+         * Gets the status of the transcoding session.
+         * @return The status.
+         */
+        public @Status int getStatus() {
+            synchronized (mLock) {
+                return mStatus;
+            }
+        }
+
+        /**
+         * Adds a client uid that is also waiting for this transcoding session.
+         * <p>
+         * Only privilege caller with android.permission.WRITE_MEDIA_STORAGE could add the
+         * uid. Note that the permission check happens on the service side upon starting the
+         * transcoding. If the client does not have the permission, the transcoding will fail.
+         * @param uid  the additional client uid to be added.
+         * @return true if successfully added, false otherwise.
+         */
+        public boolean addClientUid(int uid) {
+            if (uid < 0) {
+                throw new IllegalArgumentException("Invalid Uid");
+            }
+
+            // Get the client interface.
+            ITranscodingClient client = mManager.getTranscodingClient();
+            if (client == null) {
+                Log.e(TAG, "Service is dead...");
+                return false;
+            }
+
+            try {
+                if (!client.addClientUid(mSessionId, uid)) {
+                    Log.e(TAG, "Failed to add client uid");
+                    return false;
+                }
+            } catch (Exception ex) {
+                Log.e(TAG, "Failed to get client uids due to " + ex);
+                return false;
+            }
+            return true;
+        }
+
+        /**
+         * Query all the client that waiting for this transcoding session
+         * @return a list containing all the client uids.
+         */
+        @NonNull
+        public List<Integer> getClientUids() {
+            List<Integer> uidList = new ArrayList<Integer>();
+
+            // Get the client interface.
+            ITranscodingClient client = mManager.getTranscodingClient();
+            if (client == null) {
+                Log.e(TAG, "Service is dead...");
+                return uidList;
+            }
+
+            try {
+                int[] clientUids  = client.getClientUids(mSessionId);
+                for (int i : clientUids) {
+                    uidList.add(i);
+                }
+            } catch (Exception ex) {
+                Log.e(TAG, "Failed to get client uids due to " + ex);
+            }
+
+            return uidList;
+        }
+
+        /**
+         * Gets sessionId of the transcoding session.
+         * @return session id.
+         */
+        public int getSessionId() {
+            return mSessionId;
+        }
+
+        /**
+         * Gets the result of the transcoding session.
+         * @return The result.
+         */
+        public @Result int getResult() {
+            synchronized (mLock) {
+                return mResult;
+            }
+        }
+
+        @Override
+        public String toString() {
+            String result;
+            String status;
+
+            switch (mResult) {
+                case RESULT_NONE:
+                    result = "RESULT_NONE";
+                    break;
+                case RESULT_SUCCESS:
+                    result = "RESULT_SUCCESS";
+                    break;
+                case RESULT_ERROR:
+                    result = "RESULT_ERROR(" + mErrorCode + ")";
+                    break;
+                case RESULT_CANCELED:
+                    result = "RESULT_CANCELED";
+                    break;
+                default:
+                    result = String.valueOf(mResult);
+                    break;
+            }
+
+            switch (mStatus) {
+                case STATUS_PENDING:
+                    status = "STATUS_PENDING";
+                    break;
+                case STATUS_PAUSED:
+                    status = "STATUS_PAUSED";
+                    break;
+                case STATUS_RUNNING:
+                    status = "STATUS_RUNNING";
+                    break;
+                case STATUS_FINISHED:
+                    status = "STATUS_FINISHED";
+                    break;
+                default:
+                    status = String.valueOf(mStatus);
+                    break;
+            }
+            return String.format(" session: {id: %d, status: %s, result: %s, progress: %d}",
+                    mSessionId, status, result, mProgress);
+        }
+
+        private void updateProgress(int newProgress) {
+            synchronized (mLock) {
+                mProgress = newProgress;
+            }
+        }
+
+        private void updateStatus(int newStatus) {
+            synchronized (mLock) {
+                mStatus = newStatus;
+            }
+        }
+    }
+
+    private ITranscodingClient getTranscodingClient() {
+        synchronized (mLock) {
+            return mTranscodingClient;
+        }
+    }
+
+    /**
+     * Enqueues a TranscodingRequest for execution.
+     * <p> Upon successfully accepting the request, MediaTranscodingManager will return a
+     * {@link TranscodingSession} to the client. Client should use {@link TranscodingSession} to
+     * track the progress and get the result.
+     * <p> MediaTranscodingManager will return null if fails to accept the request due to service
+     * rebooting. Client could retry again after receiving null.
+     *
+     * @param transcodingRequest The TranscodingRequest to enqueue.
+     * @param listenerExecutor   Executor on which the listener is notified.
+     * @param listener           Listener to get notified when the transcoding session is finished.
+     * @return A TranscodingSession for this operation.
+     * @throws UnsupportedOperationException if the request could not be fulfilled.
+     */
+    @Nullable
+    public TranscodingSession enqueueRequest(
+            @NonNull TranscodingRequest transcodingRequest,
+            @NonNull @CallbackExecutor Executor listenerExecutor,
+            @NonNull OnTranscodingFinishedListener listener) {
+        Log.i(TAG, "enqueueRequest called.");
+        Objects.requireNonNull(transcodingRequest, "transcodingRequest must not be null");
+        Objects.requireNonNull(listenerExecutor, "listenerExecutor must not be null");
+        Objects.requireNonNull(listener, "listener must not be null");
+
+        // Converts the request to TranscodingRequestParcel.
+        TranscodingRequestParcel requestParcel = transcodingRequest.writeToParcel(mContext);
+
+        Log.i(TAG, "Getting transcoding request " + transcodingRequest.getSourceUri());
+
+        // Submits the request to MediaTranscoding service.
+        try {
+            TranscodingSessionParcel sessionParcel = new TranscodingSessionParcel();
+            // Synchronizes the access to mPendingTranscodingSessions to make sure the session Id is
+            // inserted in the mPendingTranscodingSessions in the callback handler.
+            synchronized (mPendingTranscodingSessions) {
+                synchronized (mLock) {
+                    if (mTranscodingClient == null) {
+                        // Try to register with the service again.
+                        IMediaTranscodingService service = getService(false /*retry*/);
+                        if (service == null) {
+                            Log.w(TAG, "Service rebooting. Try again later");
+                            return null;
+                        }
+                        mTranscodingClient = registerClient(service);
+                        // If still fails, throws an exception to tell client to try later.
+                        if (mTranscodingClient == null) {
+                            Log.w(TAG, "Service rebooting. Try again later");
+                            return null;
+                        }
+                    }
+
+                    if (!mTranscodingClient.submitRequest(requestParcel, sessionParcel)) {
+                        throw new UnsupportedOperationException("Failed to enqueue request");
+                    }
+                }
+
+                // Wraps the TranscodingSessionParcel into a TranscodingSession and returns it to
+                // client for tracking.
+                TranscodingSession session = new TranscodingSession(this, transcodingRequest,
+                        sessionParcel,
+                        listenerExecutor,
+                        listener);
+
+                // Adds the new session into pending sessions.
+                mPendingTranscodingSessions.put(session.getSessionId(), session);
+                return session;
+            }
+        } catch (RemoteException ex) {
+            Log.w(TAG, "Service rebooting. Try again later");
+            return null;
+        } catch (ServiceSpecificException ex) {
+            throw new UnsupportedOperationException(
+                    "Failed to submit request to Transcoding service. Error: " + ex);
+        }
+    }
+}
diff --git a/android/media/Metadata.java b/android/media/Metadata.java
new file mode 100644
index 0000000..ef17073
--- /dev/null
+++ b/android/media/Metadata.java
@@ -0,0 +1,569 @@
+/*
+ * Copyright (C) 2009 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.compat.annotation.UnsupportedAppUsage;
+import android.os.Parcel;
+import android.util.Log;
+import android.util.MathUtils;
+
+import java.util.Calendar;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.TimeZone;
+
+
+/**
+   Class to hold the media's metadata.  Metadata are used
+   for human consumption and can be embedded in the media (e.g
+   shoutcast) or available from an external source. The source can be
+   local (e.g thumbnail stored in the DB) or remote.
+
+   Metadata is like a Bundle. It is sparse and each key can occur at
+   most once. The key is an integer and the value is the actual metadata.
+
+   The caller is expected to know the type of the metadata and call
+   the right get* method to fetch its value.
+   
+   @hide
+   @deprecated Use {@link MediaMetadata}.
+ */
+@Deprecated public class Metadata
+{
+    // The metadata are keyed using integers rather than more heavy
+    // weight strings. We considered using Bundle to ship the metadata
+    // between the native layer and the java layer but dropped that
+    // option since keeping in sync a native implementation of Bundle
+    // and the java one would be too burdensome. Besides Bundle uses
+    // String for its keys.
+    // The key range [0 8192) is reserved for the system.
+    //
+    // We manually serialize the data in Parcels. For large memory
+    // blob (bitmaps, raw pictures) we use MemoryFile which allow the
+    // client to make the data purge-able once it is done with it.
+    //
+
+    /**
+     * {@hide}
+     */
+    public static final int ANY = 0;  // Never used for metadata returned, only for filtering.
+                                      // Keep in sync with kAny in MediaPlayerService.cpp
+
+    // Playback capabilities.
+    /**
+     * Indicate whether the media can be paused
+     */
+    @UnsupportedAppUsage
+    public static final int PAUSE_AVAILABLE         = 1; // Boolean
+    /**
+     * Indicate whether the media can be backward seeked
+     */
+    @UnsupportedAppUsage
+    public static final int SEEK_BACKWARD_AVAILABLE = 2; // Boolean
+    /**
+     * Indicate whether the media can be forward seeked
+     */
+    @UnsupportedAppUsage
+    public static final int SEEK_FORWARD_AVAILABLE  = 3; // Boolean
+    /**
+     * Indicate whether the media can be seeked
+     */
+    @UnsupportedAppUsage
+    public static final int SEEK_AVAILABLE          = 4; // Boolean
+
+    // TODO: Should we use numbers compatible with the metadata retriever?
+    /**
+     * {@hide}
+     */
+    public static final int TITLE                   = 5; // String
+    /**
+     * {@hide}
+     */
+    public static final int COMMENT                 = 6; // String
+    /**
+     * {@hide}
+     */
+    public static final int COPYRIGHT               = 7; // String
+    /**
+     * {@hide}
+     */
+    public static final int ALBUM                   = 8; // String
+    /**
+     * {@hide}
+     */
+    public static final int ARTIST                  = 9; // String
+    /**
+     * {@hide}
+     */
+    public static final int AUTHOR                  = 10; // String
+    /**
+     * {@hide}
+     */
+    public static final int COMPOSER                = 11; // String
+    /**
+     * {@hide}
+     */
+    public static final int GENRE                   = 12; // String
+    /**
+     * {@hide}
+     */
+    public static final int DATE                    = 13; // Date
+    /**
+     * {@hide}
+     */
+    public static final int DURATION                = 14; // Integer(millisec)
+    /**
+     * {@hide}
+     */
+    public static final int CD_TRACK_NUM            = 15; // Integer 1-based
+    /**
+     * {@hide}
+     */
+    public static final int CD_TRACK_MAX            = 16; // Integer
+    /**
+     * {@hide}
+     */
+    public static final int RATING                  = 17; // String
+    /**
+     * {@hide}
+     */
+    public static final int ALBUM_ART               = 18; // byte[]
+    /**
+     * {@hide}
+     */
+    public static final int VIDEO_FRAME             = 19; // Bitmap
+
+    /**
+     * {@hide}
+     */
+    public static final int BIT_RATE                = 20; // Integer, Aggregate rate of
+                                                          // all the streams in bps.
+
+    /**
+     * {@hide}
+     */
+    public static final int AUDIO_BIT_RATE          = 21; // Integer, bps
+    /**
+     * {@hide}
+     */
+    public static final int VIDEO_BIT_RATE          = 22; // Integer, bps
+    /**
+     * {@hide}
+     */
+    public static final int AUDIO_SAMPLE_RATE       = 23; // Integer, Hz
+    /**
+     * {@hide}
+     */
+    public static final int VIDEO_FRAME_RATE        = 24; // Integer, Hz
+
+    // See RFC2046 and RFC4281.
+    /**
+     * {@hide}
+     */
+    public static final int MIME_TYPE               = 25; // String
+    /**
+     * {@hide}
+     */
+    public static final int AUDIO_CODEC             = 26; // String
+    /**
+     * {@hide}
+     */
+    public static final int VIDEO_CODEC             = 27; // String
+
+    /**
+     * {@hide}
+     */
+    public static final int VIDEO_HEIGHT            = 28; // Integer
+    /**
+     * {@hide}
+     */
+    public static final int VIDEO_WIDTH             = 29; // Integer
+    /**
+     * {@hide}
+     */
+    public static final int NUM_TRACKS              = 30; // Integer
+    /**
+     * {@hide}
+     */
+    public static final int DRM_CRIPPLED            = 31; // Boolean
+
+    private static final int LAST_SYSTEM = 31;
+    private static final int FIRST_CUSTOM = 8192;
+
+    // Shorthands to set the MediaPlayer's metadata filter.
+    /**
+     * {@hide}
+     */
+    public static final Set<Integer> MATCH_NONE = Collections.EMPTY_SET;
+    /**
+     * {@hide}
+     */
+    public static final Set<Integer> MATCH_ALL = Collections.singleton(ANY);
+
+    /**
+     * {@hide}
+     */
+    public static final int STRING_VAL     = 1;
+    /**
+     * {@hide}
+     */
+    public static final int INTEGER_VAL    = 2;
+    /**
+     * {@hide}
+     */
+    public static final int BOOLEAN_VAL    = 3;
+    /**
+     * {@hide}
+     */
+    public static final int LONG_VAL       = 4;
+    /**
+     * {@hide}
+     */
+    public static final int DOUBLE_VAL     = 5;
+    /**
+     * {@hide}
+     */
+    public static final int DATE_VAL       = 6;
+    /**
+     * {@hide}
+     */
+    public static final int BYTE_ARRAY_VAL = 7;
+    // FIXME: misses a type for shared heap is missing (MemoryFile).
+    // FIXME: misses a type for bitmaps.
+    private static final int LAST_TYPE = 7;
+
+    private static final String TAG = "media.Metadata";
+    private static final int kInt32Size = 4;
+    private static final int kMetaHeaderSize = 2 * kInt32Size; //  size + marker
+    private static final int kRecordHeaderSize = 3 * kInt32Size; // size + id + type
+
+    private static final int kMetaMarker = 0x4d455441;  // 'M' 'E' 'T' 'A'
+
+    // After a successful parsing, set the parcel with the serialized metadata.
+    private Parcel mParcel;
+
+    // Map to associate a Metadata key (e.g TITLE) with the offset of
+    // the record's payload in the parcel.
+    // Used to look up if a key was present too.
+    // Key: Metadata ID
+    // Value: Offset of the metadata type field in the record.
+    private final HashMap<Integer, Integer> mKeyToPosMap =
+            new HashMap<Integer, Integer>();
+
+    /**
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    public Metadata() { }
+
+    /**
+     * Go over all the records, collecting metadata keys and records'
+     * type field offset in the Parcel. These are stored in
+     * mKeyToPosMap for latter retrieval.
+     * Format of a metadata record:
+     <pre>
+                         1                   2                   3
+      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |                     record size                               |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |                     metadata key                              |  // TITLE
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |                     metadata type                             |  // STRING_VAL
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |                                                               |
+      |                .... metadata payload ....                     |
+      |                                                               |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     </pre>
+     * @param parcel With the serialized records.
+     * @param bytesLeft How many bytes in the parcel should be processed.
+     * @return false if an error occurred during parsing.
+     */
+    private boolean scanAllRecords(Parcel parcel, int bytesLeft) {
+        int recCount = 0;
+        boolean error = false;
+
+        mKeyToPosMap.clear();
+        while (bytesLeft > kRecordHeaderSize) {
+            final int start = parcel.dataPosition();
+            // Check the size.
+            final int size = parcel.readInt();
+
+            if (size <= kRecordHeaderSize) {  // at least 1 byte should be present.
+                Log.e(TAG, "Record is too short");
+                error = true;
+                break;
+            }
+
+            // Check the metadata key.
+            final int metadataId = parcel.readInt();
+            if (!checkMetadataId(metadataId)) {
+                error = true;
+                break;
+            }
+
+            // Store the record offset which points to the type
+            // field so we can later on read/unmarshall the record
+            // payload.
+            if (mKeyToPosMap.containsKey(metadataId)) {
+                Log.e(TAG, "Duplicate metadata ID found");
+                error = true;
+                break;
+            }
+
+            mKeyToPosMap.put(metadataId, parcel.dataPosition());
+
+            // Check the metadata type.
+            final int metadataType = parcel.readInt();
+            if (metadataType <= 0 || metadataType > LAST_TYPE) {
+                Log.e(TAG, "Invalid metadata type " + metadataType);
+                error = true;
+                break;
+            }
+
+            // Skip to the next one.
+            try {
+                parcel.setDataPosition(MathUtils.addOrThrow(start, size));
+            } catch (IllegalArgumentException e) {
+                Log.e(TAG, "Invalid size: " + e.getMessage());
+                error = true;
+                break;
+            }
+
+            bytesLeft -= size;
+            ++recCount;
+        }
+
+        if (0 != bytesLeft || error) {
+            Log.e(TAG, "Ran out of data or error on record " + recCount);
+            mKeyToPosMap.clear();
+            return false;
+        } else {
+            return true;
+        }
+    }
+
+    /**
+     * Check a parcel containing metadata is well formed. The header
+     * is checked as well as the individual records format. However, the
+     * data inside the record is not checked because we do lazy access
+     * (we check/unmarshall only data the user asks for.)
+     *
+     * Format of a metadata parcel:
+     <pre>
+                         1                   2                   3
+      0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |                     metadata total size                       |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |     'M'       |     'E'       |     'T'       |     'A'       |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+      |                                                               |
+      |                .... metadata records ....                     |
+      |                                                               |
+      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+     </pre>
+     *
+     * @param parcel With the serialized data. Metadata keeps a
+     *               reference on it to access it later on. The caller
+     *               should not modify the parcel after this call (and
+     *               not call recycle on it.)
+     * @return false if an error occurred.
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    public boolean parse(Parcel parcel) {
+        if (parcel.dataAvail() < kMetaHeaderSize) {
+            Log.e(TAG, "Not enough data " + parcel.dataAvail());
+            return false;
+        }
+
+        final int pin = parcel.dataPosition();  // to roll back in case of errors.
+        final int size = parcel.readInt();
+
+        // The extra kInt32Size below is to account for the int32 'size' just read.
+        if (parcel.dataAvail() + kInt32Size < size || size < kMetaHeaderSize) {
+            Log.e(TAG, "Bad size " + size + " avail " + parcel.dataAvail() + " position " + pin);
+            parcel.setDataPosition(pin);
+            return false;
+        }
+
+        // Checks if the 'M' 'E' 'T' 'A' marker is present.
+        final int kShouldBeMetaMarker = parcel.readInt();
+        if (kShouldBeMetaMarker != kMetaMarker ) {
+            Log.e(TAG, "Marker missing " + Integer.toHexString(kShouldBeMetaMarker));
+            parcel.setDataPosition(pin);
+            return false;
+        }
+
+        // Scan the records to collect metadata ids and offsets.
+        if (!scanAllRecords(parcel, size - kMetaHeaderSize)) {
+            parcel.setDataPosition(pin);
+            return false;
+        }
+        mParcel = parcel;
+        return true;
+    }
+
+    /**
+     * @return The set of metadata ID found.
+     */
+    @UnsupportedAppUsage
+    public Set<Integer> keySet() {
+        return mKeyToPosMap.keySet();
+    }
+
+    /**
+     * @return true if a value is present for the given key.
+     */
+    @UnsupportedAppUsage
+    public boolean has(final int metadataId) {
+        if (!checkMetadataId(metadataId)) {
+            throw new IllegalArgumentException("Invalid key: " + metadataId);
+        }
+        return mKeyToPosMap.containsKey(metadataId);
+    }
+
+    // Accessors.
+    // Caller must make sure the key is present using the {@code has}
+    // method otherwise a RuntimeException will occur.
+
+    /**
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    public String getString(final int key) {
+        checkType(key, STRING_VAL);
+        return mParcel.readString();
+    }
+
+    /**
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    public int getInt(final int key) {
+        checkType(key, INTEGER_VAL);
+        return mParcel.readInt();
+    }
+
+    /**
+     * Get the boolean value indicated by key
+     */
+    @UnsupportedAppUsage
+    public boolean getBoolean(final int key) {
+        checkType(key, BOOLEAN_VAL);
+        return mParcel.readInt() == 1;
+    }
+
+    /**
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    public long getLong(final int key) {
+        checkType(key, LONG_VAL);    /**
+     * {@hide}
+     */
+        return mParcel.readLong();
+    }
+
+    /**
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    public double getDouble(final int key) {
+        checkType(key, DOUBLE_VAL);
+        return mParcel.readDouble();
+    }
+
+    /**
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    public byte[] getByteArray(final int key) {
+        checkType(key, BYTE_ARRAY_VAL);
+        return mParcel.createByteArray();
+    }
+
+    /**
+     * {@hide}
+     */
+    @UnsupportedAppUsage
+    public Date getDate(final int key) {
+        checkType(key, DATE_VAL);
+        final long timeSinceEpoch = mParcel.readLong();
+        final String timeZone = mParcel.readString();
+
+        if (timeZone.length() == 0) {
+            return new Date(timeSinceEpoch);
+        } else {
+            TimeZone tz = TimeZone.getTimeZone(timeZone);
+            Calendar cal = Calendar.getInstance(tz);
+
+            cal.setTimeInMillis(timeSinceEpoch);
+            return cal.getTime();
+        }
+    }
+
+    /**
+     * @return the last available system metadata id. Ids are
+     *         1-indexed.
+     * {@hide}
+     */
+    public static int lastSytemId() { return LAST_SYSTEM; }
+
+    /**
+     * @return the first available cutom metadata id.
+     * {@hide}
+     */
+    public static int firstCustomId() { return FIRST_CUSTOM; }
+
+    /**
+     * @return the last value of known type. Types are 1-indexed.
+     * {@hide}
+     */
+    public static int lastType() { return LAST_TYPE; }
+
+    /**
+     * Check val is either a system id or a custom one.
+     * @param val Metadata key to test.
+     * @return true if it is in a valid range.
+     **/
+    private boolean checkMetadataId(final int val) {
+        if (val <= ANY || (LAST_SYSTEM < val && val < FIRST_CUSTOM)) {
+            Log.e(TAG, "Invalid metadata ID " + val);
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Check the type of the data match what is expected.
+     */
+    private void checkType(final int key, final int expectedType) {
+        final int pos = mKeyToPosMap.get(key);
+
+        mParcel.setDataPosition(pos);
+
+        final int type = mParcel.readInt();
+        if (type != expectedType) {
+            throw new IllegalStateException("Wrong type " + expectedType + " but got " + type);
+        }
+    }
+}
diff --git a/android/media/MicrophoneDirection.java b/android/media/MicrophoneDirection.java
new file mode 100644
index 0000000..e4eec44
--- /dev/null
+++ b/android/media/MicrophoneDirection.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 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.annotation.FloatRange;
+import android.annotation.IntDef;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Interface defining mechanism for controlling the directionality and field width of
+ * audio capture.
+ */
+public interface MicrophoneDirection {
+    /**
+     * Don't do any directionality processing of the activated microphone(s).
+     */
+    int MIC_DIRECTION_UNSPECIFIED = 0;
+    /**
+     * Optimize capture for audio coming from the side of the device facing the user.
+     * In the typical case, a device with a single screen, screen-side camera/microphone and
+     * non-screen-side camera/microphone, this will be the screen side (as in a "selfie").
+     * For a different device geometry, it is the side for which the expectation is to be
+     * facing the user.
+     */
+    int MIC_DIRECTION_TOWARDS_USER = 1;
+    /**
+     * Optimize capture for audio coming from the side of the device pointing away from the user.
+     * In the typical case, a device with a single screen, screen-side camera/microphone and
+     * non-screen-side camera/microphone, this will be the non-screen side.
+     * For a different device geometry, it is the side for which the expectation is to be
+     * facing away from the user. This is the "taking a video of something else" case.
+     */
+    int MIC_DIRECTION_AWAY_FROM_USER = 2;
+    /**
+     * Optimize capture for audio coming from an off-device microphone.
+     */
+    int MIC_DIRECTION_EXTERNAL = 3;
+
+    /** @hide */
+    /*public*/ @IntDef({
+            MIC_DIRECTION_UNSPECIFIED,
+            MIC_DIRECTION_TOWARDS_USER,
+            MIC_DIRECTION_AWAY_FROM_USER,
+            MIC_DIRECTION_EXTERNAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    @interface DirectionMode{};
+    /**
+     * Specifies the logical microphone (for processing). Applications can use this to specify
+     * which side of the device to optimize capture from. Typically used in conjunction with
+     * the camera capturing video.
+     *
+     * Usage would include specifying the audio capture to follow camera being used to capture
+     * video.
+     * @param direction Direction constant.
+     * @return true if sucessful.
+     */
+    boolean setPreferredMicrophoneDirection(@DirectionMode int direction);
+
+    /**
+     * Specifies the zoom factor (i.e. the field dimension) for the selected microphone
+     * (for processing). The selected microphone is determined by the use-case for the stream.
+     *
+     * Usage would include specifying the audio focus to follow the zoom specified for the camera
+     * being used to capture video.
+     *
+     * @param zoom the desired field dimension of microphone capture. Range is from -1 (wide angle),
+     * though 0 (no zoom) to 1 (maximum zoom).
+     * @return true if sucessful.
+     */
+    boolean setPreferredMicrophoneFieldDimension(@FloatRange(from = -1.0, to = 1.0) float zoom);
+}
diff --git a/android/media/MicrophoneInfo.java b/android/media/MicrophoneInfo.java
new file mode 100644
index 0000000..9e2e25f
--- /dev/null
+++ b/android/media/MicrophoneInfo.java
@@ -0,0 +1,404 @@
+/*
+ * Copyright (C) 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.util.Pair;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+
+/**
+ * Class providing information on a microphone. It indicates the location and orientation of the
+ * microphone on the device as well as useful information like frequency response and sensitivity.
+ * It can be used by applications implementing special pre processing effects like noise suppression
+ * of beam forming that need to know about precise microphone characteristics in order to adapt
+ * their algorithms.
+ */
+public final class MicrophoneInfo {
+
+    /**
+     * A microphone that the location is unknown.
+     */
+    public static final int LOCATION_UNKNOWN = 0;
+
+    /**
+     * A microphone that locate on main body of the device.
+     */
+    public static final int LOCATION_MAINBODY = 1;
+
+    /**
+     * A microphone that locate on a movable main body of the device.
+     */
+    public static final int LOCATION_MAINBODY_MOVABLE = 2;
+
+    /**
+     * A microphone that locate on a peripheral.
+     */
+    public static final int LOCATION_PERIPHERAL = 3;
+
+    /**
+     * Unknown microphone directionality.
+     */
+    public static final int DIRECTIONALITY_UNKNOWN = 0;
+
+    /**
+     * Microphone directionality type: omni.
+     */
+    public static final int DIRECTIONALITY_OMNI = 1;
+
+    /**
+     * Microphone directionality type: bi-directional.
+     */
+    public static final int DIRECTIONALITY_BI_DIRECTIONAL = 2;
+
+    /**
+     * Microphone directionality type: cardioid.
+     */
+    public static final int DIRECTIONALITY_CARDIOID = 3;
+
+    /**
+     * Microphone directionality type: hyper cardioid.
+     */
+    public static final int DIRECTIONALITY_HYPER_CARDIOID = 4;
+
+    /**
+     * Microphone directionality type: super cardioid.
+     */
+    public static final int DIRECTIONALITY_SUPER_CARDIOID = 5;
+
+    /**
+     * The channel contains raw audio from this microphone.
+     */
+    public static final int CHANNEL_MAPPING_DIRECT = 1;
+
+    /**
+     * The channel contains processed audio from this microphone and possibly another microphone.
+     */
+    public static final int CHANNEL_MAPPING_PROCESSED = 2;
+
+    /**
+     * Value used for when the group of the microphone is unknown.
+     */
+    public static final int GROUP_UNKNOWN = -1;
+
+    /**
+     * Value used for when the index in the group of the microphone is unknown.
+     */
+    public static final int INDEX_IN_THE_GROUP_UNKNOWN = -1;
+
+    /**
+     * Value used for when the position of the microphone is unknown.
+     */
+    public static final Coordinate3F POSITION_UNKNOWN = new Coordinate3F(
+            -Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE);
+
+    /**
+     * Value used for when the orientation of the microphone is unknown.
+     */
+    public static final Coordinate3F ORIENTATION_UNKNOWN = new Coordinate3F(0.0f, 0.0f, 0.0f);
+
+    /**
+     * Value used for when the sensitivity of the microphone is unknown.
+     */
+    public static final float SENSITIVITY_UNKNOWN = -Float.MAX_VALUE;
+
+    /**
+     * Value used for when the SPL of the microphone is unknown. This value could be used when
+     * maximum SPL or minimum SPL is unknown.
+     */
+    public static final float SPL_UNKNOWN = -Float.MAX_VALUE;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "LOCATION_" }, value = {
+            LOCATION_UNKNOWN,
+            LOCATION_MAINBODY,
+            LOCATION_MAINBODY_MOVABLE,
+            LOCATION_PERIPHERAL,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MicrophoneLocation {}
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "DIRECTIONALITY_" }, value = {
+            DIRECTIONALITY_UNKNOWN,
+            DIRECTIONALITY_OMNI,
+            DIRECTIONALITY_BI_DIRECTIONAL,
+            DIRECTIONALITY_CARDIOID,
+            DIRECTIONALITY_HYPER_CARDIOID,
+            DIRECTIONALITY_SUPER_CARDIOID,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MicrophoneDirectionality {}
+
+    private Coordinate3F mPosition;
+    private Coordinate3F mOrientation;
+    private String mDeviceId;
+    private String mAddress;
+    private List<Pair<Float, Float>> mFrequencyResponse;
+    private List<Pair<Integer, Integer>> mChannelMapping;
+    private float mMaxSpl;
+    private float mMinSpl;
+    private float mSensitivity;
+    private int mLocation;
+    private int mGroup; /* Usually 0 will be used for main body. */
+    private int mIndexInTheGroup;
+    private int mPortId; /* mPortId will correspond to the id in AudioPort */
+    private int mType;
+    private int mDirectionality;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    MicrophoneInfo(String deviceId, int type, String address, int location,
+            int group, int indexInTheGroup, Coordinate3F position,
+            Coordinate3F orientation, List<Pair<Float, Float>> frequencyResponse,
+            List<Pair<Integer, Integer>> channelMapping, float sensitivity, float maxSpl,
+            float minSpl, int directionality) {
+        mDeviceId = deviceId;
+        mType = type;
+        mAddress = address;
+        mLocation = location;
+        mGroup = group;
+        mIndexInTheGroup = indexInTheGroup;
+        mPosition = position;
+        mOrientation = orientation;
+        mFrequencyResponse = frequencyResponse;
+        mChannelMapping = channelMapping;
+        mSensitivity = sensitivity;
+        mMaxSpl = maxSpl;
+        mMinSpl = minSpl;
+        mDirectionality = directionality;
+    }
+
+    /**
+     * Returns alphanumeric code that uniquely identifies the device.
+     *
+     * @return the description of the microphone
+     */
+    public String getDescription() {
+        return mDeviceId;
+    }
+
+    /**
+     * Returns The system unique device ID that corresponds to the id
+     * returned by {@link AudioDeviceInfo#getId()}.
+     *
+     * @return the microphone's id
+     */
+    public int getId() {
+        return mPortId;
+    }
+
+    /**
+     * @hide
+     * Returns the internal device type (e.g AudioSystem.DEVICE_IN_BUILTIN_MIC).
+     * The internal device type could be used when getting microphone's port id
+     * by matching type and address.
+     *
+     * @return the internal device type
+     */
+    public int getInternalDeviceType() {
+        return mType;
+    }
+
+    /**
+     * Returns the device type identifier of the microphone (e.g AudioDeviceInfo.TYPE_BUILTIN_MIC).
+     *
+     * @return the device type of the microphone
+     */
+    public int getType() {
+        return AudioDeviceInfo.convertInternalDeviceToDeviceType(mType);
+    }
+
+    /**
+     * Returns The "address" string of the microphone that corresponds to the
+     * address returned by {@link AudioDeviceInfo#getAddress()}
+     * @return the address of the microphone
+     */
+    public @NonNull String getAddress() {
+        return mAddress;
+    }
+
+    /**
+     * Returns the location of the microphone. The return value is
+     * one of {@link #LOCATION_UNKNOWN}, {@link #LOCATION_MAINBODY},
+     * {@link #LOCATION_MAINBODY_MOVABLE}, or {@link #LOCATION_PERIPHERAL}.
+     *
+     * @return the location of the microphone
+     */
+    public @MicrophoneLocation int getLocation() {
+        return mLocation;
+    }
+
+    /**
+     * Returns A device group id that can be used to group together microphones on the same
+     * peripheral, attachments or logical groups. Main body is usually group 0.
+     *
+     * @return the group of the microphone or {@link #GROUP_UNKNOWN} if the group is unknown
+     */
+    public int getGroup() {
+        return mGroup;
+    }
+
+    /**
+     * Returns unique index for device within its group.
+     *
+     * @return the microphone's index in its group or {@link #INDEX_IN_THE_GROUP_UNKNOWN} if the
+     * index in the group is unknown
+     */
+    public int getIndexInTheGroup() {
+        return mIndexInTheGroup;
+    }
+
+    /**
+     * Returns A {@link Coordinate3F} object that represents the geometric location of microphone
+     * in meters. X-axis, Y-axis and Z-axis show as the x, y, z values. For mobile devices, the axes
+     * originate from the bottom-left-back corner of the appliance. In devices with
+     * {@link android.content.pm.PackageManager#FEATURE_AUTOMOTIVE}, axes are defined with respect
+     * to the vehicle body frame, originating from the center of the vehicle's rear axle.
+     * @see <a href="https://source.android.com/devices/sensors/sensor-types#auto_axes">auto axes</a>
+     *
+     * @return the geometric location of the microphone or {@link #POSITION_UNKNOWN} if the
+     * geometric location is unknown
+     */
+    public Coordinate3F getPosition() {
+        return mPosition;
+    }
+
+    /**
+     * Returns A {@link Coordinate3F} object that represents the orientation of microphone.
+     * X-axis, Y-axis and Z-axis show as the x, y, z value. The orientation will be normalized
+     * such as sqrt(x^2 + y^2 + z^2) equals 1.
+     *
+     * @return the orientation of the microphone or {@link #ORIENTATION_UNKNOWN} if orientation
+     * is unknown
+     */
+    public Coordinate3F getOrientation() {
+        return mOrientation;
+    }
+
+    /**
+     * Returns a {@link android.util.Pair} list of frequency responses.
+     * For every {@link android.util.Pair} in the list, the first value represents frequency in Hz,
+     * and the second value represents response in dB.
+     *
+     * @return the frequency response of the microphone
+     */
+    public List<Pair<Float, Float>> getFrequencyResponse() {
+        return mFrequencyResponse;
+    }
+
+    /**
+     * Returns a {@link android.util.Pair} list for channel mapping, which indicating how this
+     * microphone is used by each channels or a capture stream. For each {@link android.util.Pair},
+     * the first value is channel index, the second value is channel mapping type, which could be
+     * either {@link #CHANNEL_MAPPING_DIRECT} or {@link #CHANNEL_MAPPING_PROCESSED}.
+     * If a channel has contributions from more than one microphone, it is likely the HAL
+     * did some extra processing to combine the sources, but this is to be inferred by the user.
+     * Empty list when the MicrophoneInfo is returned by AudioManager.getMicrophones().
+     * At least one entry when the MicrophoneInfo is returned by AudioRecord.getActiveMicrophones().
+     *
+     * @return a {@link android.util.Pair} list for channel mapping
+     */
+    public List<Pair<Integer, Integer>> getChannelMapping() {
+        return mChannelMapping;
+    }
+
+    /**
+     * Returns the level in dBFS produced by a 1000Hz tone at 94 dB SPL.
+     *
+     * @return the sensitivity of the microphone or {@link #SENSITIVITY_UNKNOWN} if the sensitivity
+     * is unknown
+     */
+    public float getSensitivity() {
+        return mSensitivity;
+    }
+
+    /**
+     * Returns the level in dB of the maximum SPL supported by the device at 1000Hz.
+     *
+     * @return the maximum level in dB or {@link #SPL_UNKNOWN} if maximum SPL is unknown
+     */
+    public float getMaxSpl() {
+        return mMaxSpl;
+    }
+
+    /**
+     * Returns the level in dB of the minimum SPL that can be registered by the device at 1000Hz.
+     *
+     * @return the minimum level in dB or {@link #SPL_UNKNOWN} if minimum SPL is unknown
+     */
+    public float getMinSpl() {
+        return mMinSpl;
+    }
+
+    /**
+     * Returns the directionality of microphone. The return value is one of
+     * {@link #DIRECTIONALITY_UNKNOWN}, {@link #DIRECTIONALITY_OMNI},
+     * {@link #DIRECTIONALITY_BI_DIRECTIONAL}, {@link #DIRECTIONALITY_CARDIOID},
+     * {@link #DIRECTIONALITY_HYPER_CARDIOID}, or {@link #DIRECTIONALITY_SUPER_CARDIOID}.
+     *
+     * @return the directionality of microphone
+     */
+    public @MicrophoneDirectionality int getDirectionality() {
+        return mDirectionality;
+    }
+
+    /**
+     * Set the port id for the device.
+     * @hide
+     */
+    public void setId(int portId) {
+        mPortId = portId;
+    }
+
+    /**
+     * Set the channel mapping for the device.
+     * @hide
+     */
+    public void setChannelMapping(List<Pair<Integer, Integer>> channelMapping) {
+        mChannelMapping = channelMapping;
+    }
+
+    /* A class containing three float value to represent a 3D coordinate */
+    public static final class Coordinate3F {
+        public final float x;
+        public final float y;
+        public final float z;
+
+        Coordinate3F(float x, float y, float z) {
+            this.x = x;
+            this.y = y;
+            this.z = z;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj) {
+                return true;
+            }
+            if (!(obj instanceof Coordinate3F)) {
+                return false;
+            }
+            Coordinate3F other = (Coordinate3F) obj;
+            return this.x == other.x && this.y == other.y && this.z == other.z;
+        }
+    }
+}
diff --git a/android/media/NativeRoutingEventHandlerDelegate.java b/android/media/NativeRoutingEventHandlerDelegate.java
new file mode 100644
index 0000000..9a6baf1
--- /dev/null
+++ b/android/media/NativeRoutingEventHandlerDelegate.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2017 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.os.Handler;
+
+/**
+ * Helper class {@link AudioTrack}, {@link AudioRecord}, {@link MediaPlayer} and {@link MediaRecorder}
+ * to handle the forwarding of native events to the appropriate listener
+ * (potentially) handled in a different thread.
+ * @hide
+ */
+class NativeRoutingEventHandlerDelegate {
+    private AudioRouting mAudioRouting;
+    private AudioRouting.OnRoutingChangedListener mOnRoutingChangedListener;
+    private Handler mHandler;
+
+    NativeRoutingEventHandlerDelegate(final AudioRouting audioRouting,
+            final AudioRouting.OnRoutingChangedListener listener, Handler handler) {
+        mAudioRouting = audioRouting;
+        mOnRoutingChangedListener = listener;
+        mHandler = handler;
+    }
+
+    void notifyClient() {
+        if (mHandler != null) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    if (mOnRoutingChangedListener != null) {
+                        mOnRoutingChangedListener.onRoutingChanged(mAudioRouting);
+                    }
+                }
+            });
+        }
+    }
+}
diff --git a/android/media/NotProvisionedException.java b/android/media/NotProvisionedException.java
new file mode 100644
index 0000000..32b8151
--- /dev/null
+++ b/android/media/NotProvisionedException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2013 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;
+
+/**
+ * Exception thrown when an operation on a MediaDrm object is attempted
+ * and the device does not have a certificate.  The app should obtain and
+ * install a certificate using the MediaDrm provisioning methods then retry
+ * the operation.
+ */
+public final class NotProvisionedException extends MediaDrmException {
+    public NotProvisionedException(String detailMessage) {
+        super(detailMessage);
+    }
+}
diff --git a/android/media/PlaybackParams.java b/android/media/PlaybackParams.java
new file mode 100644
index 0000000..080b9a4
--- /dev/null
+++ b/android/media/PlaybackParams.java
@@ -0,0 +1,264 @@
+/*
+ * Copyright 2015 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.annotation.IntDef;
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Structure for common playback params.
+ *
+ * Used by {@link AudioTrack} {@link AudioTrack#getPlaybackParams()} and
+ * {@link AudioTrack#setPlaybackParams(PlaybackParams)}
+ * to control playback behavior.
+ * <p> <strong>audio fallback mode:</strong>
+ * select out-of-range parameter handling.
+ * <ul>
+ * <li> {@link PlaybackParams#AUDIO_FALLBACK_MODE_DEFAULT}:
+ *   System will determine best handling. </li>
+ * <li> {@link PlaybackParams#AUDIO_FALLBACK_MODE_MUTE}:
+ *   Play silence for params normally out of range.</li>
+ * <li> {@link PlaybackParams#AUDIO_FALLBACK_MODE_FAIL}:
+ *   Return {@link java.lang.IllegalArgumentException} from
+ *   <code>AudioTrack.setPlaybackParams(PlaybackParams)</code>.</li>
+ * </ul>
+ * <p> <strong>pitch:</strong> increases or decreases the tonal frequency of the audio content.
+ * It is expressed as a multiplicative factor, where normal pitch is 1.0f.
+ * <p> <strong>speed:</strong> increases or decreases the time to
+ * play back a set of audio or video frames.
+ * It is expressed as a multiplicative factor, where normal speed is 1.0f.
+ * <p> Different combinations of speed and pitch may be used for audio playback;
+ * some common ones:
+ * <ul>
+ * <li> <em>Pitch equals 1.0f.</em> Speed change will be done with pitch preserved,
+ * often called <em>timestretching</em>.</li>
+ * <li> <em>Pitch equals speed.</em> Speed change will be done by <em>resampling</em>,
+ * similar to {@link AudioTrack#setPlaybackRate(int)}.</li>
+ * </ul>
+ */
+public final class PlaybackParams implements Parcelable {
+    /** @hide */
+    @IntDef(
+        value = {
+                AUDIO_FALLBACK_MODE_DEFAULT,
+                AUDIO_FALLBACK_MODE_MUTE,
+                AUDIO_FALLBACK_MODE_FAIL,
+        }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioFallbackMode {}
+    public static final int AUDIO_FALLBACK_MODE_DEFAULT = 0;
+    public static final int AUDIO_FALLBACK_MODE_MUTE = 1;
+    public static final int AUDIO_FALLBACK_MODE_FAIL = 2;
+
+    /** @hide */
+    @IntDef(
+        value = {
+                AUDIO_STRETCH_MODE_DEFAULT,
+                AUDIO_STRETCH_MODE_VOICE,
+        }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioStretchMode {}
+    /** @hide */
+    public static final int AUDIO_STRETCH_MODE_DEFAULT = 0;
+    /** @hide */
+    public static final int AUDIO_STRETCH_MODE_VOICE = 1;
+
+    // flags to indicate which params are actually set
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static final int SET_SPEED               = 1 << 0;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static final int SET_PITCH               = 1 << 1;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static final int SET_AUDIO_FALLBACK_MODE = 1 << 2;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static final int SET_AUDIO_STRETCH_MODE  = 1 << 3;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private int mSet = 0;
+
+    // params
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private int mAudioFallbackMode = AUDIO_FALLBACK_MODE_DEFAULT;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private int mAudioStretchMode = AUDIO_STRETCH_MODE_DEFAULT;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private float mPitch = 1.0f;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private float mSpeed = 1.0f;
+
+    public PlaybackParams() {
+    }
+
+    private PlaybackParams(Parcel in) {
+        mSet = in.readInt();
+        mAudioFallbackMode = in.readInt();
+        mAudioStretchMode = in.readInt();
+        mPitch = in.readFloat();
+        if (mPitch < 0.f) {
+            mPitch = 0.f;
+        }
+        mSpeed = in.readFloat();
+    }
+
+    /**
+     * Allows defaults to be returned for properties not set.
+     * Otherwise a {@link java.lang.IllegalArgumentException} exception
+     * is raised when getting those properties
+     * which have defaults but have never been set.
+     * @return this <code>PlaybackParams</code> instance.
+     */
+    public PlaybackParams allowDefaults() {
+        mSet |= SET_AUDIO_FALLBACK_MODE | SET_AUDIO_STRETCH_MODE | SET_PITCH | SET_SPEED;
+        return this;
+    }
+
+    /**
+     * Sets the audio fallback mode.
+     * @param audioFallbackMode
+     * @return this <code>PlaybackParams</code> instance.
+     */
+    public PlaybackParams setAudioFallbackMode(@AudioFallbackMode int audioFallbackMode) {
+        mAudioFallbackMode = audioFallbackMode;
+        mSet |= SET_AUDIO_FALLBACK_MODE;
+        return this;
+    }
+
+    /**
+     * Retrieves the audio fallback mode.
+     * @return audio fallback mode
+     * @throws IllegalStateException if the audio fallback mode is not set.
+     */
+    public @AudioFallbackMode int getAudioFallbackMode() {
+        if ((mSet & SET_AUDIO_FALLBACK_MODE) == 0) {
+            throw new IllegalStateException("audio fallback mode not set");
+        }
+        return mAudioFallbackMode;
+    }
+
+    /**
+     * @hide
+     * Sets the audio stretch mode.
+     * @param audioStretchMode
+     * @return this <code>PlaybackParams</code> instance.
+     */
+    @TestApi
+    public PlaybackParams setAudioStretchMode(@AudioStretchMode int audioStretchMode) {
+        mAudioStretchMode = audioStretchMode;
+        mSet |= SET_AUDIO_STRETCH_MODE;
+        return this;
+    }
+
+    /**
+     * @hide
+     * Retrieves the audio stretch mode.
+     * @return audio stretch mode
+     * @throws IllegalStateException if the audio stretch mode is not set.
+     */
+    @TestApi
+    public @AudioStretchMode int getAudioStretchMode() {
+        if ((mSet & SET_AUDIO_STRETCH_MODE) == 0) {
+            throw new IllegalStateException("audio stretch mode not set");
+        }
+        return mAudioStretchMode;
+    }
+
+    /**
+     * Sets the pitch factor.
+     * @param pitch
+     * @return this <code>PlaybackParams</code> instance.
+     * @throws IllegalArgumentException if the pitch is negative.
+     */
+    public PlaybackParams setPitch(float pitch) {
+        if (pitch < 0.f) {
+            throw new IllegalArgumentException("pitch must not be negative");
+        }
+        mPitch = pitch;
+        mSet |= SET_PITCH;
+        return this;
+    }
+
+    /**
+     * Retrieves the pitch factor.
+     * @return pitch
+     * @throws IllegalStateException if pitch is not set.
+     */
+    public float getPitch() {
+        if ((mSet & SET_PITCH) == 0) {
+            throw new IllegalStateException("pitch not set");
+        }
+        return mPitch;
+    }
+
+    /**
+     * Sets the speed factor.
+     * @param speed
+     * @return this <code>PlaybackParams</code> instance.
+     */
+    public PlaybackParams setSpeed(float speed) {
+        mSpeed = speed;
+        mSet |= SET_SPEED;
+        return this;
+    }
+
+    /**
+     * Retrieves the speed factor.
+     * @return speed
+     * @throws IllegalStateException if speed is not set.
+     */
+    public float getSpeed() {
+        if ((mSet & SET_SPEED) == 0) {
+            throw new IllegalStateException("speed not set");
+        }
+        return mSpeed;
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<PlaybackParams> CREATOR =
+            new Parcelable.Creator<PlaybackParams>() {
+                @Override
+                public PlaybackParams createFromParcel(Parcel in) {
+                    return new PlaybackParams(in);
+                }
+
+                @Override
+                public PlaybackParams[] newArray(int size) {
+                    return new PlaybackParams[size];
+                }
+            };
+
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mSet);
+        dest.writeInt(mAudioFallbackMode);
+        dest.writeInt(mAudioStretchMode);
+        dest.writeFloat(mPitch);
+        dest.writeFloat(mSpeed);
+    }
+}
diff --git a/android/media/PlayerBase.java b/android/media/PlayerBase.java
new file mode 100644
index 0000000..86ed50b
--- /dev/null
+++ b/android/media/PlayerBase.java
@@ -0,0 +1,531 @@
+/*
+ * Copyright (C) 2016 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityThread;
+import android.content.Context;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.app.IAppOpsCallback;
+import com.android.internal.app.IAppOpsService;
+
+import java.lang.ref.WeakReference;
+import java.util.Objects;
+
+/**
+ * Class to encapsulate a number of common player operations:
+ *   - AppOps for OP_PLAY_AUDIO
+ *   - more to come (routing, transport control)
+ * @hide
+ */
+public abstract class PlayerBase {
+
+    private static final String TAG = "PlayerBase";
+    /** Debug app ops */
+    private static final boolean DEBUG_APP_OPS = false;
+    private static final boolean DEBUG = DEBUG_APP_OPS || false;
+    private static IAudioService sService; //lazy initialization, use getService()
+
+    // parameters of the player that affect AppOps
+    protected AudioAttributes mAttributes;
+
+    // volumes of the subclass "player volumes", as seen by the client of the subclass
+    //   (e.g. what was passed in AudioTrack.setVolume(float)). The actual volume applied is
+    //   the combination of the player volume, and the PlayerBase pan and volume multipliers
+    protected float mLeftVolume = 1.0f;
+    protected float mRightVolume = 1.0f;
+    protected float mAuxEffectSendLevel = 0.0f;
+
+    // NEVER call into AudioService (see getService()) with mLock held: PlayerBase can run in
+    // the same process as AudioService, which can synchronously call back into this class,
+    // causing deadlocks between the two
+    private final Object mLock = new Object();
+
+    // for AppOps
+    private @Nullable IAppOpsService mAppOps;
+    private @Nullable IAppOpsCallback mAppOpsCallback;
+    @GuardedBy("mLock")
+    private boolean mHasAppOpsPlayAudio = true;
+
+    private final int mImplType;
+    // uniquely identifies the Player Interface throughout the system (P I Id)
+    protected int mPlayerIId = AudioPlaybackConfiguration.PLAYER_PIID_INVALID;
+
+    @GuardedBy("mLock")
+    private int mState;
+    @GuardedBy("mLock")
+    private int mStartDelayMs = 0;
+    @GuardedBy("mLock")
+    private float mPanMultiplierL = 1.0f;
+    @GuardedBy("mLock")
+    private float mPanMultiplierR = 1.0f;
+    @GuardedBy("mLock")
+    private float mVolMultiplier = 1.0f;
+    @GuardedBy("mLock")
+    private int mDeviceId;
+
+    /**
+     * Constructor. Must be given audio attributes, as they are required for AppOps.
+     * @param attr non-null audio attributes
+     * @param class non-null class of the implementation of this abstract class
+     * @param sessionId the audio session Id
+     */
+    PlayerBase(@NonNull AudioAttributes attr, int implType) {
+        if (attr == null) {
+            throw new IllegalArgumentException("Illegal null AudioAttributes");
+        }
+        mAttributes = attr;
+        mImplType = implType;
+        mState = AudioPlaybackConfiguration.PLAYER_STATE_IDLE;
+    };
+
+    /**
+     * Call from derived class when instantiation / initialization is successful
+     */
+    protected void baseRegisterPlayer(int sessionId) {
+        try {
+            mPlayerIId = getService().trackPlayer(
+                    new PlayerIdCard(mImplType, mAttributes, new IPlayerWrapper(this),
+                            sessionId));
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error talking to audio service, player will not be tracked", e);
+        }
+    }
+
+    /**
+     * To be called whenever the audio attributes of the player change
+     * @param attr non-null audio attributes
+     */
+    void baseUpdateAudioAttributes(@NonNull AudioAttributes attr) {
+        if (attr == null) {
+            throw new IllegalArgumentException("Illegal null AudioAttributes");
+        }
+        try {
+            getService().playerAttributes(mPlayerIId, attr);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error talking to audio service, audio attributes will not be updated", e);
+        }
+        synchronized (mLock) {
+            mAttributes = attr;
+        }
+    }
+
+    /**
+     * To be called whenever the session ID of the player changes
+     * @param sessionId, the new session Id
+     */
+    void baseUpdateSessionId(int sessionId) {
+        try {
+            getService().playerSessionId(mPlayerIId, sessionId);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error talking to audio service, the session ID will not be updated", e);
+        }
+    }
+
+    void baseUpdateDeviceId(@Nullable AudioDeviceInfo deviceInfo) {
+        int deviceId = 0;
+        if (deviceInfo != null) {
+            deviceId = deviceInfo.getId();
+        }
+        int piid;
+        synchronized (mLock) {
+            piid = mPlayerIId;
+            mDeviceId = deviceId;
+        }
+        try {
+            getService().playerEvent(piid,
+                    AudioPlaybackConfiguration.PLAYER_UPDATE_DEVICE_ID, deviceId);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error talking to audio service, "
+                    + deviceId
+                    + " device id will not be tracked for piid=" + piid, e);
+        }
+    }
+
+    private void updateState(int state, int deviceId) {
+        final int piid;
+        synchronized (mLock) {
+            mState = state;
+            piid = mPlayerIId;
+            mDeviceId = deviceId;
+        }
+        try {
+            getService().playerEvent(piid, state, deviceId);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error talking to audio service, "
+                    + AudioPlaybackConfiguration.toLogFriendlyPlayerState(state)
+                    + " state will not be tracked for piid=" + piid, e);
+        }
+    }
+
+    void baseStart(int deviceId) {
+        if (DEBUG) {
+            Log.v(TAG, "baseStart() piid=" + mPlayerIId + " deviceId=" + deviceId);
+        }
+        updateState(AudioPlaybackConfiguration.PLAYER_STATE_STARTED, deviceId);
+    }
+
+    void baseSetStartDelayMs(int delayMs) {
+        synchronized(mLock) {
+            mStartDelayMs = Math.max(delayMs, 0);
+        }
+    }
+
+    protected int getStartDelayMs() {
+        synchronized(mLock) {
+            return mStartDelayMs;
+        }
+    }
+
+    void basePause() {
+        if (DEBUG) { Log.v(TAG, "basePause() piid=" + mPlayerIId); }
+        updateState(AudioPlaybackConfiguration.PLAYER_STATE_PAUSED, 0);
+    }
+
+    void baseStop() {
+        if (DEBUG) { Log.v(TAG, "baseStop() piid=" + mPlayerIId); }
+        updateState(AudioPlaybackConfiguration.PLAYER_STATE_STOPPED, 0);
+    }
+
+    void baseSetPan(float pan) {
+        final float p = Math.min(Math.max(-1.0f, pan), 1.0f);
+        synchronized (mLock) {
+            if (p >= 0.0f) {
+                mPanMultiplierL = 1.0f - p;
+                mPanMultiplierR = 1.0f;
+            } else {
+                mPanMultiplierL = 1.0f;
+                mPanMultiplierR = 1.0f + p;
+            }
+        }
+        updatePlayerVolume();
+    }
+
+    private void updatePlayerVolume() {
+        final float finalLeftVol, finalRightVol;
+        synchronized (mLock) {
+            finalLeftVol = mVolMultiplier * mLeftVolume * mPanMultiplierL;
+            finalRightVol = mVolMultiplier * mRightVolume * mPanMultiplierR;
+        }
+        playerSetVolume(false /*muting*/, finalLeftVol, finalRightVol);
+    }
+
+    void setVolumeMultiplier(float vol) {
+        synchronized (mLock) {
+            this.mVolMultiplier = vol;
+        }
+        updatePlayerVolume();
+    }
+
+    void baseSetVolume(float leftVolume, float rightVolume) {
+        synchronized (mLock) {
+            mLeftVolume = leftVolume;
+            mRightVolume = rightVolume;
+        }
+        updatePlayerVolume();
+    }
+
+    int baseSetAuxEffectSendLevel(float level) {
+        synchronized (mLock) {
+            mAuxEffectSendLevel = level;
+        }
+        return playerSetAuxEffectSendLevel(false/*muting*/, level);
+    }
+
+    /**
+     * To be called from a subclass release or finalize method.
+     * Releases AppOps related resources.
+     */
+    void baseRelease() {
+        if (DEBUG) { Log.v(TAG, "baseRelease() piid=" + mPlayerIId + " state=" + mState); }
+        boolean releasePlayer = false;
+        synchronized (mLock) {
+            if (mState != AudioPlaybackConfiguration.PLAYER_STATE_RELEASED) {
+                releasePlayer = true;
+                mState = AudioPlaybackConfiguration.PLAYER_STATE_RELEASED;
+            }
+        }
+        try {
+            if (releasePlayer) {
+                getService().releasePlayer(mPlayerIId);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error talking to audio service, the player will still be tracked", e);
+        }
+        try {
+            if (mAppOps != null) {
+                mAppOps.stopWatchingMode(mAppOpsCallback);
+            }
+        } catch (Exception e) {
+            // nothing to do here, the object is supposed to be released anyway
+        }
+    }
+
+    private static IAudioService getService()
+    {
+        if (sService != null) {
+            return sService;
+        }
+        IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
+        sService = IAudioService.Stub.asInterface(b);
+        return sService;
+    }
+
+    /**
+     * @hide
+     * @param delayMs
+     */
+    public void setStartDelayMs(int delayMs) {
+        baseSetStartDelayMs(delayMs);
+    }
+
+    //=====================================================================
+    // Abstract methods a subclass needs to implement
+    /**
+     * Abstract method for the subclass behavior's for volume and muting commands
+     * @param muting if true, the player is to be muted, and the volume values can be ignored
+     * @param leftVolume the left volume to use if muting is false
+     * @param rightVolume the right volume to use if muting is false
+     */
+    abstract void playerSetVolume(boolean muting, float leftVolume, float rightVolume);
+
+    /**
+     * Abstract method to apply a {@link VolumeShaper.Configuration}
+     * and a {@link VolumeShaper.Operation} to the Player.
+     * This should be overridden by the Player to call into the native
+     * VolumeShaper implementation. Multiple {@code VolumeShapers} may be
+     * concurrently active for a given Player, each accessible by the
+     * {@code VolumeShaper} id.
+     *
+     * The {@code VolumeShaper} implementation caches the id returned
+     * when applying a fully specified configuration
+     * from {VolumeShaper.Configuration.Builder} to track later
+     * operation changes requested on it.
+     *
+     * @param configuration a {@code VolumeShaper.Configuration} object
+     *        created by {@link VolumeShaper.Configuration.Builder} or
+     *        an created from a {@code VolumeShaper} id
+     *        by the {@link VolumeShaper.Configuration} constructor.
+     * @param operation a {@code VolumeShaper.Operation}.
+     * @return a negative error status or a
+     *         non-negative {@code VolumeShaper} id on success.
+     */
+    /* package */ abstract int playerApplyVolumeShaper(
+            @NonNull VolumeShaper.Configuration configuration,
+            @NonNull VolumeShaper.Operation operation);
+
+    /**
+     * Abstract method to get the current VolumeShaper state.
+     * @param id the {@code VolumeShaper} id returned from
+     *           sending a fully specified {@code VolumeShaper.Configuration}
+     *           through {@link #playerApplyVolumeShaper}
+     * @return a {@code VolumeShaper.State} object or null if
+     *         there is no {@code VolumeShaper} for the id.
+     */
+    /* package */ abstract @Nullable VolumeShaper.State playerGetVolumeShaperState(int id);
+
+    abstract int playerSetAuxEffectSendLevel(boolean muting, float level);
+    abstract void playerStart();
+    abstract void playerPause();
+    abstract void playerStop();
+
+    //=====================================================================
+    /**
+     * Wrapper around an implementation of IPlayer for all subclasses of PlayerBase
+     * that doesn't keep a strong reference on PlayerBase
+     */
+    private static class IPlayerWrapper extends IPlayer.Stub {
+        private final WeakReference<PlayerBase> mWeakPB;
+
+        public IPlayerWrapper(PlayerBase pb) {
+            mWeakPB = new WeakReference<PlayerBase>(pb);
+        }
+
+        @Override
+        public void start() {
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.playerStart();
+            }
+        }
+
+        @Override
+        public void pause() {
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.playerPause();
+            }
+        }
+
+        @Override
+        public void stop() {
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.playerStop();
+            }
+        }
+
+        @Override
+        public void setVolume(float vol) {
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.setVolumeMultiplier(vol);
+            }
+        }
+
+        @Override
+        public void setPan(float pan) {
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.baseSetPan(pan);
+            }
+        }
+
+        @Override
+        public void setStartDelayMs(int delayMs) {
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.baseSetStartDelayMs(delayMs);
+            }
+        }
+
+        @Override
+        public void applyVolumeShaper(
+                @NonNull VolumeShaperConfiguration configuration,
+                @NonNull VolumeShaperOperation operation) {
+            final PlayerBase pb = mWeakPB.get();
+            if (pb != null) {
+                pb.playerApplyVolumeShaper(VolumeShaper.Configuration.fromParcelable(configuration),
+                        VolumeShaper.Operation.fromParcelable(operation));
+            }
+        }
+    }
+
+    //=====================================================================
+    /**
+     * Class holding all the information about a player that needs to be known at registration time
+     */
+    public static class PlayerIdCard implements Parcelable {
+        public final int mPlayerType;
+
+        public static final int AUDIO_ATTRIBUTES_NONE = 0;
+        public static final int AUDIO_ATTRIBUTES_DEFINED = 1;
+        public final AudioAttributes mAttributes;
+        public final IPlayer mIPlayer;
+        public final int mSessionId;
+
+        PlayerIdCard(int type, @NonNull AudioAttributes attr, @NonNull IPlayer iplayer,
+                     int sessionId) {
+            mPlayerType = type;
+            mAttributes = attr;
+            mIPlayer = iplayer;
+            mSessionId = sessionId;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mPlayerType, mSessionId);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(mPlayerType);
+            mAttributes.writeToParcel(dest, 0);
+            dest.writeStrongBinder(mIPlayer == null ? null : mIPlayer.asBinder());
+            dest.writeInt(mSessionId);
+        }
+
+        public static final @android.annotation.NonNull Parcelable.Creator<PlayerIdCard> CREATOR
+        = new Parcelable.Creator<PlayerIdCard>() {
+            /**
+             * Rebuilds an PlayerIdCard previously stored with writeToParcel().
+             * @param p Parcel object to read the PlayerIdCard from
+             * @return a new PlayerIdCard created from the data in the parcel
+             */
+            public PlayerIdCard createFromParcel(Parcel p) {
+                return new PlayerIdCard(p);
+            }
+            public PlayerIdCard[] newArray(int size) {
+                return new PlayerIdCard[size];
+            }
+        };
+
+        private PlayerIdCard(Parcel in) {
+            mPlayerType = in.readInt();
+            mAttributes = AudioAttributes.CREATOR.createFromParcel(in);
+            // IPlayer can be null if unmarshalling a Parcel coming from who knows where
+            final IBinder b = in.readStrongBinder();
+            mIPlayer = (b == null ? null : IPlayer.Stub.asInterface(b));
+            mSessionId = in.readInt();
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || !(o instanceof PlayerIdCard)) return false;
+
+            PlayerIdCard that = (PlayerIdCard) o;
+
+            // FIXME change to the binder player interface once supported as a member
+            return ((mPlayerType == that.mPlayerType) && mAttributes.equals(that.mAttributes)
+                    && (mSessionId == that.mSessionId));
+        }
+    }
+
+    //=====================================================================
+    // Utilities
+
+    /**
+     * @hide
+     * Use to generate warning or exception in legacy code paths that allowed passing stream types
+     * to qualify audio playback.
+     * @param streamType the stream type to check
+     * @throws IllegalArgumentException
+     */
+    public static void deprecateStreamTypeForPlayback(int streamType, @NonNull String className,
+            @NonNull String opName) throws IllegalArgumentException {
+        // STREAM_ACCESSIBILITY was introduced at the same time the use of stream types
+        // for audio playback was deprecated, so it is not allowed at all to qualify a playback
+        // use case
+        if (streamType == AudioManager.STREAM_ACCESSIBILITY) {
+            throw new IllegalArgumentException("Use of STREAM_ACCESSIBILITY is reserved for "
+                    + "volume control");
+        }
+        Log.w(className, "Use of stream types is deprecated for operations other than " +
+                "volume control");
+        Log.w(className, "See the documentation of " + opName + " for what to use instead with " +
+                "android.media.AudioAttributes to qualify your playback use case");
+    }
+
+    protected String getCurrentOpPackageName() {
+        return TextUtils.emptyIfNull(ActivityThread.currentOpPackageName());
+    }
+}
diff --git a/android/media/PlayerProxy.java b/android/media/PlayerProxy.java
new file mode 100644
index 0000000..ec39128
--- /dev/null
+++ b/android/media/PlayerProxy.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright (C) 2017 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.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.media.VolumeShaper;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.lang.IllegalArgumentException;
+import java.util.Objects;
+
+/**
+ * Class to remotely control a player.
+ * @hide
+ */
+@SystemApi
+public class PlayerProxy {
+
+    private final static String TAG = "PlayerProxy";
+    private final static boolean DEBUG = false;
+
+    private final AudioPlaybackConfiguration mConf; // never null
+
+    /**
+     * @hide
+     * Constructor. Proxy for this player associated with this AudioPlaybackConfiguration
+     * @param conf the configuration being proxied.
+     */
+    PlayerProxy(@NonNull AudioPlaybackConfiguration apc) {
+        if (apc == null) {
+            throw new IllegalArgumentException("Illegal null AudioPlaybackConfiguration");
+        }
+        mConf = apc;
+    };
+
+    //=====================================================================
+    // Methods matching the IPlayer interface
+    /**
+     * @hide
+     */
+    @SystemApi
+    public void start() {
+        try {
+            mConf.getIPlayer().start();
+        } catch (NullPointerException|RemoteException e) {
+            throw new IllegalStateException(
+                    "No player to proxy for start operation, player already released?", e);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @SystemApi
+    public void pause() {
+        try {
+            mConf.getIPlayer().pause();
+        } catch (NullPointerException|RemoteException e) {
+            throw new IllegalStateException(
+                    "No player to proxy for pause operation, player already released?", e);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @SystemApi
+    public void stop() {
+        try {
+            mConf.getIPlayer().stop();
+        } catch (NullPointerException|RemoteException e) {
+            throw new IllegalStateException(
+                    "No player to proxy for stop operation, player already released?", e);
+        }
+    }
+
+    /**
+     * @hide
+     * @param vol
+     */
+    @SystemApi
+    public void setVolume(float vol) {
+        try {
+            mConf.getIPlayer().setVolume(vol);
+        } catch (NullPointerException|RemoteException e) {
+            throw new IllegalStateException(
+                    "No player to proxy for setVolume operation, player already released?", e);
+        }
+    }
+
+    /**
+     * @hide
+     * @param pan
+     */
+    @SystemApi
+    public void setPan(float pan) {
+        try {
+            mConf.getIPlayer().setPan(pan);
+        } catch (NullPointerException|RemoteException e) {
+            throw new IllegalStateException(
+                    "No player to proxy for setPan operation, player already released?", e);
+        }
+    }
+
+    /**
+     * @hide
+     * @param delayMs
+     */
+    @SystemApi
+    public void setStartDelayMs(int delayMs) {
+        try {
+            mConf.getIPlayer().setStartDelayMs(delayMs);
+        } catch (NullPointerException|RemoteException e) {
+            throw new IllegalStateException(
+                    "No player to proxy for setStartDelayMs operation, player already released?",
+                    e);
+        }
+    }
+
+    /**
+     * @hide
+     * @param configuration
+     * @param operation
+     * @return volume shaper id or error
+     */
+    public void applyVolumeShaper(
+            @NonNull VolumeShaper.Configuration configuration,
+            @NonNull VolumeShaper.Operation operation) {
+        try {
+            mConf.getIPlayer().applyVolumeShaper(configuration.toParcelable(),
+                    operation.toParcelable());
+        } catch (NullPointerException|RemoteException e) {
+            throw new IllegalStateException(
+                    "No player to proxy for applyVolumeShaper operation,"
+                    + " player already released?", e);
+        }
+    }
+}
diff --git a/android/media/ProxyDataSourceCallback.java b/android/media/ProxyDataSourceCallback.java
new file mode 100644
index 0000000..14d3ce8
--- /dev/null
+++ b/android/media/ProxyDataSourceCallback.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2019 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.os.ParcelFileDescriptor;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.util.Log;
+
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+/**
+ * A DataSourceCallback that is backed by a ParcelFileDescriptor.
+ */
+class ProxyDataSourceCallback extends DataSourceCallback {
+    private static final String TAG = "TestDataSourceCallback";
+
+    ParcelFileDescriptor mPFD;
+    FileDescriptor mFD;
+
+    ProxyDataSourceCallback(ParcelFileDescriptor pfd) throws IOException {
+        mPFD = pfd.dup();
+        mFD = mPFD.getFileDescriptor();
+    }
+
+    @Override
+    public synchronized int readAt(long position, byte[] buffer, int offset, int size)
+            throws IOException {
+        try {
+            Os.lseek(mFD, position, OsConstants.SEEK_SET);
+            int ret = Os.read(mFD, buffer, offset, size);
+            return (ret == 0) ? END_OF_STREAM : ret;
+        } catch (ErrnoException e) {
+            throw new IOException(e);
+        }
+    }
+
+    @Override
+    public synchronized long getSize() throws IOException {
+        return mPFD.getStatSize();
+    }
+
+    @Override
+    public synchronized void close() {
+        try {
+            mPFD.close();
+        } catch (IOException e) {
+            Log.e(TAG, "Failed to close the PFD.", e);
+        }
+    }
+}
+
diff --git a/android/media/Rating.java b/android/media/Rating.java
new file mode 100644
index 0000000..4da23a1
--- /dev/null
+++ b/android/media/Rating.java
@@ -0,0 +1,308 @@
+/*
+ * Copyright (C) 2013 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.annotation.IntDef;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A class to encapsulate rating information used as content metadata.
+ * A rating is defined by its rating style (see {@link #RATING_HEART},
+ * {@link #RATING_THUMB_UP_DOWN}, {@link #RATING_3_STARS}, {@link #RATING_4_STARS},
+ * {@link #RATING_5_STARS} or {@link #RATING_PERCENTAGE}) and the actual rating value (which may
+ * be defined as "unrated"), both of which are defined when the rating instance is constructed
+ * through one of the factory methods.
+ */
+public final class Rating implements Parcelable {
+    private static final String TAG = "Rating";
+
+    /**
+     * @hide
+     */
+    @IntDef({RATING_NONE, RATING_HEART, RATING_THUMB_UP_DOWN, RATING_3_STARS, RATING_4_STARS,
+            RATING_5_STARS, RATING_PERCENTAGE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Style {}
+
+    /**
+     * @hide
+     */
+    @IntDef({RATING_3_STARS, RATING_4_STARS, RATING_5_STARS})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface StarStyle {}
+
+    /**
+     * Indicates a rating style is not supported. A Rating will never have this
+     * type, but can be used by other classes to indicate they do not support
+     * Rating.
+     */
+    public static final int RATING_NONE = 0;
+
+    /**
+     * A rating style with a single degree of rating, "heart" vs "no heart". Can be used to
+     * indicate the content referred to is a favorite (or not).
+     */
+    public static final int RATING_HEART = 1;
+
+    /**
+     * A rating style for "thumb up" vs "thumb down".
+     */
+    public static final int RATING_THUMB_UP_DOWN = 2;
+
+    /**
+     * A rating style with 0 to 3 stars.
+     */
+    public static final int RATING_3_STARS = 3;
+
+    /**
+     * A rating style with 0 to 4 stars.
+     */
+    public static final int RATING_4_STARS = 4;
+
+    /**
+     * A rating style with 0 to 5 stars.
+     */
+    public static final int RATING_5_STARS = 5;
+
+    /**
+     * A rating style expressed as a percentage.
+     */
+    public static final int RATING_PERCENTAGE = 6;
+
+    private static final float RATING_NOT_RATED = -1.0f;
+
+    private final int mRatingStyle;
+
+    private final float mRatingValue;
+
+    private Rating(@Style int ratingStyle, float rating) {
+        mRatingStyle = ratingStyle;
+        mRatingValue = rating;
+    }
+
+    @Override
+    public String toString() {
+        return "Rating:style=" + mRatingStyle + " rating="
+                + (mRatingValue < 0.0f ? "unrated" : String.valueOf(mRatingValue));
+    }
+
+    @Override
+    public int describeContents() {
+        return mRatingStyle;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mRatingStyle);
+        dest.writeFloat(mRatingValue);
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<Rating> CREATOR = new Parcelable.Creator<Rating>() {
+        /**
+         * Rebuilds a Rating previously stored with writeToParcel().
+         * @param p    Parcel object to read the Rating from
+         * @return a new Rating created from the data in the parcel
+         */
+        @Override
+        public Rating createFromParcel(Parcel p) {
+            return new Rating(p.readInt(), p.readFloat());
+        }
+
+        @Override
+        public Rating[] newArray(int size) {
+            return new Rating[size];
+        }
+    };
+
+    /**
+     * Return a Rating instance with no rating.
+     * Create and return a new Rating instance with no rating known for the given
+     * rating style.
+     * @param ratingStyle one of {@link #RATING_HEART}, {@link #RATING_THUMB_UP_DOWN},
+     *    {@link #RATING_3_STARS}, {@link #RATING_4_STARS}, {@link #RATING_5_STARS},
+     *    or {@link #RATING_PERCENTAGE}.
+     * @return null if an invalid rating style is passed, a new Rating instance otherwise.
+     */
+    public static Rating newUnratedRating(@Style int ratingStyle) {
+        switch(ratingStyle) {
+            case RATING_HEART:
+            case RATING_THUMB_UP_DOWN:
+            case RATING_3_STARS:
+            case RATING_4_STARS:
+            case RATING_5_STARS:
+            case RATING_PERCENTAGE:
+                return new Rating(ratingStyle, RATING_NOT_RATED);
+            default:
+                return null;
+        }
+    }
+
+    /**
+     * Return a Rating instance with a heart-based rating.
+     * Create and return a new Rating instance with a rating style of {@link #RATING_HEART},
+     * and a heart-based rating.
+     * @param hasHeart true for a "heart selected" rating, false for "heart unselected".
+     * @return a new Rating instance.
+     */
+    public static Rating newHeartRating(boolean hasHeart) {
+        return new Rating(RATING_HEART, hasHeart ? 1.0f : 0.0f);
+    }
+
+    /**
+     * Return a Rating instance with a thumb-based rating.
+     * Create and return a new Rating instance with a {@link #RATING_THUMB_UP_DOWN}
+     * rating style, and a "thumb up" or "thumb down" rating.
+     * @param thumbIsUp true for a "thumb up" rating, false for "thumb down".
+     * @return a new Rating instance.
+     */
+    public static Rating newThumbRating(boolean thumbIsUp) {
+        return new Rating(RATING_THUMB_UP_DOWN, thumbIsUp ? 1.0f : 0.0f);
+    }
+
+    /**
+     * Return a Rating instance with a star-based rating.
+     * Create and return a new Rating instance with one of the star-base rating styles
+     * and the given integer or fractional number of stars. Non integer values can for instance
+     * be used to represent an average rating value, which might not be an integer number of stars.
+     * @param starRatingStyle one of {@link #RATING_3_STARS}, {@link #RATING_4_STARS},
+     *     {@link #RATING_5_STARS}.
+     * @param starRating a number ranging from 0.0f to 3.0f, 4.0f or 5.0f according to
+     *     the rating style.
+     * @return null if the rating style is invalid, or the rating is out of range,
+     *     a new Rating instance otherwise.
+     */
+    public static Rating newStarRating(@StarStyle int starRatingStyle, float starRating) {
+        float maxRating = -1.0f;
+        switch(starRatingStyle) {
+            case RATING_3_STARS:
+                maxRating = 3.0f;
+                break;
+            case RATING_4_STARS:
+                maxRating = 4.0f;
+                break;
+            case RATING_5_STARS:
+                maxRating = 5.0f;
+                break;
+            default:
+                Log.e(TAG, "Invalid rating style (" + starRatingStyle + ") for a star rating");
+                return null;
+        }
+        if (starRating >= 0.0f && starRating <= maxRating) {
+            return new Rating(starRatingStyle, starRating);
+        } else {
+            Log.e(TAG, "Trying to set out of range star-based rating");
+            return null;
+        }
+    }
+
+    /**
+     * Return a Rating instance with a percentage-based rating.
+     * Create and return a new Rating instance with a {@link #RATING_PERCENTAGE}
+     * rating style, and a rating of the given percentage.
+     * @param percent the value of the rating
+     * @return null if the rating is out of range, a new Rating instance otherwise.
+     */
+    public static Rating newPercentageRating(float percent) {
+        if (percent >= 0.0f && percent <= 100.0f) {
+            return new Rating(RATING_PERCENTAGE, percent);
+        } else {
+            Log.e(TAG, "Invalid percentage-based rating value");
+            return null;
+        }
+    }
+
+    /**
+     * Return whether there is a rating value available.
+     * @return true if the instance was not created with {@link #newUnratedRating(int)}.
+     */
+    public boolean isRated() {
+        return mRatingValue >= 0.0f;
+    }
+
+    /**
+     * Return the rating style.
+     * @return one of {@link #RATING_HEART}, {@link #RATING_THUMB_UP_DOWN},
+     *    {@link #RATING_3_STARS}, {@link #RATING_4_STARS}, {@link #RATING_5_STARS},
+     *    or {@link #RATING_PERCENTAGE}.
+     */
+    @Style
+    public int getRatingStyle() {
+        return mRatingStyle;
+    }
+
+    /**
+     * Return whether the rating is "heart selected".
+     * @return true if the rating is "heart selected", false if the rating is "heart unselected",
+     *    if the rating style is not {@link #RATING_HEART} or if it is unrated.
+     */
+    public boolean hasHeart() {
+        if (mRatingStyle != RATING_HEART) {
+            return false;
+        } else {
+            return (mRatingValue == 1.0f);
+        }
+    }
+
+    /**
+     * Return whether the rating is "thumb up".
+     * @return true if the rating is "thumb up", false if the rating is "thumb down",
+     *    if the rating style is not {@link #RATING_THUMB_UP_DOWN} or if it is unrated.
+     */
+    public boolean isThumbUp() {
+        if (mRatingStyle != RATING_THUMB_UP_DOWN) {
+            return false;
+        } else {
+            return (mRatingValue == 1.0f);
+        }
+    }
+
+    /**
+     * Return the star-based rating value.
+     * @return a rating value greater or equal to 0.0f, or a negative value if the rating style is
+     *    not star-based, or if it is unrated.
+     */
+    public float getStarRating() {
+        float ratingValue = -1.0f;
+        switch (mRatingStyle) {
+            case RATING_3_STARS:
+            case RATING_4_STARS:
+            case RATING_5_STARS:
+                if (isRated()) {
+                    ratingValue = mRatingValue;
+                }
+        }
+        return ratingValue;
+    }
+
+    /**
+     * Return the percentage-based rating value.
+     * @return a rating value greater or equal to 0.0f, or a negative value if the rating style is
+     *    not percentage-based, or if it is unrated.
+     */
+    public float getPercentRating() {
+        if ((mRatingStyle != RATING_PERCENTAGE) || !isRated()) {
+            return -1.0f;
+        } else {
+            return mRatingValue;
+        }
+    }
+}
diff --git a/android/media/RemoteControlClient.java b/android/media/RemoteControlClient.java
new file mode 100644
index 0000000..8d47ed1
--- /dev/null
+++ b/android/media/RemoteControlClient.java
@@ -0,0 +1,1174 @@
+/*
+ * Copyright (C) 2011 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.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionLegacyHelper;
+import android.media.session.PlaybackState;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Looper;
+import android.os.SystemClock;
+import android.util.Log;
+
+/**
+ * RemoteControlClient enables exposing information meant to be consumed by remote controls
+ * capable of displaying metadata, artwork and media transport control buttons.
+ *
+ * <p>A remote control client object is associated with a media button event receiver. This
+ * event receiver must have been previously registered with
+ * {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)} before the
+ * RemoteControlClient can be registered through
+ * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.
+ *
+ * <p>Here is an example of creating a RemoteControlClient instance after registering a media
+ * button event receiver:
+ * <pre>ComponentName myEventReceiver = new ComponentName(getPackageName(), MyRemoteControlEventReceiver.class.getName());
+ * AudioManager myAudioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
+ * myAudioManager.registerMediaButtonEventReceiver(myEventReceiver);
+ * // build the PendingIntent for the remote control client
+ * Intent mediaButtonIntent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+ * mediaButtonIntent.setComponent(myEventReceiver);
+ * PendingIntent mediaPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, mediaButtonIntent, PendingIntent.FLAG_MUTABLE_UNAUDITED);
+ * // create and register the remote control client
+ * RemoteControlClient myRemoteControlClient = new RemoteControlClient(mediaPendingIntent);
+ * myAudioManager.registerRemoteControlClient(myRemoteControlClient);</pre>
+ *
+ * @deprecated Use {@link MediaSession} instead.
+ */
+@Deprecated public class RemoteControlClient
+{
+    private final static String TAG = "RemoteControlClient";
+    private final static boolean DEBUG = false;
+
+    /**
+     * Playback state of a RemoteControlClient which is stopped.
+     *
+     * @see #setPlaybackState(int)
+     */
+    public final static int PLAYSTATE_STOPPED            = 1;
+    /**
+     * Playback state of a RemoteControlClient which is paused.
+     *
+     * @see #setPlaybackState(int)
+     */
+    public final static int PLAYSTATE_PAUSED             = 2;
+    /**
+     * Playback state of a RemoteControlClient which is playing media.
+     *
+     * @see #setPlaybackState(int)
+     */
+    public final static int PLAYSTATE_PLAYING            = 3;
+    /**
+     * Playback state of a RemoteControlClient which is fast forwarding in the media
+     *    it is currently playing.
+     *
+     * @see #setPlaybackState(int)
+     */
+    public final static int PLAYSTATE_FAST_FORWARDING    = 4;
+    /**
+     * Playback state of a RemoteControlClient which is fast rewinding in the media
+     *    it is currently playing.
+     *
+     * @see #setPlaybackState(int)
+     */
+    public final static int PLAYSTATE_REWINDING          = 5;
+    /**
+     * Playback state of a RemoteControlClient which is skipping to the next
+     *    logical chapter (such as a song in a playlist) in the media it is currently playing.
+     *
+     * @see #setPlaybackState(int)
+     */
+    public final static int PLAYSTATE_SKIPPING_FORWARDS  = 6;
+    /**
+     * Playback state of a RemoteControlClient which is skipping back to the previous
+     *    logical chapter (such as a song in a playlist) in the media it is currently playing.
+     *
+     * @see #setPlaybackState(int)
+     */
+    public final static int PLAYSTATE_SKIPPING_BACKWARDS = 7;
+    /**
+     * Playback state of a RemoteControlClient which is buffering data to play before it can
+     *    start or resume playback.
+     *
+     * @see #setPlaybackState(int)
+     */
+    public final static int PLAYSTATE_BUFFERING          = 8;
+    /**
+     * Playback state of a RemoteControlClient which cannot perform any playback related
+     *    operation because of an internal error. Examples of such situations are no network
+     *    connectivity when attempting to stream data from a server, or expired user credentials
+     *    when trying to play subscription-based content.
+     *
+     * @see #setPlaybackState(int)
+     */
+    public final static int PLAYSTATE_ERROR              = 9;
+    /**
+     * @hide
+     * The value of a playback state when none has been declared.
+     * Intentionally hidden as an application shouldn't set such a playback state value.
+     */
+    public final static int PLAYSTATE_NONE               = 0;
+
+    /**
+     * @hide
+     * The default playback type, "local", indicating the presentation of the media is happening on
+     * the same device (e.g. a phone, a tablet) as where it is controlled from.
+     */
+    public final static int PLAYBACK_TYPE_LOCAL = 0;
+    /**
+     * @hide
+     * A playback type indicating the presentation of the media is happening on
+     * a different device (i.e. the remote device) than where it is controlled from.
+     */
+    public final static int PLAYBACK_TYPE_REMOTE = 1;
+    private final static int PLAYBACK_TYPE_MIN = PLAYBACK_TYPE_LOCAL;
+    private final static int PLAYBACK_TYPE_MAX = PLAYBACK_TYPE_REMOTE;
+    /**
+     * @hide
+     * Playback information indicating the playback volume is fixed, i.e. it cannot be controlled
+     * from this object. An example of fixed playback volume is a remote player, playing over HDMI
+     * where the user prefer to control the volume on the HDMI sink, rather than attenuate at the
+     * source.
+     * @see #PLAYBACKINFO_VOLUME_HANDLING.
+     */
+    public final static int PLAYBACK_VOLUME_FIXED = 0;
+    /**
+     * @hide
+     * Playback information indicating the playback volume is variable and can be controlled from
+     * this object.
+     * @see #PLAYBACKINFO_VOLUME_HANDLING.
+     */
+    public final static int PLAYBACK_VOLUME_VARIABLE = 1;
+    /**
+     * @hide (to be un-hidden)
+     * The playback information value indicating the value of a given information type is invalid.
+     * @see #PLAYBACKINFO_VOLUME_HANDLING.
+     */
+    public final static int PLAYBACKINFO_INVALID_VALUE = Integer.MIN_VALUE;
+
+    /**
+     * @hide
+     * An unknown or invalid playback position value.
+     */
+    public final static long PLAYBACK_POSITION_INVALID = -1;
+    /**
+     * @hide
+     * An invalid playback position value associated with the use of {@link #setPlaybackState(int)}
+     * used to indicate that playback position will remain unknown.
+     */
+    public final static long PLAYBACK_POSITION_ALWAYS_UNKNOWN = 0x8019771980198300L;
+    /**
+     * @hide
+     * The default playback speed, 1x.
+     */
+    public final static float PLAYBACK_SPEED_1X = 1.0f;
+
+    //==========================================
+    // Public keys for playback information
+    /**
+     * @hide
+     * Playback information that defines the type of playback associated with this
+     * RemoteControlClient. See {@link #PLAYBACK_TYPE_LOCAL} and {@link #PLAYBACK_TYPE_REMOTE}.
+     */
+    public final static int PLAYBACKINFO_PLAYBACK_TYPE = 1;
+    /**
+     * @hide
+     * Playback information that defines at what volume the playback associated with this
+     * RemoteControlClient is performed. This information is only used when the playback type is not
+     * local (see {@link #PLAYBACKINFO_PLAYBACK_TYPE}).
+     */
+    public final static int PLAYBACKINFO_VOLUME = 2;
+    /**
+     * @hide
+     * Playback information that defines the maximum volume volume value that is supported
+     * by the playback associated with this RemoteControlClient. This information is only used
+     * when the playback type is not local (see {@link #PLAYBACKINFO_PLAYBACK_TYPE}).
+     */
+    public final static int PLAYBACKINFO_VOLUME_MAX = 3;
+    /**
+     * @hide
+     * Playback information that defines how volume is handled for the presentation of the media.
+     * @see #PLAYBACK_VOLUME_FIXED
+     * @see #PLAYBACK_VOLUME_VARIABLE
+     */
+    public final static int PLAYBACKINFO_VOLUME_HANDLING = 4;
+    /**
+     * @hide
+     * Playback information that defines over what stream type the media is presented.
+     */
+    public final static int PLAYBACKINFO_USES_STREAM = 5;
+
+    //==========================================
+    // Public flags for the supported transport control capabilities
+    /**
+     * Flag indicating a RemoteControlClient makes use of the "previous" media key.
+     *
+     * @see #setTransportControlFlags(int)
+     * @see android.view.KeyEvent#KEYCODE_MEDIA_PREVIOUS
+     */
+    public final static int FLAG_KEY_MEDIA_PREVIOUS = 1 << 0;
+    /**
+     * Flag indicating a RemoteControlClient makes use of the "rewind" media key.
+     *
+     * @see #setTransportControlFlags(int)
+     * @see android.view.KeyEvent#KEYCODE_MEDIA_REWIND
+     */
+    public final static int FLAG_KEY_MEDIA_REWIND = 1 << 1;
+    /**
+     * Flag indicating a RemoteControlClient makes use of the "play" media key.
+     *
+     * @see #setTransportControlFlags(int)
+     * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY
+     */
+    public final static int FLAG_KEY_MEDIA_PLAY = 1 << 2;
+    /**
+     * Flag indicating a RemoteControlClient makes use of the "play/pause" media key.
+     *
+     * @see #setTransportControlFlags(int)
+     * @see android.view.KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE
+     */
+    public final static int FLAG_KEY_MEDIA_PLAY_PAUSE = 1 << 3;
+    /**
+     * Flag indicating a RemoteControlClient makes use of the "pause" media key.
+     *
+     * @see #setTransportControlFlags(int)
+     * @see android.view.KeyEvent#KEYCODE_MEDIA_PAUSE
+     */
+    public final static int FLAG_KEY_MEDIA_PAUSE = 1 << 4;
+    /**
+     * Flag indicating a RemoteControlClient makes use of the "stop" media key.
+     *
+     * @see #setTransportControlFlags(int)
+     * @see android.view.KeyEvent#KEYCODE_MEDIA_STOP
+     */
+    public final static int FLAG_KEY_MEDIA_STOP = 1 << 5;
+    /**
+     * Flag indicating a RemoteControlClient makes use of the "fast forward" media key.
+     *
+     * @see #setTransportControlFlags(int)
+     * @see android.view.KeyEvent#KEYCODE_MEDIA_FAST_FORWARD
+     */
+    public final static int FLAG_KEY_MEDIA_FAST_FORWARD = 1 << 6;
+    /**
+     * Flag indicating a RemoteControlClient makes use of the "next" media key.
+     *
+     * @see #setTransportControlFlags(int)
+     * @see android.view.KeyEvent#KEYCODE_MEDIA_NEXT
+     */
+    public final static int FLAG_KEY_MEDIA_NEXT = 1 << 7;
+    /**
+     * Flag indicating a RemoteControlClient can receive changes in the media playback position
+     * through the {@link OnPlaybackPositionUpdateListener} interface. This flag must be set
+     * in order for components that display the RemoteControlClient information, to display and
+     * let the user control media playback position.
+     * @see #setTransportControlFlags(int)
+     * @see #setOnGetPlaybackPositionListener(OnGetPlaybackPositionListener)
+     * @see #setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener)
+     */
+    public final static int FLAG_KEY_MEDIA_POSITION_UPDATE = 1 << 8;
+    /**
+     * Flag indicating a RemoteControlClient supports ratings.
+     * This flag must be set in order for components that display the RemoteControlClient
+     * information, to display ratings information, and, if ratings are declared editable
+     * (by calling {@link MediaMetadataEditor#addEditableKey(int)} with the
+     * {@link MediaMetadataEditor#RATING_KEY_BY_USER} key), it will enable the user to rate
+     * the media, with values being received through the interface set with
+     * {@link #setMetadataUpdateListener(OnMetadataUpdateListener)}.
+     * @see #setTransportControlFlags(int)
+     */
+    public final static int FLAG_KEY_MEDIA_RATING = 1 << 9;
+
+    /**
+     * @hide
+     * The flags for when no media keys are declared supported.
+     * Intentionally hidden as an application shouldn't set the transport control flags
+     *     to this value.
+     */
+    public final static int FLAGS_KEY_MEDIA_NONE = 0;
+
+    /**
+     * @hide
+     * Flag used to signal some type of metadata exposed by the RemoteControlClient is requested.
+     */
+    public final static int FLAG_INFORMATION_REQUEST_METADATA = 1 << 0;
+    /**
+     * @hide
+     * Flag used to signal that the transport control buttons supported by the
+     *     RemoteControlClient are requested.
+     * This can for instance happen when playback is at the end of a playlist, and the "next"
+     * operation is not supported anymore.
+     */
+    public final static int FLAG_INFORMATION_REQUEST_KEY_MEDIA = 1 << 1;
+    /**
+     * @hide
+     * Flag used to signal that the playback state of the RemoteControlClient is requested.
+     */
+    public final static int FLAG_INFORMATION_REQUEST_PLAYSTATE = 1 << 2;
+    /**
+     * @hide
+     * Flag used to signal that the album art for the RemoteControlClient is requested.
+     */
+    public final static int FLAG_INFORMATION_REQUEST_ALBUM_ART = 1 << 3;
+
+    private MediaSession mSession;
+
+    /**
+     * Class constructor.
+     * @param mediaButtonIntent The intent that will be sent for the media button events sent
+     *     by remote controls.
+     *     This intent needs to have been constructed with the {@link Intent#ACTION_MEDIA_BUTTON}
+     *     action, and have a component that will handle the intent (set with
+     *     {@link Intent#setComponent(ComponentName)}) registered with
+     *     {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)}
+     *     before this new RemoteControlClient can itself be registered with
+     *     {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.
+     * @see AudioManager#registerMediaButtonEventReceiver(ComponentName)
+     * @see AudioManager#registerRemoteControlClient(RemoteControlClient)
+     */
+    public RemoteControlClient(PendingIntent mediaButtonIntent) {
+        mRcMediaIntent = mediaButtonIntent;
+    }
+
+    /**
+     * Class constructor for a remote control client whose internal event handling
+     * happens on a user-provided Looper.
+     * @param mediaButtonIntent The intent that will be sent for the media button events sent
+     *     by remote controls.
+     *     This intent needs to have been constructed with the {@link Intent#ACTION_MEDIA_BUTTON}
+     *     action, and have a component that will handle the intent (set with
+     *     {@link Intent#setComponent(ComponentName)}) registered with
+     *     {@link AudioManager#registerMediaButtonEventReceiver(ComponentName)}
+     *     before this new RemoteControlClient can itself be registered with
+     *     {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.
+     * @param looper The Looper running the event loop.
+     * @see AudioManager#registerMediaButtonEventReceiver(ComponentName)
+     * @see AudioManager#registerRemoteControlClient(RemoteControlClient)
+     */
+    public RemoteControlClient(PendingIntent mediaButtonIntent, Looper looper) {
+        mRcMediaIntent = mediaButtonIntent;
+    }
+
+    /**
+     * @hide
+     */
+    public void registerWithSession(MediaSessionLegacyHelper helper) {
+        helper.addRccListener(mRcMediaIntent, mTransportListener);
+        mSession = helper.getSession(mRcMediaIntent);
+        setTransportControlFlags(mTransportControlFlags);
+    }
+
+    /**
+     * @hide
+     */
+    public void unregisterWithSession(MediaSessionLegacyHelper helper) {
+        helper.removeRccListener(mRcMediaIntent);
+        mSession = null;
+    }
+
+    /**
+     * Get a {@link MediaSession} associated with this RCC. It will only have a
+     * session while it is registered with
+     * {@link AudioManager#registerRemoteControlClient}. The session returned
+     * should not be modified directly by the application but may be used with
+     * other APIs that require a session.
+     *
+     * @return A media session object or null.
+     */
+    public MediaSession getMediaSession() {
+        return mSession;
+    }
+
+    /**
+     * Class used to modify metadata in a {@link RemoteControlClient} object.
+     * Use {@link RemoteControlClient#editMetadata(boolean)} to create an instance of an editor,
+     * on which you set the metadata for the RemoteControlClient instance. Once all the information
+     * has been set, use {@link #apply()} to make it the new metadata that should be displayed
+     * for the associated client. Once the metadata has been "applied", you cannot reuse this
+     * instance of the MetadataEditor.
+     *
+     * @deprecated Use {@link MediaMetadata} and {@link MediaSession} instead.
+     */
+    @Deprecated public class MetadataEditor extends MediaMetadataEditor {
+
+        // only use RemoteControlClient.editMetadata() to get a MetadataEditor instance
+        private MetadataEditor() { }
+        /**
+         * @hide
+         */
+        public Object clone() throws CloneNotSupportedException {
+            throw new CloneNotSupportedException();
+        }
+
+        /**
+         * The metadata key for the content artwork / album art.
+         */
+        public final static int BITMAP_KEY_ARTWORK = 100;
+
+        /**
+         * @hide
+         * TODO(jmtrivi) have lockscreen move to the new key name and remove
+         */
+        public final static int METADATA_KEY_ARTWORK = BITMAP_KEY_ARTWORK;
+
+        /**
+         * Adds textual information to be displayed.
+         * Note that none of the information added after {@link #apply()} has been called,
+         * will be displayed.
+         * @param key The identifier of a the metadata field to set. Valid values are
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUM},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ALBUMARTIST},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_ARTIST},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_AUTHOR},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPILATION},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_COMPOSER},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DATE},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_GENRE},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_TITLE},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_WRITER}.
+         * @param value The text for the given key, or {@code null} to signify there is no valid
+         *      information for the field.
+         * @return Returns a reference to the same MetadataEditor object, so you can chain put
+         *      calls together.
+         */
+        public synchronized MetadataEditor putString(int key, String value)
+                throws IllegalArgumentException {
+            super.putString(key, value);
+            if (mMetadataBuilder != null) {
+                // MediaMetadata supports all the same fields as MetadataEditor
+                String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key);
+                // But just in case, don't add things we don't understand
+                if (metadataKey != null) {
+                    mMetadataBuilder.putText(metadataKey, value);
+                }
+            }
+
+            return this;
+        }
+
+        /**
+         * Adds numerical information to be displayed.
+         * Note that none of the information added after {@link #apply()} has been called,
+         * will be displayed.
+         * @param key the identifier of a the metadata field to set. Valid values are
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_CD_TRACK_NUMBER},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DISC_NUMBER},
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} (with a value
+         *      expressed in milliseconds),
+         *      {@link android.media.MediaMetadataRetriever#METADATA_KEY_YEAR}.
+         * @param value The long value for the given key
+         * @return Returns a reference to the same MetadataEditor object, so you can chain put
+         *      calls together.
+         * @throws IllegalArgumentException
+         */
+        public synchronized MetadataEditor putLong(int key, long value)
+                throws IllegalArgumentException {
+            super.putLong(key, value);
+            if (mMetadataBuilder != null) {
+                // MediaMetadata supports all the same fields as MetadataEditor
+                String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key);
+                // But just in case, don't add things we don't understand
+                if (metadataKey != null) {
+                    mMetadataBuilder.putLong(metadataKey, value);
+                }
+            }
+            return this;
+        }
+
+        /**
+         * Sets the album / artwork picture to be displayed on the remote control.
+         * @param key the identifier of the bitmap to set. The only valid value is
+         *      {@link #BITMAP_KEY_ARTWORK}
+         * @param bitmap The bitmap for the artwork, or null if there isn't any.
+         * @return Returns a reference to the same MetadataEditor object, so you can chain put
+         *      calls together.
+         * @throws IllegalArgumentException
+         * @see android.graphics.Bitmap
+         */
+        @Override
+        public synchronized MetadataEditor putBitmap(int key, Bitmap bitmap)
+                throws IllegalArgumentException {
+            super.putBitmap(key, bitmap);
+            if (mMetadataBuilder != null) {
+                // MediaMetadata supports all the same fields as MetadataEditor
+                String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key);
+                // But just in case, don't add things we don't understand
+                if (metadataKey != null) {
+                    mMetadataBuilder.putBitmap(metadataKey, bitmap);
+                }
+            }
+            return this;
+        }
+
+        @Override
+        public synchronized MetadataEditor putObject(int key, Object object)
+                throws IllegalArgumentException {
+            super.putObject(key, object);
+            if (mMetadataBuilder != null &&
+                    (key == MediaMetadataEditor.RATING_KEY_BY_USER ||
+                    key == MediaMetadataEditor.RATING_KEY_BY_OTHERS)) {
+                String metadataKey = MediaMetadata.getKeyFromMetadataEditorKey(key);
+                if (metadataKey != null) {
+                    mMetadataBuilder.putRating(metadataKey, (Rating) object);
+                }
+            }
+            return this;
+        }
+
+        /**
+         * Clears all the metadata that has been set since the MetadataEditor instance was created
+         * (with {@link RemoteControlClient#editMetadata(boolean)}).
+         * Note that clearing the metadata doesn't reset the editable keys
+         * (use {@link MediaMetadataEditor#removeEditableKeys()} instead).
+         */
+        @Override
+        public synchronized void clear() {
+            super.clear();
+        }
+
+        /**
+         * Associates all the metadata that has been set since the MetadataEditor instance was
+         *     created with {@link RemoteControlClient#editMetadata(boolean)}, or since
+         *     {@link #clear()} was called, with the RemoteControlClient. Once "applied",
+         *     this MetadataEditor cannot be reused to edit the RemoteControlClient's metadata.
+         */
+        public synchronized void apply() {
+            if (mApplied) {
+                Log.e(TAG, "Can't apply a previously applied MetadataEditor");
+                return;
+            }
+            synchronized (mCacheLock) {
+                // Still build the old metadata so when creating a new editor
+                // you get the expected values.
+                // assign the edited data
+                mMetadata = new Bundle(mEditorMetadata);
+                // add the information about editable keys
+                mMetadata.putLong(String.valueOf(KEY_EDITABLE_MASK), mEditableKeys);
+                if ((mOriginalArtwork != null) && (!mOriginalArtwork.equals(mEditorArtwork))) {
+                    mOriginalArtwork.recycle();
+                }
+                mOriginalArtwork = mEditorArtwork;
+                mEditorArtwork = null;
+
+                // USE_SESSIONS
+                if (mSession != null && mMetadataBuilder != null) {
+                    mMediaMetadata = mMetadataBuilder.build();
+                    mSession.setMetadata(mMediaMetadata);
+                }
+                mApplied = true;
+            }
+        }
+    }
+
+    /**
+     * Creates a {@link MetadataEditor}.
+     * @param startEmpty Set to false if you want the MetadataEditor to contain the metadata that
+     *     was previously applied to the RemoteControlClient, or true if it is to be created empty.
+     * @return a new MetadataEditor instance.
+     */
+    public MetadataEditor editMetadata(boolean startEmpty) {
+        MetadataEditor editor = new MetadataEditor();
+        if (startEmpty) {
+            editor.mEditorMetadata = new Bundle();
+            editor.mEditorArtwork = null;
+            editor.mMetadataChanged = true;
+            editor.mArtworkChanged = true;
+            editor.mEditableKeys = 0;
+        } else {
+            editor.mEditorMetadata = new Bundle(mMetadata);
+            editor.mEditorArtwork = mOriginalArtwork;
+            editor.mMetadataChanged = false;
+            editor.mArtworkChanged = false;
+        }
+        // USE_SESSIONS
+        if (startEmpty || mMediaMetadata == null) {
+            editor.mMetadataBuilder = new MediaMetadata.Builder();
+        } else {
+            editor.mMetadataBuilder = new MediaMetadata.Builder(mMediaMetadata);
+        }
+        return editor;
+    }
+
+    /**
+     * Sets the current playback state.
+     * @param state The current playback state, one of the following values:
+     *       {@link #PLAYSTATE_STOPPED},
+     *       {@link #PLAYSTATE_PAUSED},
+     *       {@link #PLAYSTATE_PLAYING},
+     *       {@link #PLAYSTATE_FAST_FORWARDING},
+     *       {@link #PLAYSTATE_REWINDING},
+     *       {@link #PLAYSTATE_SKIPPING_FORWARDS},
+     *       {@link #PLAYSTATE_SKIPPING_BACKWARDS},
+     *       {@link #PLAYSTATE_BUFFERING},
+     *       {@link #PLAYSTATE_ERROR}.
+     */
+    public void setPlaybackState(int state) {
+        setPlaybackStateInt(state, PLAYBACK_POSITION_ALWAYS_UNKNOWN, PLAYBACK_SPEED_1X,
+                false /* legacy API, converting to method with position and speed */);
+    }
+
+    /**
+     * Sets the current playback state and the matching media position for the current playback
+     *   speed.
+     * @param state The current playback state, one of the following values:
+     *       {@link #PLAYSTATE_STOPPED},
+     *       {@link #PLAYSTATE_PAUSED},
+     *       {@link #PLAYSTATE_PLAYING},
+     *       {@link #PLAYSTATE_FAST_FORWARDING},
+     *       {@link #PLAYSTATE_REWINDING},
+     *       {@link #PLAYSTATE_SKIPPING_FORWARDS},
+     *       {@link #PLAYSTATE_SKIPPING_BACKWARDS},
+     *       {@link #PLAYSTATE_BUFFERING},
+     *       {@link #PLAYSTATE_ERROR}.
+     * @param timeInMs a 0 or positive value for the current media position expressed in ms
+     *    (same unit as for when sending the media duration, if applicable, with
+     *    {@link android.media.MediaMetadataRetriever#METADATA_KEY_DURATION} in the
+     *    {@link RemoteControlClient.MetadataEditor}). Negative values imply that position is not
+     *    known (e.g. listening to a live stream of a radio) or not applicable (e.g. when state
+     *    is {@link #PLAYSTATE_BUFFERING} and nothing had played yet).
+     * @param playbackSpeed a value expressed as a ratio of 1x playback: 1.0f is normal playback,
+     *    2.0f is 2x, 0.5f is half-speed, -2.0f is rewind at 2x speed. 0.0f means nothing is
+     *    playing (e.g. when state is {@link #PLAYSTATE_ERROR}).
+     */
+    public void setPlaybackState(int state, long timeInMs, float playbackSpeed) {
+        setPlaybackStateInt(state, timeInMs, playbackSpeed, true);
+    }
+
+    private void setPlaybackStateInt(int state, long timeInMs, float playbackSpeed,
+            boolean hasPosition) {
+        synchronized(mCacheLock) {
+            if ((mPlaybackState != state) || (mPlaybackPositionMs != timeInMs)
+                    || (mPlaybackSpeed != playbackSpeed)) {
+                // store locally
+                mPlaybackState = state;
+                // distinguish between an application not knowing the current playback position
+                // at the moment and an application using the API where only the playback state
+                // is passed, not the playback position.
+                if (hasPosition) {
+                    if (timeInMs < 0) {
+                        mPlaybackPositionMs = PLAYBACK_POSITION_INVALID;
+                    } else {
+                        mPlaybackPositionMs = timeInMs;
+                    }
+                } else {
+                    mPlaybackPositionMs = PLAYBACK_POSITION_ALWAYS_UNKNOWN;
+                }
+                mPlaybackSpeed = playbackSpeed;
+                // keep track of when the state change occurred
+                mPlaybackStateChangeTimeMs = SystemClock.elapsedRealtime();
+
+                // USE_SESSIONS
+                if (mSession != null) {
+                    int pbState = getStateFromRccState(state);
+                    long position = hasPosition ? mPlaybackPositionMs
+                            : PlaybackState.PLAYBACK_POSITION_UNKNOWN;
+
+                    PlaybackState.Builder bob = new PlaybackState.Builder(mSessionPlaybackState);
+                    bob.setState(pbState, position, playbackSpeed, SystemClock.elapsedRealtime());
+                    bob.setErrorMessage(null);
+                    mSessionPlaybackState = bob.build();
+                    mSession.setPlaybackState(mSessionPlaybackState);
+                }
+            }
+        }
+    }
+
+    /**
+     * Sets the flags for the media transport control buttons that this client supports.
+     * @param transportControlFlags A combination of the following flags:
+     *      {@link #FLAG_KEY_MEDIA_PREVIOUS},
+     *      {@link #FLAG_KEY_MEDIA_REWIND},
+     *      {@link #FLAG_KEY_MEDIA_PLAY},
+     *      {@link #FLAG_KEY_MEDIA_PLAY_PAUSE},
+     *      {@link #FLAG_KEY_MEDIA_PAUSE},
+     *      {@link #FLAG_KEY_MEDIA_STOP},
+     *      {@link #FLAG_KEY_MEDIA_FAST_FORWARD},
+     *      {@link #FLAG_KEY_MEDIA_NEXT},
+     *      {@link #FLAG_KEY_MEDIA_POSITION_UPDATE},
+     *      {@link #FLAG_KEY_MEDIA_RATING}.
+     */
+    public void setTransportControlFlags(int transportControlFlags) {
+        synchronized(mCacheLock) {
+            // store locally
+            mTransportControlFlags = transportControlFlags;
+
+            // USE_SESSIONS
+            if (mSession != null) {
+                PlaybackState.Builder bob = new PlaybackState.Builder(mSessionPlaybackState);
+                bob.setActions(getActionsFromRccControlFlags(transportControlFlags));
+                mSessionPlaybackState = bob.build();
+                mSession.setPlaybackState(mSessionPlaybackState);
+            }
+        }
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when one of the metadata values has
+     * been updated.
+     * Implement this interface to receive metadata updates after registering your listener
+     * through {@link RemoteControlClient#setMetadataUpdateListener(OnMetadataUpdateListener)}.
+     */
+    public interface OnMetadataUpdateListener {
+        /**
+         * Called on the implementer to notify that the metadata field for the given key has
+         * been updated to the new value.
+         * @param key the identifier of the updated metadata field.
+         * @param newValue the Object storing the new value for the key.
+         */
+        public abstract void onMetadataUpdate(int key, Object newValue);
+    }
+
+    /**
+     * Sets the listener to be called whenever the metadata is updated.
+     * New metadata values will be received in the same thread as the one in which
+     * RemoteControlClient was created.
+     * @param l the metadata update listener
+     */
+    public void setMetadataUpdateListener(OnMetadataUpdateListener l) {
+        synchronized(mCacheLock) {
+            mMetadataUpdateListener = l;
+        }
+    }
+
+
+    /**
+     * Interface definition for a callback to be invoked when the media playback position is
+     * requested to be updated.
+     * @see RemoteControlClient#FLAG_KEY_MEDIA_POSITION_UPDATE
+     */
+    public interface OnPlaybackPositionUpdateListener {
+        /**
+         * Called on the implementer to notify it that the playback head should be set at the given
+         * position. If the position can be changed from its current value, the implementor of
+         * the interface must also update the playback position using
+         * {@link #setPlaybackState(int, long, float)} to reflect the actual new
+         * position being used, regardless of whether it differs from the requested position.
+         * Failure to do so would cause the system to not know the new actual playback position,
+         * and user interface components would fail to show the user where playback resumed after
+         * the position was updated.
+         * @param newPositionMs the new requested position in the current media, expressed in ms.
+         */
+        void onPlaybackPositionUpdate(long newPositionMs);
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when the media playback position is
+     * queried.
+     * @see RemoteControlClient#FLAG_KEY_MEDIA_POSITION_UPDATE
+     */
+    public interface OnGetPlaybackPositionListener {
+        /**
+         * Called on the implementer of the interface to query the current playback position.
+         * @return a negative value if the current playback position (or the last valid playback
+         *     position) is not known, or a zero or positive value expressed in ms indicating the
+         *     current position, or the last valid known position.
+         */
+        long onGetPlaybackPosition();
+    }
+
+    /**
+     * Sets the listener to be called whenever the media playback position is requested
+     * to be updated.
+     * Notifications will be received in the same thread as the one in which RemoteControlClient
+     * was created.
+     * @param l the position update listener to be called
+     */
+    public void setPlaybackPositionUpdateListener(OnPlaybackPositionUpdateListener l) {
+        synchronized(mCacheLock) {
+            mPositionUpdateListener = l;
+        }
+    }
+
+    /**
+     * Sets the listener to be called whenever the media current playback position is needed.
+     * Queries will be received in the same thread as the one in which RemoteControlClient
+     * was created.
+     * @param l the listener to be called to retrieve the playback position
+     */
+    public void setOnGetPlaybackPositionListener(OnGetPlaybackPositionListener l) {
+        synchronized(mCacheLock) {
+            mPositionProvider = l;
+        }
+    }
+
+    /**
+     * @hide
+     * Flag to reflect that the application controlling this RemoteControlClient sends playback
+     * position updates. The playback position being "readable" is considered from the application's
+     * point of view.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public static int MEDIA_POSITION_READABLE = 1 << 0;
+    /**
+     * @hide
+     * Flag to reflect that the application controlling this RemoteControlClient can receive
+     * playback position updates. The playback position being "writable"
+     * is considered from the application's point of view.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public static int MEDIA_POSITION_WRITABLE = 1 << 1;
+
+    /** @hide */
+    public final static int DEFAULT_PLAYBACK_VOLUME_HANDLING = PLAYBACK_VOLUME_VARIABLE;
+    /** @hide */
+    // hard-coded to the same number of steps as AudioService.MAX_STREAM_VOLUME[STREAM_MUSIC]
+    public final static int DEFAULT_PLAYBACK_VOLUME = 15;
+
+    /**
+     * Lock for all cached data
+     */
+    private final Object mCacheLock = new Object();
+    /**
+     * Cache for the playback state.
+     * Access synchronized on mCacheLock
+     */
+    private int mPlaybackState = PLAYSTATE_NONE;
+    /**
+     * Time of last play state change
+     * Access synchronized on mCacheLock
+     */
+    private long mPlaybackStateChangeTimeMs = 0;
+    /**
+     * Last playback position in ms reported by the user
+     */
+    private long mPlaybackPositionMs = PLAYBACK_POSITION_INVALID;
+    /**
+     * Last playback speed reported by the user
+     */
+    private float mPlaybackSpeed = PLAYBACK_SPEED_1X;
+    /**
+     * Cache for the artwork bitmap.
+     * Access synchronized on mCacheLock
+     * Artwork and metadata are not kept in one Bundle because the bitmap sometimes needs to be
+     * accessed to be resized, in which case a copy will be made. This would add overhead in
+     * Bundle operations.
+     */
+    private Bitmap mOriginalArtwork;
+    /**
+     * Cache for the transport control mask.
+     * Access synchronized on mCacheLock
+     */
+    private int mTransportControlFlags = FLAGS_KEY_MEDIA_NONE;
+    /**
+     * Cache for the metadata strings.
+     * Access synchronized on mCacheLock
+     * This is re-initialized in apply() and so cannot be final.
+     */
+    private Bundle mMetadata = new Bundle();
+    /**
+     * Listener registered by user of RemoteControlClient to receive requests for playback position
+     * update requests.
+     */
+    private OnPlaybackPositionUpdateListener mPositionUpdateListener;
+    /**
+     * Provider registered by user of RemoteControlClient to provide the current playback position.
+     */
+    private OnGetPlaybackPositionListener mPositionProvider;
+    /**
+     * Listener registered by user of RemoteControlClient to receive edit changes to metadata
+     * it exposes.
+     */
+    private OnMetadataUpdateListener mMetadataUpdateListener;
+    /**
+     * The current remote control client generation ID across the system, as known by this object
+     */
+    private int mCurrentClientGenId = -1;
+
+    /**
+     * The media button intent description associated with this remote control client
+     * (can / should include target component for intent handling, used when persisting media
+     *    button event receiver across reboots).
+     */
+    private final PendingIntent mRcMediaIntent;
+
+    /**
+     * Reflects whether any "plugged in" IRemoteControlDisplay has mWantsPositonSync set to true.
+     */
+    // TODO consider using a ref count for IRemoteControlDisplay requiring sync instead
+    private boolean mNeedsPositionSync = false;
+
+    /**
+     * Cache for the current playback state using Session APIs.
+     */
+    private PlaybackState mSessionPlaybackState = null;
+
+    /**
+     * Cache for metadata using Session APIs. This is re-initialized in apply().
+     */
+    private MediaMetadata mMediaMetadata;
+
+    /**
+     * @hide
+     * Accessor to media button intent description (includes target component)
+     */
+    public PendingIntent getRcMediaIntent() {
+        return mRcMediaIntent;
+    }
+
+    /**
+     * @hide
+     * Default value for the unique identifier
+     */
+    public final static int RCSE_ID_UNREGISTERED = -1;
+
+    // USE_SESSIONS
+    private MediaSession.Callback mTransportListener = new MediaSession.Callback() {
+
+        @Override
+        public void onSeekTo(long pos) {
+            RemoteControlClient.this.onSeekTo(mCurrentClientGenId, pos);
+        }
+
+        @Override
+        public void onSetRating(Rating rating) {
+            if ((mTransportControlFlags & FLAG_KEY_MEDIA_RATING) != 0) {
+                onUpdateMetadata(mCurrentClientGenId, MetadataEditor.RATING_KEY_BY_USER, rating);
+            }
+        }
+    };
+
+    //===========================================================
+    // Message handlers
+
+    private void onSeekTo(int generationId, long timeMs) {
+        synchronized (mCacheLock) {
+            if ((mCurrentClientGenId == generationId) && (mPositionUpdateListener != null)) {
+                mPositionUpdateListener.onPlaybackPositionUpdate(timeMs);
+            }
+        }
+    }
+
+    private void onUpdateMetadata(int generationId, int key, Object value) {
+        synchronized (mCacheLock) {
+            if ((mCurrentClientGenId == generationId) && (mMetadataUpdateListener != null)) {
+                mMetadataUpdateListener.onMetadataUpdate(key, value);
+            }
+        }
+    }
+
+    //===========================================================
+    // Internal utilities
+
+    /**
+     * Returns whether, for the given playback state, the playback position is expected to
+     * be changing.
+     * @param playstate the playback state to evaluate
+     * @return true during any form of playback, false if it's not playing anything while in this
+     *     playback state
+     */
+    static boolean playbackPositionShouldMove(int playstate) {
+        switch(playstate) {
+            case PLAYSTATE_STOPPED:
+            case PLAYSTATE_PAUSED:
+            case PLAYSTATE_BUFFERING:
+            case PLAYSTATE_ERROR:
+            case PLAYSTATE_SKIPPING_FORWARDS:
+            case PLAYSTATE_SKIPPING_BACKWARDS:
+                return false;
+            case PLAYSTATE_PLAYING:
+            case PLAYSTATE_FAST_FORWARDING:
+            case PLAYSTATE_REWINDING:
+            default:
+                return true;
+        }
+    }
+
+    /**
+     * Period for playback position drift checks, 15s when playing at 1x or slower.
+     */
+    private final static long POSITION_REFRESH_PERIOD_PLAYING_MS = 15000;
+
+    /**
+     * Minimum period for playback position drift checks, never more often when every 2s, when
+     * fast forwarding or rewinding.
+     */
+    private final static long POSITION_REFRESH_PERIOD_MIN_MS = 2000;
+
+    /**
+     * The value above which the difference between client-reported playback position and
+     * estimated position is considered a drift.
+     */
+    private final static long POSITION_DRIFT_MAX_MS = 500;
+
+    /**
+     * Compute the period at which the estimated playback position should be compared against the
+     * actual playback position. Is a funciton of playback speed.
+     * @param speed 1.0f is normal playback speed
+     * @return the period in ms
+     */
+    private static long getCheckPeriodFromSpeed(float speed) {
+        if (Math.abs(speed) <= 1.0f) {
+            return POSITION_REFRESH_PERIOD_PLAYING_MS;
+        } else {
+            return Math.max((long)(POSITION_REFRESH_PERIOD_PLAYING_MS / Math.abs(speed)),
+                    POSITION_REFRESH_PERIOD_MIN_MS);
+        }
+    }
+
+    /**
+     * Get the {@link PlaybackState} state for the given
+     * {@link RemoteControlClient} state.
+     *
+     * @param rccState The state used by {@link RemoteControlClient}.
+     * @return The equivalent state used by {@link PlaybackState}.
+     */
+    private static int getStateFromRccState(int rccState) {
+        switch (rccState) {
+            case PLAYSTATE_BUFFERING:
+                return PlaybackState.STATE_BUFFERING;
+            case PLAYSTATE_ERROR:
+                return PlaybackState.STATE_ERROR;
+            case PLAYSTATE_FAST_FORWARDING:
+                return PlaybackState.STATE_FAST_FORWARDING;
+            case PLAYSTATE_NONE:
+                return PlaybackState.STATE_NONE;
+            case PLAYSTATE_PAUSED:
+                return PlaybackState.STATE_PAUSED;
+            case PLAYSTATE_PLAYING:
+                return PlaybackState.STATE_PLAYING;
+            case PLAYSTATE_REWINDING:
+                return PlaybackState.STATE_REWINDING;
+            case PLAYSTATE_SKIPPING_BACKWARDS:
+                return PlaybackState.STATE_SKIPPING_TO_PREVIOUS;
+            case PLAYSTATE_SKIPPING_FORWARDS:
+                return PlaybackState.STATE_SKIPPING_TO_NEXT;
+            case PLAYSTATE_STOPPED:
+                return PlaybackState.STATE_STOPPED;
+            default:
+                return -1;
+        }
+    }
+
+    /**
+     * Get the {@link RemoteControlClient} state for the given
+     * {@link PlaybackState} state.
+     *
+     * @param state The state used by {@link PlaybackState}.
+     * @return The equivalent state used by {@link RemoteControlClient}.
+     */
+    static int getRccStateFromState(int state) {
+        switch (state) {
+            case PlaybackState.STATE_BUFFERING:
+                return PLAYSTATE_BUFFERING;
+            case PlaybackState.STATE_ERROR:
+                return PLAYSTATE_ERROR;
+            case PlaybackState.STATE_FAST_FORWARDING:
+                return PLAYSTATE_FAST_FORWARDING;
+            case PlaybackState.STATE_NONE:
+                return PLAYSTATE_NONE;
+            case PlaybackState.STATE_PAUSED:
+                return PLAYSTATE_PAUSED;
+            case PlaybackState.STATE_PLAYING:
+                return PLAYSTATE_PLAYING;
+            case PlaybackState.STATE_REWINDING:
+                return PLAYSTATE_REWINDING;
+            case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
+                return PLAYSTATE_SKIPPING_BACKWARDS;
+            case PlaybackState.STATE_SKIPPING_TO_NEXT:
+                return PLAYSTATE_SKIPPING_FORWARDS;
+            case PlaybackState.STATE_STOPPED:
+                return PLAYSTATE_STOPPED;
+            default:
+                return -1;
+        }
+    }
+
+    private static long getActionsFromRccControlFlags(int rccFlags) {
+        long actions = 0;
+        long flag = 1;
+        while (flag <= rccFlags) {
+            if ((flag & rccFlags) != 0) {
+                actions |= getActionForRccFlag((int) flag);
+            }
+            flag = flag << 1;
+        }
+        return actions;
+    }
+
+    static int getRccControlFlagsFromActions(long actions) {
+        int rccFlags = 0;
+        long action = 1;
+        while (action <= actions && action < Integer.MAX_VALUE) {
+            if ((action & actions) != 0) {
+                rccFlags |= getRccFlagForAction(action);
+            }
+            action = action << 1;
+        }
+        return rccFlags;
+    }
+
+    private static long getActionForRccFlag(int flag) {
+        switch (flag) {
+            case FLAG_KEY_MEDIA_PREVIOUS:
+                return PlaybackState.ACTION_SKIP_TO_PREVIOUS;
+            case FLAG_KEY_MEDIA_REWIND:
+                return PlaybackState.ACTION_REWIND;
+            case FLAG_KEY_MEDIA_PLAY:
+                return PlaybackState.ACTION_PLAY;
+            case FLAG_KEY_MEDIA_PLAY_PAUSE:
+                return PlaybackState.ACTION_PLAY_PAUSE;
+            case FLAG_KEY_MEDIA_PAUSE:
+                return PlaybackState.ACTION_PAUSE;
+            case FLAG_KEY_MEDIA_STOP:
+                return PlaybackState.ACTION_STOP;
+            case FLAG_KEY_MEDIA_FAST_FORWARD:
+                return PlaybackState.ACTION_FAST_FORWARD;
+            case FLAG_KEY_MEDIA_NEXT:
+                return PlaybackState.ACTION_SKIP_TO_NEXT;
+            case FLAG_KEY_MEDIA_POSITION_UPDATE:
+                return PlaybackState.ACTION_SEEK_TO;
+            case FLAG_KEY_MEDIA_RATING:
+                return PlaybackState.ACTION_SET_RATING;
+        }
+        return 0;
+    }
+
+    private static int getRccFlagForAction(long action) {
+        // We only care about the lower set of actions that can map to rcc
+        // flags.
+        int testAction = action < Integer.MAX_VALUE ? (int) action : 0;
+        switch (testAction) {
+            case (int) PlaybackState.ACTION_SKIP_TO_PREVIOUS:
+                return FLAG_KEY_MEDIA_PREVIOUS;
+            case (int) PlaybackState.ACTION_REWIND:
+                return FLAG_KEY_MEDIA_REWIND;
+            case (int) PlaybackState.ACTION_PLAY:
+                return FLAG_KEY_MEDIA_PLAY;
+            case (int) PlaybackState.ACTION_PLAY_PAUSE:
+                return FLAG_KEY_MEDIA_PLAY_PAUSE;
+            case (int) PlaybackState.ACTION_PAUSE:
+                return FLAG_KEY_MEDIA_PAUSE;
+            case (int) PlaybackState.ACTION_STOP:
+                return FLAG_KEY_MEDIA_STOP;
+            case (int) PlaybackState.ACTION_FAST_FORWARD:
+                return FLAG_KEY_MEDIA_FAST_FORWARD;
+            case (int) PlaybackState.ACTION_SKIP_TO_NEXT:
+                return FLAG_KEY_MEDIA_NEXT;
+            case (int) PlaybackState.ACTION_SEEK_TO:
+                return FLAG_KEY_MEDIA_POSITION_UPDATE;
+            case (int) PlaybackState.ACTION_SET_RATING:
+                return FLAG_KEY_MEDIA_RATING;
+        }
+        return 0;
+    }
+}
diff --git a/android/media/RemoteController.java b/android/media/RemoteController.java
new file mode 100644
index 0000000..00fc275
--- /dev/null
+++ b/android/media/RemoteController.java
@@ -0,0 +1,698 @@
+/*
+ * Copyright (C) 2013 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.ActivityManager;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.media.session.MediaSessionLegacyHelper;
+import android.media.session.MediaSessionManager;
+import android.media.session.PlaybackState;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.UserHandle;
+import android.util.DisplayMetrics;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import java.util.List;
+
+/**
+ * The RemoteController class is used to control media playback, display and update media metadata
+ * and playback status, published by applications using the {@link RemoteControlClient} class.
+ * <p>
+ * A RemoteController shall be registered through
+ * {@link AudioManager#registerRemoteController(RemoteController)} in order for the system to send
+ * media event updates to the {@link OnClientUpdateListener} listener set in the class constructor.
+ * Implement the methods of the interface to receive the information published by the active
+ * {@link RemoteControlClient} instances.
+ * <br>By default an {@link OnClientUpdateListener} implementation will not receive bitmaps for
+ * album art. Use {@link #setArtworkConfiguration(int, int)} to receive images as well.
+ * <p>
+ * Registration requires the {@link OnClientUpdateListener} listener to be one of the enabled
+ * notification listeners (see {@link android.service.notification.NotificationListenerService}).
+ *
+ * @deprecated Use {@link MediaController} instead.
+ */
+@Deprecated public final class RemoteController
+{
+    private final static int MAX_BITMAP_DIMENSION = 512;
+    private final static String TAG = "RemoteController";
+    private final static boolean DEBUG = false;
+    private final static Object mInfoLock = new Object();
+    private final Context mContext;
+    private final int mMaxBitmapDimension;
+    private MetadataEditor mMetadataEditor;
+
+    private MediaSessionManager mSessionManager;
+    private MediaSessionManager.OnActiveSessionsChangedListener mSessionListener;
+    private MediaController.Callback mSessionCb = new MediaControllerCallback();
+
+    /**
+     * Synchronized on mInfoLock
+     */
+    private boolean mIsRegistered = false;
+    private OnClientUpdateListener mOnClientUpdateListener;
+    private PlaybackInfo mLastPlaybackInfo;
+    private int mArtworkWidth = -1;
+    private int mArtworkHeight = -1;
+    private boolean mEnabled = true;
+    // synchronized on mInfoLock, for USE_SESSION apis.
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private MediaController mCurrentSession;
+
+    /**
+     * Class constructor.
+     * @param context the {@link Context}, must be non-null.
+     * @param updateListener the listener to be called whenever new client information is available,
+     *     must be non-null.
+     * @throws IllegalArgumentException
+     */
+    public RemoteController(Context context, OnClientUpdateListener updateListener)
+            throws IllegalArgumentException {
+        this(context, updateListener, null);
+    }
+
+    /**
+     * Class constructor.
+     * @param context the {@link Context}, must be non-null.
+     * @param updateListener the listener to be called whenever new client information is available,
+     *     must be non-null.
+     * @param looper the {@link Looper} on which to run the event loop,
+     *     or null to use the current thread's looper.
+     * @throws java.lang.IllegalArgumentException
+     */
+    public RemoteController(Context context, OnClientUpdateListener updateListener, Looper looper)
+            throws IllegalArgumentException {
+        if (context == null) {
+            throw new IllegalArgumentException("Invalid null Context");
+        }
+        if (updateListener == null) {
+            throw new IllegalArgumentException("Invalid null OnClientUpdateListener");
+        }
+        if (looper != null) {
+            mEventHandler = new EventHandler(this, looper);
+        } else {
+            Looper l = Looper.myLooper();
+            if (l != null) {
+                mEventHandler = new EventHandler(this, l);
+            } else {
+                throw new IllegalArgumentException("Calling thread not associated with a looper");
+            }
+        }
+        mOnClientUpdateListener = updateListener;
+        mContext = context;
+        mSessionManager = (MediaSessionManager) context
+                .getSystemService(Context.MEDIA_SESSION_SERVICE);
+        mSessionListener = new TopTransportSessionListener();
+
+        if (ActivityManager.isLowRamDeviceStatic()) {
+            mMaxBitmapDimension = MAX_BITMAP_DIMENSION;
+        } else {
+            final DisplayMetrics dm = context.getResources().getDisplayMetrics();
+            mMaxBitmapDimension = Math.max(dm.widthPixels, dm.heightPixels);
+        }
+    }
+
+
+    /**
+     * Interface definition for the callbacks to be invoked whenever media events, metadata
+     * and playback status are available.
+     */
+    public interface OnClientUpdateListener {
+        /**
+         * Called whenever all information, previously received through the other
+         * methods of the listener, is no longer valid and is about to be refreshed.
+         * This is typically called whenever a new {@link RemoteControlClient} has been selected
+         * by the system to have its media information published.
+         * @param clearing true if there is no selected RemoteControlClient and no information
+         *     is available.
+         */
+        public void onClientChange(boolean clearing);
+
+        /**
+         * Called whenever the playback state has changed.
+         * It is called when no information is known about the playback progress in the media and
+         * the playback speed.
+         * @param state one of the playback states authorized
+         *     in {@link RemoteControlClient#setPlaybackState(int)}.
+         */
+        public void onClientPlaybackStateUpdate(int state);
+        /**
+         * Called whenever the playback state has changed, and playback position
+         * and speed are known.
+         * @param state one of the playback states authorized
+         *     in {@link RemoteControlClient#setPlaybackState(int)}.
+         * @param stateChangeTimeMs the system time at which the state change was reported,
+         *     expressed in ms. Based on {@link android.os.SystemClock#elapsedRealtime()}.
+         * @param currentPosMs a positive value for the current media playback position expressed
+         *     in ms, a negative value if the position is temporarily unknown.
+         * @param speed  a value expressed as a ratio of 1x playback: 1.0f is normal playback,
+         *    2.0f is 2x, 0.5f is half-speed, -2.0f is rewind at 2x speed. 0.0f means nothing is
+         *    playing (e.g. when state is {@link RemoteControlClient#PLAYSTATE_ERROR}).
+         */
+        public void onClientPlaybackStateUpdate(int state, long stateChangeTimeMs,
+                long currentPosMs, float speed);
+        /**
+         * Called whenever the transport control flags have changed.
+         * @param transportControlFlags one of the flags authorized
+         *     in {@link RemoteControlClient#setTransportControlFlags(int)}.
+         */
+        public void onClientTransportControlUpdate(int transportControlFlags);
+        /**
+         * Called whenever new metadata is available.
+         * See the {@link MediaMetadataEditor#putLong(int, long)},
+         *  {@link MediaMetadataEditor#putString(int, String)},
+         *  {@link MediaMetadataEditor#putBitmap(int, Bitmap)}, and
+         *  {@link MediaMetadataEditor#putObject(int, Object)} methods for the various keys that
+         *  can be queried.
+         * @param metadataEditor the container of the new metadata.
+         */
+        public void onClientMetadataUpdate(MetadataEditor metadataEditor);
+    };
+
+    /**
+     * Return the estimated playback position of the current media track or a negative value
+     * if not available.
+     *
+     * <p>The value returned is estimated by the current process and may not be perfect.
+     * The time returned by this method is calculated from the last state change time based
+     * on the current play position at that time and the last known playback speed.
+     * An application may call {@link #setSynchronizationMode(int)} to apply
+     * a synchronization policy that will periodically re-sync the estimated position
+     * with the RemoteControlClient.</p>
+     *
+     * @return the current estimated playback position in milliseconds or a negative value
+     *         if not available
+     *
+     * @see OnClientUpdateListener#onClientPlaybackStateUpdate(int, long, long, float)
+     */
+    public long getEstimatedMediaPosition() {
+        synchronized (mInfoLock) {
+            if (mCurrentSession != null) {
+                PlaybackState state = mCurrentSession.getPlaybackState();
+                if (state != null) {
+                    return state.getPosition();
+                }
+            }
+        }
+        return -1;
+    }
+
+
+    /**
+     * Send a simulated key event for a media button to be received by the current client.
+     * To simulate a key press, you must first send a KeyEvent built with
+     * a {@link KeyEvent#ACTION_DOWN} action, then another event with the {@link KeyEvent#ACTION_UP}
+     * action.
+     * <p>The key event will be sent to the registered receiver
+     * (see {@link AudioManager#registerMediaButtonEventReceiver(PendingIntent)}) whose associated
+     * {@link RemoteControlClient}'s metadata and playback state is published (there may be
+     * none under some circumstances).
+     * @param keyEvent a {@link KeyEvent} instance whose key code is one of
+     *     {@link KeyEvent#KEYCODE_MUTE},
+     *     {@link KeyEvent#KEYCODE_HEADSETHOOK},
+     *     {@link KeyEvent#KEYCODE_MEDIA_PLAY},
+     *     {@link KeyEvent#KEYCODE_MEDIA_PAUSE},
+     *     {@link KeyEvent#KEYCODE_MEDIA_PLAY_PAUSE},
+     *     {@link KeyEvent#KEYCODE_MEDIA_STOP},
+     *     {@link KeyEvent#KEYCODE_MEDIA_NEXT},
+     *     {@link KeyEvent#KEYCODE_MEDIA_PREVIOUS},
+     *     {@link KeyEvent#KEYCODE_MEDIA_REWIND},
+     *     {@link KeyEvent#KEYCODE_MEDIA_RECORD},
+     *     {@link KeyEvent#KEYCODE_MEDIA_FAST_FORWARD},
+     *     {@link KeyEvent#KEYCODE_MEDIA_CLOSE},
+     *     {@link KeyEvent#KEYCODE_MEDIA_EJECT},
+     *     or {@link KeyEvent#KEYCODE_MEDIA_AUDIO_TRACK}.
+     * @return true if the event was successfully sent, false otherwise.
+     * @throws IllegalArgumentException
+     */
+    public boolean sendMediaKeyEvent(KeyEvent keyEvent) throws IllegalArgumentException {
+        if (!KeyEvent.isMediaSessionKey(keyEvent.getKeyCode())) {
+            throw new IllegalArgumentException("not a media key event");
+        }
+        synchronized (mInfoLock) {
+            if (mCurrentSession != null) {
+                return mCurrentSession.dispatchMediaButtonEvent(keyEvent);
+            }
+            return false;
+        }
+    }
+
+
+    /**
+     * Sets the new playback position.
+     * This method can only be called on a registered RemoteController.
+     * @param timeMs a 0 or positive value for the new playback position, expressed in ms.
+     * @return true if the command to set the playback position was successfully sent.
+     * @throws IllegalArgumentException
+     */
+    public boolean seekTo(long timeMs) throws IllegalArgumentException {
+        if (!mEnabled) {
+            Log.e(TAG, "Cannot use seekTo() from a disabled RemoteController");
+            return false;
+        }
+        if (timeMs < 0) {
+            throw new IllegalArgumentException("illegal negative time value");
+        }
+        synchronized (mInfoLock) {
+            if (mCurrentSession != null) {
+                mCurrentSession.getTransportControls().seekTo(timeMs);
+            }
+        }
+        return true;
+    }
+
+
+    /**
+     * @hide
+     * @param wantBitmap
+     * @param width
+     * @param height
+     * @return true if successful
+     * @throws IllegalArgumentException
+     */
+    @UnsupportedAppUsage
+    public boolean setArtworkConfiguration(boolean wantBitmap, int width, int height)
+            throws IllegalArgumentException {
+        synchronized (mInfoLock) {
+            if (wantBitmap) {
+                if ((width > 0) && (height > 0)) {
+                    if (width > mMaxBitmapDimension) { width = mMaxBitmapDimension; }
+                    if (height > mMaxBitmapDimension) { height = mMaxBitmapDimension; }
+                    mArtworkWidth = width;
+                    mArtworkHeight = height;
+                } else {
+                    throw new IllegalArgumentException("Invalid dimensions");
+                }
+            } else {
+                mArtworkWidth = -1;
+                mArtworkHeight = -1;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Set the maximum artwork image dimensions to be received in the metadata.
+     * No bitmaps will be received unless this has been specified.
+     * @param width the maximum width in pixels
+     * @param height  the maximum height in pixels
+     * @return true if the artwork dimension was successfully set.
+     * @throws IllegalArgumentException
+     */
+    public boolean setArtworkConfiguration(int width, int height) throws IllegalArgumentException {
+        return setArtworkConfiguration(true, width, height);
+    }
+
+    /**
+     * Prevents this RemoteController from receiving artwork images.
+     * @return true if receiving artwork images was successfully disabled.
+     */
+    public boolean clearArtworkConfiguration() {
+        return setArtworkConfiguration(false, -1, -1);
+    }
+
+
+    /**
+     * Default playback position synchronization mode where the RemoteControlClient is not
+     * asked regularly for its playback position to see if it has drifted from the estimated
+     * position.
+     */
+    public static final int POSITION_SYNCHRONIZATION_NONE = 0;
+
+    /**
+     * The playback position synchronization mode where the RemoteControlClient instances which
+     * expose their playback position to the framework, will be regularly polled to check
+     * whether any drift has been noticed between their estimated position and the one they report.
+     * Note that this mode should only ever be used when needing to display very accurate playback
+     * position, as regularly polling a RemoteControlClient for its position may have an impact
+     * on battery life (if applicable) when this query will trigger network transactions in the
+     * case of remote playback.
+     */
+    public static final int POSITION_SYNCHRONIZATION_CHECK = 1;
+
+    /**
+     * Set the playback position synchronization mode.
+     * Must be called on a registered RemoteController.
+     * @param sync {@link #POSITION_SYNCHRONIZATION_NONE} or {@link #POSITION_SYNCHRONIZATION_CHECK}
+     * @return true if the synchronization mode was successfully set.
+     * @throws IllegalArgumentException
+     */
+    public boolean setSynchronizationMode(int sync) throws IllegalArgumentException {
+        if ((sync != POSITION_SYNCHRONIZATION_NONE) && (sync != POSITION_SYNCHRONIZATION_CHECK)) {
+            throw new IllegalArgumentException("Unknown synchronization mode " + sync);
+        }
+        if (!mIsRegistered) {
+            Log.e(TAG, "Cannot set synchronization mode on an unregistered RemoteController");
+            return false;
+        }
+        // deprecated, no-op
+        return true;
+    }
+
+
+    /**
+     * Creates a {@link MetadataEditor} for updating metadata values of the editable keys of
+     * the current {@link RemoteControlClient}.
+     * This method can only be called on a registered RemoteController.
+     * @return a new MetadataEditor instance.
+     */
+    public MetadataEditor editMetadata() {
+        MetadataEditor editor = new MetadataEditor();
+        editor.mEditorMetadata = new Bundle();
+        editor.mEditorArtwork = null;
+        editor.mMetadataChanged = true;
+        editor.mArtworkChanged = true;
+        editor.mEditableKeys = 0;
+        return editor;
+    }
+
+    /**
+     * A class to read the metadata published by a {@link RemoteControlClient}, or send a
+     * {@link RemoteControlClient} new values for keys that can be edited.
+     */
+    public class MetadataEditor extends MediaMetadataEditor {
+        /**
+         * @hide
+         */
+        protected MetadataEditor() { }
+
+        /**
+         * @hide
+         */
+        protected MetadataEditor(Bundle metadata, long editableKeys) {
+            mEditorMetadata = metadata;
+            mEditableKeys = editableKeys;
+
+            mEditorArtwork = (Bitmap) metadata.getParcelable(
+                    String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK));
+            if (mEditorArtwork != null) {
+                cleanupBitmapFromBundle(MediaMetadataEditor.BITMAP_KEY_ARTWORK);
+            }
+
+            mMetadataChanged = true;
+            mArtworkChanged = true;
+            mApplied = false;
+        }
+
+        private void cleanupBitmapFromBundle(int key) {
+            if (METADATA_KEYS_TYPE.get(key, METADATA_TYPE_INVALID) == METADATA_TYPE_BITMAP) {
+                mEditorMetadata.remove(String.valueOf(key));
+            }
+        }
+
+        /**
+         * Applies all of the metadata changes that have been set since the MediaMetadataEditor
+         * instance was created with {@link RemoteController#editMetadata()}
+         * or since {@link #clear()} was called.
+         */
+        public synchronized void apply() {
+            // "applying" a metadata bundle in RemoteController is only for sending edited
+            // key values back to the RemoteControlClient, so here we only care about the only
+            // editable key we support: RATING_KEY_BY_USER
+            if (!mMetadataChanged) {
+                return;
+            }
+            synchronized (mInfoLock) {
+                if (mCurrentSession != null) {
+                    if (mEditorMetadata.containsKey(
+                            String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER))) {
+                        Rating rating = (Rating) getObject(
+                                MediaMetadataEditor.RATING_KEY_BY_USER, null);
+                        if (rating != null) {
+                            mCurrentSession.getTransportControls().setRating(rating);
+                        }
+                    }
+                }
+            }
+            // NOT setting mApplied to true as this type of MetadataEditor will be applied
+            // multiple times, whenever the user of a RemoteController needs to change the
+            // metadata (e.g. user changes the rating of a song more than once during playback)
+            mApplied = false;
+        }
+
+    }
+
+    /**
+     * This receives updates when the current session changes. This is
+     * registered to receive the updates on the handler thread so it can call
+     * directly into the appropriate methods.
+     */
+    private class MediaControllerCallback extends MediaController.Callback {
+        @Override
+        public void onPlaybackStateChanged(PlaybackState state) {
+            onNewPlaybackState(state);
+        }
+
+        @Override
+        public void onMetadataChanged(MediaMetadata metadata) {
+            onNewMediaMetadata(metadata);
+        }
+    }
+
+    /**
+     * Listens for changes to the active session stack and replaces the
+     * currently tracked session if it has changed.
+     */
+    private class TopTransportSessionListener implements
+            MediaSessionManager.OnActiveSessionsChangedListener {
+
+        @Override
+        public void onActiveSessionsChanged(List<MediaController> controllers) {
+            int size = controllers.size();
+            for (int i = 0; i < size; i++) {
+                MediaController controller = controllers.get(i);
+                long flags = controller.getFlags();
+                // We only care about sessions that handle transport controls,
+                // which will be true for apps using RCC
+                if ((flags & MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS) != 0) {
+                    updateController(controller);
+                    return;
+                }
+            }
+            updateController(null);
+        }
+
+    }
+
+    //==================================================
+    // Event handling
+    private final EventHandler mEventHandler;
+    private final static int MSG_CLIENT_CHANGE      = 0;
+    private final static int MSG_NEW_PLAYBACK_STATE = 1;
+    private final static int MSG_NEW_MEDIA_METADATA = 2;
+
+    private class EventHandler extends Handler {
+
+        public EventHandler(RemoteController rc, Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch(msg.what) {
+                case MSG_CLIENT_CHANGE:
+                    onClientChange(msg.arg2 == 1);
+                    break;
+                case MSG_NEW_PLAYBACK_STATE:
+                    onNewPlaybackState((PlaybackState) msg.obj);
+                    break;
+                case MSG_NEW_MEDIA_METADATA:
+                    onNewMediaMetadata((MediaMetadata) msg.obj);
+                    break;
+                default:
+                    Log.e(TAG, "unknown event " + msg.what);
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    void startListeningToSessions() {
+        final ComponentName listenerComponent = new ComponentName(mContext,
+                mOnClientUpdateListener.getClass());
+        Handler handler = null;
+        if (Looper.myLooper() == null) {
+            handler = new Handler(Looper.getMainLooper());
+        }
+        mSessionManager.addOnActiveSessionsChangedListener(mSessionListener, listenerComponent,
+                handler);
+        mSessionListener.onActiveSessionsChanged(mSessionManager
+                .getActiveSessions(listenerComponent));
+        if (DEBUG) {
+            Log.d(TAG, "Registered session listener with component " + listenerComponent
+                    + " for user " + UserHandle.myUserId());
+        }
+    }
+
+    /**
+     * @hide
+     */
+    void stopListeningToSessions() {
+        mSessionManager.removeOnActiveSessionsChangedListener(mSessionListener);
+        if (DEBUG) {
+            Log.d(TAG, "Unregistered session listener for user "
+                    + UserHandle.myUserId());
+        }
+    }
+
+    /** If the msg is already queued, replace it with this one. */
+    private static final int SENDMSG_REPLACE = 0;
+    /** If the msg is already queued, ignore this one and leave the old. */
+    private static final int SENDMSG_NOOP = 1;
+    /** If the msg is already queued, queue this one and leave the old. */
+    private static final int SENDMSG_QUEUE = 2;
+
+    private static void sendMsg(Handler handler, int msg, int existingMsgPolicy,
+            int arg1, int arg2, Object obj, int delayMs) {
+        if (handler == null) {
+            Log.e(TAG, "null event handler, will not deliver message " + msg);
+            return;
+        }
+        if (existingMsgPolicy == SENDMSG_REPLACE) {
+            handler.removeMessages(msg);
+        } else if (existingMsgPolicy == SENDMSG_NOOP && handler.hasMessages(msg)) {
+            return;
+        }
+        handler.sendMessageDelayed(handler.obtainMessage(msg, arg1, arg2, obj), delayMs);
+    }
+
+    private void onClientChange(boolean clearing) {
+        final OnClientUpdateListener l;
+        synchronized(mInfoLock) {
+            l = mOnClientUpdateListener;
+            mMetadataEditor = null;
+        }
+        if (l != null) {
+            l.onClientChange(clearing);
+        }
+    }
+
+    private void updateController(MediaController controller) {
+        if (DEBUG) {
+            Log.d(TAG, "Updating controller to " + controller + " previous controller is "
+                    + mCurrentSession);
+        }
+        synchronized (mInfoLock) {
+            if (controller == null) {
+                if (mCurrentSession != null) {
+                    mCurrentSession.unregisterCallback(mSessionCb);
+                    mCurrentSession = null;
+                    sendMsg(mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
+                            0 /* arg1 ignored */, 1 /* clearing */, null /* obj */, 0 /* delay */);
+                }
+            } else if (mCurrentSession == null
+                    || !controller.getSessionToken()
+                            .equals(mCurrentSession.getSessionToken())) {
+                if (mCurrentSession != null) {
+                    mCurrentSession.unregisterCallback(mSessionCb);
+                }
+                sendMsg(mEventHandler, MSG_CLIENT_CHANGE, SENDMSG_REPLACE,
+                        0 /* arg1 ignored */, 0 /* clearing */, null /* obj */, 0 /* delay */);
+                mCurrentSession = controller;
+                mCurrentSession.registerCallback(mSessionCb, mEventHandler);
+
+                PlaybackState state = controller.getPlaybackState();
+                sendMsg(mEventHandler, MSG_NEW_PLAYBACK_STATE, SENDMSG_REPLACE,
+                        0 /* arg1 ignored */, 0 /* arg2 ignored */, state /* obj */, 0 /* delay */);
+
+                MediaMetadata metadata = controller.getMetadata();
+                sendMsg(mEventHandler, MSG_NEW_MEDIA_METADATA, SENDMSG_REPLACE,
+                        0 /* arg1 ignored */, 0 /* arg2 ignored*/, metadata /* obj */, 0 /*delay*/);
+            }
+            // else same controller, no need to update
+        }
+    }
+
+    private void onNewPlaybackState(PlaybackState state) {
+        final OnClientUpdateListener l;
+        synchronized (mInfoLock) {
+            l = this.mOnClientUpdateListener;
+        }
+        if (l != null) {
+            int playstate = state == null ? RemoteControlClient.PLAYSTATE_NONE
+                    : RemoteControlClient.getRccStateFromState(state.getState());
+            if (state == null || state.getPosition() == PlaybackState.PLAYBACK_POSITION_UNKNOWN) {
+                l.onClientPlaybackStateUpdate(playstate);
+            } else {
+                l.onClientPlaybackStateUpdate(playstate, state.getLastPositionUpdateTime(),
+                        state.getPosition(), state.getPlaybackSpeed());
+            }
+            if (state != null) {
+                l.onClientTransportControlUpdate(
+                        RemoteControlClient.getRccControlFlagsFromActions(state.getActions()));
+            }
+        }
+    }
+
+    private void onNewMediaMetadata(MediaMetadata metadata) {
+        if (metadata == null) {
+            // RemoteController only handles non-null metadata
+            return;
+        }
+        final OnClientUpdateListener l;
+        final MetadataEditor metadataEditor;
+        // prepare the received Bundle to be used inside a MetadataEditor
+        synchronized(mInfoLock) {
+            l = mOnClientUpdateListener;
+            boolean canRate = mCurrentSession != null
+                    && mCurrentSession.getRatingType() != Rating.RATING_NONE;
+            long editableKeys = canRate ? MediaMetadataEditor.RATING_KEY_BY_USER : 0;
+            Bundle legacyMetadata = MediaSessionLegacyHelper.getOldMetadata(metadata,
+                    mArtworkWidth, mArtworkHeight);
+            mMetadataEditor = new MetadataEditor(legacyMetadata, editableKeys);
+            metadataEditor = mMetadataEditor;
+        }
+        if (l != null) {
+            l.onClientMetadataUpdate(metadataEditor);
+        }
+    }
+
+    //==================================================
+    private static class PlaybackInfo {
+        int mState;
+        long mStateChangeTimeMs;
+        long mCurrentPosMs;
+        float mSpeed;
+
+        PlaybackInfo(int state, long stateChangeTimeMs, long currentPosMs, float speed) {
+            mState = state;
+            mStateChangeTimeMs = stateChangeTimeMs;
+            mCurrentPosMs = currentPosMs;
+            mSpeed = speed;
+        }
+    }
+
+    /**
+     * @hide
+     * Used by AudioManager to access user listener receiving the client update notifications
+     * @return
+     */
+    @UnsupportedAppUsage
+    OnClientUpdateListener getUpdateListener() {
+        return mOnClientUpdateListener;
+    }
+}
diff --git a/android/media/RemoteDisplay.java b/android/media/RemoteDisplay.java
new file mode 100644
index 0000000..2a0e54d
--- /dev/null
+++ b/android/media/RemoteDisplay.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2012 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.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.Handler;
+import android.view.Surface;
+
+import dalvik.system.CloseGuard;
+
+/**
+ * Listens for Wifi remote display connections managed by the media server.
+ *
+ * @hide
+ */
+public final class RemoteDisplay {
+    /* these constants must be kept in sync with IRemoteDisplayClient.h */
+
+    public static final int DISPLAY_FLAG_SECURE = 1 << 0;
+
+    public static final int DISPLAY_ERROR_UNKOWN = 1;
+    public static final int DISPLAY_ERROR_CONNECTION_DROPPED = 2;
+
+    private final CloseGuard mGuard = CloseGuard.get();
+    private final Listener mListener;
+    private final Handler mHandler;
+    private final String mOpPackageName;
+
+    private long mPtr;
+
+    private native long nativeListen(String iface, String opPackageName);
+    private native void nativeDispose(long ptr);
+    private native void nativePause(long ptr);
+    private native void nativeResume(long ptr);
+
+    private RemoteDisplay(Listener listener, Handler handler, String opPackageName) {
+        mListener = listener;
+        mHandler = handler;
+        mOpPackageName = opPackageName;
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            dispose(true);
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Starts listening for displays to be connected on the specified interface.
+     *
+     * @param iface The interface address and port in the form "x.x.x.x:y".
+     * @param listener The listener to invoke when displays are connected or disconnected.
+     * @param handler The handler on which to invoke the listener.
+     */
+    public static RemoteDisplay listen(String iface, Listener listener, Handler handler,
+            String opPackageName) {
+        if (iface == null) {
+            throw new IllegalArgumentException("iface must not be null");
+        }
+        if (listener == null) {
+            throw new IllegalArgumentException("listener must not be null");
+        }
+        if (handler == null) {
+            throw new IllegalArgumentException("handler must not be null");
+        }
+
+        RemoteDisplay display = new RemoteDisplay(listener, handler, opPackageName);
+        display.startListening(iface);
+        return display;
+    }
+
+    /**
+     * Disconnects the remote display and stops listening for new connections.
+     */
+    @UnsupportedAppUsage
+    public void dispose() {
+        dispose(false);
+    }
+
+    public void pause() {
+        nativePause(mPtr);
+    }
+
+    public void resume() {
+        nativeResume(mPtr);
+    }
+
+    private void dispose(boolean finalized) {
+        if (mPtr != 0) {
+            if (mGuard != null) {
+                if (finalized) {
+                    mGuard.warnIfOpen();
+                } else {
+                    mGuard.close();
+                }
+            }
+
+            nativeDispose(mPtr);
+            mPtr = 0;
+        }
+    }
+
+    private void startListening(String iface) {
+        mPtr = nativeListen(iface, mOpPackageName);
+        if (mPtr == 0) {
+            throw new IllegalStateException("Could not start listening for "
+                    + "remote display connection on \"" + iface + "\"");
+        }
+        mGuard.open("dispose");
+    }
+
+    // Called from native.
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private void notifyDisplayConnected(final Surface surface,
+            final int width, final int height, final int flags, final int session) {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mListener.onDisplayConnected(surface, width, height, flags, session);
+            }
+        });
+    }
+
+    // Called from native.
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private void notifyDisplayDisconnected() {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mListener.onDisplayDisconnected();
+            }
+        });
+    }
+
+    // Called from native.
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private void notifyDisplayError(final int error) {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                mListener.onDisplayError(error);
+            }
+        });
+    }
+
+    /**
+     * Listener invoked when the remote display connection changes state.
+     */
+    public interface Listener {
+        void onDisplayConnected(Surface surface,
+                int width, int height, int flags, int session);
+        void onDisplayDisconnected();
+        void onDisplayError(int error);
+    }
+}
diff --git a/android/media/RemoteDisplayState.java b/android/media/RemoteDisplayState.java
new file mode 100644
index 0000000..370f5b1
--- /dev/null
+++ b/android/media/RemoteDisplayState.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2013 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.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+
+/**
+ * Information available from IRemoteDisplayProvider about available remote displays.
+ *
+ * Clients must not modify the contents of this object.
+ * @hide
+ */
+public final class RemoteDisplayState implements Parcelable {
+    // Note: These constants are used by the remote display provider API.
+    // Do not change them!
+    public static final String SERVICE_INTERFACE =
+            "com.android.media.remotedisplay.RemoteDisplayProvider";
+    public static final int DISCOVERY_MODE_NONE = 0;
+    public static final int DISCOVERY_MODE_PASSIVE = 1;
+    public static final int DISCOVERY_MODE_ACTIVE = 2;
+
+    /**
+     * A list of all remote displays.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public final ArrayList<RemoteDisplayInfo> displays;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public RemoteDisplayState() {
+        displays = new ArrayList<RemoteDisplayInfo>();
+    }
+
+    RemoteDisplayState(Parcel src) {
+        displays = src.createTypedArrayList(RemoteDisplayInfo.CREATOR);
+    }
+
+    public boolean isValid() {
+        if (displays == null) {
+            return false;
+        }
+        final int count = displays.size();
+        for (int i = 0; i < count; i++) {
+            if (!displays.get(i).isValid()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeTypedList(displays);
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<RemoteDisplayState> CREATOR =
+            new Parcelable.Creator<RemoteDisplayState>() {
+        @Override
+        public RemoteDisplayState createFromParcel(Parcel in) {
+            return new RemoteDisplayState(in);
+        }
+
+        @Override
+        public RemoteDisplayState[] newArray(int size) {
+            return new RemoteDisplayState[size];
+        }
+    };
+
+    public static final class RemoteDisplayInfo implements Parcelable {
+        // Note: These constants are used by the remote display provider API.
+        // Do not change them!
+        public static final int STATUS_NOT_AVAILABLE = 0;
+        public static final int STATUS_IN_USE = 1;
+        public static final int STATUS_AVAILABLE = 2;
+        public static final int STATUS_CONNECTING = 3;
+        public static final int STATUS_CONNECTED = 4;
+
+        public static final int PLAYBACK_VOLUME_VARIABLE =
+                MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE;
+        public static final int PLAYBACK_VOLUME_FIXED =
+                MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED;
+
+        public String id;
+        public String name;
+        public String description;
+        public int status;
+        public int volume;
+        public int volumeMax;
+        public int volumeHandling;
+        public int presentationDisplayId;
+
+        public RemoteDisplayInfo(String id) {
+            this.id = id;
+            status = STATUS_NOT_AVAILABLE;
+            volumeHandling = MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED;
+            presentationDisplayId = -1;
+        }
+
+        public RemoteDisplayInfo(RemoteDisplayInfo other) {
+            id = other.id;
+            name = other.name;
+            description = other.description;
+            status = other.status;
+            volume = other.volume;
+            volumeMax = other.volumeMax;
+            volumeHandling = other.volumeHandling;
+            presentationDisplayId = other.presentationDisplayId;
+        }
+
+        RemoteDisplayInfo(Parcel in) {
+            id = in.readString();
+            name = in.readString();
+            description = in.readString();
+            status = in.readInt();
+            volume = in.readInt();
+            volumeMax = in.readInt();
+            volumeHandling = in.readInt();
+            presentationDisplayId = in.readInt();
+        }
+
+        public boolean isValid() {
+            return !TextUtils.isEmpty(id) && !TextUtils.isEmpty(name);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(id);
+            dest.writeString(name);
+            dest.writeString(description);
+            dest.writeInt(status);
+            dest.writeInt(volume);
+            dest.writeInt(volumeMax);
+            dest.writeInt(volumeHandling);
+            dest.writeInt(presentationDisplayId);
+        }
+
+        @Override
+        public String toString() {
+            return "RemoteDisplayInfo{ id=" + id
+                    + ", name=" + name
+                    + ", description=" + description
+                    + ", status=" + status
+                    + ", volume=" + volume
+                    + ", volumeMax=" + volumeMax
+                    + ", volumeHandling=" + volumeHandling
+                    + ", presentationDisplayId=" + presentationDisplayId
+                    + " }";
+        }
+
+        @SuppressWarnings("hiding")
+        public static final @android.annotation.NonNull Parcelable.Creator<RemoteDisplayInfo> CREATOR =
+                new Parcelable.Creator<RemoteDisplayInfo>() {
+            @Override
+            public RemoteDisplayInfo createFromParcel(Parcel in) {
+                return new RemoteDisplayInfo(in);
+            }
+
+            @Override
+            public RemoteDisplayInfo[] newArray(int size) {
+                return new RemoteDisplayInfo[size];
+            }
+        };
+    }
+}
diff --git a/android/media/ResampleInputStream.java b/android/media/ResampleInputStream.java
new file mode 100644
index 0000000..80919f7
--- /dev/null
+++ b/android/media/ResampleInputStream.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2008 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 java.io.InputStream;
+import java.io.IOException;
+
+
+/**
+ * ResampleInputStream
+ * @hide
+ */
+public final class ResampleInputStream extends InputStream
+{    
+    static {
+        System.loadLibrary("media_jni");
+    }
+    
+    private final static String TAG = "ResampleInputStream";
+    
+    // pcm input stream
+    private InputStream mInputStream;
+
+    // sample rates, assumed to be normalized
+    private final int mRateIn;
+    private final int mRateOut;
+    
+    // input pcm data
+    private byte[] mBuf;
+    private int mBufCount;
+    
+    // length of 2:1 fir
+    private static final int mFirLength = 29;
+    
+    // helper for bytewise read()
+    private final byte[] mOneByte = new byte[1];
+    
+    /**
+     * Create a new ResampleInputStream, which converts the sample rate
+     * @param inputStream InputStream containing 16 bit PCM.
+     * @param rateIn the input sample rate.
+     * @param rateOut the output sample rate.
+     * This only handles rateIn == rateOut / 2 for the moment.
+     */
+    public ResampleInputStream(InputStream inputStream, int rateIn, int rateOut) {
+        // only support 2:1 at the moment
+        if (rateIn != 2 * rateOut) throw new IllegalArgumentException("only support 2:1 at the moment");
+        rateIn = 2;
+        rateOut = 1;
+
+        mInputStream = inputStream;
+        mRateIn = rateIn;
+        mRateOut = rateOut;
+    }
+
+    @Override
+    public int read() throws IOException {
+        int rtn = read(mOneByte, 0, 1);
+        return rtn == 1 ? (0xff & mOneByte[0]) : -1;
+    }
+    
+    @Override
+    public int read(byte[] b) throws IOException {
+        return read(b, 0, b.length);
+    }
+
+    @Override
+    public int read(byte[] b, int offset, int length) throws IOException {
+        if (mInputStream == null) throw new IllegalStateException("not open");
+
+        // ensure that mBuf is big enough to cover requested 'length'
+        int nIn = ((length / 2) * mRateIn / mRateOut + mFirLength) * 2;
+        if (mBuf == null) {
+            mBuf = new byte[nIn];
+        } else if (nIn > mBuf.length) {
+            byte[] bf = new byte[nIn];
+            System.arraycopy(mBuf, 0, bf, 0, mBufCount);
+            mBuf = bf;
+        }
+        
+        // read until we have enough data for at least one output sample
+        while (true) {
+            int len = ((mBufCount / 2 - mFirLength) * mRateOut / mRateIn) * 2;
+            if (len > 0) {
+                length = len < length ? len : (length / 2) * 2;
+                break;
+            }
+            // TODO: should mBuf.length below be nIn instead?
+            int n = mInputStream.read(mBuf, mBufCount, mBuf.length - mBufCount);
+            if (n == -1) return -1;
+            mBufCount += n;
+        }
+
+        // resample input data
+        fir21(mBuf, 0, b, offset, length / 2);
+        
+        // move any unused bytes to front of mBuf
+        int nFwd = length * mRateIn / mRateOut;
+        mBufCount -= nFwd;
+        if (mBufCount > 0) System.arraycopy(mBuf, nFwd, mBuf, 0, mBufCount);
+        
+        return length;
+    }
+
+/*
+    @Override
+    public int available() throws IOException {
+        int nsamples = (mIn - mOut + mInputStream.available()) / 2;
+        return ((nsamples - mFirLength) * mRateOut / mRateIn) * 2;
+    }
+*/
+
+    @Override
+    public void close() throws IOException {
+        try {
+            if (mInputStream != null) mInputStream.close();
+        } finally {
+            mInputStream = null;
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        if (mInputStream != null) {
+            close();
+            throw new IllegalStateException("someone forgot to close ResampleInputStream");
+        }
+    }
+
+    //
+    // fir filter code JNI interface
+    //
+    private static native void fir21(byte[] in, int inOffset,
+            byte[] out, int outOffset, int npoints);
+
+}
diff --git a/android/media/ResourceBusyException.java b/android/media/ResourceBusyException.java
new file mode 100644
index 0000000..a5abe21
--- /dev/null
+++ b/android/media/ResourceBusyException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 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;
+
+/**
+ * Exception thrown when an operation on a MediaDrm object is attempted
+ * and hardware resources are not available, due to being in use.
+ */
+public final class ResourceBusyException extends MediaDrmException {
+    public ResourceBusyException(String detailMessage) {
+        super(detailMessage);
+    }
+}
diff --git a/android/media/Ringtone.java b/android/media/Ringtone.java
new file mode 100644
index 0000000..3cf0341
--- /dev/null
+++ b/android/media/Ringtone.java
@@ -0,0 +1,572 @@
+/*
+ * Copyright (C) 2006 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.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.content.res.Resources.NotFoundException;
+import android.database.Cursor;
+import android.media.audiofx.HapticGenerator;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Build;
+import android.os.RemoteException;
+import android.provider.MediaStore;
+import android.provider.MediaStore.MediaColumns;
+import android.provider.Settings;
+import android.util.Log;
+
+import java.io.IOException;
+import java.util.ArrayList;
+
+/**
+ * Ringtone provides a quick method for playing a ringtone, notification, or
+ * other similar types of sounds.
+ * <p>
+ * For ways of retrieving {@link Ringtone} objects or to show a ringtone
+ * picker, see {@link RingtoneManager}.
+ *
+ * @see RingtoneManager
+ */
+public class Ringtone {
+    private static final String TAG = "Ringtone";
+    private static final boolean LOGD = true;
+
+    private static final String[] MEDIA_COLUMNS = new String[] {
+        MediaStore.Audio.Media._ID,
+        MediaStore.Audio.Media.TITLE
+    };
+    /** Selection that limits query results to just audio files */
+    private static final String MEDIA_SELECTION = MediaColumns.MIME_TYPE + " LIKE 'audio/%' OR "
+            + MediaColumns.MIME_TYPE + " IN ('application/ogg', 'application/x-flac')";
+
+    // keep references on active Ringtones until stopped or completion listener called.
+    private static final ArrayList<Ringtone> sActiveRingtones = new ArrayList<Ringtone>();
+
+    private final Context mContext;
+    private final AudioManager mAudioManager;
+    private VolumeShaper.Configuration mVolumeShaperConfig;
+    private VolumeShaper mVolumeShaper;
+
+    /**
+     * Flag indicating if we're allowed to fall back to remote playback using
+     * {@link #mRemotePlayer}. Typically this is false when we're the remote
+     * player and there is nobody else to delegate to.
+     */
+    private final boolean mAllowRemote;
+    private final IRingtonePlayer mRemotePlayer;
+    private final Binder mRemoteToken;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private MediaPlayer mLocalPlayer;
+    private final MyOnCompletionListener mCompletionListener = new MyOnCompletionListener();
+    private HapticGenerator mHapticGenerator;
+
+    @UnsupportedAppUsage
+    private Uri mUri;
+    private String mTitle;
+
+    private AudioAttributes mAudioAttributes = new AudioAttributes.Builder()
+            .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
+            .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
+            .build();
+    // playback properties, use synchronized with mPlaybackSettingsLock
+    private boolean mIsLooping = false;
+    private float mVolume = 1.0f;
+    private boolean mHapticGeneratorEnabled = false;
+    private final Object mPlaybackSettingsLock = new Object();
+
+    /** {@hide} */
+    @UnsupportedAppUsage
+    public Ringtone(Context context, boolean allowRemote) {
+        mContext = context;
+        mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+        mAllowRemote = allowRemote;
+        mRemotePlayer = allowRemote ? mAudioManager.getRingtonePlayer() : null;
+        mRemoteToken = allowRemote ? new Binder() : null;
+    }
+
+    /**
+     * Sets the stream type where this ringtone will be played.
+     *
+     * @param streamType The stream, see {@link AudioManager}.
+     * @deprecated use {@link #setAudioAttributes(AudioAttributes)}
+     */
+    @Deprecated
+    public void setStreamType(int streamType) {
+        PlayerBase.deprecateStreamTypeForPlayback(streamType, "Ringtone", "setStreamType()");
+        setAudioAttributes(new AudioAttributes.Builder()
+                .setInternalLegacyStreamType(streamType)
+                .build());
+    }
+
+    /**
+     * Gets the stream type where this ringtone will be played.
+     *
+     * @return The stream type, see {@link AudioManager}.
+     * @deprecated use of stream types is deprecated, see
+     *     {@link #setAudioAttributes(AudioAttributes)}
+     */
+    @Deprecated
+    public int getStreamType() {
+        return AudioAttributes.toLegacyStreamType(mAudioAttributes);
+    }
+
+    /**
+     * Sets the {@link AudioAttributes} for this ringtone.
+     * @param attributes the non-null attributes characterizing this ringtone.
+     */
+    public void setAudioAttributes(AudioAttributes attributes)
+            throws IllegalArgumentException {
+        if (attributes == null) {
+            throw new IllegalArgumentException("Invalid null AudioAttributes for Ringtone");
+        }
+        mAudioAttributes = attributes;
+        // The audio attributes have to be set before the media player is prepared.
+        // Re-initialize it.
+        setUri(mUri, mVolumeShaperConfig);
+    }
+
+    /**
+     * Returns the {@link AudioAttributes} used by this object.
+     * @return the {@link AudioAttributes} that were set with
+     *     {@link #setAudioAttributes(AudioAttributes)} or the default attributes if none were set.
+     */
+    public AudioAttributes getAudioAttributes() {
+        return mAudioAttributes;
+    }
+
+    /**
+     * Sets the player to be looping or non-looping.
+     * @param looping whether to loop or not.
+     */
+    public void setLooping(boolean looping) {
+        synchronized (mPlaybackSettingsLock) {
+            mIsLooping = looping;
+            applyPlaybackProperties_sync();
+        }
+    }
+
+    /**
+     * Returns whether the looping mode was enabled on this player.
+     * @return true if this player loops when playing.
+     */
+    public boolean isLooping() {
+        synchronized (mPlaybackSettingsLock) {
+            return mIsLooping;
+        }
+    }
+
+    /**
+     * Sets the volume on this player.
+     * @param volume a raw scalar in range 0.0 to 1.0, where 0.0 mutes this player, and 1.0
+     *   corresponds to no attenuation being applied.
+     */
+    public void setVolume(float volume) {
+        synchronized (mPlaybackSettingsLock) {
+            if (volume < 0.0f) { volume = 0.0f; }
+            if (volume > 1.0f) { volume = 1.0f; }
+            mVolume = volume;
+            applyPlaybackProperties_sync();
+        }
+    }
+
+    /**
+     * Returns the volume scalar set on this player.
+     * @return a value between 0.0f and 1.0f.
+     */
+    public float getVolume() {
+        synchronized (mPlaybackSettingsLock) {
+            return mVolume;
+        }
+    }
+
+    /**
+     * Enable or disable the {@link android.media.audiofx.HapticGenerator} effect. The effect can
+     * only be enabled on devices that support the effect.
+     *
+     * @return true if the HapticGenerator effect is successfully enabled. Otherwise, return false.
+     * @see android.media.audiofx.HapticGenerator#isAvailable()
+     */
+    public boolean setHapticGeneratorEnabled(boolean enabled) {
+        if (!HapticGenerator.isAvailable()) {
+            return false;
+        }
+        synchronized (mPlaybackSettingsLock) {
+            mHapticGeneratorEnabled = enabled;
+            applyPlaybackProperties_sync();
+        }
+        return true;
+    }
+
+    /**
+     * Return whether the {@link android.media.audiofx.HapticGenerator} effect is enabled or not.
+     * @return true if the HapticGenerator is enabled.
+     */
+    public boolean isHapticGeneratorEnabled() {
+        synchronized (mPlaybackSettingsLock) {
+            return mHapticGeneratorEnabled;
+        }
+    }
+
+    /**
+     * Must be called synchronized on mPlaybackSettingsLock
+     */
+    private void applyPlaybackProperties_sync() {
+        if (mLocalPlayer != null) {
+            mLocalPlayer.setVolume(mVolume);
+            mLocalPlayer.setLooping(mIsLooping);
+            if (mHapticGenerator == null && mHapticGeneratorEnabled) {
+                mHapticGenerator = HapticGenerator.create(mLocalPlayer.getAudioSessionId());
+            }
+            if (mHapticGenerator != null) {
+                mHapticGenerator.setEnabled(mHapticGeneratorEnabled);
+            }
+        } else if (mAllowRemote && (mRemotePlayer != null)) {
+            try {
+                mRemotePlayer.setPlaybackProperties(
+                        mRemoteToken, mVolume, mIsLooping, mHapticGeneratorEnabled);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Problem setting playback properties: ", e);
+            }
+        } else {
+            Log.w(TAG,
+                    "Neither local nor remote player available when applying playback properties");
+        }
+    }
+
+    /**
+     * Returns a human-presentable title for ringtone. Looks in media
+     * content provider. If not in either, uses the filename
+     *
+     * @param context A context used for querying.
+     */
+    public String getTitle(Context context) {
+        if (mTitle != null) return mTitle;
+        return mTitle = getTitle(context, mUri, true /*followSettingsUri*/, mAllowRemote);
+    }
+
+    /**
+     * @hide
+     */
+    public static String getTitle(
+            Context context, Uri uri, boolean followSettingsUri, boolean allowRemote) {
+        ContentResolver res = context.getContentResolver();
+
+        String title = null;
+
+        if (uri != null) {
+            String authority = ContentProvider.getAuthorityWithoutUserId(uri.getAuthority());
+
+            if (Settings.AUTHORITY.equals(authority)) {
+                if (followSettingsUri) {
+                    Uri actualUri = RingtoneManager.getActualDefaultRingtoneUri(context,
+                            RingtoneManager.getDefaultType(uri));
+                    String actualTitle = getTitle(
+                            context, actualUri, false /*followSettingsUri*/, allowRemote);
+                    title = context
+                            .getString(com.android.internal.R.string.ringtone_default_with_actual,
+                                    actualTitle);
+                }
+            } else {
+                Cursor cursor = null;
+                try {
+                    if (MediaStore.AUTHORITY.equals(authority)) {
+                        final String mediaSelection = allowRemote ? null : MEDIA_SELECTION;
+                        cursor = res.query(uri, MEDIA_COLUMNS, mediaSelection, null, null);
+                        if (cursor != null && cursor.getCount() == 1) {
+                            cursor.moveToFirst();
+                            return cursor.getString(1);
+                        }
+                        // missing cursor is handled below
+                    }
+                } catch (SecurityException e) {
+                    IRingtonePlayer mRemotePlayer = null;
+                    if (allowRemote) {
+                        AudioManager audioManager =
+                                (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
+                        mRemotePlayer = audioManager.getRingtonePlayer();
+                    }
+                    if (mRemotePlayer != null) {
+                        try {
+                            title = mRemotePlayer.getTitle(uri);
+                        } catch (RemoteException re) {
+                        }
+                    }
+                } finally {
+                    if (cursor != null) {
+                        cursor.close();
+                    }
+                    cursor = null;
+                }
+                if (title == null) {
+                    title = uri.getLastPathSegment();
+                }
+            }
+        } else {
+            title = context.getString(com.android.internal.R.string.ringtone_silent);
+        }
+
+        if (title == null) {
+            title = context.getString(com.android.internal.R.string.ringtone_unknown);
+            if (title == null) {
+                title = "";
+            }
+        }
+
+        return title;
+    }
+
+    /**
+     * Set {@link Uri} to be used for ringtone playback. Attempts to open
+     * locally, otherwise will delegate playback to remote
+     * {@link IRingtonePlayer}.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public void setUri(Uri uri) {
+        setUri(uri, null);
+    }
+
+    /**
+     * Set {@link Uri} to be used for ringtone playback. Attempts to open
+     * locally, otherwise will delegate playback to remote
+     * {@link IRingtonePlayer}. Add {@link VolumeShaper} if required.
+     *
+     * @hide
+     */
+    public void setUri(Uri uri, @Nullable VolumeShaper.Configuration volumeShaperConfig) {
+        mVolumeShaperConfig = volumeShaperConfig;
+        destroyLocalPlayer();
+
+        mUri = uri;
+        if (mUri == null) {
+            return;
+        }
+
+        // TODO: detect READ_EXTERNAL and specific content provider case, instead of relying on throwing
+
+        // try opening uri locally before delegating to remote player
+        mLocalPlayer = new MediaPlayer();
+        try {
+            mLocalPlayer.setDataSource(mContext, mUri);
+            mLocalPlayer.setAudioAttributes(mAudioAttributes);
+            synchronized (mPlaybackSettingsLock) {
+                applyPlaybackProperties_sync();
+            }
+            if (mVolumeShaperConfig != null) {
+                mVolumeShaper = mLocalPlayer.createVolumeShaper(mVolumeShaperConfig);
+            }
+            mLocalPlayer.prepare();
+
+        } catch (SecurityException | IOException e) {
+            destroyLocalPlayer();
+            if (!mAllowRemote) {
+                Log.w(TAG, "Remote playback not allowed: " + e);
+            }
+        }
+
+        if (LOGD) {
+            if (mLocalPlayer != null) {
+                Log.d(TAG, "Successfully created local player");
+            } else {
+                Log.d(TAG, "Problem opening; delegating to remote player");
+            }
+        }
+    }
+
+    /** {@hide} */
+    @UnsupportedAppUsage
+    public Uri getUri() {
+        return mUri;
+    }
+
+    /**
+     * Plays the ringtone.
+     */
+    public void play() {
+        if (mLocalPlayer != null) {
+            // Play ringtones if stream volume is over 0 or if it is a haptic-only ringtone
+            // (typically because ringer mode is vibrate).
+            boolean isHapticOnly = AudioManager.hasHapticChannels(mContext, mUri)
+                    && !mAudioAttributes.areHapticChannelsMuted() && mVolume == 0;
+            if (isHapticOnly || mAudioManager.getStreamVolume(
+                    AudioAttributes.toLegacyStreamType(mAudioAttributes)) != 0) {
+                startLocalPlayer();
+            }
+        } else if (mAllowRemote && (mRemotePlayer != null) && (mUri != null)) {
+            final Uri canonicalUri = mUri.getCanonicalUri();
+            final boolean looping;
+            final float volume;
+            synchronized (mPlaybackSettingsLock) {
+                looping = mIsLooping;
+                volume = mVolume;
+            }
+            try {
+                mRemotePlayer.playWithVolumeShaping(mRemoteToken, canonicalUri, mAudioAttributes,
+                        volume, looping, mVolumeShaperConfig);
+            } catch (RemoteException e) {
+                if (!playFallbackRingtone()) {
+                    Log.w(TAG, "Problem playing ringtone: " + e);
+                }
+            }
+        } else {
+            if (!playFallbackRingtone()) {
+                Log.w(TAG, "Neither local nor remote playback available");
+            }
+        }
+    }
+
+    /**
+     * Stops a playing ringtone.
+     */
+    public void stop() {
+        if (mLocalPlayer != null) {
+            destroyLocalPlayer();
+        } else if (mAllowRemote && (mRemotePlayer != null)) {
+            try {
+                mRemotePlayer.stop(mRemoteToken);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Problem stopping ringtone: " + e);
+            }
+        }
+    }
+
+    private void destroyLocalPlayer() {
+        if (mLocalPlayer != null) {
+            if (mHapticGenerator != null) {
+                mHapticGenerator.release();
+                mHapticGenerator = null;
+            }
+            mLocalPlayer.setOnCompletionListener(null);
+            mLocalPlayer.reset();
+            mLocalPlayer.release();
+            mLocalPlayer = null;
+            mVolumeShaper = null;
+            synchronized (sActiveRingtones) {
+                sActiveRingtones.remove(this);
+            }
+        }
+    }
+
+    private void startLocalPlayer() {
+        if (mLocalPlayer == null) {
+            return;
+        }
+        synchronized (sActiveRingtones) {
+            sActiveRingtones.add(this);
+        }
+        mLocalPlayer.setOnCompletionListener(mCompletionListener);
+        mLocalPlayer.start();
+        if (mVolumeShaper != null) {
+            mVolumeShaper.apply(VolumeShaper.Operation.PLAY);
+        }
+    }
+
+    /**
+     * Whether this ringtone is currently playing.
+     *
+     * @return True if playing, false otherwise.
+     */
+    public boolean isPlaying() {
+        if (mLocalPlayer != null) {
+            return mLocalPlayer.isPlaying();
+        } else if (mAllowRemote && (mRemotePlayer != null)) {
+            try {
+                return mRemotePlayer.isPlaying(mRemoteToken);
+            } catch (RemoteException e) {
+                Log.w(TAG, "Problem checking ringtone: " + e);
+                return false;
+            }
+        } else {
+            Log.w(TAG, "Neither local nor remote playback available");
+            return false;
+        }
+    }
+
+    private boolean playFallbackRingtone() {
+        if (mAudioManager.getStreamVolume(AudioAttributes.toLegacyStreamType(mAudioAttributes))
+                != 0) {
+            int ringtoneType = RingtoneManager.getDefaultType(mUri);
+            if (ringtoneType == -1 ||
+                    RingtoneManager.getActualDefaultRingtoneUri(mContext, ringtoneType) != null) {
+                // Default ringtone, try fallback ringtone.
+                try {
+                    AssetFileDescriptor afd = mContext.getResources().openRawResourceFd(
+                            com.android.internal.R.raw.fallbackring);
+                    if (afd != null) {
+                        mLocalPlayer = new MediaPlayer();
+                        if (afd.getDeclaredLength() < 0) {
+                            mLocalPlayer.setDataSource(afd.getFileDescriptor());
+                        } else {
+                            mLocalPlayer.setDataSource(afd.getFileDescriptor(),
+                                    afd.getStartOffset(),
+                                    afd.getDeclaredLength());
+                        }
+                        mLocalPlayer.setAudioAttributes(mAudioAttributes);
+                        synchronized (mPlaybackSettingsLock) {
+                            applyPlaybackProperties_sync();
+                        }
+                        if (mVolumeShaperConfig != null) {
+                            mVolumeShaper = mLocalPlayer.createVolumeShaper(mVolumeShaperConfig);
+                        }
+                        mLocalPlayer.prepare();
+                        startLocalPlayer();
+                        afd.close();
+                        return true;
+                    } else {
+                        Log.e(TAG, "Could not load fallback ringtone");
+                    }
+                } catch (IOException ioe) {
+                    destroyLocalPlayer();
+                    Log.e(TAG, "Failed to open fallback ringtone");
+                } catch (NotFoundException nfe) {
+                    Log.e(TAG, "Fallback ringtone does not exist");
+                }
+            } else {
+                Log.w(TAG, "not playing fallback for " + mUri);
+            }
+        }
+        return false;
+    }
+
+    void setTitle(String title) {
+        mTitle = title;
+    }
+
+    @Override
+    protected void finalize() {
+        if (mLocalPlayer != null) {
+            mLocalPlayer.release();
+        }
+    }
+
+    class MyOnCompletionListener implements MediaPlayer.OnCompletionListener {
+        @Override
+        public void onCompletion(MediaPlayer mp) {
+            synchronized (sActiveRingtones) {
+                sActiveRingtones.remove(Ringtone.this);
+            }
+            mp.setOnCompletionListener(null); // Help the Java GC: break the refcount cycle.
+        }
+    }
+}
diff --git a/android/media/RingtoneManager.java b/android/media/RingtoneManager.java
new file mode 100644
index 0000000..4ec79b7
--- /dev/null
+++ b/android/media/RingtoneManager.java
@@ -0,0 +1,1186 @@
+/*
+ * Copyright (C) 2007 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.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
+import android.annotation.WorkerThread;
+import android.app.Activity;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.UserInfo;
+import android.content.res.AssetFileDescriptor;
+import android.database.Cursor;
+import android.database.StaleDataException;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.provider.MediaStore;
+import android.provider.MediaStore.MediaColumns;
+import android.provider.Settings;
+import android.provider.Settings.System;
+import android.util.Log;
+
+import com.android.internal.database.SortCursor;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * RingtoneManager provides access to ringtones, notification, and other types
+ * of sounds. It manages querying the different media providers and combines the
+ * results into a single cursor. It also provides a {@link Ringtone} for each
+ * ringtone. We generically call these sounds ringtones, however the
+ * {@link #TYPE_RINGTONE} refers to the type of sounds that are suitable for the
+ * phone ringer.
+ * <p>
+ * To show a ringtone picker to the user, use the
+ * {@link #ACTION_RINGTONE_PICKER} intent to launch the picker as a subactivity.
+ * 
+ * @see Ringtone
+ */
+public class RingtoneManager {
+
+    private static final String TAG = "RingtoneManager";
+
+    // Make sure these are in sync with attrs.xml:
+    // <attr name="ringtoneType">
+    
+    /**
+     * Type that refers to sounds that are used for the phone ringer.
+     */
+    public static final int TYPE_RINGTONE = 1;
+    
+    /**
+     * Type that refers to sounds that are used for notifications.
+     */
+    public static final int TYPE_NOTIFICATION = 2;
+    
+    /**
+     * Type that refers to sounds that are used for the alarm.
+     */
+    public static final int TYPE_ALARM = 4;
+    
+    /**
+     * All types of sounds.
+     */
+    public static final int TYPE_ALL = TYPE_RINGTONE | TYPE_NOTIFICATION | TYPE_ALARM;
+
+    // </attr>
+    
+    /**
+     * Activity Action: Shows a ringtone picker.
+     * <p>
+     * Input: {@link #EXTRA_RINGTONE_EXISTING_URI},
+     * {@link #EXTRA_RINGTONE_SHOW_DEFAULT},
+     * {@link #EXTRA_RINGTONE_SHOW_SILENT}, {@link #EXTRA_RINGTONE_TYPE},
+     * {@link #EXTRA_RINGTONE_DEFAULT_URI}, {@link #EXTRA_RINGTONE_TITLE},
+     * <p>
+     * Output: {@link #EXTRA_RINGTONE_PICKED_URI}.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_RINGTONE_PICKER = "android.intent.action.RINGTONE_PICKER";
+
+    /**
+     * Given to the ringtone picker as a boolean. Whether to show an item for
+     * "Default".
+     * 
+     * @see #ACTION_RINGTONE_PICKER
+     */
+    public static final String EXTRA_RINGTONE_SHOW_DEFAULT =
+            "android.intent.extra.ringtone.SHOW_DEFAULT";
+    
+    /**
+     * Given to the ringtone picker as a boolean. Whether to show an item for
+     * "Silent". If the "Silent" item is picked,
+     * {@link #EXTRA_RINGTONE_PICKED_URI} will be null.
+     * 
+     * @see #ACTION_RINGTONE_PICKER
+     */
+    public static final String EXTRA_RINGTONE_SHOW_SILENT =
+            "android.intent.extra.ringtone.SHOW_SILENT";
+
+    /**
+     * Given to the ringtone picker as a boolean. Whether to include DRM ringtones.
+     * @deprecated DRM ringtones are no longer supported
+     */
+    @Deprecated
+    public static final String EXTRA_RINGTONE_INCLUDE_DRM =
+            "android.intent.extra.ringtone.INCLUDE_DRM";
+    
+    /**
+     * Given to the ringtone picker as a {@link Uri}. The {@link Uri} of the
+     * current ringtone, which will be used to show a checkmark next to the item
+     * for this {@link Uri}. If showing an item for "Default" (@see
+     * {@link #EXTRA_RINGTONE_SHOW_DEFAULT}), this can also be one of
+     * {@link System#DEFAULT_RINGTONE_URI},
+     * {@link System#DEFAULT_NOTIFICATION_URI}, or
+     * {@link System#DEFAULT_ALARM_ALERT_URI} to have the "Default" item
+     * checked.
+     * 
+     * @see #ACTION_RINGTONE_PICKER
+     */
+    public static final String EXTRA_RINGTONE_EXISTING_URI =
+            "android.intent.extra.ringtone.EXISTING_URI";
+    
+    /**
+     * Given to the ringtone picker as a {@link Uri}. The {@link Uri} of the
+     * ringtone to play when the user attempts to preview the "Default"
+     * ringtone. This can be one of {@link System#DEFAULT_RINGTONE_URI},
+     * {@link System#DEFAULT_NOTIFICATION_URI}, or
+     * {@link System#DEFAULT_ALARM_ALERT_URI} to have the "Default" point to
+     * the current sound for the given default sound type. If you are showing a
+     * ringtone picker for some other type of sound, you are free to provide any
+     * {@link Uri} here.
+     */
+    public static final String EXTRA_RINGTONE_DEFAULT_URI =
+            "android.intent.extra.ringtone.DEFAULT_URI";
+    
+    /**
+     * Given to the ringtone picker as an int. Specifies which ringtone type(s) should be
+     * shown in the picker. One or more of {@link #TYPE_RINGTONE},
+     * {@link #TYPE_NOTIFICATION}, {@link #TYPE_ALARM}, or {@link #TYPE_ALL}
+     * (bitwise-ored together).
+     */
+    public static final String EXTRA_RINGTONE_TYPE = "android.intent.extra.ringtone.TYPE";
+
+    /**
+     * Given to the ringtone picker as a {@link CharSequence}. The title to
+     * show for the ringtone picker. This has a default value that is suitable
+     * in most cases.
+     */
+    public static final String EXTRA_RINGTONE_TITLE = "android.intent.extra.ringtone.TITLE";
+
+    /**
+     * @hide
+     * Given to the ringtone picker as an int. Additional AudioAttributes flags to use
+     * when playing the ringtone in the picker.
+     * @see #ACTION_RINGTONE_PICKER
+     */
+    public static final String EXTRA_RINGTONE_AUDIO_ATTRIBUTES_FLAGS =
+            "android.intent.extra.ringtone.AUDIO_ATTRIBUTES_FLAGS";
+
+    /**
+     * Returned from the ringtone picker as a {@link Uri}.
+     * <p>
+     * It will be one of:
+     * <li> the picked ringtone,
+     * <li> a {@link Uri} that equals {@link System#DEFAULT_RINGTONE_URI},
+     * {@link System#DEFAULT_NOTIFICATION_URI}, or
+     * {@link System#DEFAULT_ALARM_ALERT_URI} if the default was chosen,
+     * <li> null if the "Silent" item was picked.
+     * 
+     * @see #ACTION_RINGTONE_PICKER
+     */
+    public static final String EXTRA_RINGTONE_PICKED_URI =
+            "android.intent.extra.ringtone.PICKED_URI";
+    
+    // Make sure the column ordering and then ..._COLUMN_INDEX are in sync
+    
+    private static final String[] INTERNAL_COLUMNS = new String[] {
+        MediaStore.Audio.Media._ID,
+        MediaStore.Audio.Media.TITLE,
+        MediaStore.Audio.Media.TITLE,
+        MediaStore.Audio.Media.TITLE_KEY,
+    };
+
+    private static final String[] MEDIA_COLUMNS = new String[] {
+        MediaStore.Audio.Media._ID,
+        MediaStore.Audio.Media.TITLE,
+        MediaStore.Audio.Media.TITLE,
+        MediaStore.Audio.Media.TITLE_KEY,
+    };
+
+    /**
+     * The column index (in the cursor returned by {@link #getCursor()} for the
+     * row ID.
+     */
+    public static final int ID_COLUMN_INDEX = 0;
+
+    /**
+     * The column index (in the cursor returned by {@link #getCursor()} for the
+     * title.
+     */
+    public static final int TITLE_COLUMN_INDEX = 1;
+
+    /**
+     * The column index (in the cursor returned by {@link #getCursor()} for the
+     * media provider's URI.
+     */
+    public static final int URI_COLUMN_INDEX = 2;
+
+    private final Activity mActivity;
+    private final Context mContext;
+
+    @UnsupportedAppUsage
+    private Cursor mCursor;
+
+    private int mType = TYPE_RINGTONE;
+    
+    /**
+     * If a column (item from this list) exists in the Cursor, its value must
+     * be true (value of 1) for the row to be returned.
+     */
+    private final List<String> mFilterColumns = new ArrayList<String>();
+    
+    private boolean mStopPreviousRingtone = true;
+    private Ringtone mPreviousRingtone;
+
+    private boolean mIncludeParentRingtones;
+
+    /**
+     * Constructs a RingtoneManager. This constructor is recommended as its
+     * constructed instance manages cursor(s).
+     * 
+     * @param activity The activity used to get a managed cursor.
+     */
+    public RingtoneManager(Activity activity) {
+        this(activity, /* includeParentRingtones */ false);
+    }
+
+    /**
+     * Constructs a RingtoneManager. This constructor is recommended if there's the need to also
+     * list ringtones from the user's parent.
+     *
+     * @param activity The activity used to get a managed cursor.
+     * @param includeParentRingtones if true, this ringtone manager's cursor will also retrieve
+     *            ringtones from the parent of the user specified in the given activity
+     *
+     * @hide
+     */
+    public RingtoneManager(Activity activity, boolean includeParentRingtones) {
+        mActivity = activity;
+        mContext = activity;
+        setType(mType);
+        mIncludeParentRingtones = includeParentRingtones;
+    }
+
+    /**
+     * Constructs a RingtoneManager. The instance constructed by this
+     * constructor will not manage the cursor(s), so the client should handle
+     * this itself.
+     * 
+     * @param context The context to used to get a cursor.
+     */
+    public RingtoneManager(Context context) {
+        this(context, /* includeParentRingtones */ false);
+    }
+
+    /**
+     * Constructs a RingtoneManager.
+     *
+     * @param context The context to used to get a cursor.
+     * @param includeParentRingtones if true, this ringtone manager's cursor will also retrieve
+     *            ringtones from the parent of the user specified in the given context
+     *
+     * @hide
+     */
+    public RingtoneManager(Context context, boolean includeParentRingtones) {
+        mActivity = null;
+        mContext = context;
+        setType(mType);
+        mIncludeParentRingtones = includeParentRingtones;
+    }
+
+    /**
+     * Sets which type(s) of ringtones will be listed by this.
+     * 
+     * @param type The type(s), one or more of {@link #TYPE_RINGTONE},
+     *            {@link #TYPE_NOTIFICATION}, {@link #TYPE_ALARM},
+     *            {@link #TYPE_ALL}.
+     * @see #EXTRA_RINGTONE_TYPE           
+     */
+    public void setType(int type) {
+        if (mCursor != null) {
+            throw new IllegalStateException(
+                    "Setting filter columns should be done before querying for ringtones.");
+        }
+        
+        mType = type;
+        setFilterColumnsList(type);
+    }
+
+    /**
+     * Infers the volume stream type based on what type of ringtones this
+     * manager is returning.
+     * 
+     * @return The stream type.
+     */
+    public int inferStreamType() {
+        switch (mType) {
+            
+            case TYPE_ALARM:
+                return AudioManager.STREAM_ALARM;
+                
+            case TYPE_NOTIFICATION:
+                return AudioManager.STREAM_NOTIFICATION;
+                
+            default:
+                return AudioManager.STREAM_RING;
+        }
+    }
+
+    /**
+     * Whether retrieving another {@link Ringtone} will stop playing the
+     * previously retrieved {@link Ringtone}.
+     * <p>
+     * If this is false, make sure to {@link Ringtone#stop()} any previous
+     * ringtones to free resources.
+     * 
+     * @param stopPreviousRingtone If true, the previously retrieved
+     *            {@link Ringtone} will be stopped.
+     */
+    public void setStopPreviousRingtone(boolean stopPreviousRingtone) {
+        mStopPreviousRingtone = stopPreviousRingtone;
+    }
+
+    /**
+     * @see #setStopPreviousRingtone(boolean)
+     */
+    public boolean getStopPreviousRingtone() {
+        return mStopPreviousRingtone;
+    }
+
+    /**
+     * Stops playing the last {@link Ringtone} retrieved from this.
+     */
+    public void stopPreviousRingtone() {
+        if (mPreviousRingtone != null) {
+            mPreviousRingtone.stop();
+        }
+    }
+    
+    /**
+     * Returns whether DRM ringtones will be included.
+     * 
+     * @return Whether DRM ringtones will be included.
+     * @see #setIncludeDrm(boolean)
+     * Obsolete - always returns false
+     * @deprecated DRM ringtones are no longer supported
+     */
+    @Deprecated
+    public boolean getIncludeDrm() {
+        return false;
+    }
+
+    /**
+     * Sets whether to include DRM ringtones.
+     * 
+     * @param includeDrm Whether to include DRM ringtones.
+     * Obsolete - no longer has any effect
+     * @deprecated DRM ringtones are no longer supported
+     */
+    @Deprecated
+    public void setIncludeDrm(boolean includeDrm) {
+        if (includeDrm) {
+            Log.w(TAG, "setIncludeDrm no longer supported");
+        }
+    }
+
+    /**
+     * Returns a {@link Cursor} of all the ringtones available. The returned
+     * cursor will be the same cursor returned each time this method is called,
+     * so do not {@link Cursor#close()} the cursor. The cursor can be
+     * {@link Cursor#deactivate()} safely.
+     * <p>
+     * If {@link RingtoneManager#RingtoneManager(Activity)} was not used, the
+     * caller should manage the returned cursor through its activity's life
+     * cycle to prevent leaking the cursor.
+     * <p>
+     * Note that the list of ringtones available will differ depending on whether the caller
+     * has the {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.
+     *
+     * @return A {@link Cursor} of all the ringtones available.
+     * @see #ID_COLUMN_INDEX
+     * @see #TITLE_COLUMN_INDEX
+     * @see #URI_COLUMN_INDEX
+     */
+    public Cursor getCursor() {
+        if (mCursor != null && mCursor.requery()) {
+            return mCursor;
+        }
+
+        ArrayList<Cursor> ringtoneCursors = new ArrayList<Cursor>();
+        ringtoneCursors.add(getInternalRingtones());
+        ringtoneCursors.add(getMediaRingtones());
+
+        if (mIncludeParentRingtones) {
+            Cursor parentRingtonesCursor = getParentProfileRingtones();
+            if (parentRingtonesCursor != null) {
+                ringtoneCursors.add(parentRingtonesCursor);
+            }
+        }
+
+        return mCursor = new SortCursor(ringtoneCursors.toArray(new Cursor[ringtoneCursors.size()]),
+                MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
+    }
+
+    private Cursor getParentProfileRingtones() {
+        final UserManager um = UserManager.get(mContext);
+        final UserInfo parentInfo = um.getProfileParent(mContext.getUserId());
+        if (parentInfo != null && parentInfo.id != mContext.getUserId()) {
+            final Context parentContext = createPackageContextAsUser(mContext, parentInfo.id);
+            if (parentContext != null) {
+                // We don't need to re-add the internal ringtones for the work profile since
+                // they are the same as the personal profile. We just need the external
+                // ringtones.
+                final Cursor res = getMediaRingtones(parentContext);
+                return new ExternalRingtonesCursorWrapper(res, ContentProvider.maybeAddUserId(
+                        MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, parentInfo.id));
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Gets a {@link Ringtone} for the ringtone at the given position in the
+     * {@link Cursor}.
+     * 
+     * @param position The position (in the {@link Cursor}) of the ringtone.
+     * @return A {@link Ringtone} pointing to the ringtone.
+     */
+    public Ringtone getRingtone(int position) {
+        if (mStopPreviousRingtone && mPreviousRingtone != null) {
+            mPreviousRingtone.stop();
+        }
+        
+        mPreviousRingtone = getRingtone(mContext, getRingtoneUri(position), inferStreamType());
+        return mPreviousRingtone;
+    }
+
+    /**
+     * Gets a {@link Uri} for the ringtone at the given position in the {@link Cursor}.
+     * 
+     * @param position The position (in the {@link Cursor}) of the ringtone.
+     * @return A {@link Uri} pointing to the ringtone.
+     */
+    public Uri getRingtoneUri(int position) {
+        // use cursor directly instead of requerying it, which could easily
+        // cause position to shuffle.
+        try {
+            if (mCursor == null || !mCursor.moveToPosition(position)) {
+                return null;
+            }
+        } catch (StaleDataException | IllegalStateException e) {
+            Log.e(TAG, "Unexpected Exception has been catched.", e);
+            return null;
+        }
+
+        return getUriFromCursor(mContext, mCursor);
+    }
+
+    private static Uri getUriFromCursor(Context context, Cursor cursor) {
+        final Uri uri = ContentUris.withAppendedId(Uri.parse(cursor.getString(URI_COLUMN_INDEX)),
+                cursor.getLong(ID_COLUMN_INDEX));
+        return context.getContentResolver().canonicalizeOrElse(uri);
+    }
+
+    /**
+     * Gets the position of a {@link Uri} within this {@link RingtoneManager}.
+     * 
+     * @param ringtoneUri The {@link Uri} to retreive the position of.
+     * @return The position of the {@link Uri}, or -1 if it cannot be found.
+     */
+    public int getRingtonePosition(Uri ringtoneUri) {
+        try {
+            if (ringtoneUri == null) return -1;
+
+            final Cursor cursor = getCursor();
+            cursor.moveToPosition(-1);
+            while (cursor.moveToNext()) {
+                Uri uriFromCursor = getUriFromCursor(mContext, cursor);
+                if (ringtoneUri.equals(uriFromCursor)) {
+                    return cursor.getPosition();
+                }
+            }
+        } catch (NumberFormatException e) {
+            Log.e(TAG, "NumberFormatException while getting ringtone position, returning -1", e);
+        }
+        return -1;
+    }
+
+    /**
+     * Returns a valid ringtone URI. No guarantees on which it returns. If it
+     * cannot find one, returns null. If it can only find one on external storage and the caller
+     * doesn't have the {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission,
+     * returns null.
+     *
+     * @param context The context to use for querying.
+     * @return A ringtone URI, or null if one cannot be found.
+     */
+    public static Uri getValidRingtoneUri(Context context) {
+        final RingtoneManager rm = new RingtoneManager(context);
+        
+        Uri uri = getValidRingtoneUriFromCursorAndClose(context, rm.getInternalRingtones());
+
+        if (uri == null) {
+            uri = getValidRingtoneUriFromCursorAndClose(context, rm.getMediaRingtones());
+        }
+        
+        return uri;
+    }
+    
+    private static Uri getValidRingtoneUriFromCursorAndClose(Context context, Cursor cursor) {
+        if (cursor != null) {
+            Uri uri = null;
+            
+            if (cursor.moveToFirst()) {
+                uri = getUriFromCursor(context, cursor);
+            }
+            cursor.close();
+            
+            return uri;
+        } else {
+            return null;
+        }
+    }
+
+    @UnsupportedAppUsage
+    private Cursor getInternalRingtones() {
+        final Cursor res = query(
+                MediaStore.Audio.Media.INTERNAL_CONTENT_URI, INTERNAL_COLUMNS,
+                constructBooleanTrueWhereClause(mFilterColumns),
+                null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
+        return new ExternalRingtonesCursorWrapper(res, MediaStore.Audio.Media.INTERNAL_CONTENT_URI);
+    }
+
+    private Cursor getMediaRingtones() {
+        final Cursor res = getMediaRingtones(mContext);
+        return new ExternalRingtonesCursorWrapper(res, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
+    }
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private Cursor getMediaRingtones(Context context) {
+        // MediaStore now returns ringtones on other storage devices, even when
+        // we don't have storage or audio permissions
+        return query(
+                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, MEDIA_COLUMNS,
+                constructBooleanTrueWhereClause(mFilterColumns), null,
+                MediaStore.Audio.Media.DEFAULT_SORT_ORDER, context);
+    }
+
+    private void setFilterColumnsList(int type) {
+        List<String> columns = mFilterColumns;
+        columns.clear();
+        
+        if ((type & TYPE_RINGTONE) != 0) {
+            columns.add(MediaStore.Audio.AudioColumns.IS_RINGTONE);
+        }
+        
+        if ((type & TYPE_NOTIFICATION) != 0) {
+            columns.add(MediaStore.Audio.AudioColumns.IS_NOTIFICATION);
+        }
+        
+        if ((type & TYPE_ALARM) != 0) {
+            columns.add(MediaStore.Audio.AudioColumns.IS_ALARM);
+        }
+    }
+    
+    /**
+     * Constructs a where clause that consists of at least one column being 1
+     * (true). This is used to find all matching sounds for the given sound
+     * types (ringtone, notifications, etc.)
+     * 
+     * @param columns The columns that must be true.
+     * @return The where clause.
+     */
+    private static String constructBooleanTrueWhereClause(List<String> columns) {
+        
+        if (columns == null) return null;
+        
+        StringBuilder sb = new StringBuilder();
+        sb.append("(");
+
+        for (int i = columns.size() - 1; i >= 0; i--) {
+            sb.append(columns.get(i)).append("=1 or ");
+        }
+        
+        if (columns.size() > 0) {
+            // Remove last ' or '
+            sb.setLength(sb.length() - 4);
+        }
+
+        sb.append(")");
+
+        return sb.toString();
+    }
+    
+    private Cursor query(Uri uri,
+            String[] projection,
+            String selection,
+            String[] selectionArgs,
+            String sortOrder) {
+        return query(uri, projection, selection, selectionArgs, sortOrder, mContext);
+    }
+
+    private Cursor query(Uri uri,
+            String[] projection,
+            String selection,
+            String[] selectionArgs,
+            String sortOrder,
+            Context context) {
+        if (mActivity != null) {
+            return mActivity.managedQuery(uri, projection, selection, selectionArgs, sortOrder);
+        } else {
+            return context.getContentResolver().query(uri, projection, selection, selectionArgs,
+                    sortOrder);
+        }
+    }
+    
+    /**
+     * Returns a {@link Ringtone} for a given sound URI.
+     * <p>
+     * If the given URI cannot be opened for any reason, this method will
+     * attempt to fallback on another sound. If it cannot find any, it will
+     * return null.
+     * 
+     * @param context A context used to query.
+     * @param ringtoneUri The {@link Uri} of a sound or ringtone.
+     * @return A {@link Ringtone} for the given URI, or null.
+     */
+    public static Ringtone getRingtone(final Context context, Uri ringtoneUri) {
+        // Don't set the stream type
+        return getRingtone(context, ringtoneUri, -1);
+    }
+
+    /**
+     * Returns a {@link Ringtone} with {@link VolumeShaper} if required for a given sound URI.
+     * <p>
+     * If the given URI cannot be opened for any reason, this method will
+     * attempt to fallback on another sound. If it cannot find any, it will
+     * return null.
+     *
+     * @param context A context used to query.
+     * @param ringtoneUri The {@link Uri} of a sound or ringtone.
+     * @param volumeShaperConfig config for volume shaper of the ringtone if applied.
+     * @return A {@link Ringtone} for the given URI, or null.
+     *
+     * @hide
+     */
+    public static Ringtone getRingtone(
+            final Context context, Uri ringtoneUri,
+            @Nullable VolumeShaper.Configuration volumeShaperConfig) {
+        // Don't set the stream type
+        return getRingtone(context, ringtoneUri, -1 /* streamType */, volumeShaperConfig);
+    }
+
+    //FIXME bypass the notion of stream types within the class
+    /**
+     * Returns a {@link Ringtone} for a given sound URI on the given stream
+     * type. Normally, if you change the stream type on the returned
+     * {@link Ringtone}, it will re-create the {@link MediaPlayer}. This is just
+     * an optimized route to avoid that.
+     * 
+     * @param streamType The stream type for the ringtone, or -1 if it should
+     *            not be set (and the default used instead).
+     * @see #getRingtone(Context, Uri)
+     */
+    @UnsupportedAppUsage
+    private static Ringtone getRingtone(final Context context, Uri ringtoneUri, int streamType) {
+        return getRingtone(context, ringtoneUri, streamType, null /* volumeShaperConfig */);
+    }
+
+    //FIXME bypass the notion of stream types within the class
+    /**
+     * Returns a {@link Ringtone} with {@link VolumeShaper} if required for a given sound URI on
+     * the given stream type. Normally, if you change the stream type on the returned
+     * {@link Ringtone}, it will re-create the {@link MediaPlayer}. This is just
+     * an optimized route to avoid that.
+     *
+     * @param streamType The stream type for the ringtone, or -1 if it should
+     *            not be set (and the default used instead).
+     * @param volumeShaperConfig config for volume shaper of the ringtone if applied.
+     * @see #getRingtone(Context, Uri)
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private static Ringtone getRingtone(
+            final Context context, Uri ringtoneUri, int streamType,
+            @Nullable VolumeShaper.Configuration volumeShaperConfig) {
+        try {
+            final Ringtone r = new Ringtone(context, true);
+            if (streamType >= 0) {
+                //FIXME deprecated call
+                r.setStreamType(streamType);
+            }
+            r.setUri(ringtoneUri, volumeShaperConfig);
+            return r;
+        } catch (Exception ex) {
+            Log.e(TAG, "Failed to open ringtone " + ringtoneUri + ": " + ex);
+        }
+
+        return null;
+    }
+
+    /**
+     * Disables Settings.System.SYNC_PARENT_SOUNDS.
+     *
+     * @hide
+     */
+    public static void disableSyncFromParent(Context userContext) {
+        IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
+        IAudioService audioService = IAudioService.Stub.asInterface(b);
+        try {
+            audioService.disableRingtoneSync(userContext.getUserId());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to disable ringtone sync.");
+        }
+    }
+
+    /**
+     * Enables Settings.System.SYNC_PARENT_SOUNDS for the content's user
+     *
+     * @hide
+     */
+    @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+    public static void enableSyncFromParent(Context userContext) {
+        Settings.Secure.putIntForUser(userContext.getContentResolver(),
+                Settings.Secure.SYNC_PARENT_SOUNDS, 1 /* true */, userContext.getUserId());
+    }
+
+    /**
+     * Gets the current default sound's {@link Uri}. This will give the actual
+     * sound {@link Uri}, instead of using this, most clients can use
+     * {@link System#DEFAULT_RINGTONE_URI}.
+     * 
+     * @param context A context used for querying.
+     * @param type The type whose default sound should be returned. One of
+     *            {@link #TYPE_RINGTONE}, {@link #TYPE_NOTIFICATION}, or
+     *            {@link #TYPE_ALARM}.
+     * @return A {@link Uri} pointing to the default sound for the sound type.
+     * @see #setActualDefaultRingtoneUri(Context, int, Uri)
+     */
+    public static Uri getActualDefaultRingtoneUri(Context context, int type) {
+        String setting = getSettingForType(type);
+        if (setting == null) return null;
+        final String uriString = Settings.System.getStringForUser(context.getContentResolver(),
+                setting, context.getUserId());
+        Uri ringtoneUri = uriString != null ? Uri.parse(uriString) : null;
+
+        // If this doesn't verify, the user id must be kept in the uri to ensure it resolves in the
+        // correct user storage
+        if (ringtoneUri != null
+                && ContentProvider.getUserIdFromUri(ringtoneUri) == context.getUserId()) {
+            ringtoneUri = ContentProvider.getUriWithoutUserId(ringtoneUri);
+        }
+
+        return ringtoneUri;
+    }
+    
+    /**
+     * Sets the {@link Uri} of the default sound for a given sound type.
+     * 
+     * @param context A context used for querying.
+     * @param type The type whose default sound should be set. One of
+     *            {@link #TYPE_RINGTONE}, {@link #TYPE_NOTIFICATION}, or
+     *            {@link #TYPE_ALARM}.
+     * @param ringtoneUri A {@link Uri} pointing to the default sound to set.
+     * @see #getActualDefaultRingtoneUri(Context, int)
+     */
+    public static void setActualDefaultRingtoneUri(Context context, int type, Uri ringtoneUri) {
+        String setting = getSettingForType(type);
+        if (setting == null) return;
+
+        final ContentResolver resolver = context.getContentResolver();
+        if (Settings.Secure.getIntForUser(resolver, Settings.Secure.SYNC_PARENT_SOUNDS, 0,
+                    context.getUserId()) == 1) {
+            // Parent sound override is enabled. Disable it using the audio service.
+            disableSyncFromParent(context);
+        }
+        if(!isInternalRingtoneUri(ringtoneUri)) {
+            ringtoneUri = ContentProvider.maybeAddUserId(ringtoneUri, context.getUserId());
+        }
+        Settings.System.putStringForUser(resolver, setting,
+                ringtoneUri != null ? ringtoneUri.toString() : null, context.getUserId());
+
+        // Stream selected ringtone into cache so it's available for playback
+        // when CE storage is still locked
+        if (ringtoneUri != null) {
+            final Uri cacheUri = getCacheForType(type, context.getUserId());
+            try (InputStream in = openRingtone(context, ringtoneUri);
+                    OutputStream out = resolver.openOutputStream(cacheUri)) {
+                FileUtils.copy(in, out);
+            } catch (IOException e) {
+                Log.w(TAG, "Failed to cache ringtone: " + e);
+            }
+        }
+    }
+
+    private static boolean isInternalRingtoneUri(Uri uri) {
+        return isRingtoneUriInStorage(uri, MediaStore.Audio.Media.INTERNAL_CONTENT_URI);
+    }
+
+    private static boolean isExternalRingtoneUri(Uri uri) {
+        return isRingtoneUriInStorage(uri, MediaStore.Audio.Media.EXTERNAL_CONTENT_URI);
+    }
+
+    private static boolean isRingtoneUriInStorage(Uri ringtone, Uri storage) {
+        Uri uriWithoutUserId = ContentProvider.getUriWithoutUserId(ringtone);
+        return uriWithoutUserId == null ? false
+                : uriWithoutUserId.toString().startsWith(storage.toString());
+    }
+
+    /**
+     * Adds an audio file to the list of ringtones.
+     *
+     * After making sure the given file is an audio file, copies the file to the ringtone storage,
+     * and asks the system to scan that file. This call will block until
+     * the scan is completed.
+     *
+     * The directory where the copied file is stored is the directory that matches the ringtone's
+     * type, which is one of: {@link android.is.Environment#DIRECTORY_RINGTONES};
+     * {@link android.is.Environment#DIRECTORY_NOTIFICATIONS};
+     * {@link android.is.Environment#DIRECTORY_ALARMS}.
+     *
+     * This does not allow modifying the type of an existing ringtone file. To change type, use the
+     * APIs in {@link android.content.ContentResolver} to update the corresponding columns.
+     *
+     * @param fileUri Uri of the file to be added as ringtone. Must be a media file.
+     * @param type The type of the ringtone to be added. Must be one of {@link #TYPE_RINGTONE},
+     *            {@link #TYPE_NOTIFICATION}, or {@link #TYPE_ALARM}.
+     *
+     * @return The Uri of the installed ringtone, which may be the Uri of {@param fileUri} if it is
+     *         already in ringtone storage.
+     *
+     * @throws FileNotFoundexception if an appropriate unique filename to save the new ringtone file
+     *         as cannot be found, for example if the unique name is too long.
+     * @throws IllegalArgumentException if {@param fileUri} does not point to an existing audio
+     *         file, or if the {@param type} is not one of the accepted ringtone types.
+     * @throws IOException if the audio file failed to copy to ringtone storage; for example, if
+     *         external storage was not available, or if the file was copied but the media scanner
+     *         did not recognize it as a ringtone.
+     *
+     * @hide
+     */
+    @WorkerThread
+    public Uri addCustomExternalRingtone(@NonNull final Uri fileUri, final int type)
+            throws FileNotFoundException, IllegalArgumentException, IOException {
+        if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
+            throw new IOException("External storage is not mounted. Unable to install ringtones.");
+        }
+
+        // Sanity-check: are we actually being asked to install an audio file?
+        final String mimeType = mContext.getContentResolver().getType(fileUri);
+        if(mimeType == null ||
+                !(mimeType.startsWith("audio/") || mimeType.equals("application/ogg"))) {
+            throw new IllegalArgumentException("Ringtone file must have MIME type \"audio/*\"."
+                    + " Given file has MIME type \"" + mimeType + "\"");
+        }
+
+        // Choose a directory to save the ringtone. Only one type of installation at a time is
+        // allowed. Throws IllegalArgumentException if anything else is given.
+        final String subdirectory = getExternalDirectoryForType(type);
+
+        // Find a filename. Throws FileNotFoundException if none can be found.
+        final File outFile = Utils.getUniqueExternalFile(mContext, subdirectory,
+                FileUtils.buildValidFatFilename(Utils.getFileDisplayNameFromUri(mContext, fileUri)),
+                        mimeType);
+
+        // Copy contents to external ringtone storage. Throws IOException if the copy fails.
+        try (final InputStream input = mContext.getContentResolver().openInputStream(fileUri);
+                final OutputStream output = new FileOutputStream(outFile)) {
+            FileUtils.copy(input, output);
+        }
+
+        // Tell MediaScanner about the new file. Wait for it to assign a {@link Uri}.
+        return MediaStore.scanFile(mContext.getContentResolver(), outFile);
+    }
+
+    private static final String getExternalDirectoryForType(final int type) {
+        switch (type) {
+            case TYPE_RINGTONE:
+                return Environment.DIRECTORY_RINGTONES;
+            case TYPE_NOTIFICATION:
+                return Environment.DIRECTORY_NOTIFICATIONS;
+            case TYPE_ALARM:
+                return Environment.DIRECTORY_ALARMS;
+            default:
+                throw new IllegalArgumentException("Unsupported ringtone type: " + type);
+        }
+    }
+
+    /**
+     * Try opening the given ringtone locally first, but failover to
+     * {@link IRingtonePlayer} if we can't access it directly. Typically happens
+     * when process doesn't hold
+     * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE}.
+     */
+    private static InputStream openRingtone(Context context, Uri uri) throws IOException {
+        final ContentResolver resolver = context.getContentResolver();
+        try {
+            return resolver.openInputStream(uri);
+        } catch (SecurityException | IOException e) {
+            Log.w(TAG, "Failed to open directly; attempting failover: " + e);
+            final IRingtonePlayer player = context.getSystemService(AudioManager.class)
+                    .getRingtonePlayer();
+            try {
+                return new ParcelFileDescriptor.AutoCloseInputStream(player.openRingtone(uri));
+            } catch (Exception e2) {
+                throw new IOException(e2);
+            }
+        }
+    }
+
+    private static String getSettingForType(int type) {
+        if ((type & TYPE_RINGTONE) != 0) {
+            return Settings.System.RINGTONE;
+        } else if ((type & TYPE_NOTIFICATION) != 0) {
+            return Settings.System.NOTIFICATION_SOUND;
+        } else if ((type & TYPE_ALARM) != 0) {
+            return Settings.System.ALARM_ALERT;
+        } else {
+            return null;
+        }
+    }
+
+    /** {@hide} */
+    public static Uri getCacheForType(int type) {
+        return getCacheForType(type, UserHandle.getCallingUserId());
+    }
+
+    /** {@hide} */
+    public static Uri getCacheForType(int type, int userId) {
+        if ((type & TYPE_RINGTONE) != 0) {
+            return ContentProvider.maybeAddUserId(Settings.System.RINGTONE_CACHE_URI, userId);
+        } else if ((type & TYPE_NOTIFICATION) != 0) {
+            return ContentProvider.maybeAddUserId(Settings.System.NOTIFICATION_SOUND_CACHE_URI,
+                    userId);
+        } else if ((type & TYPE_ALARM) != 0) {
+            return ContentProvider.maybeAddUserId(Settings.System.ALARM_ALERT_CACHE_URI, userId);
+        }
+        return null;
+    }
+
+    /**
+     * Returns whether the given {@link Uri} is one of the default ringtones.
+     * 
+     * @param ringtoneUri The ringtone {@link Uri} to be checked.
+     * @return Whether the {@link Uri} is a default.
+     */
+    public static boolean isDefault(Uri ringtoneUri) {
+        return getDefaultType(ringtoneUri) != -1;
+    }
+    
+    /**
+     * Returns the type of a default {@link Uri}.
+     * 
+     * @param defaultRingtoneUri The default {@link Uri}. For example,
+     *            {@link System#DEFAULT_RINGTONE_URI},
+     *            {@link System#DEFAULT_NOTIFICATION_URI}, or
+     *            {@link System#DEFAULT_ALARM_ALERT_URI}.
+     * @return The type of the defaultRingtoneUri, or -1.
+     */
+    public static int getDefaultType(Uri defaultRingtoneUri) {
+        defaultRingtoneUri = ContentProvider.getUriWithoutUserId(defaultRingtoneUri);
+        if (defaultRingtoneUri == null) {
+            return -1;
+        } else if (defaultRingtoneUri.equals(Settings.System.DEFAULT_RINGTONE_URI)) {
+            return TYPE_RINGTONE;
+        } else if (defaultRingtoneUri.equals(Settings.System.DEFAULT_NOTIFICATION_URI)) {
+            return TYPE_NOTIFICATION;
+        } else if (defaultRingtoneUri.equals(Settings.System.DEFAULT_ALARM_ALERT_URI)) {
+            return TYPE_ALARM;
+        } else {
+            return -1;
+        }
+    }
+ 
+    /**
+     * Returns the {@link Uri} for the default ringtone of a particular type.
+     * Rather than returning the actual ringtone's sound {@link Uri}, this will
+     * return the symbolic {@link Uri} which will resolved to the actual sound
+     * when played.
+     * 
+     * @param type The ringtone type whose default should be returned.
+     * @return The {@link Uri} of the default ringtone for the given type.
+     */
+    public static Uri getDefaultUri(int type) {
+        if ((type & TYPE_RINGTONE) != 0) {
+            return Settings.System.DEFAULT_RINGTONE_URI;
+        } else if ((type & TYPE_NOTIFICATION) != 0) {
+            return Settings.System.DEFAULT_NOTIFICATION_URI;
+        } else if ((type & TYPE_ALARM) != 0) {
+            return Settings.System.DEFAULT_ALARM_ALERT_URI;
+        } else {
+            return null;
+        }
+    }
+
+    /**
+     * Opens a raw file descriptor to read the data under the given default URI.
+     *
+     * @param context the Context to use when resolving the Uri.
+     * @param uri The desired default URI to open.
+     * @return a new AssetFileDescriptor pointing to the file. You own this descriptor
+     * and are responsible for closing it when done. This value may be {@code null}.
+     * @throws FileNotFoundException if the provided URI could not be opened.
+     * @see #getDefaultUri
+     */
+    public static @Nullable AssetFileDescriptor openDefaultRingtoneUri(
+            @NonNull Context context, @NonNull Uri uri) throws FileNotFoundException {
+        // Try cached ringtone first since the actual provider may not be
+        // encryption aware, or it may be stored on CE media storage
+        final int type = getDefaultType(uri);
+        final Uri cacheUri = getCacheForType(type, context.getUserId());
+        final Uri actualUri = getActualDefaultRingtoneUri(context, type);
+        final ContentResolver resolver = context.getContentResolver();
+
+        AssetFileDescriptor afd = null;
+        if (cacheUri != null) {
+            afd = resolver.openAssetFileDescriptor(cacheUri, "r");
+            if (afd != null) {
+                return afd;
+            }
+        }
+        if (actualUri != null) {
+            afd = resolver.openAssetFileDescriptor(actualUri, "r");
+        }
+        return afd;
+    }
+
+    /**
+     * Returns if the {@link Ringtone} at the given position in the
+     * {@link Cursor} contains haptic channels.
+     *
+     * @param position The position (in the {@link Cursor}) of the ringtone.
+     * @return true if the ringtone contains haptic channels.
+     */
+    public boolean hasHapticChannels(int position) {
+        return AudioManager.hasHapticChannels(mContext, getRingtoneUri(position));
+    }
+
+    /**
+     * Returns if the {@link Ringtone} from a given sound URI contains
+     * haptic channels or not. As this function doesn't has a context
+     * to resolve the uri, the result may be wrong if the uri cannot be
+     * resolved correctly.
+     * Use {@link #hasHapticChannels(int)} instead when possible.
+     *
+     * @param ringtoneUri The {@link Uri} of a sound or ringtone.
+     * @return true if the ringtone contains haptic channels.
+     */
+    public static boolean hasHapticChannels(@NonNull Uri ringtoneUri) {
+        return AudioManager.hasHapticChannels(null, ringtoneUri);
+    }
+
+    /**
+     * Attempts to create a context for the given user.
+     *
+     * @return created context, or null if package does not exist
+     * @hide
+     */
+    private static Context createPackageContextAsUser(Context context, int userId) {
+        try {
+            return context.createPackageContextAsUser(context.getPackageName(), 0 /* flags */,
+                    UserHandle.of(userId));
+        } catch (NameNotFoundException e) {
+            Log.e(TAG, "Unable to create package context", e);
+            return null;
+        }
+    }
+
+    /**
+     * Ensure that ringtones have been set at least once on this device. This
+     * should be called after the device has finished scanned all media on
+     * {@link MediaStore#VOLUME_INTERNAL}, so that default ringtones can be
+     * configured.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.WRITE_SETTINGS)
+    public static void ensureDefaultRingtones(@NonNull Context context) {
+        for (int type : new int[] {
+                TYPE_RINGTONE,
+                TYPE_NOTIFICATION,
+                TYPE_ALARM,
+        }) {
+            // Skip if we've already defined it at least once, so we don't
+            // overwrite the user changing to null
+            final String setting = getDefaultRingtoneSetting(type);
+            if (Settings.System.getInt(context.getContentResolver(), setting, 0) != 0) {
+                continue;
+            }
+
+            // Try finding the scanned ringtone
+            final String filename = getDefaultRingtoneFilename(type);
+            final String whichAudio = getQueryStringForType(type);
+            final String where = MediaColumns.DISPLAY_NAME + "=? AND " + whichAudio + "=?";
+            final Uri baseUri = MediaStore.Audio.Media.INTERNAL_CONTENT_URI;
+            try (Cursor cursor = context.getContentResolver().query(baseUri,
+                    new String[] { MediaColumns._ID },
+                    where,
+                    new String[] { filename, "1" }, null)) {
+                if (cursor.moveToFirst()) {
+                    final Uri ringtoneUri = context.getContentResolver().canonicalizeOrElse(
+                            ContentUris.withAppendedId(baseUri, cursor.getLong(0)));
+                    RingtoneManager.setActualDefaultRingtoneUri(context, type, ringtoneUri);
+                    Settings.System.putInt(context.getContentResolver(), setting, 1);
+                }
+            }
+        }
+    }
+
+    private static String getDefaultRingtoneSetting(int type) {
+        switch (type) {
+            case TYPE_RINGTONE: return "ringtone_set";
+            case TYPE_NOTIFICATION: return "notification_sound_set";
+            case TYPE_ALARM: return "alarm_alert_set";
+            default: throw new IllegalArgumentException();
+        }
+    }
+
+    private static String getDefaultRingtoneFilename(int type) {
+        switch (type) {
+            case TYPE_RINGTONE: return SystemProperties.get("ro.config.ringtone");
+            case TYPE_NOTIFICATION: return SystemProperties.get("ro.config.notification_sound");
+            case TYPE_ALARM: return SystemProperties.get("ro.config.alarm_alert");
+            default: throw new IllegalArgumentException();
+        }
+    }
+
+    private static String getQueryStringForType(int type) {
+        switch (type) {
+            case TYPE_RINGTONE: return MediaStore.Audio.AudioColumns.IS_RINGTONE;
+            case TYPE_NOTIFICATION: return MediaStore.Audio.AudioColumns.IS_NOTIFICATION;
+            case TYPE_ALARM: return MediaStore.Audio.AudioColumns.IS_ALARM;
+            default: throw new IllegalArgumentException();
+        }
+    }
+}
diff --git a/android/media/RouteDiscoveryPreference.java b/android/media/RouteDiscoveryPreference.java
new file mode 100644
index 0000000..37fee84
--- /dev/null
+++ b/android/media/RouteDiscoveryPreference.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2020 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Objects;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * A media route discovery preference describing the features of routes that media router
+ * would like to discover and whether to perform active scanning.
+ * <p>
+ * When {@link MediaRouter2} instances set discovery preferences by calling
+ * {@link MediaRouter2#registerRouteCallback}, they are merged into a single discovery preference
+ * and it is delivered to call {@link MediaRoute2ProviderService#onDiscoveryPreferenceChanged}.
+ * </p><p>
+ * According to the given discovery preference, {@link MediaRoute2ProviderService} discovers
+ * routes and publishes them.
+ * </p>
+ *
+ * @see MediaRouter2#registerRouteCallback
+ */
+public final class RouteDiscoveryPreference implements Parcelable {
+    @NonNull
+    public static final Creator<RouteDiscoveryPreference> CREATOR =
+            new Creator<RouteDiscoveryPreference>() {
+                @Override
+                public RouteDiscoveryPreference createFromParcel(Parcel in) {
+                    return new RouteDiscoveryPreference(in);
+                }
+
+                @Override
+                public RouteDiscoveryPreference[] newArray(int size) {
+                    return new RouteDiscoveryPreference[size];
+                }
+            };
+
+    @NonNull
+    private final List<String> mPreferredFeatures;
+    private final boolean mShouldPerformActiveScan;
+    @Nullable
+    private final Bundle mExtras;
+
+    /**
+     * An empty discovery preference.
+     * @hide
+     */
+    @SystemApi
+    public static final RouteDiscoveryPreference EMPTY =
+            new Builder(Collections.emptyList(), false).build();
+
+    RouteDiscoveryPreference(@NonNull Builder builder) {
+        mPreferredFeatures = builder.mPreferredFeatures;
+        mShouldPerformActiveScan = builder.mActiveScan;
+        mExtras = builder.mExtras;
+    }
+
+    RouteDiscoveryPreference(@NonNull Parcel in) {
+        mPreferredFeatures = in.createStringArrayList();
+        mShouldPerformActiveScan = in.readBoolean();
+        mExtras = in.readBundle();
+    }
+
+    /**
+     * Gets the features of routes that media router would like to discover.
+     * <p>
+     * Routes that have at least one of the features will be discovered.
+     * They may include predefined features such as
+     * {@link MediaRoute2Info#FEATURE_LIVE_AUDIO}, {@link MediaRoute2Info#FEATURE_LIVE_VIDEO},
+     * or {@link MediaRoute2Info#FEATURE_REMOTE_PLAYBACK} or custom features defined by a provider.
+     * </p>
+     */
+    @NonNull
+    public List<String> getPreferredFeatures() {
+        return mPreferredFeatures;
+    }
+
+    /**
+     * Gets whether active scanning should be performed.
+     * <p>
+     * If any of discovery preferences sets this as {@code true}, active scanning will
+     * be performed regardless of other discovery preferences.
+     * </p>
+     */
+    public boolean shouldPerformActiveScan() {
+        return mShouldPerformActiveScan;
+    }
+
+    /**
+     * @hide
+     */
+    public Bundle getExtras() {
+        return mExtras;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeStringList(mPreferredFeatures);
+        dest.writeBoolean(mShouldPerformActiveScan);
+        dest.writeBundle(mExtras);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder()
+                .append("RouteDiscoveryRequest{ ")
+                .append("preferredFeatures={")
+                .append(String.join(", ", mPreferredFeatures))
+                .append("}")
+                .append(", activeScan=")
+                .append(mShouldPerformActiveScan)
+                .append(" }");
+
+        return result.toString();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (!(o instanceof RouteDiscoveryPreference)) {
+            return false;
+        }
+        RouteDiscoveryPreference other = (RouteDiscoveryPreference) o;
+        //TODO: Make this order-free
+        return Objects.equals(mPreferredFeatures, other.mPreferredFeatures)
+                && mShouldPerformActiveScan == other.mShouldPerformActiveScan;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mPreferredFeatures, mShouldPerformActiveScan);
+    }
+
+    /**
+     * Builder for {@link RouteDiscoveryPreference}.
+     */
+    public static final class Builder {
+        List<String> mPreferredFeatures;
+        boolean mActiveScan;
+        Bundle mExtras;
+
+        public Builder(@NonNull List<String> preferredFeatures, boolean activeScan) {
+            Objects.requireNonNull(preferredFeatures, "preferredFeatures must not be null");
+            mPreferredFeatures = preferredFeatures.stream().filter(str -> !TextUtils.isEmpty(str))
+                    .collect(Collectors.toList());
+            mActiveScan = activeScan;
+        }
+
+        public Builder(@NonNull RouteDiscoveryPreference preference) {
+            Objects.requireNonNull(preference, "preference must not be null");
+
+            mPreferredFeatures = preference.getPreferredFeatures();
+            mActiveScan = preference.shouldPerformActiveScan();
+            mExtras = preference.getExtras();
+        }
+
+        /**
+         * A constructor to combine all of the preferences into a single preference.
+         * It ignores extras of preferences.
+         *
+         * @hide
+         */
+        public Builder(@NonNull Collection<RouteDiscoveryPreference> preferences) {
+            Objects.requireNonNull(preferences, "preferences must not be null");
+
+            Set<String> routeFeatureSet = new HashSet<>();
+            mActiveScan = false;
+            for (RouteDiscoveryPreference preference : preferences) {
+                routeFeatureSet.addAll(preference.mPreferredFeatures);
+                mActiveScan |= preference.mShouldPerformActiveScan;
+            }
+            mPreferredFeatures = new ArrayList<>(routeFeatureSet);
+        }
+
+        /**
+         * Sets preferred route features to discover.
+         * @param preferredFeatures features of routes that media router would like to discover.
+         *                          May include predefined features
+         *                          such as {@link MediaRoute2Info#FEATURE_LIVE_AUDIO},
+         *                          {@link MediaRoute2Info#FEATURE_LIVE_VIDEO},
+         *                          or {@link MediaRoute2Info#FEATURE_REMOTE_PLAYBACK}
+         *                          or custom features defined by a provider.
+         */
+        @NonNull
+        public Builder setPreferredFeatures(@NonNull List<String> preferredFeatures) {
+            Objects.requireNonNull(preferredFeatures, "preferredFeatures must not be null");
+            mPreferredFeatures = preferredFeatures.stream().filter(str -> !TextUtils.isEmpty(str))
+                    .collect(Collectors.toList());
+            return this;
+        }
+
+        /**
+         * Sets if active scanning should be performed.
+         * <p>
+         * Since active scanning uses more system resources, set this as {@code true} only
+         * when it's necessary.
+         * </p>
+         */
+        @NonNull
+        public Builder setShouldPerformActiveScan(boolean activeScan) {
+            mActiveScan = activeScan;
+            return this;
+        }
+
+        /**
+         * Sets the extras of the route.
+         * @hide
+         */
+        @NonNull
+        public Builder setExtras(@Nullable Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Builds the {@link RouteDiscoveryPreference}.
+         */
+        @NonNull
+        public RouteDiscoveryPreference build() {
+            return new RouteDiscoveryPreference(this);
+        }
+    }
+}
diff --git a/android/media/RoutingDelegate.java b/android/media/RoutingDelegate.java
new file mode 100644
index 0000000..2359813
--- /dev/null
+++ b/android/media/RoutingDelegate.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 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.os.Handler;
+
+class RoutingDelegate implements AudioRouting.OnRoutingChangedListener {
+    private AudioRouting mAudioRouting;
+    private AudioRouting.OnRoutingChangedListener mOnRoutingChangedListener;
+    private Handler mHandler;
+
+    RoutingDelegate(final AudioRouting audioRouting,
+                    final AudioRouting.OnRoutingChangedListener listener,
+                    Handler handler) {
+        mAudioRouting = audioRouting;
+        mOnRoutingChangedListener = listener;
+        mHandler = handler;
+    }
+
+    public AudioRouting.OnRoutingChangedListener getListener() {
+        return mOnRoutingChangedListener;
+    }
+
+    public Handler getHandler() {
+        return mHandler;
+    }
+
+    @Override
+    public void onRoutingChanged(AudioRouting router) {
+        if (mOnRoutingChangedListener != null) {
+            mOnRoutingChangedListener.onRoutingChanged(mAudioRouting);
+        }
+    }
+}
diff --git a/android/media/RoutingSessionInfo.java b/android/media/RoutingSessionInfo.java
new file mode 100644
index 0000000..3bea73f
--- /dev/null
+++ b/android/media/RoutingSessionInfo.java
@@ -0,0 +1,688 @@
+/*
+ * Copyright 2019 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Describes a routing session which is created when a media route is selected.
+ */
+public final class RoutingSessionInfo implements Parcelable {
+    @NonNull
+    public static final Creator<RoutingSessionInfo> CREATOR =
+            new Creator<RoutingSessionInfo>() {
+                @Override
+                public RoutingSessionInfo createFromParcel(Parcel in) {
+                    return new RoutingSessionInfo(in);
+                }
+                @Override
+                public RoutingSessionInfo[] newArray(int size) {
+                    return new RoutingSessionInfo[size];
+                }
+            };
+
+    private static final String TAG = "RoutingSessionInfo";
+
+    final String mId;
+    final CharSequence mName;
+    final String mOwnerPackageName;
+    final String mClientPackageName;
+    @Nullable
+    final String mProviderId;
+    final List<String> mSelectedRoutes;
+    final List<String> mSelectableRoutes;
+    final List<String> mDeselectableRoutes;
+    final List<String> mTransferableRoutes;
+
+    final int mVolumeHandling;
+    final int mVolumeMax;
+    final int mVolume;
+
+    @Nullable
+    final Bundle mControlHints;
+    final boolean mIsSystemSession;
+
+    RoutingSessionInfo(@NonNull Builder builder) {
+        Objects.requireNonNull(builder, "builder must not be null.");
+
+        mId = builder.mId;
+        mName = builder.mName;
+        mOwnerPackageName = builder.mOwnerPackageName;
+        mClientPackageName = builder.mClientPackageName;
+        mProviderId = builder.mProviderId;
+
+        mSelectedRoutes = Collections.unmodifiableList(
+                convertToUniqueRouteIds(builder.mSelectedRoutes));
+        mSelectableRoutes = Collections.unmodifiableList(
+                convertToUniqueRouteIds(builder.mSelectableRoutes));
+        mDeselectableRoutes = Collections.unmodifiableList(
+                convertToUniqueRouteIds(builder.mDeselectableRoutes));
+        mTransferableRoutes = Collections.unmodifiableList(
+                convertToUniqueRouteIds(builder.mTransferableRoutes));
+
+        mVolumeHandling = builder.mVolumeHandling;
+        mVolumeMax = builder.mVolumeMax;
+        mVolume = builder.mVolume;
+
+        mControlHints = builder.mControlHints;
+        mIsSystemSession = builder.mIsSystemSession;
+    }
+
+    RoutingSessionInfo(@NonNull Parcel src) {
+        Objects.requireNonNull(src, "src must not be null.");
+
+        mId = ensureString(src.readString());
+        mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(src);
+        mOwnerPackageName = src.readString();
+        mClientPackageName = ensureString(src.readString());
+        mProviderId = src.readString();
+
+        mSelectedRoutes = ensureList(src.createStringArrayList());
+        mSelectableRoutes = ensureList(src.createStringArrayList());
+        mDeselectableRoutes = ensureList(src.createStringArrayList());
+        mTransferableRoutes = ensureList(src.createStringArrayList());
+
+        mVolumeHandling = src.readInt();
+        mVolumeMax = src.readInt();
+        mVolume = src.readInt();
+
+        mControlHints = src.readBundle();
+        mIsSystemSession = src.readBoolean();
+    }
+
+    private static String ensureString(String str) {
+        return str != null ? str : "";
+    }
+
+    private static <T> List<T> ensureList(List<? extends T> list) {
+        if (list != null) {
+            return Collections.unmodifiableList(list);
+        }
+        return Collections.emptyList();
+    }
+
+    /**
+     * Gets the id of the session. The sessions which are given by {@link MediaRouter2} will have
+     * unique IDs.
+     * <p>
+     * In order to ensure uniqueness in {@link MediaRouter2} side, the value of this method
+     * can be different from what was set in {@link MediaRoute2ProviderService}.
+     *
+     * @see Builder#Builder(String, String)
+     */
+    @NonNull
+    public String getId() {
+        if (mProviderId != null) {
+            return MediaRouter2Utils.toUniqueId(mProviderId, mId);
+        } else {
+            return mId;
+        }
+    }
+
+    /**
+     * Gets the user-visible name of the session. It may be {@code null}.
+     */
+    @Nullable
+    public CharSequence getName() {
+        return mName;
+    }
+
+    /**
+     * Gets the original id set by {@link Builder#Builder(String, String)}.
+     * @hide
+     */
+    @NonNull
+    public String getOriginalId() {
+        return mId;
+    }
+
+    /**
+     * Gets the package name of the session owner.
+     * @hide
+     */
+    @Nullable
+    public String getOwnerPackageName() {
+        return mOwnerPackageName;
+    }
+
+    /**
+     * Gets the client package name of the session
+     */
+    @NonNull
+    public String getClientPackageName() {
+        return mClientPackageName;
+    }
+
+    /**
+     * Gets the provider id of the session.
+     * @hide
+     */
+    @Nullable
+    public String getProviderId() {
+        return mProviderId;
+    }
+
+    /**
+     * Gets the list of IDs of selected routes for the session. It shouldn't be empty.
+     */
+    @NonNull
+    public List<String> getSelectedRoutes() {
+        return mSelectedRoutes;
+    }
+
+    /**
+     * Gets the list of IDs of selectable routes for the session.
+     */
+    @NonNull
+    public List<String> getSelectableRoutes() {
+        return mSelectableRoutes;
+    }
+
+    /**
+     * Gets the list of IDs of deselectable routes for the session.
+     */
+    @NonNull
+    public List<String> getDeselectableRoutes() {
+        return mDeselectableRoutes;
+    }
+
+    /**
+     * Gets the list of IDs of transferable routes for the session.
+     */
+    @NonNull
+    public List<String> getTransferableRoutes() {
+        return mTransferableRoutes;
+    }
+
+    /**
+     * Gets the information about how volume is handled on the session.
+     *
+     * @return {@link MediaRoute2Info#PLAYBACK_VOLUME_FIXED} or
+     * {@link MediaRoute2Info#PLAYBACK_VOLUME_VARIABLE}.
+     */
+    @MediaRoute2Info.PlaybackVolume
+    public int getVolumeHandling() {
+        return mVolumeHandling;
+    }
+
+    /**
+     * Gets the maximum volume of the session.
+     */
+    public int getVolumeMax() {
+        return mVolumeMax;
+    }
+
+    /**
+     * Gets the current volume of the session.
+     * <p>
+     * When it's available, it represents the volume of routing session, which is a group
+     * of selected routes. To get the volume of each route, use {@link MediaRoute2Info#getVolume()}.
+     * </p>
+     * @see MediaRoute2Info#getVolume()
+     */
+    public int getVolume() {
+        return mVolume;
+    }
+
+    /**
+     * Gets the control hints
+     */
+    @Nullable
+    public Bundle getControlHints() {
+        return mControlHints;
+    }
+
+    /**
+     * Gets whether this session is in system media route provider.
+     * @hide
+     */
+    @Nullable
+    public boolean isSystemSession() {
+        return mIsSystemSession;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mId);
+        dest.writeCharSequence(mName);
+        dest.writeString(mOwnerPackageName);
+        dest.writeString(mClientPackageName);
+        dest.writeString(mProviderId);
+        dest.writeStringList(mSelectedRoutes);
+        dest.writeStringList(mSelectableRoutes);
+        dest.writeStringList(mDeselectableRoutes);
+        dest.writeStringList(mTransferableRoutes);
+        dest.writeInt(mVolumeHandling);
+        dest.writeInt(mVolumeMax);
+        dest.writeInt(mVolume);
+        dest.writeBundle(mControlHints);
+        dest.writeBoolean(mIsSystemSession);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj) {
+            return true;
+        }
+        if (!(obj instanceof RoutingSessionInfo)) {
+            return false;
+        }
+
+        RoutingSessionInfo other = (RoutingSessionInfo) obj;
+        return Objects.equals(mId, other.mId)
+                && Objects.equals(mName, other.mName)
+                && Objects.equals(mOwnerPackageName, other.mOwnerPackageName)
+                && Objects.equals(mClientPackageName, other.mClientPackageName)
+                && Objects.equals(mProviderId, other.mProviderId)
+                && Objects.equals(mSelectedRoutes, other.mSelectedRoutes)
+                && Objects.equals(mSelectableRoutes, other.mSelectableRoutes)
+                && Objects.equals(mDeselectableRoutes, other.mDeselectableRoutes)
+                && Objects.equals(mTransferableRoutes, other.mTransferableRoutes)
+                && (mVolumeHandling == other.mVolumeHandling)
+                && (mVolumeMax == other.mVolumeMax)
+                && (mVolume == other.mVolume);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mId, mName, mOwnerPackageName, mClientPackageName, mProviderId,
+                mSelectedRoutes, mSelectableRoutes, mDeselectableRoutes, mTransferableRoutes,
+                mVolumeMax, mVolumeHandling, mVolume);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder result = new StringBuilder()
+                .append("RoutingSessionInfo{ ")
+                .append("sessionId=").append(getId())
+                .append(", name=").append(getName())
+                .append(", clientPackageName=").append(getClientPackageName())
+                .append(", selectedRoutes={")
+                .append(String.join(",", getSelectedRoutes()))
+                .append("}")
+                .append(", selectableRoutes={")
+                .append(String.join(",", getSelectableRoutes()))
+                .append("}")
+                .append(", deselectableRoutes={")
+                .append(String.join(",", getDeselectableRoutes()))
+                .append("}")
+                .append(", transferableRoutes={")
+                .append(String.join(",", getTransferableRoutes()))
+                .append("}")
+                .append(", volumeHandling=").append(getVolumeHandling())
+                .append(", volumeMax=").append(getVolumeMax())
+                .append(", volume=").append(getVolume())
+                .append(" }");
+        return result.toString();
+    }
+
+    private List<String> convertToUniqueRouteIds(@NonNull List<String> routeIds) {
+        if (routeIds == null) {
+            Log.w(TAG, "routeIds is null. Returning an empty list");
+            return Collections.emptyList();
+        }
+
+        // mProviderId can be null if not set. Return the original list for this case.
+        if (mProviderId == null) {
+            return routeIds;
+        }
+
+        List<String> result = new ArrayList<>();
+        for (String routeId : routeIds) {
+            result.add(MediaRouter2Utils.toUniqueId(mProviderId, routeId));
+        }
+        return result;
+    }
+
+    /**
+     * Builder class for {@link RoutingSessionInfo}.
+     */
+    public static final class Builder {
+        // TODO: Reorder these (important ones first)
+        final String mId;
+        CharSequence mName;
+        String mOwnerPackageName;
+        String mClientPackageName;
+        String mProviderId;
+        final List<String> mSelectedRoutes;
+        final List<String> mSelectableRoutes;
+        final List<String> mDeselectableRoutes;
+        final List<String> mTransferableRoutes;
+        int mVolumeHandling = MediaRoute2Info.PLAYBACK_VOLUME_FIXED;
+        int mVolumeMax;
+        int mVolume;
+        Bundle mControlHints;
+        boolean mIsSystemSession;
+
+        /**
+         * Constructor for builder to create {@link RoutingSessionInfo}.
+         * <p>
+         * In order to ensure ID uniqueness in {@link MediaRouter2} side, the value of
+         * {@link RoutingSessionInfo#getId()} can be different from what was set in
+         * {@link MediaRoute2ProviderService}.
+         * </p>
+         *
+         * @param id ID of the session. Must not be empty.
+         * @param clientPackageName package name of the client app which uses this session.
+         *                          If is is unknown, then just use an empty string.
+         * @see MediaRoute2Info#getId()
+         */
+        public Builder(@NonNull String id, @NonNull String clientPackageName) {
+            if (TextUtils.isEmpty(id)) {
+                throw new IllegalArgumentException("id must not be empty");
+            }
+
+            mId = id;
+            mClientPackageName =
+                    Objects.requireNonNull(clientPackageName, "clientPackageName must not be null");
+            mSelectedRoutes = new ArrayList<>();
+            mSelectableRoutes = new ArrayList<>();
+            mDeselectableRoutes = new ArrayList<>();
+            mTransferableRoutes = new ArrayList<>();
+        }
+
+        /**
+         * Constructor for builder to create {@link RoutingSessionInfo} with
+         * existing {@link RoutingSessionInfo} instance.
+         *
+         * @param sessionInfo the existing instance to copy data from.
+         */
+        public Builder(@NonNull RoutingSessionInfo sessionInfo) {
+            Objects.requireNonNull(sessionInfo, "sessionInfo must not be null");
+
+            mId = sessionInfo.mId;
+            mName = sessionInfo.mName;
+            mClientPackageName = sessionInfo.mClientPackageName;
+            mProviderId = sessionInfo.mProviderId;
+
+            mSelectedRoutes = new ArrayList<>(sessionInfo.mSelectedRoutes);
+            mSelectableRoutes = new ArrayList<>(sessionInfo.mSelectableRoutes);
+            mDeselectableRoutes = new ArrayList<>(sessionInfo.mDeselectableRoutes);
+            mTransferableRoutes = new ArrayList<>(sessionInfo.mTransferableRoutes);
+
+            if (mProviderId != null) {
+                // They must have unique IDs.
+                mSelectedRoutes.replaceAll(MediaRouter2Utils::getOriginalId);
+                mSelectableRoutes.replaceAll(MediaRouter2Utils::getOriginalId);
+                mDeselectableRoutes.replaceAll(MediaRouter2Utils::getOriginalId);
+                mTransferableRoutes.replaceAll(MediaRouter2Utils::getOriginalId);
+            }
+
+            mVolumeHandling = sessionInfo.mVolumeHandling;
+            mVolumeMax = sessionInfo.mVolumeMax;
+            mVolume = sessionInfo.mVolume;
+
+            mControlHints = sessionInfo.mControlHints;
+            mIsSystemSession = sessionInfo.mIsSystemSession;
+        }
+
+        /**
+         * Sets the user-visible name of the session.
+         */
+        @NonNull
+        public Builder setName(@Nullable CharSequence name) {
+            mName = name;
+            return this;
+        }
+
+        /**
+         * Sets the package name of the session owner. It is expected to be called by the system.
+         *
+         * @hide
+         */
+        @NonNull
+        public Builder setOwnerPackageName(@Nullable String packageName) {
+            mOwnerPackageName = packageName;
+            return this;
+        }
+
+        /**
+         * Sets the client package name of the session.
+         *
+         * @hide
+         */
+        @NonNull
+        public Builder setClientPackageName(@Nullable String packageName) {
+            mClientPackageName = packageName;
+            return this;
+        }
+
+        /**
+         * Sets the provider ID of the session.
+         *
+         * @hide
+         */
+        @NonNull
+        public Builder setProviderId(@NonNull String providerId) {
+            if (TextUtils.isEmpty(providerId)) {
+                throw new IllegalArgumentException("providerId must not be empty");
+            }
+            mProviderId = providerId;
+            return this;
+        }
+
+        /**
+         * Clears the selected routes.
+         */
+        @NonNull
+        public Builder clearSelectedRoutes() {
+            mSelectedRoutes.clear();
+            return this;
+        }
+
+        /**
+         * Adds a route to the selected routes. The {@code routeId} must not be empty.
+         */
+        @NonNull
+        public Builder addSelectedRoute(@NonNull String routeId) {
+            if (TextUtils.isEmpty(routeId)) {
+                throw new IllegalArgumentException("routeId must not be empty");
+            }
+            mSelectedRoutes.add(routeId);
+            return this;
+        }
+
+        /**
+         * Removes a route from the selected routes. The {@code routeId} must not be empty.
+         */
+        @NonNull
+        public Builder removeSelectedRoute(@NonNull String routeId) {
+            if (TextUtils.isEmpty(routeId)) {
+                throw new IllegalArgumentException("routeId must not be empty");
+            }
+            mSelectedRoutes.remove(routeId);
+            return this;
+        }
+
+        /**
+         * Clears the selectable routes.
+         */
+        @NonNull
+        public Builder clearSelectableRoutes() {
+            mSelectableRoutes.clear();
+            return this;
+        }
+
+        /**
+         * Adds a route to the selectable routes. The {@code routeId} must not be empty.
+         */
+        @NonNull
+        public Builder addSelectableRoute(@NonNull String routeId) {
+            if (TextUtils.isEmpty(routeId)) {
+                throw new IllegalArgumentException("routeId must not be empty");
+            }
+            mSelectableRoutes.add(routeId);
+            return this;
+        }
+
+        /**
+         * Removes a route from the selectable routes. The {@code routeId} must not be empty.
+         */
+        @NonNull
+        public Builder removeSelectableRoute(@NonNull String routeId) {
+            if (TextUtils.isEmpty(routeId)) {
+                throw new IllegalArgumentException("routeId must not be empty");
+            }
+            mSelectableRoutes.remove(routeId);
+            return this;
+        }
+
+        /**
+         * Clears the deselectable routes.
+         */
+        @NonNull
+        public Builder clearDeselectableRoutes() {
+            mDeselectableRoutes.clear();
+            return this;
+        }
+
+        /**
+         * Adds a route to the deselectable routes. The {@code routeId} must not be empty.
+         */
+        @NonNull
+        public Builder addDeselectableRoute(@NonNull String routeId) {
+            if (TextUtils.isEmpty(routeId)) {
+                throw new IllegalArgumentException("routeId must not be empty");
+            }
+            mDeselectableRoutes.add(routeId);
+            return this;
+        }
+
+        /**
+         * Removes a route from the deselectable routes. The {@code routeId} must not be empty.
+         */
+        @NonNull
+        public Builder removeDeselectableRoute(@NonNull String routeId) {
+            if (TextUtils.isEmpty(routeId)) {
+                throw new IllegalArgumentException("routeId must not be empty");
+            }
+            mDeselectableRoutes.remove(routeId);
+            return this;
+        }
+
+        /**
+         * Clears the transferable routes.
+         */
+        @NonNull
+        public Builder clearTransferableRoutes() {
+            mTransferableRoutes.clear();
+            return this;
+        }
+
+        /**
+         * Adds a route to the transferable routes. The {@code routeId} must not be empty.
+         */
+        @NonNull
+        public Builder addTransferableRoute(@NonNull String routeId) {
+            if (TextUtils.isEmpty(routeId)) {
+                throw new IllegalArgumentException("routeId must not be empty");
+            }
+            mTransferableRoutes.add(routeId);
+            return this;
+        }
+
+        /**
+         * Removes a route from the transferable routes. The {@code routeId} must not be empty.
+         */
+        @NonNull
+        public Builder removeTransferableRoute(@NonNull String routeId) {
+            if (TextUtils.isEmpty(routeId)) {
+                throw new IllegalArgumentException("routeId must not be empty");
+            }
+            mTransferableRoutes.remove(routeId);
+            return this;
+        }
+
+        /**
+         * Sets the session's volume handling.
+         * {@link MediaRoute2Info#PLAYBACK_VOLUME_FIXED} or
+         * {@link MediaRoute2Info#PLAYBACK_VOLUME_VARIABLE}.
+         */
+        @NonNull
+        public RoutingSessionInfo.Builder setVolumeHandling(
+                @MediaRoute2Info.PlaybackVolume int volumeHandling) {
+            mVolumeHandling = volumeHandling;
+            return this;
+        }
+
+        /**
+         * Sets the session's maximum volume, or 0 if unknown.
+         */
+        @NonNull
+        public RoutingSessionInfo.Builder setVolumeMax(int volumeMax) {
+            mVolumeMax = volumeMax;
+            return this;
+        }
+
+        /**
+         * Sets the session's current volume, or 0 if unknown.
+         */
+        @NonNull
+        public RoutingSessionInfo.Builder setVolume(int volume) {
+            mVolume = volume;
+            return this;
+        }
+
+        /**
+         * Sets control hints.
+         */
+        @NonNull
+        public Builder setControlHints(@Nullable Bundle controlHints) {
+            mControlHints = controlHints;
+            return this;
+        }
+
+        /**
+         * Sets whether this session is in system media route provider.
+         * @hide
+         */
+        @NonNull
+        public Builder setSystemSession(boolean isSystemSession) {
+            mIsSystemSession = isSystemSession;
+            return this;
+        }
+
+        /**
+         * Builds a routing session info.
+         *
+         * @throws IllegalArgumentException if no selected routes are added.
+         */
+        @NonNull
+        public RoutingSessionInfo build() {
+            if (mSelectedRoutes.isEmpty()) {
+                throw new IllegalArgumentException("selectedRoutes must not be empty");
+            }
+            return new RoutingSessionInfo(this);
+        }
+    }
+}
diff --git a/android/media/SRTRenderer.java b/android/media/SRTRenderer.java
new file mode 100644
index 0000000..505f996
--- /dev/null
+++ b/android/media/SRTRenderer.java
@@ -0,0 +1,203 @@
+package android.media;
+
+import android.content.Context;
+import android.media.SubtitleController.Renderer;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Vector;
+
+/** @hide */
+public class SRTRenderer extends Renderer {
+    private final Context mContext;
+    private final boolean mRender;
+    private final Handler mEventHandler;
+
+    private WebVttRenderingWidget mRenderingWidget;
+
+    public SRTRenderer(Context context) {
+        this(context, null);
+    }
+
+    SRTRenderer(Context mContext, Handler mEventHandler) {
+        this.mContext = mContext;
+        this.mRender = (mEventHandler == null);
+        this.mEventHandler = mEventHandler;
+    }
+
+    @Override
+    public boolean supports(MediaFormat format) {
+        if (format.containsKey(MediaFormat.KEY_MIME)) {
+            if (!format.getString(MediaFormat.KEY_MIME)
+                    .equals(MediaPlayer.MEDIA_MIMETYPE_TEXT_SUBRIP)) {
+                return false;
+            };
+            return mRender == (format.getInteger(MediaFormat.KEY_IS_TIMED_TEXT, 0) == 0);
+        }
+        return false;
+    }
+
+    @Override
+    public SubtitleTrack createTrack(MediaFormat format) {
+        if (mRender && mRenderingWidget == null) {
+            mRenderingWidget = new WebVttRenderingWidget(mContext);
+        }
+
+        if (mRender) {
+            return new SRTTrack(mRenderingWidget, format);
+        } else {
+            return new SRTTrack(mEventHandler, format);
+        }
+    }
+}
+
+class SRTTrack extends WebVttTrack {
+    private static final int MEDIA_TIMED_TEXT = 99;   // MediaPlayer.MEDIA_TIMED_TEXT
+    private static final int KEY_STRUCT_TEXT = 16;    // TimedText.KEY_STRUCT_TEXT
+    private static final int KEY_START_TIME = 7;      // TimedText.KEY_START_TIME
+    private static final int KEY_LOCAL_SETTING = 102; // TimedText.KEY_START_TIME
+
+    private static final String TAG = "SRTTrack";
+    private final Handler mEventHandler;
+
+    SRTTrack(WebVttRenderingWidget renderingWidget, MediaFormat format) {
+        super(renderingWidget, format);
+        mEventHandler = null;
+    }
+
+    SRTTrack(Handler eventHandler, MediaFormat format) {
+        super(null, format);
+        mEventHandler = eventHandler;
+    }
+
+    @Override
+    protected void onData(SubtitleData data) {
+        try {
+            TextTrackCue cue = new TextTrackCue();
+            cue.mStartTimeMs = data.getStartTimeUs() / 1000;
+            cue.mEndTimeMs = (data.getStartTimeUs() + data.getDurationUs()) / 1000;
+
+            String paragraph;
+            paragraph = new String(data.getData(), "UTF-8");
+            String[] lines = paragraph.split("\\r?\\n");
+            cue.mLines = new TextTrackCueSpan[lines.length][];
+
+            int i = 0;
+            for (String line : lines) {
+                TextTrackCueSpan[] span = new TextTrackCueSpan[] {
+                    new TextTrackCueSpan(line, -1)
+                };
+                cue.mLines[i++] = span;
+            }
+
+            addCue(cue);
+        } catch (UnsupportedEncodingException e) {
+            Log.w(TAG, "subtitle data is not UTF-8 encoded: " + e);
+        }
+    }
+
+    @Override
+    public void onData(byte[] data, boolean eos, long runID) {
+        // TODO make reentrant
+        try {
+            Reader r = new InputStreamReader(new ByteArrayInputStream(data), "UTF-8");
+            BufferedReader br = new BufferedReader(r);
+
+            String header;
+            while ((header = br.readLine()) != null) {
+                // discard subtitle number
+                header  = br.readLine();
+                if (header == null) {
+                    break;
+                }
+
+                TextTrackCue cue = new TextTrackCue();
+                String[] startEnd = header.split("-->");
+                cue.mStartTimeMs = parseMs(startEnd[0]);
+                cue.mEndTimeMs = parseMs(startEnd[1]);
+                cue.mRunID = runID;
+
+                String s;
+                List<String> paragraph = new ArrayList<String>();
+                while (!((s = br.readLine()) == null || s.trim().equals(""))) {
+                    paragraph.add(s);
+                }
+
+                int i = 0;
+                cue.mLines = new TextTrackCueSpan[paragraph.size()][];
+                cue.mStrings = paragraph.toArray(new String[0]);
+                for (String line : paragraph) {
+                    TextTrackCueSpan[] span = new TextTrackCueSpan[] {
+                            new TextTrackCueSpan(line, -1)
+                    };
+                    cue.mStrings[i] = line;
+                    cue.mLines[i++] = span;
+                }
+
+                addCue(cue);
+            }
+
+        } catch (UnsupportedEncodingException e) {
+            Log.w(TAG, "subtitle data is not UTF-8 encoded: " + e);
+        } catch (IOException ioe) {
+            // shouldn't happen
+            Log.e(TAG, ioe.getMessage(), ioe);
+        }
+    }
+
+    @Override
+    public void updateView(Vector<Cue> activeCues) {
+        if (getRenderingWidget() != null) {
+            super.updateView(activeCues);
+            return;
+        }
+
+        if (mEventHandler == null) {
+            return;
+        }
+
+        for (Cue cue : activeCues) {
+            TextTrackCue ttc = (TextTrackCue) cue;
+
+            Parcel parcel = Parcel.obtain();
+            parcel.writeInt(KEY_LOCAL_SETTING);
+            parcel.writeInt(KEY_START_TIME);
+            parcel.writeInt((int) cue.mStartTimeMs);
+
+            parcel.writeInt(KEY_STRUCT_TEXT);
+            StringBuilder sb = new StringBuilder();
+            for (String line : ttc.mStrings) {
+                sb.append(line).append('\n');
+            }
+
+            byte[] buf = sb.toString().getBytes();
+            parcel.writeInt(buf.length);
+            parcel.writeByteArray(buf);
+
+            Message msg = mEventHandler.obtainMessage(MEDIA_TIMED_TEXT, 0 /* arg1 */, 0 /* arg2 */,
+                    parcel);
+            mEventHandler.sendMessage(msg);
+        }
+        activeCues.clear();
+    }
+
+    private static long parseMs(String in) {
+        long hours = Long.parseLong(in.split(":")[0].trim());
+        long minutes = Long.parseLong(in.split(":")[1].trim());
+        long seconds = Long.parseLong(in.split(":")[2].split(",")[0].trim());
+        long millies = Long.parseLong(in.split(":")[2].split(",")[1].trim());
+
+        return hours * 60 * 60 * 1000 + minutes * 60 * 1000 + seconds * 1000 + millies;
+
+    }
+}
diff --git a/android/media/Session2Command.java b/android/media/Session2Command.java
new file mode 100644
index 0000000..26f4568
--- /dev/null
+++ b/android/media/Session2Command.java
@@ -0,0 +1,218 @@
+/*
+ * 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import java.util.Objects;
+
+/**
+ * This API is not generally intended for third party application developers.
+ * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+ * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+ * Library</a> for consistent behavior across all devices.
+ * <p>
+ * Define a command that a {@link MediaController2} can send to a {@link MediaSession2}.
+ * <p>
+ * If {@link #getCommandCode()} isn't {@link #COMMAND_CODE_CUSTOM}), it's predefined command.
+ * If {@link #getCommandCode()} is {@link #COMMAND_CODE_CUSTOM}), it's custom command and
+ * {@link #getCustomAction()} shouldn't be {@code null}.
+ * <p>
+ * Refer to the
+ * <a href="{@docRoot}reference/androidx/media2/SessionCommand2.html">AndroidX SessionCommand</a>
+ * class for the list of valid commands.
+ */
+public final class Session2Command implements Parcelable {
+    /**
+     * Command code for the custom command which can be defined by string action in the
+     * {@link Session2Command}.
+     */
+    public static final int COMMAND_CODE_CUSTOM = 0;
+
+    public static final @android.annotation.NonNull Parcelable.Creator<Session2Command> CREATOR =
+            new Parcelable.Creator<Session2Command>() {
+                @Override
+                public Session2Command createFromParcel(Parcel in) {
+                    return new Session2Command(in);
+                }
+
+                @Override
+                public Session2Command[] newArray(int size) {
+                    return new Session2Command[size];
+                }
+            };
+
+    private final int mCommandCode;
+    // Nonnull if it's custom command
+    private final String mCustomAction;
+    private final Bundle mCustomExtras;
+
+    /**
+     * Constructor for creating a command predefined in AndroidX media2.
+     *
+     * @param commandCode A command code for a command predefined in AndroidX media2.
+     */
+    public Session2Command(int commandCode) {
+        if (commandCode == COMMAND_CODE_CUSTOM) {
+            throw new IllegalArgumentException("commandCode shouldn't be COMMAND_CODE_CUSTOM");
+        }
+        mCommandCode = commandCode;
+        mCustomAction = null;
+        mCustomExtras = null;
+    }
+
+    /**
+     * Constructor for creating a custom command.
+     *
+     * @param action The action of this custom command.
+     * @param extras An extra bundle for this custom command.
+     */
+    public Session2Command(@NonNull String action, @Nullable Bundle extras) {
+        if (action == null) {
+            throw new IllegalArgumentException("action shouldn't be null");
+        }
+        mCommandCode = COMMAND_CODE_CUSTOM;
+        mCustomAction = action;
+        mCustomExtras = extras;
+    }
+
+    /**
+     * Used by parcelable creator.
+     */
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    Session2Command(Parcel in) {
+        mCommandCode = in.readInt();
+        mCustomAction = in.readString();
+        mCustomExtras = in.readBundle();
+    }
+
+    /**
+     * Gets the command code of a predefined command.
+     * This will return {@link #COMMAND_CODE_CUSTOM} for a custom command.
+     */
+    public int getCommandCode() {
+        return mCommandCode;
+    }
+
+    /**
+     * Gets the action of a custom command.
+     * This will return {@code null} for a predefined command.
+     */
+    @Nullable
+    public String getCustomAction() {
+        return mCustomAction;
+    }
+
+    /**
+     * Gets the extra bundle of a custom command.
+     * This will return {@code null} for a predefined command.
+     */
+    @Nullable
+    public Bundle getCustomExtras() {
+        return mCustomExtras;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        if (dest == null) {
+            throw new IllegalArgumentException("parcel shouldn't be null");
+        }
+        dest.writeInt(mCommandCode);
+        dest.writeString(mCustomAction);
+        dest.writeBundle(mCustomExtras);
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (!(obj instanceof Session2Command)) {
+            return false;
+        }
+        Session2Command other = (Session2Command) obj;
+        return mCommandCode == other.mCommandCode
+                && TextUtils.equals(mCustomAction, other.mCustomAction);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mCustomAction, mCommandCode);
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Contains the result of {@link Session2Command}.
+     */
+    public static final class Result {
+        private final int mResultCode;
+        private final Bundle mResultData;
+
+        /**
+         * Result code representing that the command is skipped or canceled. For an example, a seek
+         * command can be skipped if it is followed by another seek command.
+         */
+        public static final int RESULT_INFO_SKIPPED = 1;
+
+        /**
+         * Result code representing that the command is successfully completed.
+         */
+        public static final int RESULT_SUCCESS = 0;
+
+        /**
+         * Result code represents that call is ended with an unknown error.
+         */
+        public static final int RESULT_ERROR_UNKNOWN_ERROR = -1;
+
+        /**
+         * Constructor of {@link Result}.
+         *
+         * @param resultCode result code
+         * @param resultData result data
+         */
+        public Result(int resultCode, @Nullable Bundle resultData) {
+            mResultCode = resultCode;
+            mResultData = resultData;
+        }
+
+        /**
+         * Returns the result code.
+         */
+        public int getResultCode() {
+            return mResultCode;
+        }
+
+        /**
+         * Returns the result data.
+         */
+        @Nullable
+        public Bundle getResultData() {
+            return mResultData;
+        }
+    }
+}
diff --git a/android/media/Session2CommandGroup.java b/android/media/Session2CommandGroup.java
new file mode 100644
index 0000000..13aabfc
--- /dev/null
+++ b/android/media/Session2CommandGroup.java
@@ -0,0 +1,197 @@
+/*
+ * 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.Session2Command.COMMAND_CODE_CUSTOM;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This API is not generally intended for third party application developers.
+ * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+ * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+ * Library</a> for consistent behavior across all devices.
+ * <p>
+ * A set of {@link Session2Command} which represents a command group.
+ */
+public final class Session2CommandGroup implements Parcelable {
+    private static final String TAG = "Session2CommandGroup";
+
+    public static final @android.annotation.NonNull Parcelable.Creator<Session2CommandGroup>
+            CREATOR = new Parcelable.Creator<Session2CommandGroup>() {
+                @Override
+                public Session2CommandGroup createFromParcel(Parcel in) {
+                    return new Session2CommandGroup(in);
+                }
+
+                @Override
+                public Session2CommandGroup[] newArray(int size) {
+                    return new Session2CommandGroup[size];
+                }
+            };
+
+    Set<Session2Command> mCommands = new HashSet<>();
+
+    /**
+     * Creates a new Session2CommandGroup with commands copied from another object.
+     *
+     * @param commands The collection of commands to copy.
+     */
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    Session2CommandGroup(@Nullable Collection<Session2Command> commands) {
+        if (commands != null) {
+            mCommands.addAll(commands);
+        }
+    }
+
+    /**
+     * Used by parcelable creator.
+     */
+    @SuppressWarnings("WeakerAccess") /* synthetic access */
+    Session2CommandGroup(Parcel in) {
+        Parcelable[] commands = in.readParcelableArray(Session2Command.class.getClassLoader());
+        if (commands != null) {
+            for (Parcelable command : commands) {
+                mCommands.add((Session2Command) command);
+            }
+        }
+    }
+
+    /**
+     * Checks whether this command group has a command that matches given {@code command}.
+     *
+     * @param command A command to find. Shouldn't be {@code null}.
+     */
+    public boolean hasCommand(@NonNull Session2Command command) {
+        if (command == null) {
+            throw new IllegalArgumentException("command shouldn't be null");
+        }
+        return mCommands.contains(command);
+    }
+
+    /**
+     * Checks whether this command group has a command that matches given {@code commandCode}.
+     *
+     * @param commandCode A command code to find.
+     *                    Shouldn't be {@link Session2Command#COMMAND_CODE_CUSTOM}.
+     */
+    public boolean hasCommand(int commandCode) {
+        if (commandCode == COMMAND_CODE_CUSTOM) {
+            throw new IllegalArgumentException("Use hasCommand(Command) for custom command");
+        }
+        for (Session2Command command : mCommands) {
+            if (command.getCommandCode() == commandCode) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Gets all commands of this command group.
+     */
+    @NonNull
+    public Set<Session2Command> getCommands() {
+        return new HashSet<>(mCommands);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        if (dest == null) {
+            throw new IllegalArgumentException("parcel shouldn't be null");
+        }
+        dest.writeParcelableArray(mCommands.toArray(new Session2Command[0]), 0);
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Builds a {@link Session2CommandGroup} object.
+     */
+    public static final class Builder {
+        private Set<Session2Command> mCommands;
+
+        public Builder() {
+            mCommands = new HashSet<>();
+        }
+
+        /**
+         * Creates a new builder for {@link Session2CommandGroup} with commands copied from another
+         * {@link Session2CommandGroup} object.
+         * @param commandGroup
+         */
+        public Builder(@NonNull Session2CommandGroup commandGroup) {
+            if (commandGroup == null) {
+                throw new IllegalArgumentException("command group shouldn't be null");
+            }
+            mCommands = commandGroup.getCommands();
+        }
+
+        /**
+         * Adds a command to this command group.
+         *
+         * @param command A command to add. Shouldn't be {@code null}.
+         */
+        @NonNull
+        public Builder addCommand(@NonNull Session2Command command) {
+            if (command == null) {
+                throw new IllegalArgumentException("command shouldn't be null");
+            }
+            mCommands.add(command);
+            return this;
+        }
+
+        /**
+         * Removes a command from this group which matches given {@code command}.
+         *
+         * @param command A command to find. Shouldn't be {@code null}.
+         */
+        @NonNull
+        public Builder removeCommand(@NonNull Session2Command command) {
+            if (command == null) {
+                throw new IllegalArgumentException("command shouldn't be null");
+            }
+            mCommands.remove(command);
+            return this;
+        }
+
+        /**
+         * Builds {@link Session2CommandGroup}.
+         *
+         * @return a new {@link Session2CommandGroup}.
+         */
+        @NonNull
+        public Session2CommandGroup build() {
+            return new Session2CommandGroup(mCommands);
+        }
+    }
+}
diff --git a/android/media/Session2Link.java b/android/media/Session2Link.java
new file mode 100644
index 0000000..6e550e8
--- /dev/null
+++ b/android/media/Session2Link.java
@@ -0,0 +1,226 @@
+/*
+ * 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.annotation.NonNull;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.util.Log;
+
+import java.util.Objects;
+
+/**
+ * Handles incoming commands from {@link MediaController2} to {@link MediaSession2}.
+ * @hide
+ */
+// @SystemApi
+public final class Session2Link implements Parcelable {
+    private static final String TAG = "Session2Link";
+    private static final boolean DEBUG = MediaSession2.DEBUG;
+
+    public static final @android.annotation.NonNull Parcelable.Creator<Session2Link> CREATOR =
+            new Parcelable.Creator<Session2Link>() {
+                @Override
+                public Session2Link createFromParcel(Parcel in) {
+                    return new Session2Link(in);
+                }
+
+                @Override
+                public Session2Link[] newArray(int size) {
+                    return new Session2Link[size];
+                }
+            };
+
+    private final MediaSession2 mSession;
+    private final IMediaSession2 mISession;
+
+    public Session2Link(MediaSession2 session) {
+        mSession = session;
+        mISession = new Session2Stub();
+    }
+
+    Session2Link(Parcel in) {
+        mSession = null;
+        mISession = IMediaSession2.Stub.asInterface(in.readStrongBinder());
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeStrongBinder(mISession.asBinder());
+    }
+
+    @Override
+    public int hashCode() {
+        return mISession.asBinder().hashCode();
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Session2Link)) {
+            return false;
+        }
+        Session2Link other = (Session2Link) obj;
+        return Objects.equals(mISession.asBinder(), other.mISession.asBinder());
+    }
+
+    /** Link to death with mISession */
+    public void linkToDeath(@NonNull IBinder.DeathRecipient recipient, int flags) {
+        if (mISession != null) {
+            try {
+                mISession.asBinder().linkToDeath(recipient, flags);
+            } catch (RemoteException e) {
+                if (DEBUG) {
+                    Log.d(TAG, "Session died too early.", e);
+                }
+            }
+        }
+    }
+
+    /** Unlink to death with mISession */
+    public boolean unlinkToDeath(@NonNull IBinder.DeathRecipient recipient, int flags) {
+        if (mISession != null) {
+            return mISession.asBinder().unlinkToDeath(recipient, flags);
+        }
+        return true;
+    }
+
+    /** Interface method for IMediaSession2.connect */
+    public void connect(final Controller2Link caller, int seq, Bundle connectionRequest) {
+        try {
+            mISession.connect(caller, seq, connectionRequest);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Interface method for IMediaSession2.disconnect */
+    public void disconnect(final Controller2Link caller, int seq) {
+        try {
+            mISession.disconnect(caller, seq);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Interface method for IMediaSession2.sendSessionCommand */
+    public void sendSessionCommand(final Controller2Link caller, final int seq,
+            final Session2Command command, final Bundle args, ResultReceiver resultReceiver) {
+        try {
+            mISession.sendSessionCommand(caller, seq, command, args, resultReceiver);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Interface method for IMediaSession2.sendSessionCommand */
+    public void cancelSessionCommand(final Controller2Link caller, final int seq) {
+        try {
+            mISession.cancelSessionCommand(caller, seq);
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /** Stub implementation for IMediaSession2.connect */
+    public void onConnect(final Controller2Link caller, int pid, int uid, int seq,
+            Bundle connectionRequest) {
+        mSession.onConnect(caller, pid, uid, seq, connectionRequest);
+    }
+
+    /** Stub implementation for IMediaSession2.disconnect */
+    public void onDisconnect(final Controller2Link caller, int seq) {
+        mSession.onDisconnect(caller, seq);
+    }
+
+    /** Stub implementation for IMediaSession2.sendSessionCommand */
+    public void onSessionCommand(final Controller2Link caller, final int seq,
+            final Session2Command command, final Bundle args, ResultReceiver resultReceiver) {
+        mSession.onSessionCommand(caller, seq, command, args, resultReceiver);
+    }
+
+    /** Stub implementation for IMediaSession2.cancelSessionCommand */
+    public void onCancelCommand(final Controller2Link caller, final int seq) {
+        mSession.onCancelCommand(caller, seq);
+    }
+
+    private class Session2Stub extends IMediaSession2.Stub {
+        @Override
+        public void connect(final Controller2Link caller, int seq, Bundle connectionRequest) {
+            if (caller == null || connectionRequest == null) {
+                return;
+            }
+            final int pid = Binder.getCallingPid();
+            final int uid = Binder.getCallingUid();
+            final long token = Binder.clearCallingIdentity();
+            try {
+                Session2Link.this.onConnect(caller, pid, uid, seq, connectionRequest);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void disconnect(final Controller2Link caller, int seq) {
+            if (caller == null) {
+                return;
+            }
+            final long token = Binder.clearCallingIdentity();
+            try {
+                Session2Link.this.onDisconnect(caller, seq);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void sendSessionCommand(final Controller2Link caller, final int seq,
+                final Session2Command command, final Bundle args, ResultReceiver resultReceiver) {
+            if (caller == null) {
+                return;
+            }
+            final long token = Binder.clearCallingIdentity();
+            try {
+                Session2Link.this.onSessionCommand(caller, seq, command, args, resultReceiver);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+
+        @Override
+        public void cancelSessionCommand(final Controller2Link caller, final int seq) {
+            if (caller == null) {
+                return;
+            }
+            final long token = Binder.clearCallingIdentity();
+            try {
+                Session2Link.this.onCancelCommand(caller, seq);
+            } finally {
+                Binder.restoreCallingIdentity(token);
+            }
+        }
+    }
+}
diff --git a/android/media/Session2Token.java b/android/media/Session2Token.java
new file mode 100644
index 0000000..aae2e1b
--- /dev/null
+++ b/android/media/Session2Token.java
@@ -0,0 +1,272 @@
+/*
+ * 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * This API is not generally intended for third party application developers.
+ * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+ * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+ * Library</a> for consistent behavior across all devices.
+ * <p>
+ * Represents an ongoing {@link MediaSession2} or a {@link MediaSession2Service}.
+ * If it's representing a session service, it may not be ongoing.
+ * <p>
+ * This may be passed to apps by the session owner to allow them to create a
+ * {@link MediaController2} to communicate with the session.
+ * <p>
+ * It can be also obtained by {@link android.media.session.MediaSessionManager}.
+ */
+public final class Session2Token implements Parcelable {
+    private static final String TAG = "Session2Token";
+
+    public static final @android.annotation.NonNull Creator<Session2Token> CREATOR =
+            new Creator<Session2Token>() {
+                @Override
+                public Session2Token createFromParcel(Parcel p) {
+                    return new Session2Token(p);
+                }
+
+                @Override
+                public Session2Token[] newArray(int size) {
+                    return new Session2Token[size];
+                }
+            };
+
+    /**
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "TYPE_", value = {TYPE_SESSION, TYPE_SESSION_SERVICE})
+    public @interface TokenType {
+    }
+
+    /**
+     * Type for {@link MediaSession2}.
+     */
+    public static final int TYPE_SESSION = 0;
+
+    /**
+     * Type for {@link MediaSession2Service}.
+     */
+    public static final int TYPE_SESSION_SERVICE = 1;
+
+    private final int mUid;
+    @TokenType
+    private final int mType;
+    private final String mPackageName;
+    private final String mServiceName;
+    private final Session2Link mSessionLink;
+    private final ComponentName mComponentName;
+    private final Bundle mExtras;
+
+    /**
+     * Constructor for the token with type {@link #TYPE_SESSION_SERVICE}.
+     *
+     * @param context The context.
+     * @param serviceComponent The component name of the service.
+     */
+    public Session2Token(@NonNull Context context, @NonNull ComponentName serviceComponent) {
+        if (context == null) {
+            throw new IllegalArgumentException("context shouldn't be null");
+        }
+        if (serviceComponent == null) {
+            throw new IllegalArgumentException("serviceComponent shouldn't be null");
+        }
+
+        final PackageManager manager = context.getPackageManager();
+        final int uid = getUid(manager, serviceComponent.getPackageName());
+
+        if (!isInterfaceDeclared(manager, MediaSession2Service.SERVICE_INTERFACE,
+                serviceComponent)) {
+            Log.w(TAG, serviceComponent + " doesn't implement MediaSession2Service.");
+        }
+        mComponentName = serviceComponent;
+        mPackageName = serviceComponent.getPackageName();
+        mServiceName = serviceComponent.getClassName();
+        mUid = uid;
+        mType = TYPE_SESSION_SERVICE;
+        mSessionLink = null;
+        mExtras = Bundle.EMPTY;
+    }
+
+    Session2Token(int uid, int type, String packageName, Session2Link sessionLink,
+            @NonNull Bundle tokenExtras) {
+        mUid = uid;
+        mType = type;
+        mPackageName = packageName;
+        mServiceName = null;
+        mComponentName = null;
+        mSessionLink = sessionLink;
+        mExtras = tokenExtras;
+    }
+
+    Session2Token(Parcel in) {
+        mUid = in.readInt();
+        mType = in.readInt();
+        mPackageName = in.readString();
+        mServiceName = in.readString();
+        mSessionLink = in.readParcelable(null);
+        mComponentName = ComponentName.unflattenFromString(in.readString());
+
+        Bundle extras = in.readBundle();
+        if (extras == null) {
+            Log.w(TAG, "extras shouldn't be null.");
+            extras = Bundle.EMPTY;
+        } else if (MediaSession2.hasCustomParcelable(extras)) {
+            Log.w(TAG, "extras contain custom parcelable. Ignoring.");
+            extras = Bundle.EMPTY;
+        }
+        mExtras = extras;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mUid);
+        dest.writeInt(mType);
+        dest.writeString(mPackageName);
+        dest.writeString(mServiceName);
+        dest.writeParcelable(mSessionLink, flags);
+        dest.writeString(mComponentName == null ? "" : mComponentName.flattenToString());
+        dest.writeBundle(mExtras);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mType, mUid, mPackageName, mServiceName, mSessionLink);
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof Session2Token)) {
+            return false;
+        }
+        Session2Token other = (Session2Token) obj;
+        return mUid == other.mUid
+                && TextUtils.equals(mPackageName, other.mPackageName)
+                && TextUtils.equals(mServiceName, other.mServiceName)
+                && mType == other.mType
+                && Objects.equals(mSessionLink, other.mSessionLink);
+    }
+
+    @Override
+    public String toString() {
+        return "Session2Token {pkg=" + mPackageName + " type=" + mType
+                + " service=" + mServiceName + " Session2Link=" + mSessionLink + "}";
+    }
+
+    /**
+     * @return uid of the session
+     */
+    public int getUid() {
+        return mUid;
+    }
+
+    /**
+     * @return package name of the session
+     */
+    @NonNull
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    /**
+     * @return service name of the session. Can be {@code null} for {@link #TYPE_SESSION}.
+     */
+    @Nullable
+    public String getServiceName() {
+        return mServiceName;
+    }
+
+    /**
+     * @return type of the token
+     * @see #TYPE_SESSION
+     * @see #TYPE_SESSION_SERVICE
+     */
+    public @TokenType int getType() {
+        return mType;
+    }
+
+    /**
+     * @return extras of the token
+     * @see MediaSession2.Builder#setExtras(Bundle)
+     */
+    @NonNull
+    public Bundle getExtras() {
+        return new Bundle(mExtras);
+    }
+
+    Session2Link getSessionLink() {
+        return mSessionLink;
+    }
+
+    private static boolean isInterfaceDeclared(PackageManager manager, String serviceInterface,
+            ComponentName serviceComponent) {
+        Intent serviceIntent = new Intent(serviceInterface);
+        // Use queryIntentServices to find services with MediaSession2Service.SERVICE_INTERFACE.
+        // We cannot use resolveService with intent specified class name, because resolveService
+        // ignores actions if Intent.setClassName() is specified.
+        serviceIntent.setPackage(serviceComponent.getPackageName());
+
+        List<ResolveInfo> list = manager.queryIntentServices(
+                serviceIntent, PackageManager.GET_META_DATA);
+        if (list != null) {
+            for (int i = 0; i < list.size(); i++) {
+                ResolveInfo resolveInfo = list.get(i);
+                if (resolveInfo == null || resolveInfo.serviceInfo == null) {
+                    continue;
+                }
+                if (TextUtils.equals(
+                        resolveInfo.serviceInfo.name, serviceComponent.getClassName())) {
+                    return true;
+                }
+            }
+        }
+        return false;
+    }
+
+    private static int getUid(PackageManager manager, String packageName) {
+        try {
+            return manager.getApplicationInfo(packageName, 0).uid;
+        } catch (PackageManager.NameNotFoundException e) {
+            throw new IllegalArgumentException("Cannot find package " + packageName);
+        }
+    }
+}
diff --git a/android/media/SoundPool.java b/android/media/SoundPool.java
new file mode 100644
index 0000000..6403aab
--- /dev/null
+++ b/android/media/SoundPool.java
@@ -0,0 +1,615 @@
+/*
+ * Copyright (C) 2007 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.content.res.AssetFileDescriptor;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.util.AndroidRuntimeException;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.lang.ref.WeakReference;
+import java.util.concurrent.atomic.AtomicReference;
+
+
+/**
+ * The SoundPool class manages and plays audio resources for applications.
+ *
+ * <p>A SoundPool is a collection of sound samples that can be loaded into memory
+ * from a resource inside the APK or from a file in the file system. The
+ * SoundPool library uses the MediaCodec service to decode the audio
+ * into raw 16-bit PCM. This allows applications
+ * to ship with compressed streams without having to suffer the CPU load
+ * and latency of decompressing during playback.</p>
+ *
+ * <p>Soundpool sounds are expected to be short as they are
+ * predecoded into memory. Each decoded sound is internally limited to one
+ * megabyte storage, which represents approximately 5.6 seconds at 44.1kHz stereo
+ * (the duration is proportionally longer at lower sample rates or
+ * a channel mask of mono). A decoded audio sound will be truncated if it would
+ * exceed the per-sound one megabyte storage space.</p>
+ *
+ * <p>In addition to low-latency playback, SoundPool can also manage the number
+ * of audio streams being rendered at once. When the SoundPool object is
+ * constructed, the maxStreams parameter sets the maximum number of streams
+ * that can be played at a time from this single SoundPool. SoundPool tracks
+ * the number of active streams. If the maximum number of streams is exceeded,
+ * SoundPool will automatically stop a previously playing stream based first
+ * on priority and then by age within that priority. Limiting the maximum
+ * number of streams helps to cap CPU loading and reducing the likelihood that
+ * audio mixing will impact visuals or UI performance.</p>
+ *
+ * <p>Sounds can be looped by setting a non-zero loop value. A value of -1
+ * causes the sound to loop forever. In this case, the application must
+ * explicitly call the stop() function to stop the sound. Any other non-zero
+ * value will cause the sound to repeat the specified number of times, e.g.
+ * a value of 3 causes the sound to play a total of 4 times.</p>
+ *
+ * <p>The playback rate can also be changed. A playback rate of 1.0 causes
+ * the sound to play at its original frequency (resampled, if necessary,
+ * to the hardware output frequency). A playback rate of 2.0 causes the
+ * sound to play at twice its original frequency, and a playback rate of
+ * 0.5 causes it to play at half its original frequency. The playback
+ * rate range is 0.5 to 2.0.</p>
+ *
+ * <p>Priority runs low to high, i.e. higher numbers are higher priority.
+ * Priority is used when a call to play() would cause the number of active
+ * streams to exceed the value established by the maxStreams parameter when
+ * the SoundPool was created. In this case, the stream allocator will stop
+ * the lowest priority stream. If there are multiple streams with the same
+ * low priority, it will choose the oldest stream to stop. In the case
+ * where the priority of the new stream is lower than all the active
+ * streams, the new sound will not play and the play() function will return
+ * a streamID of zero.</p>
+ *
+ * <p>Let's examine a typical use case: A game consists of several levels of
+ * play. For each level, there is a set of unique sounds that are used only
+ * by that level. In this case, the game logic should create a new SoundPool
+ * object when the first level is loaded. The level data itself might contain
+ * the list of sounds to be used by this level. The loading logic iterates
+ * through the list of sounds calling the appropriate SoundPool.load()
+ * function. This should typically be done early in the process to allow time
+ * for decompressing the audio to raw PCM format before they are needed for
+ * playback.</p>
+ *
+ * <p>Once the sounds are loaded and play has started, the application can
+ * trigger sounds by calling SoundPool.play(). Playing streams can be
+ * paused or resumed, and the application can also alter the pitch by
+ * adjusting the playback rate in real-time for doppler or synthesis
+ * effects.</p>
+ *
+ * <p>Note that since streams can be stopped due to resource constraints, the
+ * streamID is a reference to a particular instance of a stream. If the stream
+ * is stopped to allow a higher priority stream to play, the stream is no
+ * longer valid. However, the application is allowed to call methods on
+ * the streamID without error. This may help simplify program logic since
+ * the application need not concern itself with the stream lifecycle.</p>
+ *
+ * <p>In our example, when the player has completed the level, the game
+ * logic should call SoundPool.release() to release all the native resources
+ * in use and then set the SoundPool reference to null. If the player starts
+ * another level, a new SoundPool is created, sounds are loaded, and play
+ * resumes.</p>
+ */
+public class SoundPool extends PlayerBase {
+    static { System.loadLibrary("soundpool"); }
+
+    // SoundPool messages
+    //
+    // must match SoundPool.h
+    private static final int SAMPLE_LOADED = 1;
+
+    private final static String TAG = "SoundPool";
+    private final static boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private final AtomicReference<EventHandler> mEventHandler = new AtomicReference<>(null);
+
+    private long mNativeContext; // accessed by native methods
+
+    private boolean mHasAppOpsPlayAudio;
+
+    private final AudioAttributes mAttributes;
+
+    /**
+     * Constructor. Constructs a SoundPool object with the following
+     * characteristics:
+     *
+     * @param maxStreams the maximum number of simultaneous streams for this
+     *                   SoundPool object
+     * @param streamType the audio stream type as described in AudioManager
+     *                   For example, game applications will normally use
+     *                   {@link AudioManager#STREAM_MUSIC}.
+     * @param srcQuality the sample-rate converter quality. Currently has no
+     *                   effect. Use 0 for the default.
+     * @return a SoundPool object, or null if creation failed
+     * @deprecated use {@link SoundPool.Builder} instead to create and configure a
+     *     SoundPool instance
+     */
+    public SoundPool(int maxStreams, int streamType, int srcQuality) {
+        this(maxStreams,
+                new AudioAttributes.Builder().setInternalLegacyStreamType(streamType).build());
+        PlayerBase.deprecateStreamTypeForPlayback(streamType, "SoundPool", "SoundPool()");
+    }
+
+    private SoundPool(int maxStreams, AudioAttributes attributes) {
+        super(attributes, AudioPlaybackConfiguration.PLAYER_TYPE_JAM_SOUNDPOOL);
+
+        // do native setup
+        if (native_setup(new WeakReference<SoundPool>(this),
+                maxStreams, attributes, getCurrentOpPackageName()) != 0) {
+            throw new RuntimeException("Native setup failed");
+        }
+        mAttributes = attributes;
+
+        // FIXME: b/174876164 implement session id for soundpool
+        baseRegisterPlayer(AudioSystem.AUDIO_SESSION_ALLOCATE);
+    }
+
+    /**
+     * Release the SoundPool resources.
+     *
+     * Release all memory and native resources used by the SoundPool
+     * object. The SoundPool can no longer be used and the reference
+     * should be set to null.
+     */
+    public final void release() {
+        baseRelease();
+        native_release();
+    }
+
+    private native final void native_release();
+
+    protected void finalize() { release(); }
+
+    /**
+     * Load the sound from the specified path.
+     *
+     * @param path the path to the audio file
+     * @param priority the priority of the sound. Currently has no effect. Use
+     *                 a value of 1 for future compatibility.
+     * @return a sound ID. This value can be used to play or unload the sound.
+     */
+    public int load(String path, int priority) {
+        int id = 0;
+        try {
+            File f = new File(path);
+            ParcelFileDescriptor fd = ParcelFileDescriptor.open(f,
+                    ParcelFileDescriptor.MODE_READ_ONLY);
+            if (fd != null) {
+                id = _load(fd.getFileDescriptor(), 0, f.length(), priority);
+                fd.close();
+            }
+        } catch (java.io.IOException e) {
+            Log.e(TAG, "error loading " + path);
+        }
+        return id;
+    }
+
+    /**
+     * Load the sound from the specified APK resource.
+     *
+     * Note that the extension is dropped. For example, if you want to load
+     * a sound from the raw resource file "explosion.mp3", you would specify
+     * "R.raw.explosion" as the resource ID. Note that this means you cannot
+     * have both an "explosion.wav" and an "explosion.mp3" in the res/raw
+     * directory.
+     *
+     * @param context the application context
+     * @param resId the resource ID
+     * @param priority the priority of the sound. Currently has no effect. Use
+     *                 a value of 1 for future compatibility.
+     * @return a sound ID. This value can be used to play or unload the sound.
+     */
+    public int load(Context context, int resId, int priority) {
+        AssetFileDescriptor afd = context.getResources().openRawResourceFd(resId);
+        int id = 0;
+        if (afd != null) {
+            id = _load(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength(), priority);
+            try {
+                afd.close();
+            } catch (java.io.IOException ex) {
+                //Log.d(TAG, "close failed:", ex);
+            }
+        }
+        return id;
+    }
+
+    /**
+     * Load the sound from an asset file descriptor.
+     *
+     * @param afd an asset file descriptor
+     * @param priority the priority of the sound. Currently has no effect. Use
+     *                 a value of 1 for future compatibility.
+     * @return a sound ID. This value can be used to play or unload the sound.
+     */
+    public int load(AssetFileDescriptor afd, int priority) {
+        if (afd != null) {
+            long len = afd.getLength();
+            if (len < 0) {
+                throw new AndroidRuntimeException("no length for fd");
+            }
+            return _load(afd.getFileDescriptor(), afd.getStartOffset(), len, priority);
+        } else {
+            return 0;
+        }
+    }
+
+    /**
+     * Load the sound from a FileDescriptor.
+     *
+     * This version is useful if you store multiple sounds in a single
+     * binary. The offset specifies the offset from the start of the file
+     * and the length specifies the length of the sound within the file.
+     *
+     * @param fd a FileDescriptor object
+     * @param offset offset to the start of the sound
+     * @param length length of the sound
+     * @param priority the priority of the sound. Currently has no effect. Use
+     *                 a value of 1 for future compatibility.
+     * @return a sound ID. This value can be used to play or unload the sound.
+     */
+    public int load(FileDescriptor fd, long offset, long length, int priority) {
+        return _load(fd, offset, length, priority);
+    }
+
+    /**
+     * Unload a sound from a sound ID.
+     *
+     * Unloads the sound specified by the soundID. This is the value
+     * returned by the load() function. Returns true if the sound is
+     * successfully unloaded, false if the sound was already unloaded.
+     *
+     * @param soundID a soundID returned by the load() function
+     * @return true if just unloaded, false if previously unloaded
+     */
+    public native final boolean unload(int soundID);
+
+    /**
+     * Play a sound from a sound ID.
+     *
+     * Play the sound specified by the soundID. This is the value
+     * returned by the load() function. Returns a non-zero streamID
+     * if successful, zero if it fails. The streamID can be used to
+     * further control playback. Note that calling play() may cause
+     * another sound to stop playing if the maximum number of active
+     * streams is exceeded. A loop value of -1 means loop forever,
+     * a value of 0 means don't loop, other values indicate the
+     * number of repeats, e.g. a value of 1 plays the audio twice.
+     * The playback rate allows the application to vary the playback
+     * rate (pitch) of the sound. A value of 1.0 means play back at
+     * the original frequency. A value of 2.0 means play back twice
+     * as fast, and a value of 0.5 means playback at half speed.
+     *
+     * @param soundID a soundID returned by the load() function
+     * @param leftVolume left volume value (range = 0.0 to 1.0)
+     * @param rightVolume right volume value (range = 0.0 to 1.0)
+     * @param priority stream priority (0 = lowest priority)
+     * @param loop loop mode (0 = no loop, -1 = loop forever)
+     * @param rate playback rate (1.0 = normal playback, range 0.5 to 2.0)
+     * @return non-zero streamID if successful, zero if failed
+     */
+    public final int play(int soundID, float leftVolume, float rightVolume,
+            int priority, int loop, float rate) {
+        // FIXME: b/174876164 implement device id for soundpool
+        baseStart(0);
+        return _play(soundID, leftVolume, rightVolume, priority, loop, rate);
+    }
+
+    /**
+     * Pause a playback stream.
+     *
+     * Pause the stream specified by the streamID. This is the
+     * value returned by the play() function. If the stream is
+     * playing, it will be paused. If the stream is not playing
+     * (e.g. is stopped or was previously paused), calling this
+     * function will have no effect.
+     *
+     * @param streamID a streamID returned by the play() function
+     */
+    public native final void pause(int streamID);
+
+    /**
+     * Resume a playback stream.
+     *
+     * Resume the stream specified by the streamID. This
+     * is the value returned by the play() function. If the stream
+     * is paused, this will resume playback. If the stream was not
+     * previously paused, calling this function will have no effect.
+     *
+     * @param streamID a streamID returned by the play() function
+     */
+    public native final void resume(int streamID);
+
+    /**
+     * Pause all active streams.
+     *
+     * Pause all streams that are currently playing. This function
+     * iterates through all the active streams and pauses any that
+     * are playing. It also sets a flag so that any streams that
+     * are playing can be resumed by calling autoResume().
+     */
+    public native final void autoPause();
+
+    /**
+     * Resume all previously active streams.
+     *
+     * Automatically resumes all streams that were paused in previous
+     * calls to autoPause().
+     */
+    public native final void autoResume();
+
+    /**
+     * Stop a playback stream.
+     *
+     * Stop the stream specified by the streamID. This
+     * is the value returned by the play() function. If the stream
+     * is playing, it will be stopped. It also releases any native
+     * resources associated with this stream. If the stream is not
+     * playing, it will have no effect.
+     *
+     * @param streamID a streamID returned by the play() function
+     */
+    public native final void stop(int streamID);
+
+    /**
+     * Set stream volume.
+     *
+     * Sets the volume on the stream specified by the streamID.
+     * This is the value returned by the play() function. The
+     * value must be in the range of 0.0 to 1.0. If the stream does
+     * not exist, it will have no effect.
+     *
+     * @param streamID a streamID returned by the play() function
+     * @param leftVolume left volume value (range = 0.0 to 1.0)
+     * @param rightVolume right volume value (range = 0.0 to 1.0)
+     */
+    public final void setVolume(int streamID, float leftVolume, float rightVolume) {
+        // unlike other subclasses of PlayerBase, we are not calling
+        // baseSetVolume(leftVolume, rightVolume) as we need to keep track of each
+        // volume separately for each player, so we still send the command, but
+        // handle mute/unmute separately through playerSetVolume()
+        _setVolume(streamID, leftVolume, rightVolume);
+    }
+
+    @Override
+    /* package */ int playerApplyVolumeShaper(
+            @NonNull VolumeShaper.Configuration configuration,
+            @Nullable VolumeShaper.Operation operation) {
+        return -1;
+    }
+
+    @Override
+    /* package */ @Nullable VolumeShaper.State playerGetVolumeShaperState(int id) {
+        return null;
+    }
+
+    @Override
+    void playerSetVolume(boolean muting, float leftVolume, float rightVolume) {
+        // not used here to control the player volume directly, but used to mute/unmute
+        _mute(muting);
+    }
+
+    @Override
+    int playerSetAuxEffectSendLevel(boolean muting, float level) {
+        // no aux send functionality so no-op
+        return AudioSystem.SUCCESS;
+    }
+
+    @Override
+    void playerStart() {
+        // FIXME implement resuming any paused sound
+    }
+
+    @Override
+    void playerPause() {
+        // FIXME implement pausing any playing sound
+    }
+
+    @Override
+    void playerStop() {
+        // FIXME implement pausing any playing sound
+    }
+
+    /**
+     * Similar, except set volume of all channels to same value.
+     * @hide
+     */
+    public void setVolume(int streamID, float volume) {
+        setVolume(streamID, volume, volume);
+    }
+
+    /**
+     * Change stream priority.
+     *
+     * Change the priority of the stream specified by the streamID.
+     * This is the value returned by the play() function. Affects the
+     * order in which streams are re-used to play new sounds. If the
+     * stream does not exist, it will have no effect.
+     *
+     * @param streamID a streamID returned by the play() function
+     */
+    public native final void setPriority(int streamID, int priority);
+
+    /**
+     * Set loop mode.
+     *
+     * Change the loop mode. A loop value of -1 means loop forever,
+     * a value of 0 means don't loop, other values indicate the
+     * number of repeats, e.g. a value of 1 plays the audio twice.
+     * If the stream does not exist, it will have no effect.
+     *
+     * @param streamID a streamID returned by the play() function
+     * @param loop loop mode (0 = no loop, -1 = loop forever)
+     */
+    public native final void setLoop(int streamID, int loop);
+
+    /**
+     * Change playback rate.
+     *
+     * The playback rate allows the application to vary the playback
+     * rate (pitch) of the sound. A value of 1.0 means playback at
+     * the original frequency. A value of 2.0 means playback twice
+     * as fast, and a value of 0.5 means playback at half speed.
+     * If the stream does not exist, it will have no effect.
+     *
+     * @param streamID a streamID returned by the play() function
+     * @param rate playback rate (1.0 = normal playback, range 0.5 to 2.0)
+     */
+    public native final void setRate(int streamID, float rate);
+
+    public interface OnLoadCompleteListener {
+        /**
+         * Called when a sound has completed loading.
+         *
+         * @param soundPool SoundPool object from the load() method
+         * @param sampleId the sample ID of the sound loaded.
+         * @param status the status of the load operation (0 = success)
+         */
+        public void onLoadComplete(SoundPool soundPool, int sampleId, int status);
+    }
+
+    /**
+     * Sets the callback hook for the OnLoadCompleteListener.
+     */
+    public void setOnLoadCompleteListener(OnLoadCompleteListener listener) {
+        if (listener == null) {
+            mEventHandler.set(null);
+            return;
+        }
+
+        Looper looper;
+        if ((looper = Looper.myLooper()) != null) {
+            mEventHandler.set(new EventHandler(looper, listener));
+        } else if ((looper = Looper.getMainLooper()) != null) {
+            mEventHandler.set(new EventHandler(looper, listener));
+        } else {
+            mEventHandler.set(null);
+        }
+    }
+
+    private native final int _load(FileDescriptor fd, long offset, long length, int priority);
+
+    private native final int native_setup(Object weakRef, int maxStreams,
+            @NonNull Object/*AudioAttributes*/ attributes, @NonNull String opPackageName);
+
+    private native final int _play(int soundID, float leftVolume, float rightVolume,
+            int priority, int loop, float rate);
+
+    private native final void _setVolume(int streamID, float leftVolume, float rightVolume);
+
+    private native final void _mute(boolean muting);
+
+    // post event from native code to message handler
+    @SuppressWarnings("unchecked")
+    private static void postEventFromNative(Object ref, int msg, int arg1, int arg2, Object obj) {
+        SoundPool soundPool = ((WeakReference<SoundPool>) ref).get();
+        if (soundPool == null) {
+            return;
+        }
+
+        Handler eventHandler = soundPool.mEventHandler.get();
+        if (eventHandler == null) {
+            return;
+        }
+
+        Message message = eventHandler.obtainMessage(msg, arg1, arg2, obj);
+        eventHandler.sendMessage(message);
+    }
+
+    private final class EventHandler extends Handler {
+        private final OnLoadCompleteListener mOnLoadCompleteListener;
+
+        EventHandler(Looper looper, @NonNull OnLoadCompleteListener onLoadCompleteListener) {
+            super(looper);
+            mOnLoadCompleteListener = onLoadCompleteListener;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.what != SAMPLE_LOADED) {
+                Log.e(TAG, "Unknown message type " + msg.what);
+                return;
+            }
+
+            if (DEBUG) Log.d(TAG, "Sample " + msg.arg1 + " loaded");
+            mOnLoadCompleteListener.onLoadComplete(SoundPool.this, msg.arg1, msg.arg2);
+        }
+    }
+
+    /**
+     * Builder class for {@link SoundPool} objects.
+     */
+    public static class Builder {
+        private int mMaxStreams = 1;
+        private AudioAttributes mAudioAttributes;
+
+        /**
+         * Constructs a new Builder with the defaults format values.
+         * If not provided, the maximum number of streams is 1 (see {@link #setMaxStreams(int)} to
+         * change it), and the audio attributes have a usage value of
+         * {@link AudioAttributes#USAGE_MEDIA} (see {@link #setAudioAttributes(AudioAttributes)} to
+         * change them).
+         */
+        public Builder() {
+        }
+
+        /**
+         * Sets the maximum of number of simultaneous streams that can be played simultaneously.
+         * @param maxStreams a value equal to 1 or greater.
+         * @return the same Builder instance
+         * @throws IllegalArgumentException
+         */
+        public Builder setMaxStreams(int maxStreams) throws IllegalArgumentException {
+            if (maxStreams <= 0) {
+                throw new IllegalArgumentException(
+                        "Strictly positive value required for the maximum number of streams");
+            }
+            mMaxStreams = maxStreams;
+            return this;
+        }
+
+        /**
+         * Sets the {@link AudioAttributes}. For examples, game applications will use attributes
+         * built with usage information set to {@link AudioAttributes#USAGE_GAME}.
+         * @param attributes a non-null
+         * @return
+         */
+        public Builder setAudioAttributes(AudioAttributes attributes)
+                throws IllegalArgumentException {
+            if (attributes == null) {
+                throw new IllegalArgumentException("Invalid null AudioAttributes");
+            }
+            mAudioAttributes = attributes;
+            return this;
+        }
+
+        public SoundPool build() {
+            if (mAudioAttributes == null) {
+                mAudioAttributes = new AudioAttributes.Builder()
+                        .setUsage(AudioAttributes.USAGE_MEDIA).build();
+            }
+            return new SoundPool(mMaxStreams, mAudioAttributes);
+        }
+    }
+}
diff --git a/android/media/SubtitleController.java b/android/media/SubtitleController.java
new file mode 100644
index 0000000..48657a6
--- /dev/null
+++ b/android/media/SubtitleController.java
@@ -0,0 +1,514 @@
+/*
+ * Copyright (C) 2013 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.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.media.MediaPlayer.TrackInfo;
+import android.media.SubtitleTrack.RenderingWidget;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.view.accessibility.CaptioningManager;
+
+import java.util.Locale;
+import java.util.Vector;
+
+/**
+ * The subtitle controller provides the architecture to display subtitles for a
+ * media source.  It allows specifying which tracks to display, on which anchor
+ * to display them, and also allows adding external, out-of-band subtitle tracks.
+ *
+ * @hide
+ */
+public class SubtitleController {
+    private MediaTimeProvider mTimeProvider;
+    private Vector<Renderer> mRenderers;
+    private Vector<SubtitleTrack> mTracks;
+    private SubtitleTrack mSelectedTrack;
+    private boolean mShowing;
+    private CaptioningManager mCaptioningManager;
+    @UnsupportedAppUsage
+    private Handler mHandler;
+
+    private static final int WHAT_SHOW = 1;
+    private static final int WHAT_HIDE = 2;
+    private static final int WHAT_SELECT_TRACK = 3;
+    private static final int WHAT_SELECT_DEFAULT_TRACK = 4;
+
+    private final Handler.Callback mCallback = new Handler.Callback() {
+        @Override
+        public boolean handleMessage(Message msg) {
+            switch (msg.what) {
+            case WHAT_SHOW:
+                doShow();
+                return true;
+            case WHAT_HIDE:
+                doHide();
+                return true;
+            case WHAT_SELECT_TRACK:
+                doSelectTrack((SubtitleTrack)msg.obj);
+                return true;
+            case WHAT_SELECT_DEFAULT_TRACK:
+                doSelectDefaultTrack();
+                return true;
+            default:
+                return false;
+            }
+        }
+    };
+
+    private CaptioningManager.CaptioningChangeListener mCaptioningChangeListener =
+        new CaptioningManager.CaptioningChangeListener() {
+            /** @hide */
+            @Override
+            public void onEnabledChanged(boolean enabled) {
+                selectDefaultTrack();
+            }
+
+            /** @hide */
+            @Override
+            public void onLocaleChanged(Locale locale) {
+                selectDefaultTrack();
+            }
+        };
+
+    /**
+     * Creates a subtitle controller for a media playback object that implements
+     * the MediaTimeProvider interface.
+     *
+     * @param timeProvider
+     */
+    @UnsupportedAppUsage
+    public SubtitleController(
+            Context context,
+            MediaTimeProvider timeProvider,
+            Listener listener) {
+        mTimeProvider = timeProvider;
+        mListener = listener;
+
+        mRenderers = new Vector<Renderer>();
+        mShowing = false;
+        mTracks = new Vector<SubtitleTrack>();
+        mCaptioningManager =
+            (CaptioningManager)context.getSystemService(Context.CAPTIONING_SERVICE);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        mCaptioningManager.removeCaptioningChangeListener(
+                mCaptioningChangeListener);
+        super.finalize();
+    }
+
+    /**
+     * @return the available subtitle tracks for this media. These include
+     * the tracks found by {@link MediaPlayer} as well as any tracks added
+     * manually via {@link #addTrack}.
+     */
+    public SubtitleTrack[] getTracks() {
+        synchronized(mTracks) {
+            SubtitleTrack[] tracks = new SubtitleTrack[mTracks.size()];
+            mTracks.toArray(tracks);
+            return tracks;
+        }
+    }
+
+    /**
+     * @return the currently selected subtitle track
+     */
+    public SubtitleTrack getSelectedTrack() {
+        return mSelectedTrack;
+    }
+
+    private RenderingWidget getRenderingWidget() {
+        if (mSelectedTrack == null) {
+            return null;
+        }
+        return mSelectedTrack.getRenderingWidget();
+    }
+
+    /**
+     * Selects a subtitle track.  As a result, this track will receive
+     * in-band data from the {@link MediaPlayer}.  However, this does
+     * not change the subtitle visibility.
+     *
+     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
+     *
+     * @param track The subtitle track to select.  This must be one of the
+     *              tracks in {@link #getTracks}.
+     * @return true if the track was successfully selected.
+     */
+    public boolean selectTrack(SubtitleTrack track) {
+        if (track != null && !mTracks.contains(track)) {
+            return false;
+        }
+
+        processOnAnchor(mHandler.obtainMessage(WHAT_SELECT_TRACK, track));
+        return true;
+    }
+
+    private void doSelectTrack(SubtitleTrack track) {
+        mTrackIsExplicit = true;
+        if (mSelectedTrack == track) {
+            return;
+        }
+
+        if (mSelectedTrack != null) {
+            mSelectedTrack.hide();
+            mSelectedTrack.setTimeProvider(null);
+        }
+
+        mSelectedTrack = track;
+        if (mAnchor != null) {
+            mAnchor.setSubtitleWidget(getRenderingWidget());
+        }
+
+        if (mSelectedTrack != null) {
+            mSelectedTrack.setTimeProvider(mTimeProvider);
+            mSelectedTrack.show();
+        }
+
+        if (mListener != null) {
+            mListener.onSubtitleTrackSelected(track);
+        }
+    }
+
+    /**
+     * @return the default subtitle track based on system preferences, or null,
+     * if no such track exists in this manager.
+     *
+     * Supports HLS-flags: AUTOSELECT, FORCED & DEFAULT.
+     *
+     * 1. If captioning is disabled, only consider FORCED tracks. Otherwise,
+     * consider all tracks, but prefer non-FORCED ones.
+     * 2. If user selected "Default" caption language:
+     *   a. If there is a considered track with DEFAULT=yes, returns that track
+     *      (favor the first one in the current language if there are more than
+     *      one default tracks, or the first in general if none of them are in
+     *      the current language).
+     *   b. Otherwise, if there is a track with AUTOSELECT=yes in the current
+     *      language, return that one.
+     *   c. If there are no default tracks, and no autoselectable tracks in the
+     *      current language, return null.
+     * 3. If there is a track with the caption language, select that one.  Prefer
+     * the one with AUTOSELECT=no.
+     *
+     * The default values for these flags are DEFAULT=no, AUTOSELECT=yes
+     * and FORCED=no.
+     */
+    public SubtitleTrack getDefaultTrack() {
+        SubtitleTrack bestTrack = null;
+        int bestScore = -1;
+
+        Locale selectedLocale = mCaptioningManager.getLocale();
+        Locale locale = selectedLocale;
+        if (locale == null) {
+            locale = Locale.getDefault();
+        }
+        boolean selectForced = !mCaptioningManager.isEnabled();
+
+        synchronized(mTracks) {
+            for (SubtitleTrack track: mTracks) {
+                MediaFormat format = track.getFormat();
+                String language = format.getString(MediaFormat.KEY_LANGUAGE);
+                boolean forced =
+                    format.getInteger(MediaFormat.KEY_IS_FORCED_SUBTITLE, 0) != 0;
+                boolean autoselect =
+                    format.getInteger(MediaFormat.KEY_IS_AUTOSELECT, 1) != 0;
+                boolean is_default =
+                    format.getInteger(MediaFormat.KEY_IS_DEFAULT, 0) != 0;
+
+                boolean languageMatches =
+                    (locale == null ||
+                    locale.getLanguage().equals("") ||
+                    locale.getISO3Language().equals(language) ||
+                    locale.getLanguage().equals(language));
+                // is_default is meaningless unless caption language is 'default'
+                int score = (forced ? 0 : 8) +
+                    (((selectedLocale == null) && is_default) ? 4 : 0) +
+                    (autoselect ? 0 : 2) + (languageMatches ? 1 : 0);
+
+                if (selectForced && !forced) {
+                    continue;
+                }
+
+                // we treat null locale/language as matching any language
+                if ((selectedLocale == null && is_default) ||
+                    (languageMatches &&
+                     (autoselect || forced || selectedLocale != null))) {
+                    if (score > bestScore) {
+                        bestScore = score;
+                        bestTrack = track;
+                    }
+                }
+            }
+        }
+        return bestTrack;
+    }
+
+    private boolean mTrackIsExplicit = false;
+    private boolean mVisibilityIsExplicit = false;
+
+    /** @hide - should be called from anchor thread */
+    public void selectDefaultTrack() {
+        processOnAnchor(mHandler.obtainMessage(WHAT_SELECT_DEFAULT_TRACK));
+    }
+
+    private void doSelectDefaultTrack() {
+        if (mTrackIsExplicit) {
+            // If track selection is explicit, but visibility
+            // is not, it falls back to the captioning setting
+            if (!mVisibilityIsExplicit) {
+                if (mCaptioningManager.isEnabled() ||
+                    (mSelectedTrack != null &&
+                     mSelectedTrack.getFormat().getInteger(
+                            MediaFormat.KEY_IS_FORCED_SUBTITLE, 0) != 0)) {
+                    show();
+                } else if (mSelectedTrack != null
+                        && mSelectedTrack.getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
+                    hide();
+                }
+                mVisibilityIsExplicit = false;
+            }
+            return;
+        }
+
+        // We can have a default (forced) track even if captioning
+        // is not enabled.  This is handled by getDefaultTrack().
+        // Show this track unless subtitles were explicitly hidden.
+        SubtitleTrack track = getDefaultTrack();
+        if (track != null) {
+            selectTrack(track);
+            mTrackIsExplicit = false;
+            if (!mVisibilityIsExplicit) {
+                show();
+                mVisibilityIsExplicit = false;
+            }
+        }
+    }
+
+    /** @hide - must be called from anchor thread */
+    @UnsupportedAppUsage
+    public void reset() {
+        checkAnchorLooper();
+        hide();
+        selectTrack(null);
+        mTracks.clear();
+        mTrackIsExplicit = false;
+        mVisibilityIsExplicit = false;
+        mCaptioningManager.removeCaptioningChangeListener(
+                mCaptioningChangeListener);
+    }
+
+    /**
+     * Adds a new, external subtitle track to the manager.
+     *
+     * @param format the format of the track that will include at least
+     *               the MIME type {@link MediaFormat@KEY_MIME}.
+     * @return the created {@link SubtitleTrack} object
+     */
+    public SubtitleTrack addTrack(MediaFormat format) {
+        synchronized(mRenderers) {
+            for (Renderer renderer: mRenderers) {
+                if (renderer.supports(format)) {
+                    SubtitleTrack track = renderer.createTrack(format);
+                    if (track != null) {
+                        synchronized(mTracks) {
+                            if (mTracks.size() == 0) {
+                                mCaptioningManager.addCaptioningChangeListener(
+                                        mCaptioningChangeListener);
+                            }
+                            mTracks.add(track);
+                        }
+                        return track;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Show the selected (or default) subtitle track.
+     *
+     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
+     */
+    @UnsupportedAppUsage
+    public void show() {
+        processOnAnchor(mHandler.obtainMessage(WHAT_SHOW));
+    }
+
+    private void doShow() {
+        mShowing = true;
+        mVisibilityIsExplicit = true;
+        if (mSelectedTrack != null) {
+            mSelectedTrack.show();
+        }
+    }
+
+    /**
+     * Hide the selected (or default) subtitle track.
+     *
+     * Should be called from the anchor's (UI) thread. {@see #Anchor.getSubtitleLooper}
+     */
+    @UnsupportedAppUsage
+    public void hide() {
+        processOnAnchor(mHandler.obtainMessage(WHAT_HIDE));
+    }
+
+    private void doHide() {
+        mVisibilityIsExplicit = true;
+        if (mSelectedTrack != null) {
+            mSelectedTrack.hide();
+        }
+        mShowing = false;
+    }
+
+    /**
+     * Interface for supporting a single or multiple subtitle types in {@link
+     * MediaPlayer}.
+     */
+    public abstract static class Renderer {
+        /**
+         * Called by {@link MediaPlayer}'s {@link SubtitleController} when a new
+         * subtitle track is detected, to see if it should use this object to
+         * parse and display this subtitle track.
+         *
+         * @param format the format of the track that will include at least
+         *               the MIME type {@link MediaFormat@KEY_MIME}.
+         *
+         * @return true if and only if the track format is supported by this
+         * renderer
+         */
+        public abstract boolean supports(MediaFormat format);
+
+        /**
+         * Called by {@link MediaPlayer}'s {@link SubtitleController} for each
+         * subtitle track that was detected and is supported by this object to
+         * create a {@link SubtitleTrack} object.  This object will be created
+         * for each track that was found.  If the track is selected for display,
+         * this object will be used to parse and display the track data.
+         *
+         * @param format the format of the track that will include at least
+         *               the MIME type {@link MediaFormat@KEY_MIME}.
+         * @return a {@link SubtitleTrack} object that will be used to parse
+         * and render the subtitle track.
+         */
+        public abstract SubtitleTrack createTrack(MediaFormat format);
+    }
+
+    /**
+     * Add support for a subtitle format in {@link MediaPlayer}.
+     *
+     * @param renderer a {@link SubtitleController.Renderer} object that adds
+     *                 support for a subtitle format.
+     */
+    @UnsupportedAppUsage
+    public void registerRenderer(Renderer renderer) {
+        synchronized(mRenderers) {
+            // TODO how to get available renderers in the system
+            if (!mRenderers.contains(renderer)) {
+                // TODO should added renderers override existing ones (to allow replacing?)
+                mRenderers.add(renderer);
+            }
+        }
+    }
+
+    /** @hide */
+    public boolean hasRendererFor(MediaFormat format) {
+        synchronized(mRenderers) {
+            // TODO how to get available renderers in the system
+            for (Renderer renderer: mRenderers) {
+                if (renderer.supports(format)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * Subtitle anchor, an object that is able to display a subtitle renderer,
+     * e.g. a VideoView.
+     */
+    public interface Anchor {
+        /**
+         * Anchor should use the supplied subtitle rendering widget, or
+         * none if it is null.
+         * @hide
+         */
+        public void setSubtitleWidget(RenderingWidget subtitleWidget);
+
+        /**
+         * Anchors provide the looper on which all track visibility changes
+         * (track.show/hide, setSubtitleWidget) will take place.
+         * @hide
+         */
+        public Looper getSubtitleLooper();
+    }
+
+    private Anchor mAnchor;
+
+    /**
+     *  @hide - called from anchor's looper (if any, both when unsetting and
+     *  setting)
+     */
+    public void setAnchor(Anchor anchor) {
+        if (mAnchor == anchor) {
+            return;
+        }
+
+        if (mAnchor != null) {
+            checkAnchorLooper();
+            mAnchor.setSubtitleWidget(null);
+        }
+        mAnchor = anchor;
+        mHandler = null;
+        if (mAnchor != null) {
+            mHandler = new Handler(mAnchor.getSubtitleLooper(), mCallback);
+            checkAnchorLooper();
+            mAnchor.setSubtitleWidget(getRenderingWidget());
+        }
+    }
+
+    private void checkAnchorLooper() {
+        assert mHandler != null : "Should have a looper already";
+        assert Looper.myLooper() == mHandler.getLooper() : "Must be called from the anchor's looper";
+    }
+
+    private void processOnAnchor(Message m) {
+        assert mHandler != null : "Should have a looper already";
+        if (Looper.myLooper() == mHandler.getLooper()) {
+            mHandler.dispatchMessage(m);
+        } else {
+            mHandler.sendMessage(m);
+        }
+    }
+
+    public interface Listener {
+        /**
+         * Called when a subtitle track has been selected.
+         *
+         * @param track selected subtitle track or null
+         * @hide
+         */
+        public void onSubtitleTrackSelected(SubtitleTrack track);
+    }
+
+    private Listener mListener;
+}
diff --git a/android/media/SubtitleData.java b/android/media/SubtitleData.java
new file mode 100644
index 0000000..2ef6982
--- /dev/null
+++ b/android/media/SubtitleData.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2011 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.annotation.NonNull;
+import android.os.Parcel;
+
+/**
+ * Class encapsulating subtitle data, as received through the
+ * {@link MediaPlayer.OnSubtitleDataListener} interface.
+ * The subtitle data includes:
+ * <ul>
+ * <li> the track index</li>
+ * <li> the start time (in microseconds) of the data</li>
+ * <li> the duration (in microseconds) of the data</li>
+ * <li> the actual data.</li>
+ * </ul>
+ * The data is stored in a byte-array, and is encoded in one of the supported in-band
+ * subtitle formats. The subtitle encoding is determined by the MIME type of the
+ * {@link MediaPlayer.TrackInfo} of the subtitle track, one of
+ * {@link MediaFormat#MIMETYPE_TEXT_CEA_608}, {@link MediaFormat#MIMETYPE_TEXT_CEA_708},
+ * {@link MediaFormat#MIMETYPE_TEXT_VTT}.
+ * <p>
+ * Here is an example of iterating over the tracks of a {@link MediaPlayer}, and checking which
+ * encoding is used for the subtitle tracks:
+ * <p>
+ * <pre class="prettyprint">
+ * MediaPlayer mp = new MediaPlayer();
+ * mp.setDataSource(myContentLocation);
+ * mp.prepare(); // synchronous prepare, ready to use when method returns
+ * final TrackInfo[] trackInfos = mp.getTrackInfo();
+ * for (TrackInfo info : trackInfo) {
+ *     if (info.getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
+ *         final String mime = info.getFormat().getString(MediaFormat.KEY_MIME);
+ *         if (MediaFormat.MIMETYPE_TEXT_CEA_608.equals(mime) {
+ *             // subtitle encoding is CEA 608
+ *         } else if (MediaFormat.MIMETYPE_TEXT_CEA_708.equals(mime) {
+ *             // subtitle encoding is CEA 708
+ *         } else if (MediaFormat.MIMETYPE_TEXT_VTT.equals(mime) {
+ *             // subtitle encoding is WebVTT
+ *         }
+ *     }
+ * }
+ * </pre>
+ * <p>
+ * See
+ * {@link MediaPlayer#setOnSubtitleDataListener(android.media.MediaPlayer.OnSubtitleDataListener, android.os.Handler)}
+ * to receive subtitle data from a MediaPlayer object.
+ *
+ * @see android.media.MediaPlayer
+ */
+public final class SubtitleData
+{
+    private static final String TAG = "SubtitleData";
+
+    private int mTrackIndex;
+    private long mStartTimeUs;
+    private long mDurationUs;
+    private byte[] mData;
+
+    /** @hide */
+    public SubtitleData(Parcel parcel) {
+        if (!parseParcel(parcel)) {
+            throw new IllegalArgumentException("parseParcel() fails");
+        }
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param trackIndex the index of the media player track which contains this subtitle data.
+     * @param startTimeUs the start time in microsecond for the subtitle data
+     * @param durationUs the duration in microsecond for the subtitle data
+     * @param data the data array for the subtitle data. It should not be null.
+     *            No data copying is made.
+     */
+    public SubtitleData(int trackIndex, long startTimeUs, long durationUs, @NonNull byte[] data) {
+        if (data == null) {
+            throw new IllegalArgumentException("null data is not allowed");
+        }
+        mTrackIndex = trackIndex;
+        mStartTimeUs = startTimeUs;
+        mDurationUs = durationUs;
+        mData = data;
+    }
+
+    /**
+     * Returns the index of the media player track which contains this subtitle data.
+     * @return an index in the array returned by {@link MediaPlayer#getTrackInfo()}.
+     */
+    public int getTrackIndex() {
+        return mTrackIndex;
+    }
+
+    /**
+     * Returns the media time at which the subtitle should be displayed, expressed in microseconds.
+     * @return the display start time for the subtitle
+     */
+    public long getStartTimeUs() {
+        return mStartTimeUs;
+    }
+
+    /**
+     * Returns the duration in microsecond during which the subtitle should be displayed.
+     * @return the display duration for the subtitle
+     */
+    public long getDurationUs() {
+        return mDurationUs;
+    }
+
+    /**
+     * Returns the encoded data for the subtitle content.
+     * Encoding format depends on the subtitle type, refer to
+     * <a href="https://en.wikipedia.org/wiki/CEA-708">CEA 708</a>,
+     * <a href="https://en.wikipedia.org/wiki/EIA-608">CEA/EIA 608</a> and
+     * <a href="https://www.w3.org/TR/webvtt1/">WebVTT</a>, defined by the MIME type
+     * of the subtitle track.
+     * @return the encoded subtitle data
+     */
+    public @NonNull byte[] getData() {
+        return mData;
+    }
+
+    private boolean parseParcel(Parcel parcel) {
+        parcel.setDataPosition(0);
+        if (parcel.dataAvail() == 0) {
+            return false;
+        }
+
+        mTrackIndex = parcel.readInt();
+        mStartTimeUs = parcel.readLong();
+        mDurationUs = parcel.readLong();
+        mData = new byte[parcel.readInt()];
+        parcel.readByteArray(mData);
+
+        return true;
+    }
+}
diff --git a/android/media/SubtitleTrack.java b/android/media/SubtitleTrack.java
new file mode 100644
index 0000000..10669f4
--- /dev/null
+++ b/android/media/SubtitleTrack.java
@@ -0,0 +1,734 @@
+/*
+ * Copyright (C) 2013 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.compat.annotation.UnsupportedAppUsage;
+import android.graphics.Canvas;
+import android.media.MediaPlayer.TrackInfo;
+import android.os.Handler;
+import android.util.Log;
+import android.util.LongSparseArray;
+import android.util.Pair;
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.Vector;
+
+/**
+ * A subtitle track abstract base class that is responsible for parsing and displaying
+ * an instance of a particular type of subtitle.
+ *
+ * @hide
+ */
+public abstract class SubtitleTrack implements MediaTimeProvider.OnMediaTimeListener {
+    private static final String TAG = "SubtitleTrack";
+    private long mLastUpdateTimeMs;
+    private long mLastTimeMs;
+
+    private Runnable mRunnable;
+
+    /** @hide TODO private */
+    final protected LongSparseArray<Run> mRunsByEndTime = new LongSparseArray<Run>();
+    /** @hide TODO private */
+    final protected LongSparseArray<Run> mRunsByID = new LongSparseArray<Run>();
+
+    /** @hide TODO private */
+    protected CueList mCues;
+    /** @hide TODO private */
+    final protected Vector<Cue> mActiveCues = new Vector<Cue>();
+    /** @hide */
+    protected boolean mVisible;
+
+    /** @hide */
+    public boolean DEBUG = false;
+
+    /** @hide */
+    protected Handler mHandler = new Handler();
+
+    private MediaFormat mFormat;
+
+    public SubtitleTrack(MediaFormat format) {
+        mFormat = format;
+        mCues = new CueList();
+        clearActiveCues();
+        mLastTimeMs = -1;
+    }
+
+    /** @hide */
+    public final MediaFormat getFormat() {
+        return mFormat;
+    }
+
+    private long mNextScheduledTimeMs = -1;
+
+    protected void onData(SubtitleData data) {
+        long runID = data.getStartTimeUs() + 1;
+        onData(data.getData(), true /* eos */, runID);
+        setRunDiscardTimeMs(
+                runID,
+                (data.getStartTimeUs() + data.getDurationUs()) / 1000);
+    }
+
+    /**
+     * Called when there is input data for the subtitle track.  The
+     * complete subtitle for a track can include multiple whole units
+     * (runs).  Each of these units can have multiple sections.  The
+     * contents of a run are submitted in sequential order, with eos
+     * indicating the last section of the run.  Calls from different
+     * runs must not be intermixed.
+     *
+     * @param data subtitle data byte buffer
+     * @param eos true if this is the last section of the run.
+     * @param runID mostly-unique ID for this run of data.  Subtitle cues
+     *              with runID of 0 are discarded immediately after
+     *              display.  Cues with runID of ~0 are discarded
+     *              only at the deletion of the track object.  Cues
+     *              with other runID-s are discarded at the end of the
+     *              run, which defaults to the latest timestamp of
+     *              any of its cues (with this runID).
+     */
+    public abstract void onData(byte[] data, boolean eos, long runID);
+
+    /**
+     * Called when adding the subtitle rendering widget to the view hierarchy,
+     * as well as when showing or hiding the subtitle track, or when the video
+     * surface position has changed.
+     *
+     * @return the widget that renders this subtitle track. For most renderers
+     *         there should be a single shared instance that is used for all
+     *         tracks supported by that renderer, as at most one subtitle track
+     *         is visible at one time.
+     */
+    public abstract RenderingWidget getRenderingWidget();
+
+    /**
+     * Called when the active cues have changed, and the contents of the subtitle
+     * view should be updated.
+     *
+     * @hide
+     */
+    public abstract void updateView(Vector<Cue> activeCues);
+
+    /** @hide */
+    protected synchronized void updateActiveCues(boolean rebuild, long timeMs) {
+        // out-of-order times mean seeking or new active cues being added
+        // (during their own timespan)
+        if (rebuild || mLastUpdateTimeMs > timeMs) {
+            clearActiveCues();
+        }
+
+        for(Iterator<Pair<Long, Cue> > it =
+                mCues.entriesBetween(mLastUpdateTimeMs, timeMs).iterator(); it.hasNext(); ) {
+            Pair<Long, Cue> event = it.next();
+            Cue cue = event.second;
+
+            if (cue.mEndTimeMs == event.first) {
+                // remove past cues
+                if (DEBUG) Log.v(TAG, "Removing " + cue);
+                mActiveCues.remove(cue);
+                if (cue.mRunID == 0) {
+                    it.remove();
+                }
+            } else if (cue.mStartTimeMs == event.first) {
+                // add new cues
+                // TRICKY: this will happen in start order
+                if (DEBUG) Log.v(TAG, "Adding " + cue);
+                if (cue.mInnerTimesMs != null) {
+                    cue.onTime(timeMs);
+                }
+                mActiveCues.add(cue);
+            } else if (cue.mInnerTimesMs != null) {
+                // cue is modified
+                cue.onTime(timeMs);
+            }
+        }
+
+        /* complete any runs */
+        while (mRunsByEndTime.size() > 0 &&
+               mRunsByEndTime.keyAt(0) <= timeMs) {
+            removeRunsByEndTimeIndex(0); // removes element
+        }
+        mLastUpdateTimeMs = timeMs;
+    }
+
+    private void removeRunsByEndTimeIndex(int ix) {
+        Run run = mRunsByEndTime.valueAt(ix);
+        while (run != null) {
+            Cue cue = run.mFirstCue;
+            while (cue != null) {
+                mCues.remove(cue);
+                Cue nextCue = cue.mNextInRun;
+                cue.mNextInRun = null;
+                cue = nextCue;
+            }
+            mRunsByID.remove(run.mRunID);
+            Run nextRun = run.mNextRunAtEndTimeMs;
+            run.mPrevRunAtEndTimeMs = null;
+            run.mNextRunAtEndTimeMs = null;
+            run = nextRun;
+        }
+        mRunsByEndTime.removeAt(ix);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        /* remove all cues (untangle all cross-links) */
+        int size = mRunsByEndTime.size();
+        for(int ix = size - 1; ix >= 0; ix--) {
+            removeRunsByEndTimeIndex(ix);
+        }
+
+        super.finalize();
+    }
+
+    private synchronized void takeTime(long timeMs) {
+        mLastTimeMs = timeMs;
+    }
+
+    /** @hide */
+    protected synchronized void clearActiveCues() {
+        if (DEBUG) Log.v(TAG, "Clearing " + mActiveCues.size() + " active cues");
+        mActiveCues.clear();
+        mLastUpdateTimeMs = -1;
+    }
+
+    /** @hide */
+    protected void scheduleTimedEvents() {
+        /* get times for the next event */
+        if (mTimeProvider != null) {
+            mNextScheduledTimeMs = mCues.nextTimeAfter(mLastTimeMs);
+            if (DEBUG) Log.d(TAG, "sched @" + mNextScheduledTimeMs + " after " + mLastTimeMs);
+            mTimeProvider.notifyAt(
+                    mNextScheduledTimeMs >= 0 ?
+                        (mNextScheduledTimeMs * 1000) : MediaTimeProvider.NO_TIME,
+                    this);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void onTimedEvent(long timeUs) {
+        if (DEBUG) Log.d(TAG, "onTimedEvent " + timeUs);
+        synchronized (this) {
+            long timeMs = timeUs / 1000;
+            updateActiveCues(false, timeMs);
+            takeTime(timeMs);
+        }
+        updateView(mActiveCues);
+        scheduleTimedEvents();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void onSeek(long timeUs) {
+        if (DEBUG) Log.d(TAG, "onSeek " + timeUs);
+        synchronized (this) {
+            long timeMs = timeUs / 1000;
+            updateActiveCues(true, timeMs);
+            takeTime(timeMs);
+        }
+        updateView(mActiveCues);
+        scheduleTimedEvents();
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public void onStop() {
+        synchronized (this) {
+            if (DEBUG) Log.d(TAG, "onStop");
+            clearActiveCues();
+            mLastTimeMs = -1;
+        }
+        updateView(mActiveCues);
+        mNextScheduledTimeMs = -1;
+        if (mTimeProvider != null) {
+            mTimeProvider.notifyAt(MediaTimeProvider.NO_TIME, this);
+        }
+    }
+
+    /** @hide */
+    protected MediaTimeProvider mTimeProvider;
+
+    /** @hide */
+    public void show() {
+        if (mVisible) {
+            return;
+        }
+
+        mVisible = true;
+        RenderingWidget renderingWidget = getRenderingWidget();
+        if (renderingWidget != null) {
+            renderingWidget.setVisible(true);
+        }
+        if (mTimeProvider != null) {
+            mTimeProvider.scheduleUpdate(this);
+        }
+    }
+
+    /** @hide */
+    public void hide() {
+        if (!mVisible) {
+            return;
+        }
+
+        if (mTimeProvider != null) {
+            mTimeProvider.cancelNotifications(this);
+        }
+        RenderingWidget renderingWidget = getRenderingWidget();
+        if (renderingWidget != null) {
+            renderingWidget.setVisible(false);
+        }
+        mVisible = false;
+    }
+
+    /** @hide */
+    protected synchronized boolean addCue(Cue cue) {
+        mCues.add(cue);
+
+        if (cue.mRunID != 0) {
+            Run run = mRunsByID.get(cue.mRunID);
+            if (run == null) {
+                run = new Run();
+                mRunsByID.put(cue.mRunID, run);
+                run.mEndTimeMs = cue.mEndTimeMs;
+            } else if (run.mEndTimeMs < cue.mEndTimeMs) {
+                run.mEndTimeMs = cue.mEndTimeMs;
+            }
+
+            // link-up cues in the same run
+            cue.mNextInRun = run.mFirstCue;
+            run.mFirstCue = cue;
+        }
+
+        // if a cue is added that should be visible, need to refresh view
+        long nowMs = -1;
+        if (mTimeProvider != null) {
+            try {
+                nowMs = mTimeProvider.getCurrentTimeUs(
+                        false /* precise */, true /* monotonic */) / 1000;
+            } catch (IllegalStateException e) {
+                // handle as it we are not playing
+            }
+        }
+
+        if (DEBUG) Log.v(TAG, "mVisible=" + mVisible + ", " +
+                cue.mStartTimeMs + " <= " + nowMs + ", " +
+                cue.mEndTimeMs + " >= " + mLastTimeMs);
+
+        if (mVisible &&
+                cue.mStartTimeMs <= nowMs &&
+                // we don't trust nowMs, so check any cue since last callback
+                cue.mEndTimeMs >= mLastTimeMs) {
+            if (mRunnable != null) {
+                mHandler.removeCallbacks(mRunnable);
+            }
+            final SubtitleTrack track = this;
+            final long thenMs = nowMs;
+            mRunnable = new Runnable() {
+                @Override
+                public void run() {
+                    // even with synchronized, it is possible that we are going
+                    // to do multiple updates as the runnable could be already
+                    // running.
+                    synchronized (track) {
+                        mRunnable = null;
+                        updateActiveCues(true, thenMs);
+                        updateView(mActiveCues);
+                    }
+                }
+            };
+            // delay update so we don't update view on every cue.  TODO why 10?
+            if (mHandler.postDelayed(mRunnable, 10 /* delay */)) {
+                if (DEBUG) Log.v(TAG, "scheduling update");
+            } else {
+                if (DEBUG) Log.w(TAG, "failed to schedule subtitle view update");
+            }
+            return true;
+        }
+
+        if (mVisible &&
+                cue.mEndTimeMs >= mLastTimeMs &&
+                (cue.mStartTimeMs < mNextScheduledTimeMs ||
+                 mNextScheduledTimeMs < 0)) {
+            scheduleTimedEvents();
+        }
+
+        return false;
+    }
+
+    /** @hide */
+    public synchronized void setTimeProvider(MediaTimeProvider timeProvider) {
+        if (mTimeProvider == timeProvider) {
+            return;
+        }
+        if (mTimeProvider != null) {
+            mTimeProvider.cancelNotifications(this);
+        }
+        mTimeProvider = timeProvider;
+        if (mTimeProvider != null) {
+            mTimeProvider.scheduleUpdate(this);
+        }
+    }
+
+
+    /** @hide */
+    static class CueList {
+        private static final String TAG = "CueList";
+        // simplistic, inefficient implementation
+        private SortedMap<Long, Vector<Cue> > mCues;
+        public boolean DEBUG = false;
+
+        private boolean addEvent(Cue cue, long timeMs) {
+            Vector<Cue> cues = mCues.get(timeMs);
+            if (cues == null) {
+                cues = new Vector<Cue>(2);
+                mCues.put(timeMs, cues);
+            } else if (cues.contains(cue)) {
+                // do not duplicate cues
+                return false;
+            }
+
+            cues.add(cue);
+            return true;
+        }
+
+        private void removeEvent(Cue cue, long timeMs) {
+            Vector<Cue> cues = mCues.get(timeMs);
+            if (cues != null) {
+                cues.remove(cue);
+                if (cues.size() == 0) {
+                    mCues.remove(timeMs);
+                }
+            }
+        }
+
+        public void add(Cue cue) {
+            // ignore non-positive-duration cues
+            if (cue.mStartTimeMs >= cue.mEndTimeMs)
+                return;
+
+            if (!addEvent(cue, cue.mStartTimeMs)) {
+                return;
+            }
+
+            long lastTimeMs = cue.mStartTimeMs;
+            if (cue.mInnerTimesMs != null) {
+                for (long timeMs: cue.mInnerTimesMs) {
+                    if (timeMs > lastTimeMs && timeMs < cue.mEndTimeMs) {
+                        addEvent(cue, timeMs);
+                        lastTimeMs = timeMs;
+                    }
+                }
+            }
+
+            addEvent(cue, cue.mEndTimeMs);
+        }
+
+        public void remove(Cue cue) {
+            removeEvent(cue, cue.mStartTimeMs);
+            if (cue.mInnerTimesMs != null) {
+                for (long timeMs: cue.mInnerTimesMs) {
+                    removeEvent(cue, timeMs);
+                }
+            }
+            removeEvent(cue, cue.mEndTimeMs);
+        }
+
+        public Iterable<Pair<Long, Cue>> entriesBetween(
+                final long lastTimeMs, final long timeMs) {
+            return new Iterable<Pair<Long, Cue> >() {
+                @Override
+                public Iterator<Pair<Long, Cue> > iterator() {
+                    if (DEBUG) Log.d(TAG, "slice (" + lastTimeMs + ", " + timeMs + "]=");
+                    try {
+                        return new EntryIterator(
+                                mCues.subMap(lastTimeMs + 1, timeMs + 1));
+                    } catch(IllegalArgumentException e) {
+                        return new EntryIterator(null);
+                    }
+                }
+            };
+        }
+
+        public long nextTimeAfter(long timeMs) {
+            SortedMap<Long, Vector<Cue>> tail = null;
+            try {
+                tail = mCues.tailMap(timeMs + 1);
+                if (tail != null) {
+                    return tail.firstKey();
+                } else {
+                    return -1;
+                }
+            } catch(IllegalArgumentException e) {
+                return -1;
+            } catch(NoSuchElementException e) {
+                return -1;
+            }
+        }
+
+        class EntryIterator implements Iterator<Pair<Long, Cue> > {
+            @Override
+            public boolean hasNext() {
+                return !mDone;
+            }
+
+            @Override
+            public Pair<Long, Cue> next() {
+                if (mDone) {
+                    throw new NoSuchElementException("");
+                }
+                mLastEntry = new Pair<Long, Cue>(
+                        mCurrentTimeMs, mListIterator.next());
+                mLastListIterator = mListIterator;
+                if (!mListIterator.hasNext()) {
+                    nextKey();
+                }
+                return mLastEntry;
+            }
+
+            @Override
+            public void remove() {
+                // only allow removing end tags
+                if (mLastListIterator == null ||
+                        mLastEntry.second.mEndTimeMs != mLastEntry.first) {
+                    throw new IllegalStateException("");
+                }
+
+                // remove end-cue
+                mLastListIterator.remove();
+                mLastListIterator = null;
+                if (mCues.get(mLastEntry.first).size() == 0) {
+                    mCues.remove(mLastEntry.first);
+                }
+
+                // remove rest of the cues
+                Cue cue = mLastEntry.second;
+                removeEvent(cue, cue.mStartTimeMs);
+                if (cue.mInnerTimesMs != null) {
+                    for (long timeMs: cue.mInnerTimesMs) {
+                        removeEvent(cue, timeMs);
+                    }
+                }
+            }
+
+            public EntryIterator(SortedMap<Long, Vector<Cue> > cues) {
+                if (DEBUG) Log.v(TAG, cues + "");
+                mRemainingCues = cues;
+                mLastListIterator = null;
+                nextKey();
+            }
+
+            private void nextKey() {
+                do {
+                    try {
+                        if (mRemainingCues == null) {
+                            throw new NoSuchElementException("");
+                        }
+                        mCurrentTimeMs = mRemainingCues.firstKey();
+                        mListIterator =
+                            mRemainingCues.get(mCurrentTimeMs).iterator();
+                        try {
+                            mRemainingCues =
+                                mRemainingCues.tailMap(mCurrentTimeMs + 1);
+                        } catch (IllegalArgumentException e) {
+                            mRemainingCues = null;
+                        }
+                        mDone = false;
+                    } catch (NoSuchElementException e) {
+                        mDone = true;
+                        mRemainingCues = null;
+                        mListIterator = null;
+                        return;
+                    }
+                } while (!mListIterator.hasNext());
+            }
+
+            private long mCurrentTimeMs;
+            private Iterator<Cue> mListIterator;
+            private boolean mDone;
+            private SortedMap<Long, Vector<Cue> > mRemainingCues;
+            private Iterator<Cue> mLastListIterator;
+            private Pair<Long,Cue> mLastEntry;
+        }
+
+        CueList() {
+            mCues = new TreeMap<Long, Vector<Cue>>();
+        }
+    }
+
+    /** @hide */
+    public static class Cue {
+        public long mStartTimeMs;
+        public long mEndTimeMs;
+        public long[] mInnerTimesMs;
+        public long mRunID;
+
+        /** @hide */
+        public Cue mNextInRun;
+
+        public void onTime(long timeMs) { }
+    }
+
+    /** @hide update mRunsByEndTime (with default end time) */
+    protected void finishedRun(long runID) {
+        if (runID != 0 && runID != ~0) {
+            Run run = mRunsByID.get(runID);
+            if (run != null) {
+                run.storeByEndTimeMs(mRunsByEndTime);
+            }
+        }
+    }
+
+    /** @hide update mRunsByEndTime with given end time */
+    public void setRunDiscardTimeMs(long runID, long timeMs) {
+        if (runID != 0 && runID != ~0) {
+            Run run = mRunsByID.get(runID);
+            if (run != null) {
+                run.mEndTimeMs = timeMs;
+                run.storeByEndTimeMs(mRunsByEndTime);
+            }
+        }
+    }
+
+    /** @hide whether this is a text track who fires events instead getting rendered */
+    public int getTrackType() {
+        return getRenderingWidget() == null
+                ? TrackInfo.MEDIA_TRACK_TYPE_TIMEDTEXT
+                : TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE;
+    }
+
+
+    /** @hide */
+    private static class Run {
+        public Cue mFirstCue;
+        public Run mNextRunAtEndTimeMs;
+        public Run mPrevRunAtEndTimeMs;
+        public long mEndTimeMs = -1;
+        public long mRunID = 0;
+        private long mStoredEndTimeMs = -1;
+
+        public void storeByEndTimeMs(LongSparseArray<Run> runsByEndTime) {
+            // remove old value if any
+            int ix = runsByEndTime.indexOfKey(mStoredEndTimeMs);
+            if (ix >= 0) {
+                if (mPrevRunAtEndTimeMs == null) {
+                    assert(this == runsByEndTime.valueAt(ix));
+                    if (mNextRunAtEndTimeMs == null) {
+                        runsByEndTime.removeAt(ix);
+                    } else {
+                        runsByEndTime.setValueAt(ix, mNextRunAtEndTimeMs);
+                    }
+                }
+                removeAtEndTimeMs();
+            }
+
+            // add new value
+            if (mEndTimeMs >= 0) {
+                mPrevRunAtEndTimeMs = null;
+                mNextRunAtEndTimeMs = runsByEndTime.get(mEndTimeMs);
+                if (mNextRunAtEndTimeMs != null) {
+                    mNextRunAtEndTimeMs.mPrevRunAtEndTimeMs = this;
+                }
+                runsByEndTime.put(mEndTimeMs, this);
+                mStoredEndTimeMs = mEndTimeMs;
+            }
+        }
+
+        public void removeAtEndTimeMs() {
+            Run prev = mPrevRunAtEndTimeMs;
+
+            if (mPrevRunAtEndTimeMs != null) {
+                mPrevRunAtEndTimeMs.mNextRunAtEndTimeMs = mNextRunAtEndTimeMs;
+                mPrevRunAtEndTimeMs = null;
+            }
+            if (mNextRunAtEndTimeMs != null) {
+                mNextRunAtEndTimeMs.mPrevRunAtEndTimeMs = prev;
+                mNextRunAtEndTimeMs = null;
+            }
+        }
+    }
+
+    /**
+     * Interface for rendering subtitles onto a Canvas.
+     */
+    public interface RenderingWidget {
+        /**
+         * Sets the widget's callback, which is used to send updates when the
+         * rendered data has changed.
+         *
+         * @param callback update callback
+         */
+        @UnsupportedAppUsage
+        public void setOnChangedListener(OnChangedListener callback);
+
+        /**
+         * Sets the widget's size.
+         *
+         * @param width width in pixels
+         * @param height height in pixels
+         */
+        @UnsupportedAppUsage
+        public void setSize(int width, int height);
+
+        /**
+         * Sets whether the widget should draw subtitles.
+         *
+         * @param visible true if subtitles should be drawn, false otherwise
+         */
+        public void setVisible(boolean visible);
+
+        /**
+         * Renders subtitles onto a {@link Canvas}.
+         *
+         * @param c canvas on which to render subtitles
+         */
+        @UnsupportedAppUsage
+        public void draw(Canvas c);
+
+        /**
+         * Called when the widget is attached to a window.
+         */
+        @UnsupportedAppUsage
+        public void onAttachedToWindow();
+
+        /**
+         * Called when the widget is detached from a window.
+         */
+        @UnsupportedAppUsage
+        public void onDetachedFromWindow();
+
+        /**
+         * Callback used to send updates about changes to rendering data.
+         */
+        public interface OnChangedListener {
+            /**
+             * Called when the rendering data has changed.
+             *
+             * @param renderingWidget the widget whose data has changed
+             */
+            public void onChanged(RenderingWidget renderingWidget);
+        }
+    }
+}
diff --git a/android/media/SyncParams.java b/android/media/SyncParams.java
new file mode 100644
index 0000000..5d1575a
--- /dev/null
+++ b/android/media/SyncParams.java
@@ -0,0 +1,282 @@
+/*
+ * Copyright 2015 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 java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+import android.annotation.IntDef;
+
+/**
+ * Structure for common A/V sync params.
+ *
+ * Used by {@link MediaSync} {link MediaSync#getSyncParams()} and
+ * {link MediaSync#setSyncParams(SyncParams)}
+ * to control A/V sync behavior.
+ * <p> <strong>audio adjust mode:</strong>
+ * select handling of audio track when changing playback speed due to sync.
+ * <ul>
+ * <li> {@link SyncParams#AUDIO_ADJUST_MODE_DEFAULT}:
+ *   System will determine best handling. </li>
+ * <li> {@link SyncParams#AUDIO_ADJUST_MODE_STRETCH}:
+ *   Change the speed of audio playback without altering its pitch.</li>
+ * <li> {@link SyncParams#AUDIO_ADJUST_MODE_RESAMPLE}:
+ *   Change the speed of audio playback by resampling the audio.</li>
+ * </ul>
+ * <p> <strong>sync source:</strong> select
+ * clock source for sync.
+ * <ul>
+ * <li> {@link SyncParams#SYNC_SOURCE_DEFAULT}:
+ *   System will determine best selection.</li>
+ * <li> {@link SyncParams#SYNC_SOURCE_SYSTEM_CLOCK}:
+ *   Use system clock for sync source.</li>
+ * <li> {@link SyncParams#SYNC_SOURCE_AUDIO}:
+ *   Use audio track for sync source.</li>
+ * <li> {@link SyncParams#SYNC_SOURCE_VSYNC}:
+ *   Syncronize media to vsync.</li>
+ * </ul>
+ * <p> <strong>tolerance:</strong> specifies the amount of allowed playback rate
+ * change to keep media in sync with the sync source. The handling of this depends
+ * on the sync source, but must not be negative, and must be less than one.
+ * <p> <strong>frameRate:</strong> initial hint for video frame rate. Used when
+ * sync source is vsync. Negative values can be used to clear a previous hint.
+ */
+public final class SyncParams {
+    /** @hide */
+    @IntDef(
+        value = {
+                SYNC_SOURCE_DEFAULT,
+                SYNC_SOURCE_SYSTEM_CLOCK,
+                SYNC_SOURCE_AUDIO,
+                SYNC_SOURCE_VSYNC,
+        }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SyncSource {}
+
+    /**
+     * Use the default sync source (default). If media has video, the sync renders to a
+     * surface that directly renders to a display, and tolerance is non zero (e.g. not
+     * less than 0.001) vsync source is used for clock source.  Otherwise, if media has
+     * audio, audio track is used. Finally, if media has no audio, system clock is used.
+     */
+    public static final int SYNC_SOURCE_DEFAULT = 0;
+
+    /**
+     * Use system monotonic clock for sync source.
+     *
+     * @see System#nanoTime
+     */
+    public static final int SYNC_SOURCE_SYSTEM_CLOCK = 1;
+
+    /**
+     * Use audio track for sync source. This requires audio data and an audio track.
+     *
+     * @see android.media.AudioTrack#getTimestamp(android.media.AudioTimestamp)
+     */
+    public static final int SYNC_SOURCE_AUDIO = 2;
+
+    /**
+     * Use vsync as the sync source. This requires video data and an output surface that
+     * directly renders to the display, e.g. {@link android.view.SurfaceView}
+     * <p>
+     * This mode allows smoother playback experience by adjusting the playback speed
+     * to match the vsync rate, e.g. playing 30fps content on a 59.94Hz display.
+     * When using this mode, the tolerance should be set to greater than 0 (e.g. at least
+     * 1/1000), so that the playback speed can actually be adjusted.
+     * <p>
+     * This mode can also be used to play 25fps content on a 60Hz display using
+     * a 2:3 pulldown (basically playing the content at 24fps), which results on
+     * better playback experience on most devices. In this case the tolerance should be
+     * at least (1/24).
+     *
+     * @see android.view.Choreographer.FrameCallback#doFrame
+     * @see android.view.Display#getAppVsyncOffsetNanos
+     */
+    public static final int SYNC_SOURCE_VSYNC = 3;
+
+    /** @hide */
+    @IntDef(
+        value = {
+                AUDIO_ADJUST_MODE_DEFAULT,
+                AUDIO_ADJUST_MODE_STRETCH,
+                AUDIO_ADJUST_MODE_RESAMPLE,
+        }
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioAdjustMode {}
+
+    /**
+     * System will determine best handling of audio for playback rate
+     * adjustments.
+     * <p>
+     * Used by default. This will make audio play faster or slower as required
+     * by the sync source without changing its pitch; however, system may fall
+     * back to some other method (e.g. change the pitch, or mute the audio) if
+     * time stretching is no longer supported for the playback rate.
+     */
+    public static final int AUDIO_ADJUST_MODE_DEFAULT = 0;
+
+    /**
+     * Time stretch audio when playback rate must be adjusted.
+     * <p>
+     * This will make audio play faster or slower as required by the sync source
+     * without changing its pitch, as long as it is supported for the playback
+     * rate.
+     */
+    public static final int AUDIO_ADJUST_MODE_STRETCH = 1;
+
+    /**
+     * Resample audio when playback rate must be adjusted.
+     * <p>
+     * This will make audio play faster or slower as required by the sync source
+     * by changing its pitch (making it lower to play slower, and higher to play
+     * faster.)
+     */
+    public static final int AUDIO_ADJUST_MODE_RESAMPLE = 2;
+
+    // flags to indicate which params are actually set
+    private static final int SET_SYNC_SOURCE         = 1 << 0;
+    private static final int SET_AUDIO_ADJUST_MODE   = 1 << 1;
+    private static final int SET_TOLERANCE           = 1 << 2;
+    private static final int SET_FRAME_RATE          = 1 << 3;
+    private int mSet = 0;
+
+    // params
+    private int mAudioAdjustMode = AUDIO_ADJUST_MODE_DEFAULT;
+    private int mSyncSource = SYNC_SOURCE_DEFAULT;
+    private float mTolerance = 0.f;
+    private float mFrameRate = 0.f;
+
+    /**
+     * Allows defaults to be returned for properties not set.
+     * Otherwise a {@link java.lang.IllegalArgumentException} exception
+     * is raised when getting those properties
+     * which have defaults but have never been set.
+     * @return this <code>SyncParams</code> instance.
+     */
+    public SyncParams allowDefaults() {
+        mSet |= SET_SYNC_SOURCE | SET_AUDIO_ADJUST_MODE | SET_TOLERANCE;
+        return this;
+    }
+
+    /**
+     * Sets the audio adjust mode.
+     * @param audioAdjustMode
+     * @return this <code>SyncParams</code> instance.
+     */
+    public SyncParams setAudioAdjustMode(@AudioAdjustMode int audioAdjustMode) {
+        mAudioAdjustMode = audioAdjustMode;
+        mSet |= SET_AUDIO_ADJUST_MODE;
+        return this;
+    }
+
+    /**
+     * Retrieves the audio adjust mode.
+     * @return audio adjust mode
+     * @throws IllegalStateException if the audio adjust mode is not set.
+     */
+    public @AudioAdjustMode int getAudioAdjustMode() {
+        if ((mSet & SET_AUDIO_ADJUST_MODE) == 0) {
+            throw new IllegalStateException("audio adjust mode not set");
+        }
+        return mAudioAdjustMode;
+    }
+
+    /**
+     * Sets the sync source.
+     * @param syncSource
+     * @return this <code>SyncParams</code> instance.
+     */
+    public SyncParams setSyncSource(@SyncSource int syncSource) {
+        mSyncSource = syncSource;
+        mSet |= SET_SYNC_SOURCE;
+        return this;
+    }
+
+    /**
+     * Retrieves the sync source.
+     * @return sync source
+     * @throws IllegalStateException if the sync source is not set.
+     */
+    public @SyncSource int getSyncSource() {
+        if ((mSet & SET_SYNC_SOURCE) == 0) {
+            throw new IllegalStateException("sync source not set");
+        }
+        return mSyncSource;
+    }
+
+    /**
+     * Sets the tolerance. The default tolerance is platform specific, but is never more than 1/24.
+     * @param tolerance A non-negative number representing
+     *     the maximum deviation of the playback rate from the playback rate
+     *     set. ({@code abs(actual_rate - set_rate) / set_rate})
+     * @return this <code>SyncParams</code> instance.
+     * @throws IllegalArgumentException if the tolerance is negative, or not less than one.
+     */
+    public SyncParams setTolerance(float tolerance) {
+        if (tolerance < 0.f || tolerance >= 1.f) {
+            throw new IllegalArgumentException("tolerance must be less than one and non-negative");
+        }
+        mTolerance = tolerance;
+        mSet |= SET_TOLERANCE;
+        return this;
+    }
+
+    /**
+     * Retrieves the tolerance factor.
+     * @return tolerance factor. A non-negative number representing
+     *     the maximum deviation of the playback rate from the playback rate
+     *     set. ({@code abs(actual_rate - set_rate) / set_rate})
+     * @throws IllegalStateException if tolerance is not set.
+     */
+    public float getTolerance() {
+        if ((mSet & SET_TOLERANCE) == 0) {
+            throw new IllegalStateException("tolerance not set");
+        }
+        return mTolerance;
+    }
+
+    /**
+     * Sets the video frame rate hint to be used. By default the frame rate is unspecified.
+     * @param frameRate A non-negative number used as an initial hint on
+     *     the video frame rate to be used when using vsync as the sync source. A negative
+     *     number is used to clear a previous hint.
+     * @return this <code>SyncParams</code> instance.
+     */
+    public SyncParams setFrameRate(float frameRate) {
+        mFrameRate = frameRate;
+        mSet |= SET_FRAME_RATE;
+        return this;
+    }
+
+    /**
+     * Retrieves the video frame rate hint.
+     * @return frame rate factor. A non-negative number representing
+     *     the maximum deviation of the playback rate from the playback rate
+     *     set. ({@code abs(actual_rate - set_rate) / set_rate}), or a negative
+     *     number representing the desire to clear a previous hint using these params.
+     * @throws IllegalStateException if frame rate is not set.
+     */
+    public float getFrameRate() {
+        if ((mSet & SET_FRAME_RATE) == 0) {
+            throw new IllegalStateException("frame rate not set");
+        }
+        return mFrameRate;
+    }
+
+}
diff --git a/android/media/ThumbnailUtils.java b/android/media/ThumbnailUtils.java
new file mode 100644
index 0000000..e6d95eb
--- /dev/null
+++ b/android/media/ThumbnailUtils.java
@@ -0,0 +1,579 @@
+/*
+ * Copyright (C) 2009 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.MediaMetadataRetriever.METADATA_KEY_DURATION;
+import static android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT;
+import static android.media.MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH;
+import static android.media.MediaMetadataRetriever.OPTION_CLOSEST_SYNC;
+import static android.os.Environment.MEDIA_UNKNOWN;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ContentResolver;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.ImageDecoder;
+import android.graphics.ImageDecoder.ImageInfo;
+import android.graphics.ImageDecoder.Source;
+import android.graphics.Matrix;
+import android.graphics.Rect;
+import android.media.MediaMetadataRetriever.BitmapParams;
+import android.net.Uri;
+import android.os.Build;
+import android.os.CancellationSignal;
+import android.os.Environment;
+import android.os.ParcelFileDescriptor;
+import android.provider.MediaStore;
+import android.util.Log;
+import android.util.Size;
+
+import com.android.internal.util.ArrayUtils;
+
+import libcore.io.IoUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Objects;
+import java.util.function.ToIntFunction;
+
+/**
+ * Utilities for generating visual thumbnails from files.
+ */
+public class ThumbnailUtils {
+    private static final String TAG = "ThumbnailUtils";
+
+    /** @hide */
+    @Deprecated
+    @UnsupportedAppUsage
+    public static final int TARGET_SIZE_MICRO_THUMBNAIL = 96;
+
+    /* Options used internally. */
+    private static final int OPTIONS_NONE = 0x0;
+    private static final int OPTIONS_SCALE_UP = 0x1;
+
+    /**
+     * Constant used to indicate we should recycle the input in
+     * {@link #extractThumbnail(Bitmap, int, int, int)} unless the output is the input.
+     */
+    public static final int OPTIONS_RECYCLE_INPUT = 0x2;
+
+    private static Size convertKind(int kind) {
+        return MediaStore.Images.Thumbnails.getKindSize(kind);
+    }
+
+    private static class Resizer implements ImageDecoder.OnHeaderDecodedListener {
+        private final Size size;
+        private final CancellationSignal signal;
+
+        public Resizer(Size size, CancellationSignal signal) {
+            this.size = size;
+            this.signal = signal;
+        }
+
+        @Override
+        public void onHeaderDecoded(ImageDecoder decoder, ImageInfo info, Source source) {
+            // One last-ditch check to see if we've been canceled.
+            if (signal != null) signal.throwIfCanceled();
+
+            // We don't know how clients will use the decoded data, so we have
+            // to default to the more flexible "software" option.
+            decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE);
+
+            // We requested a rough thumbnail size, but the remote size may have
+            // returned something giant, so defensively scale down as needed.
+            final int widthSample = info.getSize().getWidth() / size.getWidth();
+            final int heightSample = info.getSize().getHeight() / size.getHeight();
+            final int sample = Math.max(widthSample, heightSample);
+            if (sample > 1) {
+                decoder.setTargetSampleSize(sample);
+            }
+        }
+    }
+
+    /**
+     * Create a thumbnail for given audio file.
+     *
+     * @param filePath The audio file.
+     * @param kind The desired thumbnail kind, such as
+     *            {@link android.provider.MediaStore.Images.Thumbnails#MINI_KIND}.
+     * @deprecated Callers should migrate to using
+     *             {@link #createAudioThumbnail(File, Size, CancellationSignal)},
+     *             as it offers more control over resizing and cancellation.
+     */
+    @Deprecated
+    public static @Nullable Bitmap createAudioThumbnail(@NonNull String filePath, int kind) {
+        try {
+            return createAudioThumbnail(new File(filePath), convertKind(kind), null);
+        } catch (IOException e) {
+            Log.w(TAG, e);
+            return null;
+        }
+    }
+
+    /**
+     * Create a thumbnail for given audio file.
+     * <p>
+     * This method should only be used for files that you have direct access to;
+     * if you'd like to work with media hosted outside your app, consider using
+     * {@link ContentResolver#loadThumbnail(Uri, Size, CancellationSignal)}
+     * which enables remote providers to efficiently cache and invalidate
+     * thumbnails.
+     *
+     * @param file The audio file.
+     * @param size The desired thumbnail size.
+     * @throws IOException If any trouble was encountered while generating or
+     *             loading the thumbnail, or if
+     *             {@link CancellationSignal#cancel()} was invoked.
+     */
+    public static @NonNull Bitmap createAudioThumbnail(@NonNull File file, @NonNull Size size,
+            @Nullable CancellationSignal signal) throws IOException {
+        // Checkpoint before going deeper
+        if (signal != null) signal.throwIfCanceled();
+
+        final Resizer resizer = new Resizer(size, signal);
+        try (MediaMetadataRetriever retriever = new MediaMetadataRetriever()) {
+            retriever.setDataSource(file.getAbsolutePath());
+            final byte[] raw = retriever.getEmbeddedPicture();
+            if (raw != null) {
+                return ImageDecoder.decodeBitmap(ImageDecoder.createSource(raw), resizer);
+            }
+        } catch (RuntimeException e) {
+            throw new IOException("Failed to create thumbnail", e);
+        }
+
+        // Only poke around for files on external storage
+        if (MEDIA_UNKNOWN.equals(Environment.getExternalStorageState(file))) {
+            throw new IOException("No embedded album art found");
+        }
+
+        // Ignore "Downloads" or top-level directories
+        final File parent = file.getParentFile();
+        final File grandParent = parent != null ? parent.getParentFile() : null;
+        if (parent != null
+                && parent.getName().equals(Environment.DIRECTORY_DOWNLOADS)) {
+            throw new IOException("No thumbnails in Downloads directories");
+        }
+        if (grandParent != null
+                && MEDIA_UNKNOWN.equals(Environment.getExternalStorageState(grandParent))) {
+            throw new IOException("No thumbnails in top-level directories");
+        }
+
+        // If no embedded image found, look around for best standalone file
+        final File[] found = ArrayUtils
+                .defeatNullable(file.getParentFile().listFiles((dir, name) -> {
+                    final String lower = name.toLowerCase();
+                    return (lower.endsWith(".jpg") || lower.endsWith(".png"));
+                }));
+
+        final ToIntFunction<File> score = (f) -> {
+            final String lower = f.getName().toLowerCase();
+            if (lower.equals("albumart.jpg")) return 4;
+            if (lower.startsWith("albumart") && lower.endsWith(".jpg")) return 3;
+            if (lower.contains("albumart") && lower.endsWith(".jpg")) return 2;
+            if (lower.endsWith(".jpg")) return 1;
+            return 0;
+        };
+        final Comparator<File> bestScore = (a, b) -> {
+            return score.applyAsInt(a) - score.applyAsInt(b);
+        };
+
+        final File bestFile = Arrays.asList(found).stream().max(bestScore).orElse(null);
+        if (bestFile == null) {
+            throw new IOException("No album art found");
+        }
+
+        // Checkpoint before going deeper
+        if (signal != null) signal.throwIfCanceled();
+
+        return ImageDecoder.decodeBitmap(ImageDecoder.createSource(bestFile), resizer);
+    }
+
+    /**
+     * Create a thumbnail for given image file.
+     *
+     * @param filePath The image file.
+     * @param kind The desired thumbnail kind, such as
+     *            {@link android.provider.MediaStore.Images.Thumbnails#MINI_KIND}.
+     * @deprecated Callers should migrate to using
+     *             {@link #createImageThumbnail(File, Size, CancellationSignal)},
+     *             as it offers more control over resizing and cancellation.
+     */
+    @Deprecated
+    public static @Nullable Bitmap createImageThumbnail(@NonNull String filePath, int kind) {
+        try {
+            return createImageThumbnail(new File(filePath), convertKind(kind), null);
+        } catch (IOException e) {
+            Log.w(TAG, e);
+            return null;
+        }
+    }
+
+    /**
+     * Create a thumbnail for given image file.
+     * <p>
+     * This method should only be used for files that you have direct access to;
+     * if you'd like to work with media hosted outside your app, consider using
+     * {@link ContentResolver#loadThumbnail(Uri, Size, CancellationSignal)}
+     * which enables remote providers to efficiently cache and invalidate
+     * thumbnails.
+     *
+     * @param file The audio file.
+     * @param size The desired thumbnail size.
+     * @throws IOException If any trouble was encountered while generating or
+     *             loading the thumbnail, or if
+     *             {@link CancellationSignal#cancel()} was invoked.
+     */
+    public static @NonNull Bitmap createImageThumbnail(@NonNull File file, @NonNull Size size,
+            @Nullable CancellationSignal signal) throws IOException {
+        // Checkpoint before going deeper
+        if (signal != null) signal.throwIfCanceled();
+
+        final Resizer resizer = new Resizer(size, signal);
+        final String mimeType = MediaFile.getMimeTypeForFile(file.getName());
+        Bitmap bitmap = null;
+        ExifInterface exif = null;
+        int orientation = 0;
+
+        // get orientation
+        if (MediaFile.isExifMimeType(mimeType)) {
+            exif = new ExifInterface(file);
+            switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0)) {
+                case ExifInterface.ORIENTATION_ROTATE_90:
+                    orientation = 90;
+                    break;
+                case ExifInterface.ORIENTATION_ROTATE_180:
+                    orientation = 180;
+                    break;
+                case ExifInterface.ORIENTATION_ROTATE_270:
+                    orientation = 270;
+                    break;
+            }
+        }
+
+        if (mimeType.equals("image/heif")
+                || mimeType.equals("image/heif-sequence")
+                || mimeType.equals("image/heic")
+                || mimeType.equals("image/heic-sequence")
+                || mimeType.equals("image/avif")) {
+            try (MediaMetadataRetriever retriever = new MediaMetadataRetriever()) {
+                retriever.setDataSource(file.getAbsolutePath());
+                bitmap = retriever.getThumbnailImageAtIndex(-1,
+                        new MediaMetadataRetriever.BitmapParams(), size.getWidth(),
+                        size.getWidth() * size.getHeight());
+            } catch (RuntimeException e) {
+                throw new IOException("Failed to create thumbnail", e);
+            }
+        }
+
+        if (bitmap == null && exif != null) {
+            final byte[] raw = exif.getThumbnailBytes();
+            if (raw != null) {
+                try {
+                    bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(raw), resizer);
+                } catch (ImageDecoder.DecodeException e) {
+                    Log.w(TAG, e);
+                }
+            }
+        }
+
+        // Checkpoint before going deeper
+        if (signal != null) signal.throwIfCanceled();
+
+        if (bitmap == null) {
+            bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(file), resizer);
+            // Use ImageDecoder to do full file decoding, we don't need to handle the orientation
+            return bitmap;
+        }
+
+        // Transform the bitmap if the orientation of the image is not 0.
+        if (orientation != 0 && bitmap != null) {
+            final int width = bitmap.getWidth();
+            final int height = bitmap.getHeight();
+
+            final Matrix m = new Matrix();
+            m.setRotate(orientation, width / 2, height / 2);
+            bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, m, false);
+        }
+
+        return bitmap;
+    }
+
+    /**
+     * Create a thumbnail for given video file.
+     *
+     * @param filePath The video file.
+     * @param kind The desired thumbnail kind, such as
+     *            {@link android.provider.MediaStore.Images.Thumbnails#MINI_KIND}.
+     * @deprecated Callers should migrate to using
+     *             {@link #createVideoThumbnail(File, Size, CancellationSignal)},
+     *             as it offers more control over resizing and cancellation.
+     */
+    @Deprecated
+    public static @Nullable Bitmap createVideoThumbnail(@NonNull String filePath, int kind) {
+        try {
+            return createVideoThumbnail(new File(filePath), convertKind(kind), null);
+        } catch (IOException e) {
+            Log.w(TAG, e);
+            return null;
+        }
+    }
+
+    /**
+     * Create a thumbnail for given video file.
+     * <p>
+     * This method should only be used for files that you have direct access to;
+     * if you'd like to work with media hosted outside your app, consider using
+     * {@link ContentResolver#loadThumbnail(Uri, Size, CancellationSignal)}
+     * which enables remote providers to efficiently cache and invalidate
+     * thumbnails.
+     *
+     * @param file The video file.
+     * @param size The desired thumbnail size.
+     * @throws IOException If any trouble was encountered while generating or
+     *             loading the thumbnail, or if
+     *             {@link CancellationSignal#cancel()} was invoked.
+     */
+    public static @NonNull Bitmap createVideoThumbnail(@NonNull File file, @NonNull Size size,
+            @Nullable CancellationSignal signal) throws IOException {
+        // Checkpoint before going deeper
+        if (signal != null) signal.throwIfCanceled();
+
+        final Resizer resizer = new Resizer(size, signal);
+        try (MediaMetadataRetriever mmr = new MediaMetadataRetriever()) {
+            mmr.setDataSource(file.getAbsolutePath());
+
+            // Try to retrieve thumbnail from metadata
+            final byte[] raw = mmr.getEmbeddedPicture();
+            if (raw != null) {
+                return ImageDecoder.decodeBitmap(ImageDecoder.createSource(raw), resizer);
+            }
+
+            final BitmapParams params = new BitmapParams();
+            params.setPreferredConfig(Bitmap.Config.ARGB_8888);
+
+            final int width = Integer.parseInt(mmr.extractMetadata(METADATA_KEY_VIDEO_WIDTH));
+            final int height = Integer.parseInt(mmr.extractMetadata(METADATA_KEY_VIDEO_HEIGHT));
+            // Fall back to middle of video
+            // Note: METADATA_KEY_DURATION unit is in ms, not us.
+            final long thumbnailTimeUs =
+                    Long.parseLong(mmr.extractMetadata(METADATA_KEY_DURATION)) * 1000 / 2;
+
+            // If we're okay with something larger than native format, just
+            // return a frame without up-scaling it
+            if (size.getWidth() > width && size.getHeight() > height) {
+                return Objects.requireNonNull(
+                        mmr.getFrameAtTime(thumbnailTimeUs, OPTION_CLOSEST_SYNC, params));
+            } else {
+                return Objects.requireNonNull(
+                        mmr.getScaledFrameAtTime(thumbnailTimeUs, OPTION_CLOSEST_SYNC,
+                        size.getWidth(), size.getHeight(), params));
+            }
+        } catch (RuntimeException e) {
+            throw new IOException("Failed to create thumbnail", e);
+        }
+    }
+
+    /**
+     * Creates a centered bitmap of the desired size.
+     *
+     * @param source original bitmap source
+     * @param width targeted width
+     * @param height targeted height
+     */
+    public static Bitmap extractThumbnail(
+            Bitmap source, int width, int height) {
+        return extractThumbnail(source, width, height, OPTIONS_NONE);
+    }
+
+    /**
+     * Creates a centered bitmap of the desired size.
+     *
+     * @param source original bitmap source
+     * @param width targeted width
+     * @param height targeted height
+     * @param options options used during thumbnail extraction
+     */
+    public static Bitmap extractThumbnail(
+            Bitmap source, int width, int height, int options) {
+        if (source == null) {
+            return null;
+        }
+
+        float scale;
+        if (source.getWidth() < source.getHeight()) {
+            scale = width / (float) source.getWidth();
+        } else {
+            scale = height / (float) source.getHeight();
+        }
+        Matrix matrix = new Matrix();
+        matrix.setScale(scale, scale);
+        Bitmap thumbnail = transform(matrix, source, width, height,
+                OPTIONS_SCALE_UP | options);
+        return thumbnail;
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private static int computeSampleSize(BitmapFactory.Options options,
+            int minSideLength, int maxNumOfPixels) {
+        return 1;
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private static int computeInitialSampleSize(BitmapFactory.Options options,
+            int minSideLength, int maxNumOfPixels) {
+        return 1;
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private static void closeSilently(ParcelFileDescriptor c) {
+        IoUtils.closeQuietly(c);
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private static ParcelFileDescriptor makeInputStream(
+            Uri uri, ContentResolver cr) {
+        try {
+            return cr.openFileDescriptor(uri, "r");
+        } catch (IOException ex) {
+            return null;
+        }
+    }
+
+    /**
+     * Transform source Bitmap to targeted width and height.
+     */
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private static Bitmap transform(Matrix scaler,
+            Bitmap source,
+            int targetWidth,
+            int targetHeight,
+            int options) {
+        boolean scaleUp = (options & OPTIONS_SCALE_UP) != 0;
+        boolean recycle = (options & OPTIONS_RECYCLE_INPUT) != 0;
+
+        int deltaX = source.getWidth() - targetWidth;
+        int deltaY = source.getHeight() - targetHeight;
+        if (!scaleUp && (deltaX < 0 || deltaY < 0)) {
+            /*
+            * In this case the bitmap is smaller, at least in one dimension,
+            * than the target.  Transform it by placing as much of the image
+            * as possible into the target and leaving the top/bottom or
+            * left/right (or both) black.
+            */
+            Bitmap b2 = Bitmap.createBitmap(targetWidth, targetHeight,
+            Bitmap.Config.ARGB_8888);
+            Canvas c = new Canvas(b2);
+
+            int deltaXHalf = Math.max(0, deltaX / 2);
+            int deltaYHalf = Math.max(0, deltaY / 2);
+            Rect src = new Rect(
+            deltaXHalf,
+            deltaYHalf,
+            deltaXHalf + Math.min(targetWidth, source.getWidth()),
+            deltaYHalf + Math.min(targetHeight, source.getHeight()));
+            int dstX = (targetWidth  - src.width())  / 2;
+            int dstY = (targetHeight - src.height()) / 2;
+            Rect dst = new Rect(
+                    dstX,
+                    dstY,
+                    targetWidth - dstX,
+                    targetHeight - dstY);
+            c.drawBitmap(source, src, dst, null);
+            if (recycle) {
+                source.recycle();
+            }
+            c.setBitmap(null);
+            return b2;
+        }
+        float bitmapWidthF = source.getWidth();
+        float bitmapHeightF = source.getHeight();
+
+        float bitmapAspect = bitmapWidthF / bitmapHeightF;
+        float viewAspect   = (float) targetWidth / targetHeight;
+
+        if (bitmapAspect > viewAspect) {
+            float scale = targetHeight / bitmapHeightF;
+            if (scale < .9F || scale > 1F) {
+                scaler.setScale(scale, scale);
+            } else {
+                scaler = null;
+            }
+        } else {
+            float scale = targetWidth / bitmapWidthF;
+            if (scale < .9F || scale > 1F) {
+                scaler.setScale(scale, scale);
+            } else {
+                scaler = null;
+            }
+        }
+
+        Bitmap b1;
+        if (scaler != null) {
+            // this is used for minithumb and crop, so we want to filter here.
+            b1 = Bitmap.createBitmap(source, 0, 0,
+            source.getWidth(), source.getHeight(), scaler, true);
+        } else {
+            b1 = source;
+        }
+
+        if (recycle && b1 != source) {
+            source.recycle();
+        }
+
+        int dx1 = Math.max(0, b1.getWidth() - targetWidth);
+        int dy1 = Math.max(0, b1.getHeight() - targetHeight);
+
+        Bitmap b2 = Bitmap.createBitmap(
+                b1,
+                dx1 / 2,
+                dy1 / 2,
+                targetWidth,
+                targetHeight);
+
+        if (b2 != b1) {
+            if (recycle || b1 != source) {
+                b1.recycle();
+            }
+        }
+
+        return b2;
+    }
+
+    @Deprecated
+    private static class SizedThumbnailBitmap {
+        public byte[] mThumbnailData;
+        public Bitmap mBitmap;
+        public int mThumbnailWidth;
+        public int mThumbnailHeight;
+    }
+
+    @Deprecated
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    private static void createThumbnailFromEXIF(String filePath, int targetSize,
+            int maxPixels, SizedThumbnailBitmap sizedThumbBitmap) {
+    }
+}
diff --git a/android/media/TimedMetaData.java b/android/media/TimedMetaData.java
new file mode 100644
index 0000000..b99b30c
--- /dev/null
+++ b/android/media/TimedMetaData.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2015 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.annotation.NonNull;
+import android.os.Parcel;
+
+/**
+ * Class that embodies one timed metadata access unit, including
+ *
+ * <ul>
+ * <li> a time stamp, and </li>
+ * <li> raw uninterpreted byte-array extracted directly from the container. </li>
+ * </ul>
+ *
+ * @see MediaPlayer#setOnTimedMetaDataAvailableListener(android.media.MediaPlayer.OnTimedMetaDataAvailableListener)
+ */
+public final class TimedMetaData {
+    private static final String TAG = "TimedMetaData";
+
+    private long mTimestampUs;
+    private byte[] mMetaData;
+
+    /**
+     * @hide
+     */
+    static TimedMetaData createTimedMetaDataFromParcel(Parcel parcel) {
+        return new TimedMetaData(parcel);
+    }
+
+    private TimedMetaData(Parcel parcel) {
+        if (!parseParcel(parcel)) {
+            throw new IllegalArgumentException("parseParcel() fails");
+        }
+    }
+
+    /**
+     * Constructor.
+     *
+     * @param timestampUs the timestamp in microsecond for the timed metadata
+     * @param metaData the metadata array for the timed metadata. No data copying is made.
+     *     It should not be null.
+     */
+    public TimedMetaData(long timestampUs, @NonNull byte[] metaData) {
+        if (metaData == null) {
+            throw new IllegalArgumentException("null metaData is not allowed");
+        }
+        mTimestampUs = timestampUs;
+        mMetaData = metaData;
+    }
+
+    /**
+     * @return the timestamp associated with this metadata access unit in microseconds;
+     * 0 denotes playback start.
+     */
+    public long getTimestamp() {
+        return mTimestampUs;
+    }
+
+    /**
+     * @return raw, uninterpreted content of this metadata access unit; for ID3 tags this includes
+     * everything starting from the 3 byte signature "ID3".
+     */
+    public byte[] getMetaData() {
+        return mMetaData;
+    }
+
+    private boolean parseParcel(Parcel parcel) {
+        parcel.setDataPosition(0);
+        if (parcel.dataAvail() == 0) {
+            return false;
+        }
+
+        mTimestampUs = parcel.readLong();
+        mMetaData = new byte[parcel.readInt()];
+        parcel.readByteArray(mMetaData);
+
+        return true;
+    }
+}
diff --git a/android/media/TimedText.java b/android/media/TimedText.java
new file mode 100644
index 0000000..fd61547
--- /dev/null
+++ b/android/media/TimedText.java
@@ -0,0 +1,748 @@
+/*
+ * Copyright (C) 2011 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.compat.annotation.UnsupportedAppUsage;
+import android.graphics.Rect;
+import android.os.Build;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Class to hold the timed text's metadata, including:
+ * <ul>
+ * <li> The characters for rendering</li>
+ * <li> The rendering position for the timed text</li>
+ * </ul>
+ *
+ * <p> To render the timed text, applications need to do the following:
+ *
+ * <ul>
+ * <li> Implement the {@link MediaPlayer.OnTimedTextListener} interface</li>
+ * <li> Register the {@link MediaPlayer.OnTimedTextListener} callback on a MediaPlayer object that is used for playback</li>
+ * <li> When a onTimedText callback is received, do the following:
+ * <ul>
+ * <li> call {@link #getText} to get the characters for rendering</li>
+ * <li> call {@link #getBounds} to get the text rendering area/region</li>
+ * </ul>
+ * </li>
+ * </ul>
+ *
+ * @see android.media.MediaPlayer
+ */
+public final class TimedText
+{
+    private static final int FIRST_PUBLIC_KEY                 = 1;
+
+    // These keys must be in sync with the keys in TextDescription.h
+    private static final int KEY_DISPLAY_FLAGS                 = 1; // int
+    private static final int KEY_STYLE_FLAGS                   = 2; // int
+    private static final int KEY_BACKGROUND_COLOR_RGBA         = 3; // int
+    private static final int KEY_HIGHLIGHT_COLOR_RGBA          = 4; // int
+    private static final int KEY_SCROLL_DELAY                  = 5; // int
+    private static final int KEY_WRAP_TEXT                     = 6; // int
+    private static final int KEY_START_TIME                    = 7; // int
+    private static final int KEY_STRUCT_BLINKING_TEXT_LIST     = 8; // List<CharPos>
+    private static final int KEY_STRUCT_FONT_LIST              = 9; // List<Font>
+    private static final int KEY_STRUCT_HIGHLIGHT_LIST         = 10; // List<CharPos>
+    private static final int KEY_STRUCT_HYPER_TEXT_LIST        = 11; // List<HyperText>
+    private static final int KEY_STRUCT_KARAOKE_LIST           = 12; // List<Karaoke>
+    private static final int KEY_STRUCT_STYLE_LIST             = 13; // List<Style>
+    private static final int KEY_STRUCT_TEXT_POS               = 14; // TextPos
+    private static final int KEY_STRUCT_JUSTIFICATION          = 15; // Justification
+    private static final int KEY_STRUCT_TEXT                   = 16; // Text
+
+    private static final int LAST_PUBLIC_KEY                  = 16;
+
+    private static final int FIRST_PRIVATE_KEY                = 101;
+
+    // The following keys are used between TimedText.java and
+    // TextDescription.cpp in order to parce the Parcel.
+    private static final int KEY_GLOBAL_SETTING               = 101;
+    private static final int KEY_LOCAL_SETTING                = 102;
+    private static final int KEY_START_CHAR                   = 103;
+    private static final int KEY_END_CHAR                     = 104;
+    private static final int KEY_FONT_ID                      = 105;
+    private static final int KEY_FONT_SIZE                    = 106;
+    private static final int KEY_TEXT_COLOR_RGBA              = 107;
+
+    private static final int LAST_PRIVATE_KEY                 = 107;
+
+    private static final String TAG = "TimedText";
+
+    private final HashMap<Integer, Object> mKeyObjectMap =
+            new HashMap<Integer, Object>();
+
+    private int mDisplayFlags = -1;
+    private int mBackgroundColorRGBA = -1;
+    private int mHighlightColorRGBA = -1;
+    private int mScrollDelay = -1;
+    private int mWrapText = -1;
+
+    private List<CharPos> mBlinkingPosList = null;
+    private List<CharPos> mHighlightPosList = null;
+    private List<Karaoke> mKaraokeList = null;
+    private List<Font> mFontList = null;
+    private List<Style> mStyleList = null;
+    private List<HyperText> mHyperTextList = null;
+
+    private Rect mTextBounds = null;
+    private String mTextChars = null;
+
+    private Justification mJustification;
+
+    /**
+     * Helper class to hold the start char offset and end char offset
+     * for Blinking Text or Highlight Text. endChar is the end offset
+     * of the text (startChar + number of characters to be highlighted
+     * or blinked). The member variables in this class are read-only.
+     * {@hide}
+     */
+    public static final class CharPos {
+        /**
+         * The offset of the start character
+         */
+        public final int startChar;
+
+        /**
+         * The offset of the end character
+         */
+        public final int endChar;
+
+        /**
+         * Constuctor
+         * @param startChar the offset of the start character.
+         * @param endChar the offset of the end character.
+         */
+        public CharPos(int startChar, int endChar) {
+            this.startChar = startChar;
+            this.endChar = endChar;
+        }
+    }
+
+    /**
+     * Helper class to hold the justification for text display in the text box.
+     * The member variables in this class are read-only.
+     * {@hide}
+     */
+    public static final class Justification {
+        /**
+         * horizontal justification  0: left, 1: centered, -1: right
+         */
+        public final int horizontalJustification;
+
+        /**
+         * vertical justification  0: top, 1: centered, -1: bottom
+         */
+        public final int verticalJustification;
+
+        /**
+         * Constructor
+         * @param horizontal the horizontal justification of the text.
+         * @param vertical the vertical justification of the text.
+         */
+        public Justification(int horizontal, int vertical) {
+            this.horizontalJustification = horizontal;
+            this.verticalJustification = vertical;
+        }
+    }
+
+    /**
+     * Helper class to hold the style information to display the text.
+     * The member variables in this class are read-only.
+     * {@hide}
+     */
+    public static final class Style {
+        /**
+         * The offset of the start character which applys this style
+         */
+        public final int startChar;
+
+        /**
+         * The offset of the end character which applys this style
+         */
+        public final int endChar;
+
+        /**
+         * ID of the font. This ID will be used to choose the font
+         * to be used from the font list.
+         */
+        public final int fontID;
+
+        /**
+         * True if the characters should be bold
+         */
+        public final boolean isBold;
+
+        /**
+         * True if the characters should be italic
+         */
+        public final boolean isItalic;
+
+        /**
+         * True if the characters should be underlined
+         */
+        public final boolean isUnderlined;
+
+        /**
+         * The size of the font
+         */
+        public final int fontSize;
+
+        /**
+         * To specify the RGBA color: 8 bits each of red, green, blue,
+         * and an alpha(transparency) value
+         */
+        public final int colorRGBA;
+
+        /**
+         * Constructor
+         * @param startChar the offset of the start character which applys this style
+         * @param endChar the offset of the end character which applys this style
+         * @param fontId the ID of the font.
+         * @param isBold whether the characters should be bold.
+         * @param isItalic whether the characters should be italic.
+         * @param isUnderlined whether the characters should be underlined.
+         * @param fontSize the size of the font.
+         * @param colorRGBA red, green, blue, and alpha value for color.
+         */
+        public Style(int startChar, int endChar, int fontId,
+                     boolean isBold, boolean isItalic, boolean isUnderlined,
+                     int fontSize, int colorRGBA) {
+            this.startChar = startChar;
+            this.endChar = endChar;
+            this.fontID = fontId;
+            this.isBold = isBold;
+            this.isItalic = isItalic;
+            this.isUnderlined = isUnderlined;
+            this.fontSize = fontSize;
+            this.colorRGBA = colorRGBA;
+        }
+    }
+
+    /**
+     * Helper class to hold the font ID and name.
+     * The member variables in this class are read-only.
+     * {@hide}
+     */
+    public static final class Font {
+        /**
+         * The font ID
+         */
+        public final int ID;
+
+        /**
+         * The font name
+         */
+        public final String name;
+
+        /**
+         * Constructor
+         * @param id the font ID.
+         * @param name the font name.
+         */
+        public Font(int id, String name) {
+            this.ID = id;
+            this.name = name;
+        }
+    }
+
+    /**
+     * Helper class to hold the karaoke information.
+     * The member variables in this class are read-only.
+     * {@hide}
+     */
+    public static final class Karaoke {
+        /**
+         * The start time (in milliseconds) to highlight the characters
+         * specified by startChar and endChar.
+         */
+        public final int startTimeMs;
+
+        /**
+         * The end time (in milliseconds) to highlight the characters
+         * specified by startChar and endChar.
+         */
+        public final int endTimeMs;
+
+        /**
+         * The offset of the start character to be highlighted
+         */
+        public final int startChar;
+
+        /**
+         * The offset of the end character to be highlighted
+         */
+        public final int endChar;
+
+        /**
+         * Constructor
+         * @param startTimeMs the start time (in milliseconds) to highlight
+         * the characters between startChar and endChar.
+         * @param endTimeMs the end time (in milliseconds) to highlight
+         * the characters between startChar and endChar.
+         * @param startChar the offset of the start character to be highlighted.
+         * @param endChar the offset of the end character to be highlighted.
+         */
+        public Karaoke(int startTimeMs, int endTimeMs, int startChar, int endChar) {
+            this.startTimeMs = startTimeMs;
+            this.endTimeMs = endTimeMs;
+            this.startChar = startChar;
+            this.endChar = endChar;
+        }
+    }
+
+    /**
+     * Helper class to hold the hyper text information.
+     * The member variables in this class are read-only.
+     * {@hide}
+     */
+    public static final class HyperText {
+        /**
+         * The offset of the start character
+         */
+        public final int startChar;
+
+        /**
+         * The offset of the end character
+         */
+        public final int endChar;
+
+        /**
+         * The linked-to URL
+         */
+        public final String URL;
+
+        /**
+         * The "alt" string for user display
+         */
+        public final String altString;
+
+
+        /**
+         * Constructor
+         * @param startChar the offset of the start character.
+         * @param endChar the offset of the end character.
+         * @param url the linked-to URL.
+         * @param alt the "alt" string for display.
+         */
+        public HyperText(int startChar, int endChar, String url, String alt) {
+            this.startChar = startChar;
+            this.endChar = endChar;
+            this.URL = url;
+            this.altString = alt;
+        }
+    }
+
+    /**
+     * @param obj the byte array which contains the timed text.
+     * @throws IllegalArgumentExcept if parseParcel() fails.
+     * {@hide}
+     */
+    public TimedText(Parcel parcel) {
+        if (!parseParcel(parcel)) {
+            mKeyObjectMap.clear();
+            throw new IllegalArgumentException("parseParcel() fails");
+        }
+    }
+
+    /**
+     * @param text the characters in the timed text.
+     * @param bounds the rectangle area or region for rendering the timed text.
+     * {@hide}
+     */
+    public TimedText(String text, Rect bounds) {
+        mTextChars = text;
+        mTextBounds = bounds;
+    }
+
+    /**
+     * Get the characters in the timed text.
+     *
+     * @return the characters as a String object in the TimedText. Applications
+     * should stop rendering previous timed text at the current rendering region if
+     * a null is returned, until the next non-null timed text is received.
+     */
+    public String getText() {
+        return mTextChars;
+    }
+
+    /**
+     * Get the rectangle area or region for rendering the timed text as specified
+     * by a Rect object.
+     *
+     * @return the rectangle region to render the characters in the timed text.
+     * If no bounds information is available (a null is returned), render the
+     * timed text at the center bottom of the display.
+     */
+    public Rect getBounds() {
+        return mTextBounds;
+    }
+
+    /*
+     * Go over all the records, collecting metadata keys and fields in the
+     * Parcel. These are stored in mKeyObjectMap for application to retrieve.
+     * @return false if an error occurred during parsing. Otherwise, true.
+     */
+    private boolean parseParcel(Parcel parcel) {
+        parcel.setDataPosition(0);
+        if (parcel.dataAvail() == 0) {
+            return false;
+        }
+
+        int type = parcel.readInt();
+        if (type == KEY_LOCAL_SETTING) {
+            type = parcel.readInt();
+            if (type != KEY_START_TIME) {
+                return false;
+            }
+            int mStartTimeMs = parcel.readInt();
+            mKeyObjectMap.put(type, mStartTimeMs);
+
+            type = parcel.readInt();
+            if (type != KEY_STRUCT_TEXT) {
+                return false;
+            }
+
+            int textLen = parcel.readInt();
+            byte[] text = parcel.createByteArray();
+            if (text == null || text.length == 0) {
+                mTextChars = null;
+            } else {
+                mTextChars = new String(text);
+            }
+
+        } else if (type != KEY_GLOBAL_SETTING) {
+            Log.w(TAG, "Invalid timed text key found: " + type);
+            return false;
+        }
+
+        while (parcel.dataAvail() > 0) {
+            int key = parcel.readInt();
+            if (!isValidKey(key)) {
+                Log.w(TAG, "Invalid timed text key found: " + key);
+                return false;
+            }
+
+            Object object = null;
+
+            switch (key) {
+                case KEY_STRUCT_STYLE_LIST: {
+                    readStyle(parcel);
+                    object = mStyleList;
+                    break;
+                }
+                case KEY_STRUCT_FONT_LIST: {
+                    readFont(parcel);
+                    object = mFontList;
+                    break;
+                }
+                case KEY_STRUCT_HIGHLIGHT_LIST: {
+                    readHighlight(parcel);
+                    object = mHighlightPosList;
+                    break;
+                }
+                case KEY_STRUCT_KARAOKE_LIST: {
+                    readKaraoke(parcel);
+                    object = mKaraokeList;
+                    break;
+                }
+                case KEY_STRUCT_HYPER_TEXT_LIST: {
+                    readHyperText(parcel);
+                    object = mHyperTextList;
+
+                    break;
+                }
+                case KEY_STRUCT_BLINKING_TEXT_LIST: {
+                    readBlinkingText(parcel);
+                    object = mBlinkingPosList;
+
+                    break;
+                }
+                case KEY_WRAP_TEXT: {
+                    mWrapText = parcel.readInt();
+                    object = mWrapText;
+                    break;
+                }
+                case KEY_HIGHLIGHT_COLOR_RGBA: {
+                    mHighlightColorRGBA = parcel.readInt();
+                    object = mHighlightColorRGBA;
+                    break;
+                }
+                case KEY_DISPLAY_FLAGS: {
+                    mDisplayFlags = parcel.readInt();
+                    object = mDisplayFlags;
+                    break;
+                }
+                case KEY_STRUCT_JUSTIFICATION: {
+
+                    int horizontal = parcel.readInt();
+                    int vertical = parcel.readInt();
+                    mJustification = new Justification(horizontal, vertical);
+
+                    object = mJustification;
+                    break;
+                }
+                case KEY_BACKGROUND_COLOR_RGBA: {
+                    mBackgroundColorRGBA = parcel.readInt();
+                    object = mBackgroundColorRGBA;
+                    break;
+                }
+                case KEY_STRUCT_TEXT_POS: {
+                    int top = parcel.readInt();
+                    int left = parcel.readInt();
+                    int bottom = parcel.readInt();
+                    int right = parcel.readInt();
+                    mTextBounds = new Rect(left, top, right, bottom);
+
+                    break;
+                }
+                case KEY_SCROLL_DELAY: {
+                    mScrollDelay = parcel.readInt();
+                    object = mScrollDelay;
+                    break;
+                }
+                default: {
+                    break;
+                }
+            }
+
+            if (object != null) {
+                if (mKeyObjectMap.containsKey(key)) {
+                    mKeyObjectMap.remove(key);
+                }
+                // Previous mapping will be replaced with the new object, if there was one.
+                mKeyObjectMap.put(key, object);
+            }
+        }
+
+        return true;
+    }
+
+    /*
+     * To parse and store the Style list.
+     */
+    private void readStyle(Parcel parcel) {
+        boolean endOfStyle = false;
+        int startChar = -1;
+        int endChar = -1;
+        int fontId = -1;
+        boolean isBold = false;
+        boolean isItalic = false;
+        boolean isUnderlined = false;
+        int fontSize = -1;
+        int colorRGBA = -1;
+        while (!endOfStyle && (parcel.dataAvail() > 0)) {
+            int key = parcel.readInt();
+            switch (key) {
+                case KEY_START_CHAR: {
+                    startChar = parcel.readInt();
+                    break;
+                }
+                case KEY_END_CHAR: {
+                    endChar = parcel.readInt();
+                    break;
+                }
+                case KEY_FONT_ID: {
+                    fontId = parcel.readInt();
+                    break;
+                }
+                case KEY_STYLE_FLAGS: {
+                    int flags = parcel.readInt();
+                    // In the absence of any bits set in flags, the text
+                    // is plain. Otherwise, 1: bold, 2: italic, 4: underline
+                    isBold = ((flags % 2) == 1);
+                    isItalic = ((flags % 4) >= 2);
+                    isUnderlined = ((flags / 4) == 1);
+                    break;
+                }
+                case KEY_FONT_SIZE: {
+                    fontSize = parcel.readInt();
+                    break;
+                }
+                case KEY_TEXT_COLOR_RGBA: {
+                    colorRGBA = parcel.readInt();
+                    break;
+                }
+                default: {
+                    // End of the Style parsing. Reset the data position back
+                    // to the position before the last parcel.readInt() call.
+                    parcel.setDataPosition(parcel.dataPosition() - 4);
+                    endOfStyle = true;
+                    break;
+                }
+            }
+        }
+
+        Style style = new Style(startChar, endChar, fontId, isBold,
+                                isItalic, isUnderlined, fontSize, colorRGBA);
+        if (mStyleList == null) {
+            mStyleList = new ArrayList<Style>();
+        }
+        mStyleList.add(style);
+    }
+
+    /*
+     * To parse and store the Font list
+     */
+    private void readFont(Parcel parcel) {
+        int entryCount = parcel.readInt();
+
+        for (int i = 0; i < entryCount; i++) {
+            int id = parcel.readInt();
+            int nameLen = parcel.readInt();
+
+            byte[] text = parcel.createByteArray();
+            final String name = new String(text, 0, nameLen);
+
+            Font font = new Font(id, name);
+
+            if (mFontList == null) {
+                mFontList = new ArrayList<Font>();
+            }
+            mFontList.add(font);
+        }
+    }
+
+    /*
+     * To parse and store the Highlight list
+     */
+    private void readHighlight(Parcel parcel) {
+        int startChar = parcel.readInt();
+        int endChar = parcel.readInt();
+        CharPos pos = new CharPos(startChar, endChar);
+
+        if (mHighlightPosList == null) {
+            mHighlightPosList = new ArrayList<CharPos>();
+        }
+        mHighlightPosList.add(pos);
+    }
+
+    /*
+     * To parse and store the Karaoke list
+     */
+    private void readKaraoke(Parcel parcel) {
+        int entryCount = parcel.readInt();
+
+        for (int i = 0; i < entryCount; i++) {
+            int startTimeMs = parcel.readInt();
+            int endTimeMs = parcel.readInt();
+            int startChar = parcel.readInt();
+            int endChar = parcel.readInt();
+            Karaoke kara = new Karaoke(startTimeMs, endTimeMs,
+                                       startChar, endChar);
+
+            if (mKaraokeList == null) {
+                mKaraokeList = new ArrayList<Karaoke>();
+            }
+            mKaraokeList.add(kara);
+        }
+    }
+
+    /*
+     * To parse and store HyperText list
+     */
+    private void readHyperText(Parcel parcel) {
+        int startChar = parcel.readInt();
+        int endChar = parcel.readInt();
+
+        int len = parcel.readInt();
+        byte[] url = parcel.createByteArray();
+        final String urlString = new String(url, 0, len);
+
+        len = parcel.readInt();
+        byte[] alt = parcel.createByteArray();
+        final String altString = new String(alt, 0, len);
+        HyperText hyperText = new HyperText(startChar, endChar, urlString, altString);
+
+
+        if (mHyperTextList == null) {
+            mHyperTextList = new ArrayList<HyperText>();
+        }
+        mHyperTextList.add(hyperText);
+    }
+
+    /*
+     * To parse and store blinking text list
+     */
+    private void readBlinkingText(Parcel parcel) {
+        int startChar = parcel.readInt();
+        int endChar = parcel.readInt();
+        CharPos blinkingPos = new CharPos(startChar, endChar);
+
+        if (mBlinkingPosList == null) {
+            mBlinkingPosList = new ArrayList<CharPos>();
+        }
+        mBlinkingPosList.add(blinkingPos);
+    }
+
+    /*
+     * To check whether the given key is valid.
+     * @param key the key to be checked.
+     * @return true if the key is a valid one. Otherwise, false.
+     */
+    private boolean isValidKey(final int key) {
+        if (!((key >= FIRST_PUBLIC_KEY) && (key <= LAST_PUBLIC_KEY))
+                && !((key >= FIRST_PRIVATE_KEY) && (key <= LAST_PRIVATE_KEY))) {
+            return false;
+        }
+        return true;
+    }
+
+    /*
+     * To check whether the given key is contained in this TimedText object.
+     * @param key the key to be checked.
+     * @return true if the key is contained in this TimedText object.
+     *         Otherwise, false.
+     */
+    private boolean containsKey(final int key) {
+        if (isValidKey(key) && mKeyObjectMap.containsKey(key)) {
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * @return a set of the keys contained in this TimedText object.
+     */
+    private Set keySet() {
+        return mKeyObjectMap.keySet();
+    }
+
+    /*
+     * To retrieve the object associated with the key. Caller must make sure
+     * the key is present using the containsKey method otherwise a
+     * RuntimeException will occur.
+     * @param key the key used to retrieve the object.
+     * @return an object. The object could be 1) an instance of Integer; 2) a
+     * List of CharPos, Karaoke, Font, Style, and HyperText, or 3) an instance of
+     * Justification.
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private Object getObject(final int key) {
+        if (containsKey(key)) {
+            return mKeyObjectMap.get(key);
+        } else {
+            throw new IllegalArgumentException("Invalid key: " + key);
+        }
+    }
+}
diff --git a/android/media/ToneGenerator.java b/android/media/ToneGenerator.java
new file mode 100644
index 0000000..6a695e6
--- /dev/null
+++ b/android/media/ToneGenerator.java
@@ -0,0 +1,908 @@
+/*
+ * Copyright (C) 2008 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.annotation.NonNull;
+import android.app.ActivityThread;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.text.TextUtils;
+
+
+/**
+ * This class provides methods to play DTMF tones (ITU-T Recommendation Q.23),
+ * call supervisory tones (3GPP TS 22.001, CEPT) and proprietary tones (3GPP TS 31.111).
+ * Depending on call state and routing options, tones are mixed to the downlink audio
+ * or output to the speaker phone or headset.
+ * This API is not for generating tones over the uplink audio path.
+ */
+public class ToneGenerator
+{
+
+    /* Values for toneType parameter of ToneGenerator() constructor */
+    /*
+     * List of all available tones: These constants must be kept consistant with
+     * the enum in ToneGenerator C++ class.     */
+
+    /**
+     * Default value for an unknown or unspecified tone.
+     * @hide
+     */
+    public static final int TONE_UNKNOWN = -1;
+
+    /**
+     * DTMF tone for key 0: 1336Hz, 941Hz, continuous</p>
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_0 = 0;
+    /**
+     * DTMF tone for key 1: 1209Hz, 697Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_1 = 1;
+    /**
+     * DTMF tone for key 2: 1336Hz, 697Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_2 = 2;
+    /**
+     * DTMF tone for key 3: 1477Hz, 697Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_3 = 3;
+    /**
+     * DTMF tone for key 4: 1209Hz, 770Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_4 = 4;
+    /**
+     * DTMF tone for key 5: 1336Hz, 770Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_5 = 5;
+    /**
+     * DTMF tone for key 6: 1477Hz, 770Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_6 = 6;
+    /**
+     * DTMF tone for key 7: 1209Hz, 852Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_7 = 7;
+    /**
+     * DTMF tone for key 8: 1336Hz, 852Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_8 = 8;
+    /**
+     * DTMF tone for key 9: 1477Hz, 852Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_9 = 9;
+    /**
+     * DTMF tone for key *: 1209Hz, 941Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_S = 10;
+    /**
+     * DTMF tone for key #: 1477Hz, 941Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_P = 11;
+    /**
+     * DTMF tone for key A: 1633Hz, 697Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_A = 12;
+    /**
+     * DTMF tone for key B: 1633Hz, 770Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_B = 13;
+    /**
+     * DTMF tone for key C: 1633Hz, 852Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_C = 14;
+    /**
+     * DTMF tone for key D: 1633Hz, 941Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_DTMF_D = 15;
+    /**
+     * Call supervisory tone, Dial tone:
+     *      CEPT:           425Hz, continuous
+     *      ANSI (IS-95):   350Hz+440Hz, continuous
+     *      JAPAN:          400Hz, continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_SUP_DIAL = 16;
+    /**
+     * Call supervisory tone, Busy:
+     *      CEPT:           425Hz, 500ms ON, 500ms OFF...
+     *      ANSI (IS-95):   480Hz+620Hz, 500ms ON, 500ms OFF...
+     *      JAPAN:          400Hz, 500ms ON, 500ms OFF...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_SUP_BUSY = 17;
+    /**
+     * Call supervisory tone, Congestion:
+     *      CEPT, JAPAN:    425Hz, 200ms ON, 200ms OFF...
+     *      ANSI (IS-95):   480Hz+620Hz, 250ms ON, 250ms OFF...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_SUP_CONGESTION = 18;
+    /**
+     * Call supervisory tone, Radio path acknowlegment :
+     *      CEPT, ANSI:    425Hz, 200ms ON
+     *      JAPAN:         400Hz, 1s ON, 2s OFF...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_SUP_RADIO_ACK = 19;
+    /**
+     * Call supervisory tone, Radio path not available: 425Hz, 200ms ON, 200 OFF 3 bursts
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_SUP_RADIO_NOTAVAIL = 20;
+    /**
+     * Call supervisory tone, Error/Special info: 950Hz+1400Hz+1800Hz, 330ms ON, 1s OFF...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_SUP_ERROR = 21;
+    /**
+     * Call supervisory tone, Call Waiting:
+     *      CEPT, JAPAN:    425Hz, 200ms ON, 600ms OFF, 200ms ON, 3s OFF...
+     *      ANSI (IS-95):   440 Hz, 300 ms ON, 9.7 s OFF,
+     *                      (100 ms ON, 100 ms OFF, 100 ms ON, 9.7s OFF ...)
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_SUP_CALL_WAITING = 22;
+    /**
+     * Call supervisory tone, Ring Tone:
+     *      CEPT, JAPAN:    425Hz, 1s ON, 4s OFF...
+     *      ANSI (IS-95):   440Hz + 480Hz, 2s ON, 4s OFF...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_SUP_RINGTONE = 23;
+    /**
+     * Proprietary tone, general beep: 400Hz+1200Hz, 35ms ON
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_PROP_BEEP = 24;
+    /**
+     * Proprietary tone, positive acknowlegement: 1200Hz, 100ms ON, 100ms OFF 2 bursts
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_PROP_ACK = 25;
+    /**
+     * Proprietary tone, negative acknowlegement: 300Hz+400Hz+500Hz, 400ms ON
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_PROP_NACK = 26;
+    /**
+     * Proprietary tone, prompt tone: 400Hz+1200Hz, 200ms ON
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int  TONE_PROP_PROMPT = 27;
+    /**
+     * Proprietary tone, general double beep: twice 400Hz+1200Hz, 35ms ON, 200ms OFF, 35ms ON
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_PROP_BEEP2 = 28;
+    /**
+     * Call supervisory tone (IS-95), intercept tone: alternating 440 Hz and 620 Hz tones,
+     * each on for 250 ms
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_SUP_INTERCEPT = 29;
+    /**
+     * Call supervisory tone (IS-95), abbreviated intercept: intercept tone limited to 4 seconds
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_SUP_INTERCEPT_ABBREV = 30;
+    /**
+     * Call supervisory tone (IS-95), abbreviated congestion: congestion tone limited to 4 seconds
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_SUP_CONGESTION_ABBREV = 31;
+    /**
+     * Call supervisory tone (IS-95), confirm tone: a 350 Hz tone added to a 440 Hz tone
+     * repeated 3 times in a 100 ms on, 100 ms off cycle
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_SUP_CONFIRM = 32;
+    /**
+     * Call supervisory tone (IS-95), pip tone: four bursts of 480 Hz tone (0.1 s on, 0.1 s off).
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_SUP_PIP = 33;
+    /**
+     *  CDMA Dial tone : 425Hz  continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_DIAL_TONE_LITE = 34;
+    /**
+     * CDMA USA Ringback: 440Hz+480Hz 2s ON, 4000 OFF ...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_NETWORK_USA_RINGBACK = 35;
+    /**
+     *  CDMA Intercept tone: 440Hz 250ms ON, 620Hz 250ms ON ...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_INTERCEPT = 36;
+    /**
+     * CDMA Abbr Intercept tone: 440Hz 250ms ON, 620Hz 250ms ON
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_ABBR_INTERCEPT = 37;
+    /**
+     * CDMA Reorder tone: 480Hz+620Hz 250ms ON, 250ms OFF...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_REORDER = 38;
+    /**
+     *
+     * CDMA Abbr Reorder tone: 480Hz+620Hz 250ms ON, 250ms OFF repeated for 8 times
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_ABBR_REORDER = 39;
+    /**
+     * CDMA Network Busy tone: 480Hz+620Hz 500ms ON, 500ms OFF continuous
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_NETWORK_BUSY = 40;
+    /**
+     * CDMA Confirm tone: 350Hz+440Hz 100ms ON, 100ms OFF repeated for 3 times
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_CONFIRM = 41;
+    /**
+     *
+     * CDMA answer tone: silent tone - defintion Frequency 0, 0ms ON, 0ms OFF
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_ANSWER = 42;
+    /**
+     *
+     * CDMA Network Callwaiting tone: 440Hz 300ms ON
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_NETWORK_CALLWAITING = 43;
+    /**
+     * CDMA PIP tone: 480Hz 100ms ON, 100ms OFF repeated for 4 times
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_PIP = 44;
+    /**
+     *  ISDN Call Signal Normal tone: {2091Hz 32ms ON, 2556 64ms ON} 20 times,
+     *  2091 32ms ON, 2556 48ms ON, 4s OFF
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_CALL_SIGNAL_ISDN_NORMAL = 45;
+    /**
+     *  ISDN Call Signal Intergroup tone: {2091Hz 32ms ON, 2556 64ms ON} 8 times,
+     * 2091Hz 32ms ON, 400ms OFF, {2091Hz 32ms ON, 2556Hz 64ms ON} times,
+     * 2091Hz 32ms ON, 4s OFF.
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_CALL_SIGNAL_ISDN_INTERGROUP = 46;
+    /**
+     * ISDN Call Signal SP PRI tone:{2091Hz 32ms ON, 2556 64ms ON} 4 times
+     * 2091Hz 16ms ON, 200ms OFF, {2091Hz 32ms ON, 2556Hz 64ms ON} 4 times,
+     * 2091Hz 16ms ON, 200ms OFF
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_CALL_SIGNAL_ISDN_SP_PRI = 47;
+    /**
+     * ISDN Call sign PAT3 tone: silent tone
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_CALL_SIGNAL_ISDN_PAT3 = 48;
+    /**
+     * ISDN Ping Ring tone: {2091Hz 32ms ON, 2556Hz 64ms ON} 5 times
+     * 2091Hz 20ms ON
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_CALL_SIGNAL_ISDN_PING_RING = 49;
+    /**
+     *
+     * ISDN Pat5 tone: silent tone
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_CALL_SIGNAL_ISDN_PAT5 = 50;
+    /**
+     *
+     * ISDN Pat6 tone: silent tone
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_CALL_SIGNAL_ISDN_PAT6 = 51;
+    /**
+     * ISDN Pat7 tone: silent tone
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_CALL_SIGNAL_ISDN_PAT7 = 52;
+    /**
+     * TONE_CDMA_HIGH_L tone: {3700Hz 25ms, 4000Hz 25ms} 40 times
+     * 4000ms OFF, Repeat ....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_HIGH_L = 53;
+    /**
+     * TONE_CDMA_MED_L tone: {2600Hz 25ms, 2900Hz 25ms} 40 times
+     * 4000ms OFF, Repeat ....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_MED_L = 54;
+    /**
+     * TONE_CDMA_LOW_L tone: {1300Hz 25ms, 1450Hz 25ms} 40 times,
+     * 4000ms OFF, Repeat ....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_LOW_L = 55;
+    /**
+     * CDMA HIGH SS tone: {3700Hz 25ms, 4000Hz 25ms} repeat 16 times,
+     * 400ms OFF, repeat ....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_HIGH_SS = 56;
+    /**
+     * CDMA MED SS tone: {2600Hz 25ms, 2900Hz 25ms} repeat 16 times,
+     * 400ms OFF, repeat ....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_MED_SS = 57;
+    /**
+     * CDMA LOW SS tone: {1300z 25ms, 1450Hz 25ms} repeat 16 times,
+     * 400ms OFF, repeat ....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_LOW_SS = 58;
+    /**
+     * CDMA HIGH SSL tone: {3700Hz 25ms, 4000Hz 25ms} 8 times,
+     * 200ms OFF, {3700Hz 25ms, 4000Hz 25ms} repeat 8 times,
+     * 200ms OFF, {3700Hz 25ms, 4000Hz 25ms} repeat 16 times,
+     * 4000ms OFF, repeat ...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_HIGH_SSL = 59;
+    /**
+     * CDMA MED SSL tone: {2600Hz 25ms, 2900Hz 25ms} 8 times,
+     * 200ms OFF, {2600Hz 25ms, 2900Hz 25ms} repeat 8 times,
+     * 200ms OFF, {2600Hz 25ms, 2900Hz 25ms} repeat 16 times,
+     * 4000ms OFF, repeat ...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_MED_SSL = 60;
+    /**
+     * CDMA LOW SSL tone: {1300Hz 25ms, 1450Hz 25ms} 8 times,
+     * 200ms OFF, {1300Hz 25ms, 1450Hz 25ms} repeat 8 times,
+     * 200ms OFF, {1300Hz 25ms, 1450Hz 25ms} repeat 16 times,
+     * 4000ms OFF, repeat ...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_LOW_SSL = 61;
+    /**
+     * CDMA HIGH SS2 tone: {3700Hz 25ms, 4000Hz 25ms} 20 times,
+     * 1000ms OFF, {3700Hz 25ms, 4000Hz 25ms} 20 times,
+     * 3000ms OFF, repeat ....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_HIGH_SS_2 = 62;
+    /**
+     * CDMA MED SS2 tone: {2600Hz 25ms, 2900Hz 25ms} 20 times,
+     * 1000ms OFF, {2600Hz 25ms, 2900Hz 25ms} 20 times,
+     * 3000ms OFF, repeat ....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_MED_SS_2 = 63;
+    /**
+     * CDMA LOW SS2 tone: {1300Hz 25ms, 1450Hz 25ms} 20 times,
+     * 1000ms OFF, {1300Hz 25ms, 1450Hz 25ms} 20 times,
+     * 3000ms OFF, repeat ....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_LOW_SS_2 = 64;
+    /**
+     *  CDMA HIGH SLS tone: {3700Hz 25ms, 4000Hz 25ms} 10 times,
+     *  500ms OFF, {3700Hz 25ms, 4000Hz 25ms} 20 times, 500ms OFF,
+     *  {3700Hz 25ms, 4000Hz 25ms} 10 times, 3000ms OFF, REPEAT
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_HIGH_SLS = 65;
+    /**
+     *  CDMA MED  SLS tone: {2600Hz 25ms, 2900Hz 25ms} 10 times,
+     *  500ms OFF, {2600Hz 25ms, 2900Hz 25ms} 20 times, 500ms OFF,
+     *  {2600Hz 25ms, 2900Hz 25ms} 10 times, 3000ms OFF, REPEAT
+     *
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_MED_SLS = 66;
+    /**
+     *  CDMA LOW SLS tone: {1300Hz 25ms, 1450Hz 25ms} 10 times,
+     *  500ms OFF, {1300Hz 25ms, 1450Hz 25ms} 20 times, 500ms OFF,
+     *  {1300Hz 25ms, 1450Hz 25ms} 10 times, 3000ms OFF, REPEAT
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_LOW_SLS = 67;
+    /**
+     *  CDMA HIGH S X4 tone: {3700Hz 25ms, 4000Hz 25ms} 10 times,
+     *  500ms OFF, {3700Hz 25ms, 4000Hz 25ms} 10 times, 500ms OFF,
+     *  {3700Hz 25ms, 4000Hz 25ms} 10 times, 500ms OFF,
+     *  {3700Hz 25ms, 4000Hz 25ms} 10 times, 2500ms OFF, REPEAT....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_HIGH_S_X4 = 68;
+    /**
+     *  CDMA MED S X4 tone: {2600Hz 25ms, 2900Hz 25ms} 10 times,
+     *  500ms OFF, {2600Hz 25ms, 2900Hz 25ms} 10 times, 500ms OFF,
+     *  {2600Hz 25ms, 2900Hz 25ms} 10 times, 500ms OFF,
+     *  {2600Hz 25ms, 2900Hz 25ms} 10 times, 2500ms OFF, REPEAT....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_MED_S_X4 = 69;
+    /**
+     *  CDMA LOW  S X4 tone: {2600Hz 25ms, 2900Hz 25ms} 10 times,
+     *  500ms OFF, {2600Hz 25ms, 2900Hz 25ms} 10 times, 500ms OFF,
+     *  {2600Hz 25ms, 2900Hz 25ms} 10 times, 500ms OFF,
+     *  {2600Hz 25ms, 2900Hz 25ms} 10 times, 2500ms OFF, REPEAT....
+     *
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_LOW_S_X4 = 70;
+    /**
+     * CDMA HIGH PBX L: {3700Hz 25ms, 4000Hz 25ms}20 times,
+     * 2000ms OFF,  REPEAT....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_HIGH_PBX_L = 71;
+    /**
+     *  CDMA MED PBX L: {2600Hz 25ms, 2900Hz 25ms}20 times,
+     * 2000ms OFF,  REPEAT....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_MED_PBX_L = 72;
+    /**
+     * CDMA LOW PBX L: {1300Hz 25ms,1450Hz 25ms}20 times,
+     * 2000ms OFF,  REPEAT....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_LOW_PBX_L = 73;
+    /**
+     * CDMA HIGH PBX SS tone: {3700Hz 25ms, 4000Hz 25ms} 8 times
+     * 200 ms OFF, {3700Hz 25ms 4000Hz 25ms}8 times,
+     * 2000ms OFF, REPEAT....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_HIGH_PBX_SS = 74;
+    /**
+     * CDMA MED PBX SS tone: {2600Hz 25ms, 2900Hz 25ms} 8 times
+     * 200 ms OFF, {2600Hz 25ms 2900Hz 25ms}8 times,
+     * 2000ms OFF, REPEAT....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_MED_PBX_SS = 75;
+    /**
+     * CDMA LOW PBX SS tone: {1300Hz 25ms, 1450Hz 25ms} 8 times
+     * 200 ms OFF, {1300Hz 25ms 1450Hz 25ms}8 times,
+     * 2000ms OFF, REPEAT....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_LOW_PBX_SS = 76;
+    /**
+     * CDMA HIGH PBX SSL tone:{3700Hz 25ms, 4000Hz 25ms} 8 times
+     * 200ms OFF, {3700Hz 25ms, 4000Hz 25ms} 8 times, 200ms OFF,
+     * {3700Hz 25ms, 4000Hz 25ms} 16 times, 1000ms OFF, REPEAT....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_HIGH_PBX_SSL = 77;
+    /**
+     * CDMA MED PBX SSL tone:{2600Hz 25ms, 2900Hz 25ms} 8 times
+     * 200ms OFF, {2600Hz 25ms, 2900Hz 25ms} 8 times, 200ms OFF,
+     * {2600Hz 25ms, 2900Hz 25ms} 16 times, 1000ms OFF, REPEAT....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_MED_PBX_SSL = 78;
+    /**
+     * CDMA LOW PBX SSL tone:{1300Hz 25ms, 1450Hz 25ms} 8 times
+     * 200ms OFF, {1300Hz 25ms, 1450Hz 25ms} 8 times, 200ms OFF,
+     * {1300Hz 25ms, 1450Hz 25ms} 16 times, 1000ms OFF, REPEAT....
+     *
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_LOW_PBX_SSL = 79;
+    /**
+     * CDMA HIGH PBX SSL tone:{3700Hz 25ms, 4000Hz 25ms} 8 times
+     * 200ms OFF, {3700Hz 25ms, 4000Hz 25ms} 16 times, 200ms OFF,
+     * {3700Hz 25ms, 4000Hz 25ms} 8 times, 1000ms OFF, REPEAT....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_HIGH_PBX_SLS = 80;
+    /**
+     * CDMA HIGH PBX SLS tone:{2600Hz 25ms, 2900Hz 25ms} 8 times
+     * 200ms OFF, {2600Hz 25ms, 2900Hz 25ms} 16 times, 200ms OFF,
+     * {2600Hz 25ms, 2900Hz 25ms} 8 times, 1000ms OFF, REPEAT....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_MED_PBX_SLS = 81;
+    /**
+     * CDMA HIGH PBX SLS tone:{1300Hz 25ms, 1450Hz 25ms} 8 times
+     * 200ms OFF, {1300Hz 25ms, 1450Hz 25ms} 16 times, 200ms OFF,
+     * {1300Hz 25ms, 1450Hz 25ms} 8 times, 1000ms OFF, REPEAT....
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_LOW_PBX_SLS = 82;
+    /**
+     * CDMA HIGH PBX X S4 tone: {3700Hz 25ms 4000Hz 25ms} 8 times,
+     * 200ms OFF, {3700Hz 25ms 4000Hz 25ms} 8 times, 200ms OFF,
+     * {3700Hz 25ms 4000Hz 25ms} 8 times, 200ms OFF,
+     * {3700Hz 25ms 4000Hz 25ms} 8 times, 800ms OFF, REPEAT...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_HIGH_PBX_S_X4 = 83;
+    /**
+     * CDMA MED PBX X S4 tone: {2600Hz 25ms 2900Hz 25ms} 8 times,
+     * 200ms OFF, {2600Hz 25ms 2900Hz 25ms} 8 times, 200ms OFF,
+     * {2600Hz 25ms 2900Hz 25ms} 8 times, 200ms OFF,
+     * {2600Hz 25ms 2900Hz 25ms} 8 times, 800ms OFF, REPEAT...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_MED_PBX_S_X4 = 84;
+    /**
+     * CDMA LOW PBX X S4 tone: {1300Hz 25ms 1450Hz 25ms} 8 times,
+     * 200ms OFF, {1300Hz 25ms 1450Hz 25ms} 8 times, 200ms OFF,
+     * {1300Hz 25ms 1450Hz 25ms} 8 times, 200ms OFF,
+     * {1300Hz 25ms 1450Hz 25ms} 8 times, 800ms OFF, REPEAT...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_LOW_PBX_S_X4 = 85;
+    /**
+     * CDMA Alert Network Lite tone: 1109Hz 62ms ON, 784Hz 62ms ON, 740Hz 62ms ON
+     * 622Hz 62ms ON, 1109Hz 62ms ON
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int    TONE_CDMA_ALERT_NETWORK_LITE = 86;
+    /**
+     * CDMA Alert Auto Redial tone: {1245Hz 62ms ON, 659Hz 62ms ON} 3 times,
+     * 1245 62ms ON
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int    TONE_CDMA_ALERT_AUTOREDIAL_LITE = 87;
+    /**
+     * CDMA One Min Beep tone: 1150Hz+770Hz 400ms ON
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int    TONE_CDMA_ONE_MIN_BEEP = 88;
+    /**
+     *
+     * CDMA KEYPAD Volume key lite tone: 941Hz+1477Hz 120ms ON
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int    TONE_CDMA_KEYPAD_VOLUME_KEY_LITE = 89;
+    /**
+     * CDMA PRESSHOLDKEY LITE tone: 587Hz 375ms ON, 1175Hz 125ms ON
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int    TONE_CDMA_PRESSHOLDKEY_LITE = 90;
+    /**
+     * CDMA ALERT INCALL LITE tone: 587Hz 62ms, 784 62ms, 831Hz 62ms,
+     * 784Hz 62ms, 1109 62ms, 784Hz 62ms, 831Hz 62ms, 784Hz 62ms
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int    TONE_CDMA_ALERT_INCALL_LITE = 91;
+    /**
+     * CDMA EMERGENCY RINGBACK tone: {941Hz 125ms ON, 10ms OFF} 3times
+     * 4990ms OFF, REPEAT...
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int    TONE_CDMA_EMERGENCY_RINGBACK = 92;
+    /**
+     * CDMA ALERT CALL GUARD tone: {1319Hz 125ms ON, 125ms OFF} 3 times
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int    TONE_CDMA_ALERT_CALL_GUARD = 93;
+    /**
+     * CDMA SOFT ERROR LITE  tone: 1047Hz 125ms ON, 370Hz 125ms
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int    TONE_CDMA_SOFT_ERROR_LITE = 94;
+    /**
+     * CDMA CALLDROP LITE tone: 1480Hz 125ms, 1397Hz 125ms, 784Hz 125ms
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int    TONE_CDMA_CALLDROP_LITE = 95;
+    /**
+     * CDMA_NETWORK_BUSY_ONE_SHOT tone: 425Hz 500ms ON, 500ms OFF.
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int    TONE_CDMA_NETWORK_BUSY_ONE_SHOT = 96;
+    /**
+     * CDMA_ABBR_ALERT tone: 1150Hz+770Hz 400ms ON
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int    TONE_CDMA_ABBR_ALERT = 97;
+    /**
+     * CDMA_SIGNAL_OFF - silent tone
+     *
+     * @see #ToneGenerator(int, int)
+     */
+    public static final int TONE_CDMA_SIGNAL_OFF = 98;
+
+    /** Maximum volume, for use with {@link #ToneGenerator(int,int)} */
+    public static final int MAX_VOLUME = 100;
+    /** Minimum volume setting, for use with {@link #ToneGenerator(int,int)} */
+    public static final int MIN_VOLUME = 0;
+
+
+    /**
+     * ToneGenerator class contructor specifying output stream type and volume.
+     *
+     * @param streamType The streame type used for tone playback (e.g. STREAM_MUSIC).
+     * @param volume     The volume of the tone, given in percentage of maximum volume (from 0-100).
+     *
+     */
+    public ToneGenerator(int streamType, int volume) {
+        native_setup(streamType, volume, getCurrentOpPackageName());
+    }
+
+    /**
+     * This method starts the playback of a tone of the specified type.
+     * only one tone can play at a time: if a tone is playing while this method is called,
+     * this tone is stopped and replaced by the one requested.
+     * @param toneType   The type of tone generated chosen from the following list:
+     * <ul>
+     * <li>{@link #TONE_DTMF_0}
+     * <li>{@link #TONE_DTMF_1}
+     * <li>{@link #TONE_DTMF_2}
+     * <li>{@link #TONE_DTMF_3}
+     * <li>{@link #TONE_DTMF_4}
+     * <li>{@link #TONE_DTMF_5}
+     * <li>{@link #TONE_DTMF_6}
+     * <li>{@link #TONE_DTMF_7}
+     * <li>{@link #TONE_DTMF_8}
+     * <li>{@link #TONE_DTMF_9}
+     * <li>{@link #TONE_DTMF_A}
+     * <li>{@link #TONE_DTMF_B}
+     * <li>{@link #TONE_DTMF_C}
+     * <li>{@link #TONE_DTMF_D}
+     * <li>{@link #TONE_SUP_DIAL}
+     * <li>{@link #TONE_SUP_BUSY}
+     * <li>{@link #TONE_SUP_CONGESTION}
+     * <li>{@link #TONE_SUP_RADIO_ACK}
+     * <li>{@link #TONE_SUP_RADIO_NOTAVAIL}
+     * <li>{@link #TONE_SUP_ERROR}
+     * <li>{@link #TONE_SUP_CALL_WAITING}
+     * <li>{@link #TONE_SUP_RINGTONE}
+     * <li>{@link #TONE_PROP_BEEP}
+     * <li>{@link #TONE_PROP_ACK}
+     * <li>{@link #TONE_PROP_NACK}
+     * <li>{@link #TONE_PROP_PROMPT}
+     * <li>{@link #TONE_PROP_BEEP2}
+     * <li>{@link #TONE_SUP_INTERCEPT}
+     * <li>{@link #TONE_SUP_INTERCEPT_ABBREV}
+     * <li>{@link #TONE_SUP_CONGESTION_ABBREV}
+     * <li>{@link #TONE_SUP_CONFIRM}
+     * <li>{@link #TONE_SUP_PIP}
+     * <li>{@link #TONE_CDMA_DIAL_TONE_LITE}
+     * <li>{@link #TONE_CDMA_NETWORK_USA_RINGBACK}
+     * <li>{@link #TONE_CDMA_INTERCEPT}
+     * <li>{@link #TONE_CDMA_ABBR_INTERCEPT}
+     * <li>{@link #TONE_CDMA_REORDER}
+     * <li>{@link #TONE_CDMA_ABBR_REORDER}
+     * <li>{@link #TONE_CDMA_NETWORK_BUSY}
+     * <li>{@link #TONE_CDMA_CONFIRM}
+     * <li>{@link #TONE_CDMA_ANSWER}
+     * <li>{@link #TONE_CDMA_NETWORK_CALLWAITING}
+     * <li>{@link #TONE_CDMA_PIP}
+     * <li>{@link #TONE_CDMA_CALL_SIGNAL_ISDN_NORMAL}
+     * <li>{@link #TONE_CDMA_CALL_SIGNAL_ISDN_INTERGROUP}
+     * <li>{@link #TONE_CDMA_CALL_SIGNAL_ISDN_SP_PRI}
+     * <li>{@link #TONE_CDMA_CALL_SIGNAL_ISDN_PAT3}
+     * <li>{@link #TONE_CDMA_CALL_SIGNAL_ISDN_PING_RING}
+     * <li>{@link #TONE_CDMA_CALL_SIGNAL_ISDN_PAT5}
+     * <li>{@link #TONE_CDMA_CALL_SIGNAL_ISDN_PAT6}
+     * <li>{@link #TONE_CDMA_CALL_SIGNAL_ISDN_PAT7}
+     * <li>{@link #TONE_CDMA_HIGH_L}
+     * <li>{@link #TONE_CDMA_MED_L}
+     * <li>{@link #TONE_CDMA_LOW_L}
+     * <li>{@link #TONE_CDMA_HIGH_SS}
+     * <li>{@link #TONE_CDMA_MED_SS}
+     * <li>{@link #TONE_CDMA_LOW_SS}
+     * <li>{@link #TONE_CDMA_HIGH_SSL}
+     * <li>{@link #TONE_CDMA_MED_SSL}
+     * <li>{@link #TONE_CDMA_LOW_SSL}
+     * <li>{@link #TONE_CDMA_HIGH_SS_2}
+     * <li>{@link #TONE_CDMA_MED_SS_2}
+     * <li>{@link #TONE_CDMA_LOW_SS_2}
+     * <li>{@link #TONE_CDMA_HIGH_SLS}
+     * <li>{@link #TONE_CDMA_MED_SLS}
+     * <li>{@link #TONE_CDMA_LOW_SLS}
+     * <li>{@link #TONE_CDMA_HIGH_S_X4}
+     * <li>{@link #TONE_CDMA_MED_S_X4}
+     * <li>{@link #TONE_CDMA_LOW_S_X4}
+     * <li>{@link #TONE_CDMA_HIGH_PBX_L}
+     * <li>{@link #TONE_CDMA_MED_PBX_L}
+     * <li>{@link #TONE_CDMA_LOW_PBX_L}
+     * <li>{@link #TONE_CDMA_HIGH_PBX_SS}
+     * <li>{@link #TONE_CDMA_MED_PBX_SS}
+     * <li>{@link #TONE_CDMA_LOW_PBX_SS}
+     * <li>{@link #TONE_CDMA_HIGH_PBX_SSL}
+     * <li>{@link #TONE_CDMA_MED_PBX_SSL}
+     * <li>{@link #TONE_CDMA_LOW_PBX_SSL}
+     * <li>{@link #TONE_CDMA_HIGH_PBX_SLS}
+     * <li>{@link #TONE_CDMA_MED_PBX_SLS}
+     * <li>{@link #TONE_CDMA_LOW_PBX_SLS}
+     * <li>{@link #TONE_CDMA_HIGH_PBX_S_X4}
+     * <li>{@link #TONE_CDMA_MED_PBX_S_X4}
+     * <li>{@link #TONE_CDMA_LOW_PBX_S_X4}
+     * <li>{@link #TONE_CDMA_ALERT_NETWORK_LITE}
+     * <li>{@link #TONE_CDMA_ALERT_AUTOREDIAL_LITE}
+     * <li>{@link #TONE_CDMA_ONE_MIN_BEEP}
+     * <li>{@link #TONE_CDMA_KEYPAD_VOLUME_KEY_LITE}
+     * <li>{@link #TONE_CDMA_PRESSHOLDKEY_LITE}
+     * <li>{@link #TONE_CDMA_ALERT_INCALL_LITE}
+     * <li>{@link #TONE_CDMA_EMERGENCY_RINGBACK}
+     * <li>{@link #TONE_CDMA_ALERT_CALL_GUARD}
+     * <li>{@link #TONE_CDMA_SOFT_ERROR_LITE}
+     * <li>{@link #TONE_CDMA_CALLDROP_LITE}
+     * <li>{@link #TONE_CDMA_NETWORK_BUSY_ONE_SHOT}
+     * <li>{@link #TONE_CDMA_ABBR_ALERT}
+     * <li>{@link #TONE_CDMA_SIGNAL_OFF}
+     * </ul>
+     * @see #ToneGenerator(int, int)
+    */
+    public boolean startTone(int toneType) {
+        return startTone(toneType, -1);
+    }
+
+    /**
+     * This method starts the playback of a tone of the specified type for the specified duration.
+     * @param toneType   The type of tone generated @see {@link #startTone(int)}.
+     * @param durationMs  The tone duration in milliseconds. If the tone is limited in time by definition,
+     * the actual duration will be the minimum of durationMs and the defined tone duration. Setting durationMs to -1,
+     * is equivalent to calling {@link #startTone(int)}.
+    */
+    public native boolean startTone(int toneType, int durationMs);
+
+    /**
+     * This method stops the tone currently playing playback.
+     * @see #ToneGenerator(int, int)
+     */
+    public native void stopTone();
+
+    /**
+     * Releases resources associated with this ToneGenerator object. It is good
+     * practice to call this method when you're done using the ToneGenerator.
+     */
+    public native void release();
+
+    private native void native_setup(
+            int streamType, int volume, @NonNull String opPackageName);
+
+    private native final void native_finalize();
+
+    /**
+    * Returns the audio session ID.
+    *
+    * @return the ID of the audio session this ToneGenerator belongs to or 0 if an error
+    * occured.
+    */
+    public native final int getAudioSessionId();
+
+    @Override
+    protected void finalize() { native_finalize(); }
+
+    private String getCurrentOpPackageName() {
+        return TextUtils.emptyIfNull(ActivityThread.currentOpPackageName());
+    }
+
+    @SuppressWarnings("unused")
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private long mNativeContext; // accessed by native methods
+}
diff --git a/android/media/TtmlRenderer.java b/android/media/TtmlRenderer.java
new file mode 100644
index 0000000..3a6c390
--- /dev/null
+++ b/android/media/TtmlRenderer.java
@@ -0,0 +1,749 @@
+/*
+ * Copyright (C) 2014 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.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.os.Build;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.accessibility.CaptioningManager;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlPullParserFactory;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.TreeSet;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/** @hide */
+public class TtmlRenderer extends SubtitleController.Renderer {
+    private final Context mContext;
+
+    private static final String MEDIA_MIMETYPE_TEXT_TTML = "application/ttml+xml";
+
+    private TtmlRenderingWidget mRenderingWidget;
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public TtmlRenderer(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public boolean supports(MediaFormat format) {
+        if (format.containsKey(MediaFormat.KEY_MIME)) {
+            return format.getString(MediaFormat.KEY_MIME).equals(MEDIA_MIMETYPE_TEXT_TTML);
+        }
+        return false;
+    }
+
+    @Override
+    public SubtitleTrack createTrack(MediaFormat format) {
+        if (mRenderingWidget == null) {
+            mRenderingWidget = new TtmlRenderingWidget(mContext);
+        }
+        return new TtmlTrack(mRenderingWidget, format);
+    }
+}
+
+/**
+ * A class which provides utillity methods for TTML parsing.
+ *
+ * @hide
+ */
+final class TtmlUtils {
+    public static final String TAG_TT = "tt";
+    public static final String TAG_HEAD = "head";
+    public static final String TAG_BODY = "body";
+    public static final String TAG_DIV = "div";
+    public static final String TAG_P = "p";
+    public static final String TAG_SPAN = "span";
+    public static final String TAG_BR = "br";
+    public static final String TAG_STYLE = "style";
+    public static final String TAG_STYLING = "styling";
+    public static final String TAG_LAYOUT = "layout";
+    public static final String TAG_REGION = "region";
+    public static final String TAG_METADATA = "metadata";
+    public static final String TAG_SMPTE_IMAGE = "smpte:image";
+    public static final String TAG_SMPTE_DATA = "smpte:data";
+    public static final String TAG_SMPTE_INFORMATION = "smpte:information";
+    public static final String PCDATA = "#pcdata";
+    public static final String ATTR_BEGIN = "begin";
+    public static final String ATTR_DURATION = "dur";
+    public static final String ATTR_END = "end";
+    public static final long INVALID_TIMESTAMP = Long.MAX_VALUE;
+
+    /**
+     * Time expression RE according to the spec:
+     * http://www.w3.org/TR/ttaf1-dfxp/#timing-value-timeExpression
+     */
+    private static final Pattern CLOCK_TIME = Pattern.compile(
+            "^([0-9][0-9]+):([0-9][0-9]):([0-9][0-9])"
+            + "(?:(\\.[0-9]+)|:([0-9][0-9])(?:\\.([0-9]+))?)?$");
+
+    private static final Pattern OFFSET_TIME = Pattern.compile(
+            "^([0-9]+(?:\\.[0-9]+)?)(h|m|s|ms|f|t)$");
+
+    private TtmlUtils() {
+    }
+
+    /**
+     * Parses the given time expression and returns a timestamp in millisecond.
+     * <p>
+     * For the format of the time expression, please refer <a href=
+     * "http://www.w3.org/TR/ttaf1-dfxp/#timing-value-timeExpression">timeExpression</a>
+     *
+     * @param time A string which includes time expression.
+     * @param frameRate the framerate of the stream.
+     * @param subframeRate the sub-framerate of the stream
+     * @param tickRate the tick rate of the stream.
+     * @return the parsed timestamp in micro-second.
+     * @throws NumberFormatException if the given string does not match to the
+     *             format.
+     */
+    public static long parseTimeExpression(String time, int frameRate, int subframeRate,
+            int tickRate) throws NumberFormatException {
+        Matcher matcher = CLOCK_TIME.matcher(time);
+        if (matcher.matches()) {
+            String hours = matcher.group(1);
+            double durationSeconds = Long.parseLong(hours) * 3600;
+            String minutes = matcher.group(2);
+            durationSeconds += Long.parseLong(minutes) * 60;
+            String seconds = matcher.group(3);
+            durationSeconds += Long.parseLong(seconds);
+            String fraction = matcher.group(4);
+            durationSeconds += (fraction != null) ? Double.parseDouble(fraction) : 0;
+            String frames = matcher.group(5);
+            durationSeconds += (frames != null) ? ((double)Long.parseLong(frames)) / frameRate : 0;
+            String subframes = matcher.group(6);
+            durationSeconds += (subframes != null) ? ((double)Long.parseLong(subframes))
+                    / subframeRate / frameRate
+                    : 0;
+            return (long)(durationSeconds * 1000);
+        }
+        matcher = OFFSET_TIME.matcher(time);
+        if (matcher.matches()) {
+            String timeValue = matcher.group(1);
+            double value = Double.parseDouble(timeValue);
+            String unit = matcher.group(2);
+            if (unit.equals("h")) {
+                value *= 3600L * 1000000L;
+            } else if (unit.equals("m")) {
+                value *= 60 * 1000000;
+            } else if (unit.equals("s")) {
+                value *= 1000000;
+            } else if (unit.equals("ms")) {
+                value *= 1000;
+            } else if (unit.equals("f")) {
+                value = value / frameRate * 1000000;
+            } else if (unit.equals("t")) {
+                value = value / tickRate * 1000000;
+            }
+            return (long)value;
+        }
+        throw new NumberFormatException("Malformed time expression : " + time);
+    }
+
+    /**
+     * Applies <a href
+     * src="http://www.w3.org/TR/ttaf1-dfxp/#content-attribute-space">the
+     * default space policy</a> to the given string.
+     *
+     * @param in A string to apply the policy.
+     */
+    public static String applyDefaultSpacePolicy(String in) {
+        return applySpacePolicy(in, true);
+    }
+
+    /**
+     * Applies the space policy to the given string. This applies <a href
+     * src="http://www.w3.org/TR/ttaf1-dfxp/#content-attribute-space">the
+     * default space policy</a> with linefeed-treatment as treat-as-space
+     * or preserve.
+     *
+     * @param in A string to apply the policy.
+     * @param treatLfAsSpace Whether convert line feeds to spaces or not.
+     */
+    public static String applySpacePolicy(String in, boolean treatLfAsSpace) {
+        // Removes CR followed by LF. ref:
+        // http://www.w3.org/TR/xml/#sec-line-ends
+        String crRemoved = in.replaceAll("\r\n", "\n");
+        // Apply suppress-at-line-break="auto" and
+        // white-space-treatment="ignore-if-surrounding-linefeed"
+        String spacesNeighboringLfRemoved = crRemoved.replaceAll(" *\n *", "\n");
+        // Apply linefeed-treatment="treat-as-space"
+        String lfToSpace = treatLfAsSpace ? spacesNeighboringLfRemoved.replaceAll("\n", " ")
+                : spacesNeighboringLfRemoved;
+        // Apply white-space-collapse="true"
+        String spacesCollapsed = lfToSpace.replaceAll("[ \t\\x0B\f\r]+", " ");
+        return spacesCollapsed;
+    }
+
+    /**
+     * Returns the timed text for the given time period.
+     *
+     * @param root The root node of the TTML document.
+     * @param startUs The start time of the time period in microsecond.
+     * @param endUs The end time of the time period in microsecond.
+     */
+    public static String extractText(TtmlNode root, long startUs, long endUs) {
+        StringBuilder text = new StringBuilder();
+        extractText(root, startUs, endUs, text, false);
+        return text.toString().replaceAll("\n$", "");
+    }
+
+    private static void extractText(TtmlNode node, long startUs, long endUs, StringBuilder out,
+            boolean inPTag) {
+        if (node.mName.equals(TtmlUtils.PCDATA) && inPTag) {
+            out.append(node.mText);
+        } else if (node.mName.equals(TtmlUtils.TAG_BR) && inPTag) {
+            out.append("\n");
+        } else if (node.mName.equals(TtmlUtils.TAG_METADATA)) {
+            // do nothing.
+        } else if (node.isActive(startUs, endUs)) {
+            boolean pTag = node.mName.equals(TtmlUtils.TAG_P);
+            int length = out.length();
+            for (int i = 0; i < node.mChildren.size(); ++i) {
+                extractText(node.mChildren.get(i), startUs, endUs, out, pTag || inPTag);
+            }
+            if (pTag && length != out.length()) {
+                out.append("\n");
+            }
+        }
+    }
+
+    /**
+     * Returns a TTML fragment string for the given time period.
+     *
+     * @param root The root node of the TTML document.
+     * @param startUs The start time of the time period in microsecond.
+     * @param endUs The end time of the time period in microsecond.
+     */
+    public static String extractTtmlFragment(TtmlNode root, long startUs, long endUs) {
+        StringBuilder fragment = new StringBuilder();
+        extractTtmlFragment(root, startUs, endUs, fragment);
+        return fragment.toString();
+    }
+
+    private static void extractTtmlFragment(TtmlNode node, long startUs, long endUs,
+            StringBuilder out) {
+        if (node.mName.equals(TtmlUtils.PCDATA)) {
+            out.append(node.mText);
+        } else if (node.mName.equals(TtmlUtils.TAG_BR)) {
+            out.append("<br/>");
+        } else if (node.isActive(startUs, endUs)) {
+            out.append("<");
+            out.append(node.mName);
+            out.append(node.mAttributes);
+            out.append(">");
+            for (int i = 0; i < node.mChildren.size(); ++i) {
+                extractTtmlFragment(node.mChildren.get(i), startUs, endUs, out);
+            }
+            out.append("</");
+            out.append(node.mName);
+            out.append(">");
+        }
+    }
+}
+
+/**
+ * A container class which represents a cue in TTML.
+ * @hide
+ */
+class TtmlCue extends SubtitleTrack.Cue {
+    public String mText;
+    public String mTtmlFragment;
+
+    public TtmlCue(long startTimeMs, long endTimeMs, String text, String ttmlFragment) {
+        this.mStartTimeMs = startTimeMs;
+        this.mEndTimeMs = endTimeMs;
+        this.mText = text;
+        this.mTtmlFragment = ttmlFragment;
+    }
+}
+
+/**
+ * A container class which represents a node in TTML.
+ *
+ * @hide
+ */
+class TtmlNode {
+    public final String mName;
+    public final String mAttributes;
+    public final TtmlNode mParent;
+    public final String mText;
+    public final List<TtmlNode> mChildren = new ArrayList<TtmlNode>();
+    public final long mRunId;
+    public final long mStartTimeMs;
+    public final long mEndTimeMs;
+
+    public TtmlNode(String name, String attributes, String text, long startTimeMs, long endTimeMs,
+            TtmlNode parent, long runId) {
+        this.mName = name;
+        this.mAttributes = attributes;
+        this.mText = text;
+        this.mStartTimeMs = startTimeMs;
+        this.mEndTimeMs = endTimeMs;
+        this.mParent = parent;
+        this.mRunId = runId;
+    }
+
+    /**
+     * Check if this node is active in the given time range.
+     *
+     * @param startTimeMs The start time of the range to check in microsecond.
+     * @param endTimeMs The end time of the range to check in microsecond.
+     * @return return true if the given range overlaps the time range of this
+     *         node.
+     */
+    public boolean isActive(long startTimeMs, long endTimeMs) {
+        return this.mEndTimeMs > startTimeMs && this.mStartTimeMs < endTimeMs;
+    }
+}
+
+/**
+ * A simple TTML parser (http://www.w3.org/TR/ttaf1-dfxp/) which supports DFXP
+ * presentation profile.
+ * <p>
+ * Supported features in this parser are:
+ * <ul>
+ * <li>content
+ * <li>core
+ * <li>presentation
+ * <li>profile
+ * <li>structure
+ * <li>time-offset
+ * <li>timing
+ * <li>tickRate
+ * <li>time-clock-with-frames
+ * <li>time-clock
+ * <li>time-offset-with-frames
+ * <li>time-offset-with-ticks
+ * </ul>
+ * </p>
+ *
+ * @hide
+ */
+class TtmlParser {
+    static final String TAG = "TtmlParser";
+
+    // TODO: read and apply the following attributes if specified.
+    private static final int DEFAULT_FRAMERATE = 30;
+    private static final int DEFAULT_SUBFRAMERATE = 1;
+    private static final int DEFAULT_TICKRATE = 1;
+
+    private XmlPullParser mParser;
+    private final TtmlNodeListener mListener;
+    private long mCurrentRunId;
+
+    public TtmlParser(TtmlNodeListener listener) {
+        mListener = listener;
+    }
+
+    /**
+     * Parse TTML data. Once this is called, all the previous data are
+     * reset and it starts parsing for the given text.
+     *
+     * @param ttmlText TTML text to parse.
+     * @throws XmlPullParserException
+     * @throws IOException
+     */
+    public void parse(String ttmlText, long runId) throws XmlPullParserException, IOException {
+        mParser = null;
+        mCurrentRunId = runId;
+        loadParser(ttmlText);
+        parseTtml();
+    }
+
+    private void loadParser(String ttmlFragment) throws XmlPullParserException {
+        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
+        factory.setNamespaceAware(false);
+        mParser = factory.newPullParser();
+        StringReader in = new StringReader(ttmlFragment);
+        mParser.setInput(in);
+    }
+
+    private void extractAttribute(XmlPullParser parser, int i, StringBuilder out) {
+        out.append(" ");
+        out.append(parser.getAttributeName(i));
+        out.append("=\"");
+        out.append(parser.getAttributeValue(i));
+        out.append("\"");
+    }
+
+    private void parseTtml() throws XmlPullParserException, IOException {
+        LinkedList<TtmlNode> nodeStack = new LinkedList<TtmlNode>();
+        int depthInUnsupportedTag = 0;
+        boolean active = true;
+        while (!isEndOfDoc()) {
+            int eventType = mParser.getEventType();
+            TtmlNode parent = nodeStack.peekLast();
+            if (active) {
+                if (eventType == XmlPullParser.START_TAG) {
+                    if (!isSupportedTag(mParser.getName())) {
+                        Log.w(TAG, "Unsupported tag " + mParser.getName() + " is ignored.");
+                        depthInUnsupportedTag++;
+                        active = false;
+                    } else {
+                        TtmlNode node = parseNode(parent);
+                        nodeStack.addLast(node);
+                        if (parent != null) {
+                            parent.mChildren.add(node);
+                        }
+                    }
+                } else if (eventType == XmlPullParser.TEXT) {
+                    String text = TtmlUtils.applyDefaultSpacePolicy(mParser.getText());
+                    if (!TextUtils.isEmpty(text)) {
+                        parent.mChildren.add(new TtmlNode(
+                                TtmlUtils.PCDATA, "", text, 0, TtmlUtils.INVALID_TIMESTAMP,
+                                parent, mCurrentRunId));
+
+                    }
+                } else if (eventType == XmlPullParser.END_TAG) {
+                    if (mParser.getName().equals(TtmlUtils.TAG_P)) {
+                        mListener.onTtmlNodeParsed(nodeStack.getLast());
+                    } else if (mParser.getName().equals(TtmlUtils.TAG_TT)) {
+                        mListener.onRootNodeParsed(nodeStack.getLast());
+                    }
+                    nodeStack.removeLast();
+                }
+            } else {
+                if (eventType == XmlPullParser.START_TAG) {
+                    depthInUnsupportedTag++;
+                } else if (eventType == XmlPullParser.END_TAG) {
+                    depthInUnsupportedTag--;
+                    if (depthInUnsupportedTag == 0) {
+                        active = true;
+                    }
+                }
+            }
+            mParser.next();
+        }
+    }
+
+    private TtmlNode parseNode(TtmlNode parent) throws XmlPullParserException, IOException {
+        int eventType = mParser.getEventType();
+        if (!(eventType == XmlPullParser.START_TAG)) {
+            return null;
+        }
+        StringBuilder attrStr = new StringBuilder();
+        long start = 0;
+        long end = TtmlUtils.INVALID_TIMESTAMP;
+        long dur = 0;
+        for (int i = 0; i < mParser.getAttributeCount(); ++i) {
+            String attr = mParser.getAttributeName(i);
+            String value = mParser.getAttributeValue(i);
+            // TODO: check if it's safe to ignore the namespace of attributes as follows.
+            attr = attr.replaceFirst("^.*:", "");
+            if (attr.equals(TtmlUtils.ATTR_BEGIN)) {
+                start = TtmlUtils.parseTimeExpression(value, DEFAULT_FRAMERATE,
+                        DEFAULT_SUBFRAMERATE, DEFAULT_TICKRATE);
+            } else if (attr.equals(TtmlUtils.ATTR_END)) {
+                end = TtmlUtils.parseTimeExpression(value, DEFAULT_FRAMERATE, DEFAULT_SUBFRAMERATE,
+                        DEFAULT_TICKRATE);
+            } else if (attr.equals(TtmlUtils.ATTR_DURATION)) {
+                dur = TtmlUtils.parseTimeExpression(value, DEFAULT_FRAMERATE, DEFAULT_SUBFRAMERATE,
+                        DEFAULT_TICKRATE);
+            } else {
+                extractAttribute(mParser, i, attrStr);
+            }
+        }
+        if (parent != null) {
+            start += parent.mStartTimeMs;
+            if (end != TtmlUtils.INVALID_TIMESTAMP) {
+                end += parent.mStartTimeMs;
+            }
+        }
+        if (dur > 0) {
+            if (end != TtmlUtils.INVALID_TIMESTAMP) {
+                Log.e(TAG, "'dur' and 'end' attributes are defined at the same time." +
+                        "'end' value is ignored.");
+            }
+            end = start + dur;
+        }
+        if (parent != null) {
+            // If the end time remains unspecified, then the end point is
+            // interpreted as the end point of the external time interval.
+            if (end == TtmlUtils.INVALID_TIMESTAMP &&
+                    parent.mEndTimeMs != TtmlUtils.INVALID_TIMESTAMP &&
+                    end > parent.mEndTimeMs) {
+                end = parent.mEndTimeMs;
+            }
+        }
+        TtmlNode node = new TtmlNode(mParser.getName(), attrStr.toString(), null, start, end,
+                parent, mCurrentRunId);
+        return node;
+    }
+
+    private boolean isEndOfDoc() throws XmlPullParserException {
+        return (mParser.getEventType() == XmlPullParser.END_DOCUMENT);
+    }
+
+    private static boolean isSupportedTag(String tag) {
+        if (tag.equals(TtmlUtils.TAG_TT) || tag.equals(TtmlUtils.TAG_HEAD) ||
+                tag.equals(TtmlUtils.TAG_BODY) || tag.equals(TtmlUtils.TAG_DIV) ||
+                tag.equals(TtmlUtils.TAG_P) || tag.equals(TtmlUtils.TAG_SPAN) ||
+                tag.equals(TtmlUtils.TAG_BR) || tag.equals(TtmlUtils.TAG_STYLE) ||
+                tag.equals(TtmlUtils.TAG_STYLING) || tag.equals(TtmlUtils.TAG_LAYOUT) ||
+                tag.equals(TtmlUtils.TAG_REGION) || tag.equals(TtmlUtils.TAG_METADATA) ||
+                tag.equals(TtmlUtils.TAG_SMPTE_IMAGE) || tag.equals(TtmlUtils.TAG_SMPTE_DATA) ||
+                tag.equals(TtmlUtils.TAG_SMPTE_INFORMATION)) {
+            return true;
+        }
+        return false;
+    }
+}
+
+/** @hide */
+interface TtmlNodeListener {
+    void onTtmlNodeParsed(TtmlNode node);
+    void onRootNodeParsed(TtmlNode node);
+}
+
+/** @hide */
+class TtmlTrack extends SubtitleTrack implements TtmlNodeListener {
+    private static final String TAG = "TtmlTrack";
+
+    private final TtmlParser mParser = new TtmlParser(this);
+    private final TtmlRenderingWidget mRenderingWidget;
+    private String mParsingData;
+    private Long mCurrentRunID;
+
+    private final LinkedList<TtmlNode> mTtmlNodes;
+    private final TreeSet<Long> mTimeEvents;
+    private TtmlNode mRootNode;
+
+    TtmlTrack(TtmlRenderingWidget renderingWidget, MediaFormat format) {
+        super(format);
+
+        mTtmlNodes = new LinkedList<TtmlNode>();
+        mTimeEvents = new TreeSet<Long>();
+        mRenderingWidget = renderingWidget;
+        mParsingData = "";
+    }
+
+    @Override
+    public TtmlRenderingWidget getRenderingWidget() {
+        return mRenderingWidget;
+    }
+
+    @Override
+    public void onData(byte[] data, boolean eos, long runID) {
+        try {
+            // TODO: handle UTF-8 conversion properly
+            String str = new String(data, "UTF-8");
+
+            // implement intermixing restriction for TTML.
+            synchronized(mParser) {
+                if (mCurrentRunID != null && runID != mCurrentRunID) {
+                    throw new IllegalStateException(
+                            "Run #" + mCurrentRunID +
+                            " in progress.  Cannot process run #" + runID);
+                }
+                mCurrentRunID = runID;
+                mParsingData += str;
+                if (eos) {
+                    try {
+                        mParser.parse(mParsingData, mCurrentRunID);
+                    } catch (XmlPullParserException e) {
+                        e.printStackTrace();
+                    } catch (IOException e) {
+                        e.printStackTrace();
+                    }
+                    finishedRun(runID);
+                    mParsingData = "";
+                    mCurrentRunID = null;
+                }
+            }
+        } catch (java.io.UnsupportedEncodingException e) {
+            Log.w(TAG, "subtitle data is not UTF-8 encoded: " + e);
+        }
+    }
+
+    @Override
+    public void onTtmlNodeParsed(TtmlNode node) {
+        mTtmlNodes.addLast(node);
+        addTimeEvents(node);
+    }
+
+    @Override
+    public void onRootNodeParsed(TtmlNode node) {
+        mRootNode = node;
+        TtmlCue cue = null;
+        while ((cue = getNextResult()) != null) {
+            addCue(cue);
+        }
+        mRootNode = null;
+        mTtmlNodes.clear();
+        mTimeEvents.clear();
+    }
+
+    @Override
+    public void updateView(Vector<SubtitleTrack.Cue> activeCues) {
+        if (!mVisible) {
+            // don't keep the state if we are not visible
+            return;
+        }
+
+        if (DEBUG && mTimeProvider != null) {
+            try {
+                Log.d(TAG, "at " +
+                        (mTimeProvider.getCurrentTimeUs(false, true) / 1000) +
+                        " ms the active cues are:");
+            } catch (IllegalStateException e) {
+                Log.d(TAG, "at (illegal state) the active cues are:");
+            }
+        }
+
+        mRenderingWidget.setActiveCues(activeCues);
+    }
+
+    /**
+     * Returns a {@link TtmlCue} in the presentation time order.
+     * {@code null} is returned if there is no more timed text to show.
+     */
+    public TtmlCue getNextResult() {
+        while (mTimeEvents.size() >= 2) {
+            long start = mTimeEvents.pollFirst();
+            long end = mTimeEvents.first();
+            List<TtmlNode> activeCues = getActiveNodes(start, end);
+            if (!activeCues.isEmpty()) {
+                return new TtmlCue(start, end,
+                        TtmlUtils.applySpacePolicy(TtmlUtils.extractText(
+                                mRootNode, start, end), false),
+                        TtmlUtils.extractTtmlFragment(mRootNode, start, end));
+            }
+        }
+        return null;
+    }
+
+    private void addTimeEvents(TtmlNode node) {
+        mTimeEvents.add(node.mStartTimeMs);
+        mTimeEvents.add(node.mEndTimeMs);
+        for (int i = 0; i < node.mChildren.size(); ++i) {
+            addTimeEvents(node.mChildren.get(i));
+        }
+    }
+
+    private List<TtmlNode> getActiveNodes(long startTimeUs, long endTimeUs) {
+        List<TtmlNode> activeNodes = new ArrayList<TtmlNode>();
+        for (int i = 0; i < mTtmlNodes.size(); ++i) {
+            TtmlNode node = mTtmlNodes.get(i);
+            if (node.isActive(startTimeUs, endTimeUs)) {
+                activeNodes.add(node);
+            }
+        }
+        return activeNodes;
+    }
+}
+
+/**
+ * Widget capable of rendering TTML captions.
+ *
+ * @hide
+ */
+class TtmlRenderingWidget extends LinearLayout implements SubtitleTrack.RenderingWidget {
+
+    /** Callback for rendering changes. */
+    private OnChangedListener mListener;
+    private final TextView mTextView;
+
+    public TtmlRenderingWidget(Context context) {
+        this(context, null);
+    }
+
+    public TtmlRenderingWidget(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public TtmlRenderingWidget(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public TtmlRenderingWidget(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+        // Cannot render text over video when layer type is hardware.
+        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+
+        CaptioningManager captionManager = (CaptioningManager) context.getSystemService(
+                Context.CAPTIONING_SERVICE);
+        mTextView = new TextView(context);
+        mTextView.setTextColor(captionManager.getUserStyle().foregroundColor);
+        addView(mTextView, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
+        mTextView.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
+    }
+
+    @Override
+    public void setOnChangedListener(OnChangedListener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    public void setSize(int width, int height) {
+        final int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
+        final int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
+
+        measure(widthSpec, heightSpec);
+        layout(0, 0, width, height);
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        if (visible) {
+            setVisibility(View.VISIBLE);
+        } else {
+            setVisibility(View.GONE);
+        }
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+    }
+
+    public void setActiveCues(Vector<SubtitleTrack.Cue> activeCues) {
+        final int count = activeCues.size();
+        String subtitleText = "";
+        for (int i = 0; i < count; i++) {
+            TtmlCue cue = (TtmlCue) activeCues.get(i);
+            subtitleText += cue.mText + "\n";
+        }
+        mTextView.setText(subtitleText);
+
+        if (mListener != null) {
+            mListener.onChanged(this);
+        }
+    }
+}
diff --git a/android/media/UnsupportedSchemeException.java b/android/media/UnsupportedSchemeException.java
new file mode 100644
index 0000000..d7b5d47
--- /dev/null
+++ b/android/media/UnsupportedSchemeException.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2013 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;
+
+/**
+ * Exception thrown when an attempt is made to construct a MediaDrm object
+ * using a crypto scheme UUID that is not supported by the device
+ */
+public final class UnsupportedSchemeException extends MediaDrmException {
+    public UnsupportedSchemeException(String detailMessage) {
+        super(detailMessage);
+    }
+}
diff --git a/android/media/Utils.java b/android/media/Utils.java
new file mode 100644
index 0000000..ecb6b3d
--- /dev/null
+++ b/android/media/Utils.java
@@ -0,0 +1,660 @@
+/*
+ * Copyright (C) 2014 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Environment;
+import android.os.FileUtils;
+import android.os.Handler;
+import android.provider.OpenableColumns;
+import android.util.Log;
+import android.util.Pair;
+import android.util.Range;
+import android.util.Rational;
+import android.util.Size;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Objects;
+import java.util.Vector;
+import java.util.concurrent.Executor;
+
+/**
+ * Media Utilities
+ *
+ * This class is hidden but public to allow CTS testing and verification
+ * of the static methods and classes.
+ *
+ * @hide
+ */
+public class Utils {
+    private static final String TAG = "Utils";
+
+    /**
+     * Sorts distinct (non-intersecting) range array in ascending order.
+     * @throws java.lang.IllegalArgumentException if ranges are not distinct
+     */
+    public static <T extends Comparable<? super T>> void sortDistinctRanges(Range<T>[] ranges) {
+        Arrays.sort(ranges, new Comparator<Range<T>>() {
+            @Override
+            public int compare(Range<T> lhs, Range<T> rhs) {
+                if (lhs.getUpper().compareTo(rhs.getLower()) < 0) {
+                    return -1;
+                } else if (lhs.getLower().compareTo(rhs.getUpper()) > 0) {
+                    return 1;
+                }
+                throw new IllegalArgumentException(
+                        "sample rate ranges must be distinct (" + lhs + " and " + rhs + ")");
+            }
+        });
+    }
+
+    /**
+     * Returns the intersection of two sets of non-intersecting ranges
+     * @param one a sorted set of non-intersecting ranges in ascending order
+     * @param another another sorted set of non-intersecting ranges in ascending order
+     * @return the intersection of the two sets, sorted in ascending order
+     */
+    public static <T extends Comparable<? super T>>
+            Range<T>[] intersectSortedDistinctRanges(Range<T>[] one, Range<T>[] another) {
+        int ix = 0;
+        Vector<Range<T>> result = new Vector<Range<T>>();
+        for (Range<T> range: another) {
+            while (ix < one.length &&
+                    one[ix].getUpper().compareTo(range.getLower()) < 0) {
+                ++ix;
+            }
+            while (ix < one.length &&
+                    one[ix].getUpper().compareTo(range.getUpper()) < 0) {
+                result.add(range.intersect(one[ix]));
+                ++ix;
+            }
+            if (ix == one.length) {
+                break;
+            }
+            if (one[ix].getLower().compareTo(range.getUpper()) <= 0) {
+                result.add(range.intersect(one[ix]));
+            }
+        }
+        return result.toArray(new Range[result.size()]);
+    }
+
+    /**
+     * Returns the index of the range that contains a value in a sorted array of distinct ranges.
+     * @param ranges a sorted array of non-intersecting ranges in ascending order
+     * @param value the value to search for
+     * @return if the value is in one of the ranges, it returns the index of that range.  Otherwise,
+     * the return value is {@code (-1-index)} for the {@code index} of the range that is
+     * immediately following {@code value}.
+     */
+    public static <T extends Comparable<? super T>>
+            int binarySearchDistinctRanges(Range<T>[] ranges, T value) {
+        return Arrays.binarySearch(ranges, Range.create(value, value),
+                new Comparator<Range<T>>() {
+                    @Override
+                    public int compare(Range<T> lhs, Range<T> rhs) {
+                        if (lhs.getUpper().compareTo(rhs.getLower()) < 0) {
+                            return -1;
+                        } else if (lhs.getLower().compareTo(rhs.getUpper()) > 0) {
+                            return 1;
+                        }
+                        return 0;
+                    }
+                });
+    }
+
+    /**
+     * Returns greatest common divisor
+     */
+    static int gcd(int a, int b) {
+        if (a == 0 && b == 0) {
+            return 1;
+        }
+        if (b < 0) {
+            b = -b;
+        }
+        if (a < 0) {
+            a = -a;
+        }
+        while (a != 0) {
+            int c = b % a;
+            b = a;
+            a = c;
+        }
+        return b;
+    }
+
+    /** Returns the equivalent factored range {@code newrange}, where for every
+     * {@code e}: {@code newrange.contains(e)} implies that {@code range.contains(e * factor)},
+     * and {@code !newrange.contains(e)} implies that {@code !range.contains(e * factor)}.
+     */
+    static Range<Integer>factorRange(Range<Integer> range, int factor) {
+        if (factor == 1) {
+            return range;
+        }
+        return Range.create(divUp(range.getLower(), factor), range.getUpper() / factor);
+    }
+
+    /** Returns the equivalent factored range {@code newrange}, where for every
+     * {@code e}: {@code newrange.contains(e)} implies that {@code range.contains(e * factor)},
+     * and {@code !newrange.contains(e)} implies that {@code !range.contains(e * factor)}.
+     */
+    static Range<Long>factorRange(Range<Long> range, long factor) {
+        if (factor == 1) {
+            return range;
+        }
+        return Range.create(divUp(range.getLower(), factor), range.getUpper() / factor);
+    }
+
+    private static Rational scaleRatio(Rational ratio, int num, int den) {
+        int common = gcd(num, den);
+        num /= common;
+        den /= common;
+        return new Rational(
+                (int)(ratio.getNumerator() * (double)num),     // saturate to int
+                (int)(ratio.getDenominator() * (double)den));  // saturate to int
+    }
+
+    static Range<Rational> scaleRange(Range<Rational> range, int num, int den) {
+        if (num == den) {
+            return range;
+        }
+        return Range.create(
+                scaleRatio(range.getLower(), num, den),
+                scaleRatio(range.getUpper(), num, den));
+    }
+
+    static Range<Integer> alignRange(Range<Integer> range, int align) {
+        return range.intersect(
+                divUp(range.getLower(), align) * align,
+                (range.getUpper() / align) * align);
+    }
+
+    static int divUp(int num, int den) {
+        return (num + den - 1) / den;
+    }
+
+    static long divUp(long num, long den) {
+        return (num + den - 1) / den;
+    }
+
+    /**
+     * Returns least common multiple
+     */
+    private static long lcm(int a, int b) {
+        if (a == 0 || b == 0) {
+            throw new IllegalArgumentException("lce is not defined for zero arguments");
+        }
+        return (long)a * b / gcd(a, b);
+    }
+
+    static Range<Integer> intRangeFor(double v) {
+        return Range.create((int)v, (int)Math.ceil(v));
+    }
+
+    static Range<Long> longRangeFor(double v) {
+        return Range.create((long)v, (long)Math.ceil(v));
+    }
+
+    static Size parseSize(Object o, Size fallback) {
+        if (o == null) {
+            return fallback;
+        }
+        try {
+            return Size.parseSize((String) o);
+        } catch (ClassCastException e) {
+        } catch (NumberFormatException e) {
+        }
+        Log.w(TAG, "could not parse size '" + o + "'");
+        return fallback;
+    }
+
+    static int parseIntSafely(Object o, int fallback) {
+        if (o == null) {
+            return fallback;
+        }
+        try {
+            String s = (String)o;
+            return Integer.parseInt(s);
+        } catch (ClassCastException e) {
+        } catch (NumberFormatException e) {
+        }
+        Log.w(TAG, "could not parse integer '" + o + "'");
+        return fallback;
+    }
+
+    static Range<Integer> parseIntRange(Object o, Range<Integer> fallback) {
+        if (o == null) {
+            return fallback;
+        }
+        try {
+            String s = (String)o;
+            int ix = s.indexOf('-');
+            if (ix >= 0) {
+                return Range.create(
+                        Integer.parseInt(s.substring(0, ix), 10),
+                        Integer.parseInt(s.substring(ix + 1), 10));
+            }
+            int value = Integer.parseInt(s);
+            return Range.create(value, value);
+        } catch (ClassCastException e) {
+        } catch (NumberFormatException e) {
+        } catch (IllegalArgumentException e) {
+        }
+        Log.w(TAG, "could not parse integer range '" + o + "'");
+        return fallback;
+    }
+
+    static Range<Long> parseLongRange(Object o, Range<Long> fallback) {
+        if (o == null) {
+            return fallback;
+        }
+        try {
+            String s = (String)o;
+            int ix = s.indexOf('-');
+            if (ix >= 0) {
+                return Range.create(
+                        Long.parseLong(s.substring(0, ix), 10),
+                        Long.parseLong(s.substring(ix + 1), 10));
+            }
+            long value = Long.parseLong(s);
+            return Range.create(value, value);
+        } catch (ClassCastException e) {
+        } catch (NumberFormatException e) {
+        } catch (IllegalArgumentException e) {
+        }
+        Log.w(TAG, "could not parse long range '" + o + "'");
+        return fallback;
+    }
+
+    static Range<Rational> parseRationalRange(Object o, Range<Rational> fallback) {
+        if (o == null) {
+            return fallback;
+        }
+        try {
+            String s = (String)o;
+            int ix = s.indexOf('-');
+            if (ix >= 0) {
+                return Range.create(
+                        Rational.parseRational(s.substring(0, ix)),
+                        Rational.parseRational(s.substring(ix + 1)));
+            }
+            Rational value = Rational.parseRational(s);
+            return Range.create(value, value);
+        } catch (ClassCastException e) {
+        } catch (NumberFormatException e) {
+        } catch (IllegalArgumentException e) {
+        }
+        Log.w(TAG, "could not parse rational range '" + o + "'");
+        return fallback;
+    }
+
+    static Pair<Size, Size> parseSizeRange(Object o) {
+        if (o == null) {
+            return null;
+        }
+        try {
+            String s = (String)o;
+            int ix = s.indexOf('-');
+            if (ix >= 0) {
+                return Pair.create(
+                        Size.parseSize(s.substring(0, ix)),
+                        Size.parseSize(s.substring(ix + 1)));
+            }
+            Size value = Size.parseSize(s);
+            return Pair.create(value, value);
+        } catch (ClassCastException e) {
+        } catch (NumberFormatException e) {
+        } catch (IllegalArgumentException e) {
+        }
+        Log.w(TAG, "could not parse size range '" + o + "'");
+        return null;
+    }
+
+    /**
+     * Creates a unique file in the specified external storage with the desired name. If the name is
+     * taken, the new file's name will have '(%d)' to avoid overwriting files.
+     *
+     * @param context {@link Context} to query the file name from.
+     * @param subdirectory One of the directories specified in {@link android.os.Environment}
+     * @param fileName desired name for the file.
+     * @param mimeType MIME type of the file to create.
+     * @return the File object in the storage, or null if an error occurs.
+     */
+    public static File getUniqueExternalFile(Context context, String subdirectory, String fileName,
+            String mimeType) {
+        File externalStorage = Environment.getExternalStoragePublicDirectory(subdirectory);
+        // Make sure the storage subdirectory exists
+        externalStorage.mkdirs();
+
+        File outFile = null;
+        try {
+            // Ensure the file has a unique name, as to not override any existing file
+            outFile = FileUtils.buildUniqueFile(externalStorage, mimeType, fileName);
+        } catch (FileNotFoundException e) {
+            // This might also be reached if the number of repeated files gets too high
+            Log.e(TAG, "Unable to get a unique file name: " + e);
+            return null;
+        }
+        return outFile;
+    }
+
+    /**
+     * Returns a file's display name from its {@link android.content.ContentResolver.SCHEME_FILE}
+     * or {@link android.content.ContentResolver.SCHEME_CONTENT} Uri. The display name of a file
+     * includes its extension.
+     *
+     * @param context Context trying to resolve the file's display name.
+     * @param uri Uri of the file.
+     * @return the file's display name, or the uri's string if something fails or the uri isn't in
+     *            the schemes specified above.
+     */
+    static String getFileDisplayNameFromUri(Context context, Uri uri) {
+        String scheme = uri.getScheme();
+
+        if (ContentResolver.SCHEME_FILE.equals(scheme)) {
+            return uri.getLastPathSegment();
+        } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
+            // We need to query the ContentResolver to get the actual file name as the Uri masks it.
+            // This means we want the name used for display purposes only.
+            String[] proj = {
+                    OpenableColumns.DISPLAY_NAME
+            };
+            try (Cursor cursor = context.getContentResolver().query(uri, proj, null, null, null)) {
+                if (cursor != null && cursor.getCount() != 0) {
+                    cursor.moveToFirst();
+                    return cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
+                }
+            }
+        }
+
+        // This will only happen if the Uri isn't either SCHEME_CONTENT or SCHEME_FILE, so we assume
+        // it already represents the file's name.
+        return uri.toString();
+    }
+
+    /**
+     * {@code ListenerList} is a helper class that delivers events to listeners.
+     *
+     * It is written to isolate the <strong>mechanics</strong> of event delivery from the
+     * <strong>details</strong> of those events.
+     *
+     * The {@code ListenerList} is parameterized on the generic type {@code V}
+     * of the object delivered by {@code notify()}.
+     * This gives compile time type safety over run-time casting of a general {@code Object},
+     * much like {@code HashMap&lt;String, Object&gt;} does not give type safety of the
+     * stored {@code Object} value and may allow
+     * permissive storage of {@code Object}s that are not expected by users of the
+     * {@code HashMap}, later resulting in run-time cast exceptions that
+     * could have been caught by replacing
+     * {@code Object} with a more precise type to enforce a compile time contract.
+     *
+     * The {@code ListenerList} is implemented as a single method callback
+     * - or a "listener" according to Android style guidelines.
+     *
+     * The {@code ListenerList} can be trivially extended by a suitable lambda to implement
+     * a <strong> multiple method abstract class</strong> "callback",
+     * in which the generic type {@code V} could be an {@code Object}
+     * to encapsulate the details of the parameters of each callback method, and
+     * {@code instanceof} could be used to disambiguate which callback method to use.
+     * A {@link Bundle} could alternatively encapsulate those generic parameters,
+     * perhaps more conveniently.
+     * Again, this is a detail of the event, not the mechanics of the event delivery,
+     * which this class is concerned with.
+     *
+     * For details on how to use this class to implement a <strong>single listener</strong>
+     * {@code ListenerList}, see notes on {@link #add}.
+     *
+     * For details on how to optimize this class to implement
+     * a listener based on {@link Handler}s
+     * instead of {@link Executor}s, see{@link #ListenerList(boolean, boolean, boolean)}.
+     *
+     * This is a TestApi for CTS Unit Testing, not exposed for general Application use.
+     * @hide
+     *
+     * @param <V> The class of the object returned to the listener.
+     */
+    public static class ListenerList<V> {
+        /**
+         * The Listener interface for callback.
+         *
+         * @param <V> The class of the object returned to the listener
+         */
+        public interface Listener<V> {
+            /**
+             * General event listener interface which is managed by the {@code ListenerList}.
+             *
+             * @param eventCode is an integer representing the event type. This is an
+             *     implementation defined parameter.
+             * @param info is the object returned to the listener.  It is expected
+             *     that the listener makes a private copy of the {@code info} object before
+             *     modification, as it is the same instance passed to all listeners.
+             *     This is an implementation defined parameter that may be null.
+             */
+            void onEvent(int eventCode, @Nullable V info);
+        }
+
+        private interface ListenerWithCancellation<V> extends Listener<V> {
+            void cancel();
+        }
+
+        /**
+         * Default {@code ListenerList} constructor for {@link Executor} based implementation.
+         *
+         * TODO: consider adding a "name" for debugging if this is used for
+         * multiple listener implementations.
+         */
+        public ListenerList() {
+            this(true /* restrictSingleCallerOnEvent */,
+                true /* clearCallingIdentity */,
+                false /* forceRemoveConsistency*/);
+        }
+
+        /**
+         * Specific {@code ListenerList} constructor for customization.
+         *
+         * See the internal notes for the corresponding private variables on the behavior of
+         * the boolean configuration parameters.
+         *
+         * {@code ListenerList(true, true, false)} is the default and used for
+         * {@link Executor} based notification implementation.
+         *
+         * {@code ListenerList(false, false, false)} may be used for as an optimization
+         * where the {@link Executor} is actually a {@link Handler} post.
+         *
+         * @param restrictSingleCallerOnEvent whether the listener will only be called by
+         *     a single thread at a time.
+         * @param clearCallingIdentity whether the binder calling identity on
+         *     {@link #notify} is cleared.
+         * @param forceRemoveConsistency whether remove() guarantees no more callbacks to
+         *     the listener immediately after the call.
+         */
+        public ListenerList(boolean restrictSingleCallerOnEvent,
+                boolean clearCallingIdentity,
+                boolean forceRemoveConsistency) {
+            mRestrictSingleCallerOnEvent = restrictSingleCallerOnEvent;
+            mClearCallingIdentity = clearCallingIdentity;
+            mForceRemoveConsistency = forceRemoveConsistency;
+        }
+
+        /**
+         * Adds a listener to the {@code ListenerList}.
+         *
+         * The {@code ListenerList} is most often used to hold {@code multiple} listeners.
+         *
+         * Per Android style, for a single method Listener interface, the add and remove
+         * would be wrapped in "addSomeListener" or "removeSomeListener";
+         * or a lambda implemented abstract class callback, wrapped in
+         * "registerSomeCallback" or "unregisterSomeCallback".
+         *
+         * We allow a general {@code key} to be attached to add and remove that specific
+         * listener.  It could be the {@code listener} object itself.
+         *
+         * For some implementations, there may be only a {@code single} listener permitted.
+         *
+         * Per Android style, for a single listener {@code ListenerList},
+         * the naming of the wrapping call to {@link #add} would be
+         * "setSomeListener" with a nullable listener, which would be null
+         * to call {@link #remove}.
+         *
+         * In that case, the caller may use this {@link #add} with a single constant object for
+         * the {@code key} to enforce only one Listener in the {@code ListenerList}.
+         * Likewise on remove it would use that
+         * same single constant object to remove the listener.
+         * That {@code key} object could be the {@code ListenerList} itself for convenience.
+         *
+         * @param key is a unique object that is used to identify the listener
+         *     when {@code remove()} is called. It can be the listener itself.
+         * @param executor is used to execute the callback.
+         * @param listener is the {@link AudioTrack.ListenerList.Listener}
+         *     interface to be called upon {@link notify}.
+         */
+        public void add(
+                @NonNull Object key, @NonNull Executor executor, @NonNull Listener<V> listener) {
+            Objects.requireNonNull(key);
+            Objects.requireNonNull(executor);
+            Objects.requireNonNull(listener);
+
+            // construct wrapper outside of lock.
+            ListenerWithCancellation<V> listenerWithCancellation =
+                    new ListenerWithCancellation<V>() {
+                        private final Object mLock = new Object(); // our lock is per Listener.
+                        private volatile boolean mCancelled = false; // atomic rmw not needed.
+
+                        @Override
+                        public void onEvent(int eventCode, V info) {
+                            executor.execute(() -> {
+                                // Note deep execution of locking and cancellation
+                                // so this works after posting on different threads.
+                                if (mRestrictSingleCallerOnEvent || mForceRemoveConsistency) {
+                                    synchronized (mLock) {
+                                        if (mCancelled) return;
+                                        listener.onEvent(eventCode, info);
+                                    }
+                                } else {
+                                    if (mCancelled) return;
+                                    listener.onEvent(eventCode, info);
+                                }
+                            });
+                        }
+
+                        @Override
+                        public void cancel() {
+                            if (mForceRemoveConsistency) {
+                                synchronized (mLock) {
+                                    mCancelled = true;
+                                }
+                            } else {
+                                mCancelled = true;
+                            }
+                        }
+                    };
+
+            synchronized (mListeners) {
+                // TODO: consider an option to check the existence of the key
+                // and throw an ISE if it exists.
+                mListeners.put(key, listenerWithCancellation);  // replaces old value
+            }
+        }
+
+        /**
+         * Removes a listener from the {@code ListenerList}.
+         *
+         * @param key the unique object associated with the listener during {@link #add}.
+         */
+        public void remove(@NonNull Object key) {
+            Objects.requireNonNull(key);
+
+            ListenerWithCancellation<V> listener;
+            synchronized (mListeners) {
+                listener = mListeners.get(key);
+                if (listener == null) { // TODO: consider an option to throw ISE Here.
+                    return;
+                }
+                mListeners.remove(key);  // removes if exist
+            }
+
+            // cancel outside of lock
+            listener.cancel();
+        }
+
+        /**
+         * Notifies all listeners on the List.
+         *
+         * @param eventCode to pass to all listeners.
+         * @param info to pass to all listeners. This is an implemention defined parameter
+         *     which may be {@code null}.
+         */
+        public void notify(int eventCode, @Nullable V info) {
+            Object[] listeners; // note we can't cast an object array to a listener array
+            synchronized (mListeners) {
+                if (mListeners.size() == 0) {
+                    return;
+                }
+                listeners = mListeners.values().toArray(); // guarantees a copy.
+            }
+
+            // notify outside of lock.
+            final Long identity = mClearCallingIdentity ? Binder.clearCallingIdentity() : null;
+            try {
+                for (Object object : listeners) {
+                    final ListenerWithCancellation<V> listener =
+                            (ListenerWithCancellation<V>) object;
+                    listener.onEvent(eventCode, info);
+                }
+            } finally {
+                if (identity != null) {
+                    Binder.restoreCallingIdentity(identity);
+                }
+            }
+        }
+
+        @GuardedBy("mListeners")
+        private HashMap<Object, ListenerWithCancellation<V>> mListeners = new HashMap<>();
+
+        // An Executor may run in multiple threads, whereas a Handler runs on a single Looper.
+        // Should be true for an Executor to avoid concurrent calling into the same listener,
+        // can be false for a Handler as a Handler forces single thread caller for each listener.
+        private final boolean mRestrictSingleCallerOnEvent; // default true
+
+        // An Executor may run in the calling thread, whereas a handler will post to the Looper.
+        // Should be true for an Executor to prevent privilege escalation,
+        // can be false for a Handler as its thread is not the calling binder thread.
+        private final boolean mClearCallingIdentity; // default true
+
+        // Guaranteeing no listener callbacks after removal requires taking the same lock for the
+        // remove as the callback; this is a reversal in calling layers,
+        // hence the risk of lock order inversion is great.
+        //
+        // Set to true only if you can control the caller's listen and remove methods and/or
+        // the threading of the Executor used for each listener.
+        // When set to false, we do not lock, but still do a best effort to cancel messages
+        // on the fly.
+        private final boolean mForceRemoveConsistency; // default false
+    }
+}
diff --git a/android/media/VolumeAutomation.java b/android/media/VolumeAutomation.java
new file mode 100644
index 0000000..ff2e645
--- /dev/null
+++ b/android/media/VolumeAutomation.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2017 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.annotation.NonNull;
+import android.media.VolumeShaper.Configuration;
+
+/**
+ * {@code VolumeAutomation} defines an interface for automatic volume control
+ * of {@link AudioTrack} and {@link MediaPlayer} objects.
+ */
+public interface VolumeAutomation {
+    /**
+     * Returns a {@link VolumeShaper} object that can be used modify the volume envelope
+     * of the player or track.
+     *
+     * @param configuration the {@link VolumeShaper.Configuration configuration}
+     *        that specifies the curve and duration to use.
+     * @return a {@code VolumeShaper} object
+     * @throws IllegalArgumentException if the {@code configuration} is not allowed by the player.
+     * @throws IllegalStateException if too many {@code VolumeShaper}s are requested
+     *         or the state of the player does not permit its creation (e.g. player is released).
+     */
+    public @NonNull VolumeShaper createVolumeShaper(
+            @NonNull VolumeShaper.Configuration configuration);
+}
diff --git a/android/media/VolumePolicy.java b/android/media/VolumePolicy.java
new file mode 100644
index 0000000..b193b70
--- /dev/null
+++ b/android/media/VolumePolicy.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2015 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.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.Objects;
+
+/** @hide */
+public final class VolumePolicy implements Parcelable {
+    public static final VolumePolicy DEFAULT = new VolumePolicy(false, false, false, 400);
+
+    /**
+     * Accessibility volume policy where the STREAM_MUSIC volume (i.e. media volume) affects
+     * the STREAM_ACCESSIBILITY volume, and vice-versa.
+     */
+    public static final int A11Y_MODE_MEDIA_A11Y_VOLUME = 0;
+    /**
+     * Accessibility volume policy where the STREAM_ACCESSIBILITY volume is independent from
+     * any other volume.
+     */
+    public static final int A11Y_MODE_INDEPENDENT_A11Y_VOLUME = 1;
+
+    /** Allow volume adjustments lower from vibrate to enter ringer mode = silent */
+    public final boolean volumeDownToEnterSilent;
+
+    /** Allow volume adjustments higher to exit ringer mode = silent */
+    public final boolean volumeUpToExitSilent;
+
+    /** Automatically enter do not disturb when ringer mode = silent */
+    public final boolean doNotDisturbWhenSilent;
+
+    /** Only allow volume adjustment from vibrate to silent after this
+        number of milliseconds since an adjustment from normal to vibrate. */
+    public final int vibrateToSilentDebounce;
+
+    public VolumePolicy(boolean volumeDownToEnterSilent, boolean volumeUpToExitSilent,
+            boolean doNotDisturbWhenSilent, int vibrateToSilentDebounce) {
+        this.volumeDownToEnterSilent = volumeDownToEnterSilent;
+        this.volumeUpToExitSilent = volumeUpToExitSilent;
+        this.doNotDisturbWhenSilent = doNotDisturbWhenSilent;
+        this.vibrateToSilentDebounce = vibrateToSilentDebounce;
+    }
+
+    @Override
+    public String toString() {
+        return "VolumePolicy[volumeDownToEnterSilent=" + volumeDownToEnterSilent
+                + ",volumeUpToExitSilent=" + volumeUpToExitSilent
+                + ",doNotDisturbWhenSilent=" + doNotDisturbWhenSilent
+                + ",vibrateToSilentDebounce=" + vibrateToSilentDebounce + "]";
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(volumeDownToEnterSilent, volumeUpToExitSilent, doNotDisturbWhenSilent,
+                vibrateToSilentDebounce);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof VolumePolicy)) return false;
+        if (o == this) return true;
+        final VolumePolicy other = (VolumePolicy) o;
+        return other.volumeDownToEnterSilent == volumeDownToEnterSilent
+                && other.volumeUpToExitSilent == volumeUpToExitSilent
+                && other.doNotDisturbWhenSilent == doNotDisturbWhenSilent
+                && other.vibrateToSilentDebounce == vibrateToSilentDebounce;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(volumeDownToEnterSilent ? 1 : 0);
+        dest.writeInt(volumeUpToExitSilent ? 1 : 0);
+        dest.writeInt(doNotDisturbWhenSilent ? 1 : 0);
+        dest.writeInt(vibrateToSilentDebounce);
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<VolumePolicy> CREATOR
+            = new Parcelable.Creator<VolumePolicy>() {
+        @Override
+        public VolumePolicy createFromParcel(Parcel p) {
+            return new VolumePolicy(p.readInt() != 0,
+                    p.readInt() != 0,
+                    p.readInt() != 0,
+                    p.readInt());
+        }
+
+        @Override
+        public VolumePolicy[] newArray(int size) {
+            return new VolumePolicy[size];
+        }
+    };
+}
\ No newline at end of file
diff --git a/android/media/VolumeProvider.java b/android/media/VolumeProvider.java
new file mode 100644
index 0000000..7cf63f4
--- /dev/null
+++ b/android/media/VolumeProvider.java
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2014 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.annotation.IntDef;
+import android.annotation.Nullable;
+import android.media.session.MediaSession;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Handles requests to adjust or set the volume on a session. This is also used
+ * to push volume updates back to the session. The provider must call
+ * {@link #setCurrentVolume(int)} each time the volume being provided changes.
+ * <p>
+ * You can set a volume provider on a session by calling
+ * {@link MediaSession#setPlaybackToRemote}.
+ */
+public abstract class VolumeProvider {
+
+    /**
+     * @hide
+     */
+    @IntDef({VOLUME_CONTROL_FIXED, VOLUME_CONTROL_RELATIVE, VOLUME_CONTROL_ABSOLUTE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ControlType {}
+
+    /**
+     * The volume is fixed and can not be modified. Requests to change volume
+     * should be ignored.
+     */
+    public static final int VOLUME_CONTROL_FIXED = 0;
+
+    /**
+     * The volume control uses relative adjustment via
+     * {@link #onAdjustVolume(int)}. Attempts to set the volume to a specific
+     * value should be ignored.
+     */
+    public static final int VOLUME_CONTROL_RELATIVE = 1;
+
+    /**
+     * The volume control uses an absolute value. It may be adjusted using
+     * {@link #onAdjustVolume(int)} or set directly using
+     * {@link #onSetVolumeTo(int)}.
+     */
+    public static final int VOLUME_CONTROL_ABSOLUTE = 2;
+
+    private final int mControlType;
+    private final int mMaxVolume;
+    private final String mControlId;
+    private int mCurrentVolume;
+    private Callback mCallback;
+
+    /**
+     * Create a new volume provider for handling volume events. You must specify
+     * the type of volume control, the maximum volume that can be used, and the
+     * current volume on the output.
+     *
+     * @param volumeControl The method for controlling volume that is used by
+     *            this provider.
+     * @param maxVolume The maximum allowed volume.
+     * @param currentVolume The current volume on the output.
+     */
+
+    public VolumeProvider(@ControlType int volumeControl, int maxVolume, int currentVolume) {
+        this(volumeControl, maxVolume, currentVolume, null);
+    }
+
+    /**
+     * Create a new volume provider for handling volume events. You must specify
+     * the type of volume control, the maximum volume that can be used, and the
+     * current volume on the output.
+     *
+     * @param volumeControl The method for controlling volume that is used by
+     *            this provider.
+     * @param maxVolume The maximum allowed volume.
+     * @param currentVolume The current volume on the output.
+     * @param volumeControlId The volume control ID of this provider.
+     */
+    public VolumeProvider(@ControlType int volumeControl, int maxVolume, int currentVolume,
+            @Nullable String volumeControlId) {
+        mControlType = volumeControl;
+        mMaxVolume = maxVolume;
+        mCurrentVolume = currentVolume;
+        mControlId = volumeControlId;
+    }
+
+    /**
+     * Get the volume control type that this volume provider uses.
+     *
+     * @return The volume control type for this volume provider
+     */
+    @ControlType
+    public final int getVolumeControl() {
+        return mControlType;
+    }
+
+    /**
+     * Get the maximum volume this provider allows.
+     *
+     * @return The max allowed volume.
+     */
+    public final int getMaxVolume() {
+        return mMaxVolume;
+    }
+
+    /**
+     * Gets the current volume. This will be the last value set by
+     * {@link #setCurrentVolume(int)}.
+     *
+     * @return The current volume.
+     */
+    public final int getCurrentVolume() {
+        return mCurrentVolume;
+    }
+
+    /**
+     * Notify the system that the current volume has been changed. This must be
+     * called every time the volume changes to ensure it is displayed properly.
+     *
+     * @param currentVolume The current volume on the output.
+     */
+    public final void setCurrentVolume(int currentVolume) {
+        mCurrentVolume = currentVolume;
+        if (mCallback != null) {
+            mCallback.onVolumeChanged(this);
+        }
+    }
+
+    /**
+     * Gets the volume control ID. It can be used to identify which volume provider is
+     * used by the session.
+     *
+     * @return the volume control ID or {@code null} if it isn't set.
+     */
+    @Nullable
+    public final String getVolumeControlId() {
+        return mControlId;
+    }
+
+    /**
+     * Override to handle requests to set the volume of the current output.
+     * After the volume has been modified {@link #setCurrentVolume} must be
+     * called to notify the system.
+     *
+     * @param volume The volume to set the output to.
+     */
+    public void onSetVolumeTo(int volume) {
+    }
+
+    /**
+     * Override to handle requests to adjust the volume of the current output.
+     * Direction will be one of {@link AudioManager#ADJUST_LOWER},
+     * {@link AudioManager#ADJUST_RAISE}, {@link AudioManager#ADJUST_SAME}.
+     * After the volume has been modified {@link #setCurrentVolume} must be
+     * called to notify the system.
+     *
+     * @param direction The direction to change the volume in.
+     */
+    public void onAdjustVolume(int direction) {
+    }
+
+    /**
+     * Sets a callback to receive volume changes.
+     * @hide
+     */
+    public void setCallback(Callback callback) {
+        mCallback = callback;
+    }
+
+    /**
+     * Listens for changes to the volume.
+     * @hide
+     */
+    public abstract static class Callback {
+        /**
+         * Called when volume changed.
+         */
+        public abstract void onVolumeChanged(VolumeProvider volumeProvider);
+    }
+}
diff --git a/android/media/VolumeShaper.java b/android/media/VolumeShaper.java
new file mode 100644
index 0000000..5bad693
--- /dev/null
+++ b/android/media/VolumeShaper.java
@@ -0,0 +1,1592 @@
+/*
+ * Copyright 2017 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.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.os.Build;
+import android.os.BadParcelableException;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * The {@code VolumeShaper} class is used to automatically control audio volume during media
+ * playback, allowing simple implementation of transition effects and ducking.
+ * It is created from implementations of {@code VolumeAutomation},
+ * such as {@code MediaPlayer} and {@code AudioTrack} (referred to as "players" below),
+ * by {@link MediaPlayer#createVolumeShaper} or {@link AudioTrack#createVolumeShaper}.
+ *
+ * A {@code VolumeShaper} is intended for short volume changes.
+ * If the audio output sink changes during
+ * a {@code VolumeShaper} transition, the precise curve position may be lost, and the
+ * {@code VolumeShaper} may advance to the end of the curve for the new audio output sink.
+ *
+ * The {@code VolumeShaper} appears as an additional scaling on the audio output,
+ * and adjusts independently of track or stream volume controls.
+ */
+public final class VolumeShaper implements AutoCloseable {
+    /* member variables */
+    private int mId;
+    private final WeakReference<PlayerBase> mWeakPlayerBase;
+
+    /* package */ VolumeShaper(
+            @NonNull Configuration configuration, @NonNull PlayerBase playerBase) {
+        mWeakPlayerBase = new WeakReference<PlayerBase>(playerBase);
+        mId = applyPlayer(configuration, new Operation.Builder().defer().build());
+    }
+
+    /* package */ int getId() {
+        return mId;
+    }
+
+    /**
+     * Applies the {@link VolumeShaper.Operation} to the {@code VolumeShaper}.
+     *
+     * Applying {@link VolumeShaper.Operation#PLAY} after {@code PLAY}
+     * or {@link VolumeShaper.Operation#REVERSE} after
+     * {@code REVERSE} has no effect.
+     *
+     * Applying {@link VolumeShaper.Operation#PLAY} when the player
+     * hasn't started will synchronously start the {@code VolumeShaper} when
+     * playback begins.
+     *
+     * @param operation the {@code operation} to apply.
+     * @throws IllegalStateException if the player is uninitialized or if there
+     *         is a critical failure. In that case, the {@code VolumeShaper} should be
+     *         recreated.
+     */
+    public void apply(@NonNull Operation operation) {
+        /* void */ applyPlayer(new VolumeShaper.Configuration(mId), operation);
+    }
+
+    /**
+     * Replaces the current {@code VolumeShaper}
+     * {@code configuration} with a new {@code configuration}.
+     *
+     * This allows the user to change the volume shape
+     * while the existing {@code VolumeShaper} is in effect.
+     *
+     * The effect of {@code replace()} is similar to an atomic close of
+     * the existing {@code VolumeShaper} and creation of a new {@code VolumeShaper}.
+     *
+     * If the {@code operation} is {@link VolumeShaper.Operation#PLAY} then the
+     * new curve starts immediately.
+     *
+     * If the {@code operation} is
+     * {@link VolumeShaper.Operation#REVERSE}, then the new curve will
+     * be delayed until {@code PLAY} is applied.
+     *
+     * @param configuration the new {@code configuration} to use.
+     * @param operation the {@code operation} to apply to the {@code VolumeShaper}
+     * @param join if true, match the start volume of the
+     *             new {@code configuration} to the current volume of the existing
+     *             {@code VolumeShaper}, to avoid discontinuity.
+     * @throws IllegalStateException if the player is uninitialized or if there
+     *         is a critical failure. In that case, the {@code VolumeShaper} should be
+     *         recreated.
+     */
+    public void replace(
+            @NonNull Configuration configuration, @NonNull Operation operation, boolean join) {
+        mId = applyPlayer(
+                configuration,
+                new Operation.Builder(operation).replace(mId, join).build());
+    }
+
+    /**
+     * Returns the current volume scale attributable to the {@code VolumeShaper}.
+     *
+     * This is the last volume from the {@code VolumeShaper} used for the player,
+     * or the initial volume if the {@code VolumeShaper} hasn't been started with
+     * {@link VolumeShaper.Operation#PLAY}.
+     *
+     * @return the volume, linearly represented as a value between 0.f and 1.f.
+     * @throws IllegalStateException if the player is uninitialized or if there
+     *         is a critical failure.  In that case, the {@code VolumeShaper} should be
+     *         recreated.
+     */
+    public float getVolume() {
+        return getStatePlayer(mId).getVolume();
+    }
+
+    /**
+     * Releases the {@code VolumeShaper} object; any volume scale due to the
+     * {@code VolumeShaper} is removed after closing.
+     *
+     * If the volume does not reach 1.f when the {@code VolumeShaper} is closed
+     * (or finalized), there may be an abrupt change of volume.
+     *
+     * {@code close()} may be safely called after a prior {@code close()}.
+     * This class implements the Java {@code AutoClosable} interface and
+     * may be used with try-with-resources.
+     */
+    @Override
+    public void close() {
+        try {
+            /* void */ applyPlayer(
+                    new VolumeShaper.Configuration(mId),
+                    new Operation.Builder().terminate().build());
+        } catch (IllegalStateException ise) {
+            ; // ok
+        }
+        if (mWeakPlayerBase != null) {
+            mWeakPlayerBase.clear();
+        }
+    }
+
+    @Override
+    protected void finalize() {
+        close(); // ensure we remove the native VolumeShaper
+    }
+
+    /**
+     * Internal call to apply the {@code configuration} and {@code operation} to the player.
+     * Returns a valid shaper id or throws the appropriate exception.
+     * @param configuration
+     * @param operation
+     * @return id a non-negative shaper id.
+     * @throws IllegalStateException if the player has been deallocated or is uninitialized.
+     */
+    private int applyPlayer(
+            @NonNull VolumeShaper.Configuration configuration,
+            @NonNull VolumeShaper.Operation operation) {
+        final int id;
+        if (mWeakPlayerBase != null) {
+            PlayerBase player = mWeakPlayerBase.get();
+            if (player == null) {
+                throw new IllegalStateException("player deallocated");
+            }
+            id = player.playerApplyVolumeShaper(configuration, operation);
+        } else {
+            throw new IllegalStateException("uninitialized shaper");
+        }
+        if (id < 0) {
+            // TODO - get INVALID_OPERATION from platform.
+            final int VOLUME_SHAPER_INVALID_OPERATION = -38; // must match with platform
+            // Due to RPC handling, we translate integer codes to exceptions right before
+            // delivering to the user.
+            if (id == VOLUME_SHAPER_INVALID_OPERATION) {
+                throw new IllegalStateException("player or VolumeShaper deallocated");
+            } else {
+                throw new IllegalArgumentException("invalid configuration or operation: " + id);
+            }
+        }
+        return id;
+    }
+
+    /**
+     * Internal call to retrieve the current {@code VolumeShaper} state.
+     * @param id
+     * @return the current {@code VolumeShaper.State}
+     * @throws IllegalStateException if the player has been deallocated or is uninitialized.
+     */
+    private @NonNull VolumeShaper.State getStatePlayer(int id) {
+        final VolumeShaper.State state;
+        if (mWeakPlayerBase != null) {
+            PlayerBase player = mWeakPlayerBase.get();
+            if (player == null) {
+                throw new IllegalStateException("player deallocated");
+            }
+            state = player.playerGetVolumeShaperState(id);
+        } else {
+            throw new IllegalStateException("uninitialized shaper");
+        }
+        if (state == null) {
+            throw new IllegalStateException("shaper cannot be found");
+        }
+        return state;
+    }
+
+    /**
+     * The {@code VolumeShaper.Configuration} class contains curve
+     * and duration information.
+     * It is constructed by the {@link VolumeShaper.Configuration.Builder}.
+     * <p>
+     * A {@code VolumeShaper.Configuration} is used by
+     * {@link VolumeAutomation#createVolumeShaper(Configuration)
+     * VolumeAutomation.createVolumeShaper(Configuration)} to create
+     * a {@code VolumeShaper} and
+     * by {@link VolumeShaper#replace(Configuration, Operation, boolean)
+     * VolumeShaper.replace(Configuration, Operation, boolean)}
+     * to replace an existing {@code configuration}.
+     * <p>
+     * The {@link AudioTrack} and {@link MediaPlayer} classes implement
+     * the {@link VolumeAutomation} interface.
+     */
+    public static final class Configuration implements Parcelable {
+        private static final int MAXIMUM_CURVE_POINTS = 16;
+
+        /**
+         * Returns the maximum number of curve points allowed for
+         * {@link VolumeShaper.Builder#setCurve(float[], float[])}.
+         */
+        public static int getMaximumCurvePoints() {
+            return MAXIMUM_CURVE_POINTS;
+        }
+
+        // These values must match the native VolumeShaper::Configuration::Type
+        /** @hide */
+        @IntDef({
+            TYPE_ID,
+            TYPE_SCALE,
+            })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Type {}
+
+        /**
+         * Specifies a {@link VolumeShaper} handle created by {@link #VolumeShaper(int)}
+         * from an id returned by {@code setVolumeShaper()}.
+         * The type, curve, etc. may not be queried from
+         * a {@code VolumeShaper} object of this type;
+         * the handle is used to identify and change the operation of
+         * an existing {@code VolumeShaper} sent to the player.
+         */
+        /* package */ static final int TYPE_ID = 0;
+
+        /**
+         * Specifies a {@link VolumeShaper} to be used
+         * as an additional scale to the current volume.
+         * This is created by the {@link VolumeShaper.Builder}.
+         */
+        /* package */ static final int TYPE_SCALE = 1;
+
+        // These values must match the native InterpolatorType enumeration.
+        /** @hide */
+        @IntDef({
+            INTERPOLATOR_TYPE_STEP,
+            INTERPOLATOR_TYPE_LINEAR,
+            INTERPOLATOR_TYPE_CUBIC,
+            INTERPOLATOR_TYPE_CUBIC_MONOTONIC,
+            })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface InterpolatorType {}
+
+        /**
+         * Stepwise volume curve.
+         */
+        public static final int INTERPOLATOR_TYPE_STEP = 0;
+
+        /**
+         * Linear interpolated volume curve.
+         */
+        public static final int INTERPOLATOR_TYPE_LINEAR = 1;
+
+        /**
+         * Cubic interpolated volume curve.
+         * This is default if unspecified.
+         */
+        public static final int INTERPOLATOR_TYPE_CUBIC = 2;
+
+        /**
+         * Cubic interpolated volume curve
+         * that preserves local monotonicity.
+         * So long as the control points are locally monotonic,
+         * the curve interpolation between those points are monotonic.
+         * This is useful for cubic spline interpolated
+         * volume ramps and ducks.
+         */
+        public static final int INTERPOLATOR_TYPE_CUBIC_MONOTONIC = 3;
+
+        // These values must match the native VolumeShaper::Configuration::InterpolatorType
+        /** @hide */
+        @IntDef({
+            OPTION_FLAG_VOLUME_IN_DBFS,
+            OPTION_FLAG_CLOCK_TIME,
+            })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface OptionFlag {}
+
+        /**
+         * @hide
+         * Use a dB full scale volume range for the volume curve.
+         *<p>
+         * The volume scale is typically from 0.f to 1.f on a linear scale;
+         * this option changes to -inf to 0.f on a db full scale,
+         * where 0.f is equivalent to a scale of 1.f.
+         */
+        public static final int OPTION_FLAG_VOLUME_IN_DBFS = (1 << 0);
+
+        /**
+         * @hide
+         * Use clock time instead of media time.
+         *<p>
+         * The default implementation of {@code VolumeShaper} is to apply
+         * volume changes by the media time of the player.
+         * Hence, the {@code VolumeShaper} will speed or slow down to
+         * match player changes of playback rate, pause, or resume.
+         *<p>
+         * The {@code OPTION_FLAG_CLOCK_TIME} option allows the {@code VolumeShaper}
+         * progress to be determined by clock time instead of media time.
+         */
+        public static final int OPTION_FLAG_CLOCK_TIME = (1 << 1);
+
+        private static final int OPTION_FLAG_PUBLIC_ALL =
+                OPTION_FLAG_VOLUME_IN_DBFS | OPTION_FLAG_CLOCK_TIME;
+
+        /**
+         * A one second linear ramp from silence to full volume.
+         * Use {@link VolumeShaper.Builder#reflectTimes()}
+         * or {@link VolumeShaper.Builder#invertVolumes()} to generate
+         * the matching linear duck.
+         */
+        public static final Configuration LINEAR_RAMP = new VolumeShaper.Configuration.Builder()
+                .setInterpolatorType(INTERPOLATOR_TYPE_LINEAR)
+                .setCurve(new float[] {0.f, 1.f} /* times */,
+                        new float[] {0.f, 1.f} /* volumes */)
+                .setDuration(1000)
+                .build();
+
+        /**
+         * A one second cubic ramp from silence to full volume.
+         * Use {@link VolumeShaper.Builder#reflectTimes()}
+         * or {@link VolumeShaper.Builder#invertVolumes()} to generate
+         * the matching cubic duck.
+         */
+        public static final Configuration CUBIC_RAMP = new VolumeShaper.Configuration.Builder()
+                .setInterpolatorType(INTERPOLATOR_TYPE_CUBIC)
+                .setCurve(new float[] {0.f, 1.f} /* times */,
+                        new float[] {0.f, 1.f}  /* volumes */)
+                .setDuration(1000)
+                .build();
+
+        /**
+         * A one second sine curve
+         * from silence to full volume for energy preserving cross fades.
+         * Use {@link VolumeShaper.Builder#reflectTimes()} to generate
+         * the matching cosine duck.
+         */
+        public static final Configuration SINE_RAMP;
+
+        /**
+         * A one second sine-squared s-curve ramp
+         * from silence to full volume.
+         * Use {@link VolumeShaper.Builder#reflectTimes()}
+         * or {@link VolumeShaper.Builder#invertVolumes()} to generate
+         * the matching sine-squared s-curve duck.
+         */
+        public static final Configuration SCURVE_RAMP;
+
+        static {
+            final int POINTS = MAXIMUM_CURVE_POINTS;
+            final float times[] = new float[POINTS];
+            final float sines[] = new float[POINTS];
+            final float scurve[] = new float[POINTS];
+            for (int i = 0; i < POINTS; ++i) {
+                times[i] = (float)i / (POINTS - 1);
+                final float sine = (float)Math.sin(times[i] * Math.PI / 2.);
+                sines[i] = sine;
+                scurve[i] = sine * sine;
+            }
+            SINE_RAMP = new VolumeShaper.Configuration.Builder()
+                .setInterpolatorType(INTERPOLATOR_TYPE_CUBIC)
+                .setCurve(times, sines)
+                .setDuration(1000)
+                .build();
+            SCURVE_RAMP = new VolumeShaper.Configuration.Builder()
+                .setInterpolatorType(INTERPOLATOR_TYPE_CUBIC)
+                .setCurve(times, scurve)
+                .setDuration(1000)
+                .build();
+        }
+
+        /*
+         * member variables - these are all final
+         */
+
+        // type of VolumeShaper
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private final int mType;
+
+        // valid when mType is TYPE_ID
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private final int mId;
+
+        // valid when mType is TYPE_SCALE
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private final int mOptionFlags;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private final double mDurationMs;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private final int mInterpolatorType;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private final float[] mTimes;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private final float[] mVolumes;
+
+        @Override
+        public String toString() {
+            return "VolumeShaper.Configuration{"
+                    + "mType = " + mType
+                    + ", mId = " + mId
+                    + (mType == TYPE_ID
+                        ? "}"
+                        : ", mOptionFlags = 0x" + Integer.toHexString(mOptionFlags).toUpperCase()
+                        + ", mDurationMs = " + mDurationMs
+                        + ", mInterpolatorType = " + mInterpolatorType
+                        + ", mTimes[] = " + Arrays.toString(mTimes)
+                        + ", mVolumes[] = " + Arrays.toString(mVolumes)
+                        + "}");
+        }
+
+        @Override
+        public int hashCode() {
+            return mType == TYPE_ID
+                    ? Objects.hash(mType, mId)
+                    : Objects.hash(mType, mId,
+                            mOptionFlags, mDurationMs, mInterpolatorType,
+                            Arrays.hashCode(mTimes), Arrays.hashCode(mVolumes));
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof Configuration)) return false;
+            if (o == this) return true;
+            final Configuration other = (Configuration) o;
+            // Note that exact floating point equality may not be guaranteed
+            // for a theoretically idempotent operation; for example,
+            // there are many cases where a + b - b != a.
+            return mType == other.mType
+                    && mId == other.mId
+                    && (mType == TYPE_ID
+                        ||  (mOptionFlags == other.mOptionFlags
+                            && mDurationMs == other.mDurationMs
+                            && mInterpolatorType == other.mInterpolatorType
+                            && Arrays.equals(mTimes, other.mTimes)
+                            && Arrays.equals(mVolumes, other.mVolumes)));
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            VolumeShaperConfiguration parcelable = toParcelable();
+            parcelable.writeToParcel(dest, flags);
+        }
+
+        /** @hide */
+        public VolumeShaperConfiguration toParcelable() {
+            VolumeShaperConfiguration parcelable = new VolumeShaperConfiguration();
+            parcelable.type = typeToAidl(mType);
+            parcelable.id = mId;
+            if (mType != TYPE_ID) {
+                parcelable.optionFlags = optionFlagsToAidl(mOptionFlags);
+                parcelable.durationMs = mDurationMs;
+                parcelable.interpolatorConfig = toInterpolatorParcelable();
+            }
+            return parcelable;
+        }
+
+        private InterpolatorConfig toInterpolatorParcelable() {
+            InterpolatorConfig parcelable = new InterpolatorConfig();
+            parcelable.type = interpolatorTypeToAidl(mInterpolatorType);
+            parcelable.firstSlope = 0.f; // first slope (specifying for native side)
+            parcelable.lastSlope = 0.f; // last slope (specifying for native side)
+            parcelable.xy = new float[mTimes.length * 2];
+            for (int i = 0; i < mTimes.length; ++i) {
+                parcelable.xy[i * 2] = mTimes[i];
+                parcelable.xy[i * 2 + 1] = mVolumes[i];
+            }
+            return parcelable;
+        }
+
+        /** @hide */
+        public static Configuration fromParcelable(VolumeShaperConfiguration parcelable) {
+            // this needs to match the native VolumeShaper.Configuration parceling
+            final int type = typeFromAidl(parcelable.type);
+            final int id = parcelable.id;
+            if (type == TYPE_ID) {
+                return new VolumeShaper.Configuration(id);
+            } else {
+                final int optionFlags = optionFlagsFromAidl(parcelable.optionFlags);
+                final double durationMs = parcelable.durationMs;
+                final int interpolatorType = interpolatorTypeFromAidl(
+                        parcelable.interpolatorConfig.type);
+                // parcelable.interpolatorConfig.firstSlope is ignored on the Java side
+                // parcelable.interpolatorConfig.lastSlope is ignored on the Java side
+                final int length = parcelable.interpolatorConfig.xy.length;
+                if (length % 2 != 0) {
+                    throw new android.os.BadParcelableException("xy length must be even");
+                }
+                final float[] times = new float[length / 2];
+                final float[] volumes = new float[length / 2];
+                for (int i = 0; i < length / 2; ++i) {
+                    times[i] = parcelable.interpolatorConfig.xy[i * 2];
+                    volumes[i] = parcelable.interpolatorConfig.xy[i * 2 + 1];
+                }
+
+                return new VolumeShaper.Configuration(
+                        type,
+                        id,
+                        optionFlags,
+                        durationMs,
+                        interpolatorType,
+                        times,
+                        volumes);
+            }
+        }
+
+        public static final @android.annotation.NonNull Parcelable.Creator<VolumeShaper.Configuration> CREATOR
+                = new Parcelable.Creator<VolumeShaper.Configuration>() {
+            @Override
+            public VolumeShaper.Configuration createFromParcel(Parcel p) {
+                return fromParcelable(VolumeShaperConfiguration.CREATOR.createFromParcel(p));
+            }
+
+            @Override
+            public VolumeShaper.Configuration[] newArray(int size) {
+                return new VolumeShaper.Configuration[size];
+            }
+        };
+
+        private static @InterpolatorType
+        int interpolatorTypeFromAidl(@android.media.InterpolatorType int aidl) {
+            switch (aidl) {
+                case android.media.InterpolatorType.STEP:
+                    return INTERPOLATOR_TYPE_STEP;
+                case android.media.InterpolatorType.LINEAR:
+                    return INTERPOLATOR_TYPE_LINEAR;
+                case android.media.InterpolatorType.CUBIC:
+                    return INTERPOLATOR_TYPE_CUBIC;
+                case android.media.InterpolatorType.CUBIC_MONOTONIC:
+                    return INTERPOLATOR_TYPE_CUBIC_MONOTONIC;
+                default:
+                    throw new BadParcelableException("Unknown interpolator type");
+            }
+        }
+
+        private static @android.media.InterpolatorType
+        int interpolatorTypeToAidl(@InterpolatorType int type) {
+            switch (type) {
+                case INTERPOLATOR_TYPE_STEP:
+                    return android.media.InterpolatorType.STEP;
+                case INTERPOLATOR_TYPE_LINEAR:
+                    return android.media.InterpolatorType.LINEAR;
+                case INTERPOLATOR_TYPE_CUBIC:
+                    return android.media.InterpolatorType.CUBIC;
+                case INTERPOLATOR_TYPE_CUBIC_MONOTONIC:
+                    return android.media.InterpolatorType.CUBIC_MONOTONIC;
+                default:
+                    throw new RuntimeException("Unknown interpolator type");
+            }
+        }
+
+        private static @Type
+        int typeFromAidl(@android.media.VolumeShaperConfigurationType int aidl) {
+            switch (aidl) {
+                case VolumeShaperConfigurationType.ID:
+                    return TYPE_ID;
+                case VolumeShaperConfigurationType.SCALE:
+                    return TYPE_SCALE;
+                default:
+                    throw new BadParcelableException("Unknown type");
+            }
+        }
+
+        private static @android.media.VolumeShaperConfigurationType
+        int typeToAidl(@Type int type) {
+            switch (type) {
+                case TYPE_ID:
+                    return VolumeShaperConfigurationType.ID;
+                case TYPE_SCALE:
+                    return VolumeShaperConfigurationType.SCALE;
+                default:
+                    throw new RuntimeException("Unknown type");
+            }
+        }
+
+        private static int optionFlagsFromAidl(int aidl) {
+            int result = 0;
+            if ((aidl & (1 << VolumeShaperConfigurationOptionFlag.VOLUME_IN_DBFS)) != 0) {
+                result |= OPTION_FLAG_VOLUME_IN_DBFS;
+            }
+            if ((aidl & (1 << VolumeShaperConfigurationOptionFlag.CLOCK_TIME)) != 0) {
+                result |= OPTION_FLAG_CLOCK_TIME;
+            }
+            return result;
+        }
+
+        private static int optionFlagsToAidl(int flags) {
+            int result = 0;
+            if ((flags & OPTION_FLAG_VOLUME_IN_DBFS) != 0) {
+                result |= (1 << VolumeShaperConfigurationOptionFlag.VOLUME_IN_DBFS);
+            }
+            if ((flags & OPTION_FLAG_CLOCK_TIME) != 0) {
+                result |= (1 << VolumeShaperConfigurationOptionFlag.CLOCK_TIME);
+            }
+            return result;
+        }
+
+        /**
+         * @hide
+         * Constructs a {@code VolumeShaper} from an id.
+         *
+         * This is an opaque handle for controlling a {@code VolumeShaper} that has
+         * already been sent to a player.  The {@code id} is returned from the
+         * initial {@code setVolumeShaper()} call on success.
+         *
+         * These configurations are for native use only,
+         * they are never returned directly to the user.
+         *
+         * @param id
+         * @throws IllegalArgumentException if id is negative.
+         */
+        public Configuration(int id) {
+            if (id < 0) {
+                throw new IllegalArgumentException("negative id " + id);
+            }
+            mType = TYPE_ID;
+            mId = id;
+            mInterpolatorType = 0;
+            mOptionFlags = 0;
+            mDurationMs = 0;
+            mTimes = null;
+            mVolumes = null;
+        }
+
+        /**
+         * Direct constructor for VolumeShaper.
+         * Use the Builder instead.
+         */
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private Configuration(@Type int type,
+                int id,
+                @OptionFlag int optionFlags,
+                double durationMs,
+                @InterpolatorType int interpolatorType,
+                @NonNull float[] times,
+                @NonNull float[] volumes) {
+            mType = type;
+            mId = id;
+            mOptionFlags = optionFlags;
+            mDurationMs = durationMs;
+            mInterpolatorType = interpolatorType;
+            // Builder should have cloned these arrays already.
+            mTimes = times;
+            mVolumes = volumes;
+        }
+
+        /**
+         * @hide
+         * Returns the {@code VolumeShaper} type.
+         */
+        public @Type int getType() {
+            return mType;
+        }
+
+        /**
+         * @hide
+         * Returns the {@code VolumeShaper} id.
+         */
+        public int getId() {
+            return mId;
+        }
+
+        /**
+         * Returns the interpolator type.
+         */
+        public @InterpolatorType int getInterpolatorType() {
+            return mInterpolatorType;
+        }
+
+        /**
+         * @hide
+         * Returns the option flags
+         */
+        public @OptionFlag int getOptionFlags() {
+            return mOptionFlags & OPTION_FLAG_PUBLIC_ALL;
+        }
+
+        /* package */ @OptionFlag int getAllOptionFlags() {
+            return mOptionFlags;
+        }
+
+        /**
+         * Returns the duration of the volume shape in milliseconds.
+         */
+        public long getDuration() {
+            // casting is safe here as the duration was set as a long in the Builder
+            return (long) mDurationMs;
+        }
+
+        /**
+         * Returns the times (x) coordinate array of the volume curve points.
+         */
+        public float[] getTimes() {
+            return mTimes;
+        }
+
+        /**
+         * Returns the volumes (y) coordinate array of the volume curve points.
+         */
+        public float[] getVolumes() {
+            return mVolumes;
+        }
+
+        /**
+         * Checks the validity of times and volumes point representation.
+         *
+         * {@code times[]} and {@code volumes[]} are two arrays representing points
+         * for the volume curve.
+         *
+         * Note that {@code times[]} and {@code volumes[]} are explicitly checked against
+         * null here to provide the proper error string - those are legitimate
+         * arguments to this method.
+         *
+         * @param times the x coordinates for the points,
+         *        must be between 0.f and 1.f and be monotonic.
+         * @param volumes the y coordinates for the points,
+         *        must be between 0.f and 1.f for linear and
+         *        must be no greater than 0.f for log (dBFS).
+         * @param log set to true if the scale is logarithmic.
+         * @return null if no error, or the reason in a {@code String} for an error.
+         */
+        private static @Nullable String checkCurveForErrors(
+                @Nullable float[] times, @Nullable float[] volumes, boolean log) {
+            if (times == null) {
+                return "times array must be non-null";
+            } else if (volumes == null) {
+                return "volumes array must be non-null";
+            } else if (times.length != volumes.length) {
+                return "array length must match";
+            } else if (times.length < 2) {
+                return "array length must be at least 2";
+            } else if (times.length > MAXIMUM_CURVE_POINTS) {
+                return "array length must be no larger than " + MAXIMUM_CURVE_POINTS;
+            } else if (times[0] != 0.f) {
+                return "times must start at 0.f";
+            } else if (times[times.length - 1] != 1.f) {
+                return "times must end at 1.f";
+            }
+
+            // validate points along the curve
+            for (int i = 1; i < times.length; ++i) {
+                if (!(times[i] > times[i - 1]) /* handle nan */) {
+                    return "times not monotonic increasing, check index " + i;
+                }
+            }
+            if (log) {
+                for (int i = 0; i < volumes.length; ++i) {
+                    if (!(volumes[i] <= 0.f) /* handle nan */) {
+                        return "volumes for log scale cannot be positive, "
+                                + "check index " + i;
+                    }
+                }
+            } else {
+                for (int i = 0; i < volumes.length; ++i) {
+                    if (!(volumes[i] >= 0.f) || !(volumes[i] <= 1.f) /* handle nan */) {
+                        return "volumes for linear scale must be between 0.f and 1.f, "
+                                + "check index " + i;
+                    }
+                }
+            }
+            return null; // no errors
+        }
+
+        private static void checkCurveForErrorsAndThrowException(
+                @Nullable float[] times, @Nullable float[] volumes, boolean log, boolean ise) {
+            final String error = checkCurveForErrors(times, volumes, log);
+            if (error != null) {
+                if (ise) {
+                    throw new IllegalStateException(error);
+                } else {
+                    throw new IllegalArgumentException(error);
+                }
+            }
+        }
+
+        private static void checkValidVolumeAndThrowException(float volume, boolean log) {
+            if (log) {
+                if (!(volume <= 0.f) /* handle nan */) {
+                    throw new IllegalArgumentException("dbfs volume must be 0.f or less");
+                }
+            } else {
+                if (!(volume >= 0.f) || !(volume <= 1.f) /* handle nan */) {
+                    throw new IllegalArgumentException("volume must be >= 0.f and <= 1.f");
+                }
+            }
+        }
+
+        private static void clampVolume(float[] volumes, boolean log) {
+            if (log) {
+                for (int i = 0; i < volumes.length; ++i) {
+                    if (!(volumes[i] <= 0.f) /* handle nan */) {
+                        volumes[i] = 0.f;
+                    }
+                }
+            } else {
+                for (int i = 0; i < volumes.length; ++i) {
+                    if (!(volumes[i] >= 0.f) /* handle nan */) {
+                        volumes[i] = 0.f;
+                    } else if (!(volumes[i] <= 1.f)) {
+                        volumes[i] = 1.f;
+                    }
+                }
+            }
+        }
+
+        /**
+         * Builder class for a {@link VolumeShaper.Configuration} object.
+         * <p> Here is an example where {@code Builder} is used to define the
+         * {@link VolumeShaper.Configuration}.
+         *
+         * <pre class="prettyprint">
+         * VolumeShaper.Configuration LINEAR_RAMP =
+         *         new VolumeShaper.Configuration.Builder()
+         *             .setInterpolatorType(VolumeShaper.Configuration.INTERPOLATOR_TYPE_LINEAR)
+         *             .setCurve(new float[] { 0.f, 1.f }, // times
+         *                       new float[] { 0.f, 1.f }) // volumes
+         *             .setDuration(1000)
+         *             .build();
+         * </pre>
+         * <p>
+         */
+        public static final class Builder {
+            private int mType = TYPE_SCALE;
+            private int mId = -1; // invalid
+            private int mInterpolatorType = INTERPOLATOR_TYPE_CUBIC;
+            private int mOptionFlags = OPTION_FLAG_CLOCK_TIME;
+            private double mDurationMs = 1000.;
+            private float[] mTimes = null;
+            private float[] mVolumes = null;
+
+            /**
+             * Constructs a new {@code Builder} with the defaults.
+             */
+            public Builder() {
+            }
+
+            /**
+             * Constructs a new {@code Builder} with settings
+             * copied from a given {@code VolumeShaper.Configuration}.
+             * @param configuration prototypical configuration
+             *        which will be reused in the new {@code Builder}.
+             */
+            public Builder(@NonNull Configuration configuration) {
+                mType = configuration.getType();
+                mId = configuration.getId();
+                mOptionFlags = configuration.getAllOptionFlags();
+                mInterpolatorType = configuration.getInterpolatorType();
+                mDurationMs = configuration.getDuration();
+                mTimes = configuration.getTimes().clone();
+                mVolumes = configuration.getVolumes().clone();
+            }
+
+            /**
+             * @hide
+             * Set the {@code id} for system defined shapers.
+             * @param id the {@code id} to set. If non-negative, then it is used.
+             *        If -1, then the system is expected to assign one.
+             * @return the same {@code Builder} instance.
+             * @throws IllegalArgumentException if {@code id} < -1.
+             */
+            public @NonNull Builder setId(int id) {
+                if (id < -1) {
+                    throw new IllegalArgumentException("invalid id: " + id);
+                }
+                mId = id;
+                return this;
+            }
+
+            /**
+             * Sets the interpolator type.
+             *
+             * If omitted the default interpolator type is {@link #INTERPOLATOR_TYPE_CUBIC}.
+             *
+             * @param interpolatorType method of interpolation used for the volume curve.
+             *        One of {@link #INTERPOLATOR_TYPE_STEP},
+             *        {@link #INTERPOLATOR_TYPE_LINEAR},
+             *        {@link #INTERPOLATOR_TYPE_CUBIC},
+             *        {@link #INTERPOLATOR_TYPE_CUBIC_MONOTONIC}.
+             * @return the same {@code Builder} instance.
+             * @throws IllegalArgumentException if {@code interpolatorType} is not valid.
+             */
+            public @NonNull Builder setInterpolatorType(@InterpolatorType int interpolatorType) {
+                switch (interpolatorType) {
+                    case INTERPOLATOR_TYPE_STEP:
+                    case INTERPOLATOR_TYPE_LINEAR:
+                    case INTERPOLATOR_TYPE_CUBIC:
+                    case INTERPOLATOR_TYPE_CUBIC_MONOTONIC:
+                        mInterpolatorType = interpolatorType;
+                        break;
+                    default:
+                        throw new IllegalArgumentException("invalid interpolatorType: "
+                                + interpolatorType);
+                }
+                return this;
+            }
+
+            /**
+             * @hide
+             * Sets the optional flags
+             *
+             * If omitted, flags are 0. If {@link #OPTION_FLAG_VOLUME_IN_DBFS} has
+             * changed the volume curve needs to be set again as the acceptable
+             * volume domain has changed.
+             *
+             * @param optionFlags new value to replace the old {@code optionFlags}.
+             * @return the same {@code Builder} instance.
+             * @throws IllegalArgumentException if flag is not recognized.
+             */
+            @TestApi
+            public @NonNull Builder setOptionFlags(@OptionFlag int optionFlags) {
+                if ((optionFlags & ~OPTION_FLAG_PUBLIC_ALL) != 0) {
+                    throw new IllegalArgumentException("invalid bits in flag: " + optionFlags);
+                }
+                mOptionFlags = mOptionFlags & ~OPTION_FLAG_PUBLIC_ALL | optionFlags;
+                return this;
+            }
+
+            /**
+             * Sets the {@code VolumeShaper} duration in milliseconds.
+             *
+             * If omitted, the default duration is 1 second.
+             *
+             * @param durationMillis
+             * @return the same {@code Builder} instance.
+             * @throws IllegalArgumentException if {@code durationMillis}
+             *         is not strictly positive.
+             */
+            public @NonNull Builder setDuration(long durationMillis) {
+                if (durationMillis <= 0) {
+                    throw new IllegalArgumentException(
+                            "duration: " + durationMillis + " not positive");
+                }
+                mDurationMs = (double) durationMillis;
+                return this;
+            }
+
+            /**
+             * Sets the volume curve.
+             *
+             * The volume curve is represented by a set of control points given by
+             * two float arrays of equal length,
+             * one representing the time (x) coordinates
+             * and one corresponding to the volume (y) coordinates.
+             * The length must be at least 2
+             * and no greater than {@link VolumeShaper.Configuration#getMaximumCurvePoints()}.
+             * <p>
+             * The volume curve is normalized as follows:
+             * time (x) coordinates should be monotonically increasing, from 0.f to 1.f;
+             * volume (y) coordinates must be within 0.f to 1.f.
+             * <p>
+             * The time scale is set by {@link #setDuration}.
+             * <p>
+             * @param times an array of float values representing
+             *        the time line of the volume curve.
+             * @param volumes an array of float values representing
+             *        the amplitude of the volume curve.
+             * @return the same {@code Builder} instance.
+             * @throws IllegalArgumentException if {@code times} or {@code volumes} is invalid.
+             */
+
+            /* Note: volume (y) coordinates must be non-positive for log scaling,
+             * if {@link VolumeShaper.Configuration#OPTION_FLAG_VOLUME_IN_DBFS} is set.
+             */
+
+            public @NonNull Builder setCurve(@NonNull float[] times, @NonNull float[] volumes) {
+                final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
+                checkCurveForErrorsAndThrowException(times, volumes, log, false /* ise */);
+                mTimes = times.clone();
+                mVolumes = volumes.clone();
+                return this;
+            }
+
+            /**
+             * Reflects the volume curve so that
+             * the shaper changes volume from the end
+             * to the start.
+             *
+             * @return the same {@code Builder} instance.
+             * @throws IllegalStateException if curve has not been set.
+             */
+            public @NonNull Builder reflectTimes() {
+                final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
+                checkCurveForErrorsAndThrowException(mTimes, mVolumes, log, true /* ise */);
+                int i;
+                for (i = 0; i < mTimes.length / 2; ++i) {
+                    float temp = mTimes[i];
+                    mTimes[i] = 1.f - mTimes[mTimes.length - 1 - i];
+                    mTimes[mTimes.length - 1 - i] = 1.f - temp;
+                    temp = mVolumes[i];
+                    mVolumes[i] = mVolumes[mVolumes.length - 1 - i];
+                    mVolumes[mVolumes.length - 1 - i] = temp;
+                }
+                if ((mTimes.length & 1) != 0) {
+                    mTimes[i] = 1.f - mTimes[i];
+                }
+                return this;
+            }
+
+            /**
+             * Inverts the volume curve so that the max volume
+             * becomes the min volume and vice versa.
+             *
+             * @return the same {@code Builder} instance.
+             * @throws IllegalStateException if curve has not been set.
+             */
+            public @NonNull Builder invertVolumes() {
+                final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
+                checkCurveForErrorsAndThrowException(mTimes, mVolumes, log, true /* ise */);
+                float min = mVolumes[0];
+                float max = mVolumes[0];
+                for (int i = 1; i < mVolumes.length; ++i) {
+                    if (mVolumes[i] < min) {
+                        min = mVolumes[i];
+                    } else if (mVolumes[i] > max) {
+                        max = mVolumes[i];
+                    }
+                }
+
+                final float maxmin = max + min;
+                for (int i = 0; i < mVolumes.length; ++i) {
+                    mVolumes[i] = maxmin - mVolumes[i];
+                }
+                return this;
+            }
+
+            /**
+             * Scale the curve end volume to a target value.
+             *
+             * Keeps the start volume the same.
+             * This works best if the volume curve is monotonic.
+             *
+             * @param volume the target end volume to use.
+             * @return the same {@code Builder} instance.
+             * @throws IllegalArgumentException if {@code volume} is not valid.
+             * @throws IllegalStateException if curve has not been set.
+             */
+            public @NonNull Builder scaleToEndVolume(float volume) {
+                final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
+                checkCurveForErrorsAndThrowException(mTimes, mVolumes, log, true /* ise */);
+                checkValidVolumeAndThrowException(volume, log);
+                final float startVolume = mVolumes[0];
+                final float endVolume = mVolumes[mVolumes.length - 1];
+                if (endVolume == startVolume) {
+                    // match with linear ramp
+                    final float offset = volume - startVolume;
+                    for (int i = 0; i < mVolumes.length; ++i) {
+                        mVolumes[i] = mVolumes[i] + offset * mTimes[i];
+                    }
+                } else {
+                    // scale
+                    final float scale = (volume - startVolume) / (endVolume - startVolume);
+                    for (int i = 0; i < mVolumes.length; ++i) {
+                        mVolumes[i] = scale * (mVolumes[i] - startVolume) + startVolume;
+                    }
+                }
+                clampVolume(mVolumes, log);
+                return this;
+            }
+
+            /**
+             * Scale the curve start volume to a target value.
+             *
+             * Keeps the end volume the same.
+             * This works best if the volume curve is monotonic.
+             *
+             * @param volume the target start volume to use.
+             * @return the same {@code Builder} instance.
+             * @throws IllegalArgumentException if {@code volume} is not valid.
+             * @throws IllegalStateException if curve has not been set.
+             */
+            public @NonNull Builder scaleToStartVolume(float volume) {
+                final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
+                checkCurveForErrorsAndThrowException(mTimes, mVolumes, log, true /* ise */);
+                checkValidVolumeAndThrowException(volume, log);
+                final float startVolume = mVolumes[0];
+                final float endVolume = mVolumes[mVolumes.length - 1];
+                if (endVolume == startVolume) {
+                    // match with linear ramp
+                    final float offset = volume - startVolume;
+                    for (int i = 0; i < mVolumes.length; ++i) {
+                        mVolumes[i] = mVolumes[i] + offset * (1.f - mTimes[i]);
+                    }
+                } else {
+                    final float scale = (volume - endVolume) / (startVolume - endVolume);
+                    for (int i = 0; i < mVolumes.length; ++i) {
+                        mVolumes[i] = scale * (mVolumes[i] - endVolume) + endVolume;
+                    }
+                }
+                clampVolume(mVolumes, log);
+                return this;
+            }
+
+            /**
+             * Builds a new {@link VolumeShaper} object.
+             *
+             * @return a new {@link VolumeShaper} object.
+             * @throws IllegalStateException if curve is not properly set.
+             */
+            public @NonNull Configuration build() {
+                final boolean log = (mOptionFlags & OPTION_FLAG_VOLUME_IN_DBFS) != 0;
+                checkCurveForErrorsAndThrowException(mTimes, mVolumes, log, true /* ise */);
+                return new Configuration(mType, mId, mOptionFlags, mDurationMs,
+                        mInterpolatorType, mTimes, mVolumes);
+            }
+        } // Configuration.Builder
+    } // Configuration
+
+    /**
+     * The {@code VolumeShaper.Operation} class is used to specify operations
+     * to the {@code VolumeShaper} that affect the volume change.
+     */
+    public static final class Operation implements Parcelable {
+        /**
+         * Forward playback from current volume time position.
+         * At the end of the {@code VolumeShaper} curve,
+         * the last volume value persists.
+         */
+        public static final Operation PLAY =
+                new VolumeShaper.Operation.Builder()
+                    .build();
+
+        /**
+         * Reverse playback from current volume time position.
+         * When the position reaches the start of the {@code VolumeShaper} curve,
+         * the first volume value persists.
+         */
+        public static final Operation REVERSE =
+                new VolumeShaper.Operation.Builder()
+                    .reverse()
+                    .build();
+
+        // No user serviceable parts below.
+
+        // These flags must match the native VolumeShaper::Operation::Flag
+        /** @hide */
+        @IntDef({
+            FLAG_NONE,
+            FLAG_REVERSE,
+            FLAG_TERMINATE,
+            FLAG_JOIN,
+            FLAG_DEFER,
+            })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Flag {}
+
+        /**
+         * No special {@code VolumeShaper} operation.
+         */
+        private static final int FLAG_NONE = 0;
+
+        /**
+         * Reverse the {@code VolumeShaper} progress.
+         *
+         * Reverses the {@code VolumeShaper} curve from its current
+         * position. If the {@code VolumeShaper} curve has not started,
+         * it automatically is considered finished.
+         */
+        private static final int FLAG_REVERSE = 1 << 0;
+
+        /**
+         * Terminate the existing {@code VolumeShaper}.
+         * This flag is generally used by itself;
+         * it takes precedence over all other flags.
+         */
+        private static final int FLAG_TERMINATE = 1 << 1;
+
+        /**
+         * Attempt to join as best as possible to the previous {@code VolumeShaper}.
+         * This requires the previous {@code VolumeShaper} to be active and
+         * {@link #setReplaceId} to be set.
+         */
+        private static final int FLAG_JOIN = 1 << 2;
+
+        /**
+         * Defer playback until next operation is sent. This is used
+         * when starting a {@code VolumeShaper} effect.
+         */
+        private static final int FLAG_DEFER = 1 << 3;
+
+        /**
+         * Use the id specified in the configuration, creating
+         * {@code VolumeShaper} as needed; the configuration should be
+         * TYPE_SCALE.
+         */
+        private static final int FLAG_CREATE_IF_NEEDED = 1 << 4;
+
+        private static final int FLAG_PUBLIC_ALL = FLAG_REVERSE | FLAG_TERMINATE;
+
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private final int mFlags;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private final int mReplaceId;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private final float mXOffset;
+
+        @Override
+        public String toString() {
+            return "VolumeShaper.Operation{"
+                    + "mFlags = 0x" + Integer.toHexString(mFlags).toUpperCase()
+                    + ", mReplaceId = " + mReplaceId
+                    + ", mXOffset = " + mXOffset
+                    + "}";
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mFlags, mReplaceId, mXOffset);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof Operation)) return false;
+            if (o == this) return true;
+            final Operation other = (Operation) o;
+
+            return mFlags == other.mFlags
+                    && mReplaceId == other.mReplaceId
+                    && Float.compare(mXOffset, other.mXOffset) == 0;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            toParcelable().writeToParcel(dest, flags);
+        }
+
+        /** @hide */
+        public VolumeShaperOperation toParcelable() {
+            VolumeShaperOperation result = new VolumeShaperOperation();
+            result.flags = flagsToAidl(mFlags);
+            result.replaceId = mReplaceId;
+            result.xOffset = mXOffset;
+            return result;
+        }
+
+        /** @hide */
+        public static Operation fromParcelable(VolumeShaperOperation parcelable) {
+            return new VolumeShaper.Operation(
+                    flagsFromAidl(parcelable.flags),
+                    parcelable.replaceId,
+                    parcelable.xOffset);
+        }
+
+        public static final @android.annotation.NonNull Parcelable.Creator<VolumeShaper.Operation> CREATOR
+                = new Parcelable.Creator<VolumeShaper.Operation>() {
+            @Override
+            public VolumeShaper.Operation createFromParcel(Parcel p) {
+                return fromParcelable(VolumeShaperOperation.CREATOR.createFromParcel(p));
+            }
+
+            @Override
+            public VolumeShaper.Operation[] newArray(int size) {
+                return new VolumeShaper.Operation[size];
+            }
+        };
+
+        private static int flagsFromAidl(int aidl) {
+            int result = 0;
+            if ((aidl & (1 << VolumeShaperOperationFlag.REVERSE)) != 0) {
+                result |= FLAG_REVERSE;
+            }
+            if ((aidl & (1 << VolumeShaperOperationFlag.TERMINATE)) != 0) {
+                result |= FLAG_TERMINATE;
+            }
+            if ((aidl & (1 << VolumeShaperOperationFlag.JOIN)) != 0) {
+                result |= FLAG_JOIN;
+            }
+            if ((aidl & (1 << VolumeShaperOperationFlag.DELAY)) != 0) {
+                result |= FLAG_DEFER;
+            }
+            if ((aidl & (1 << VolumeShaperOperationFlag.CREATE_IF_NECESSARY)) != 0) {
+                result |= FLAG_CREATE_IF_NEEDED;
+            }
+            return result;
+        }
+
+        private static int flagsToAidl(int flags) {
+            int result = 0;
+            if ((flags & FLAG_REVERSE) != 0) {
+                result |= (1 << VolumeShaperOperationFlag.REVERSE);
+            }
+            if ((flags & FLAG_TERMINATE) != 0) {
+                result |= (1 << VolumeShaperOperationFlag.TERMINATE);
+            }
+            if ((flags & FLAG_JOIN) != 0) {
+                result |= (1 << VolumeShaperOperationFlag.JOIN);
+            }
+            if ((flags & FLAG_DEFER) != 0) {
+                result |= (1 << VolumeShaperOperationFlag.DELAY);
+            }
+            if ((flags & FLAG_CREATE_IF_NEEDED) != 0) {
+                result |= (1 << VolumeShaperOperationFlag.CREATE_IF_NECESSARY);
+            }
+            return result;
+        }
+
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private Operation(@Flag int flags, int replaceId, float xOffset) {
+            mFlags = flags;
+            mReplaceId = replaceId;
+            mXOffset = xOffset;
+        }
+
+        /**
+         * @hide
+         * {@code Builder} class for {@link VolumeShaper.Operation} object.
+         *
+         * Not for public use.
+         */
+        public static final class Builder {
+            int mFlags;
+            int mReplaceId;
+            float mXOffset;
+
+            /**
+             * Constructs a new {@code Builder} with the defaults.
+             */
+            public Builder() {
+                mFlags = 0;
+                mReplaceId = -1;
+                mXOffset = Float.NaN;
+            }
+
+            /**
+             * Constructs a new {@code Builder} from a given {@code VolumeShaper.Operation}
+             * @param operation the {@code VolumeShaper.operation} whose data will be
+             *        reused in the new {@code Builder}.
+             */
+            public Builder(@NonNull VolumeShaper.Operation operation) {
+                mReplaceId = operation.mReplaceId;
+                mFlags = operation.mFlags;
+                mXOffset = operation.mXOffset;
+            }
+
+            /**
+             * Replaces the previous {@code VolumeShaper} specified by {@code id}.
+             *
+             * The {@code VolumeShaper} specified by the {@code id} is removed
+             * if it exists. The configuration should be TYPE_SCALE.
+             *
+             * @param id the {@code id} of the previous {@code VolumeShaper}.
+             * @param join if true, match the volume of the previous
+             * shaper to the start volume of the new {@code VolumeShaper}.
+             * @return the same {@code Builder} instance.
+             */
+            public @NonNull Builder replace(int id, boolean join) {
+                mReplaceId = id;
+                if (join) {
+                    mFlags |= FLAG_JOIN;
+                } else {
+                    mFlags &= ~FLAG_JOIN;
+                }
+                return this;
+            }
+
+            /**
+             * Defers all operations.
+             * @return the same {@code Builder} instance.
+             */
+            public @NonNull Builder defer() {
+                mFlags |= FLAG_DEFER;
+                return this;
+            }
+
+            /**
+             * Terminates the {@code VolumeShaper}.
+             *
+             * Do not call directly, use {@link VolumeShaper#close()}.
+             * @return the same {@code Builder} instance.
+             */
+            public @NonNull Builder terminate() {
+                mFlags |= FLAG_TERMINATE;
+                return this;
+            }
+
+            /**
+             * Reverses direction.
+             * @return the same {@code Builder} instance.
+             */
+            public @NonNull Builder reverse() {
+                mFlags ^= FLAG_REVERSE;
+                return this;
+            }
+
+            /**
+             * Use the id specified in the configuration, creating
+             * {@code VolumeShaper} only as needed; the configuration should be
+             * TYPE_SCALE.
+             *
+             * If the {@code VolumeShaper} with the same id already exists
+             * then the operation has no effect.
+             *
+             * @return the same {@code Builder} instance.
+             */
+            public @NonNull Builder createIfNeeded() {
+                mFlags |= FLAG_CREATE_IF_NEEDED;
+                return this;
+            }
+
+            /**
+             * Sets the {@code xOffset} to use for the {@code VolumeShaper}.
+             *
+             * The {@code xOffset} is the position on the volume curve,
+             * and setting takes effect when the {@code VolumeShaper} is used next.
+             *
+             * @param xOffset a value between (or equal to) 0.f and 1.f, or Float.NaN to ignore.
+             * @return the same {@code Builder} instance.
+             * @throws IllegalArgumentException if {@code xOffset} is not between 0.f and 1.f,
+             *         or a Float.NaN.
+             */
+            public @NonNull Builder setXOffset(float xOffset) {
+                if (xOffset < -0.f) {
+                    throw new IllegalArgumentException("Negative xOffset not allowed");
+                } else if (xOffset > 1.f) {
+                    throw new IllegalArgumentException("xOffset > 1.f not allowed");
+                }
+                // Float.NaN passes through
+                mXOffset = xOffset;
+                return this;
+            }
+
+            /**
+             * Sets the operation flag.  Do not call this directly but one of the
+             * other builder methods.
+             *
+             * @param flags new value for {@code flags}, consisting of ORed flags.
+             * @return the same {@code Builder} instance.
+             * @throws IllegalArgumentException if {@code flags} contains invalid set bits.
+             */
+            private @NonNull Builder setFlags(@Flag int flags) {
+                if ((flags & ~FLAG_PUBLIC_ALL) != 0) {
+                    throw new IllegalArgumentException("flag has unknown bits set: " + flags);
+                }
+                mFlags = mFlags & ~FLAG_PUBLIC_ALL | flags;
+                return this;
+            }
+
+            /**
+             * Builds a new {@link VolumeShaper.Operation} object.
+             *
+             * @return a new {@code VolumeShaper.Operation} object
+             */
+            public @NonNull Operation build() {
+                return new Operation(mFlags, mReplaceId, mXOffset);
+            }
+        } // Operation.Builder
+    } // Operation
+
+    /**
+     * @hide
+     * {@code VolumeShaper.State} represents the current progress
+     * of the {@code VolumeShaper}.
+     *
+     *  Not for public use.
+     */
+    public static final class State implements Parcelable {
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private float mVolume;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private float mXOffset;
+
+        @Override
+        public String toString() {
+            return "VolumeShaper.State{"
+                    + "mVolume = " + mVolume
+                    + ", mXOffset = " + mXOffset
+                    + "}";
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mVolume, mXOffset);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (!(o instanceof State)) return false;
+            if (o == this) return true;
+            final State other = (State) o;
+            return mVolume == other.mVolume
+                    && mXOffset == other.mXOffset;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            toParcelable().writeToParcel(dest, flags);
+        }
+
+        /** @hide */
+        public VolumeShaperState toParcelable() {
+            VolumeShaperState result = new VolumeShaperState();
+            result.volume = mVolume;
+            result.xOffset = mXOffset;
+            return result;
+        }
+
+        /** @hide */
+        public static State fromParcelable(VolumeShaperState p) {
+            return new VolumeShaper.State(p.volume, p.xOffset);
+        }
+
+        public static final @android.annotation.NonNull Parcelable.Creator<VolumeShaper.State> CREATOR
+                = new Parcelable.Creator<VolumeShaper.State>() {
+            @Override
+            public VolumeShaper.State createFromParcel(Parcel p) {
+                return fromParcelable(VolumeShaperState.CREATOR.createFromParcel(p));
+            }
+
+            @Override
+            public VolumeShaper.State[] newArray(int size) {
+                return new VolumeShaper.State[size];
+            }
+        };
+
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        /* package */ State(float volume, float xOffset) {
+            mVolume = volume;
+            mXOffset = xOffset;
+        }
+
+        /**
+         * Gets the volume of the {@link VolumeShaper.State}.
+         * @return linear volume between 0.f and 1.f.
+         */
+        public float getVolume() {
+            return mVolume;
+        }
+
+        /**
+         * Gets the {@code xOffset} position on the normalized curve
+         * of the {@link VolumeShaper.State}.
+         * @return the curve x position between 0.f and 1.f.
+         */
+        public float getXOffset() {
+            return mXOffset;
+        }
+    } // State
+}
diff --git a/android/media/WebVttRenderer.java b/android/media/WebVttRenderer.java
new file mode 100644
index 0000000..bc14294
--- /dev/null
+++ b/android/media/WebVttRenderer.java
@@ -0,0 +1,1868 @@
+/*
+ * Copyright (C) 2013 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.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.text.Layout.Alignment;
+import android.text.SpannableStringBuilder;
+import android.util.ArrayMap;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.accessibility.CaptioningManager;
+import android.view.accessibility.CaptioningManager.CaptionStyle;
+import android.view.accessibility.CaptioningManager.CaptioningChangeListener;
+import android.widget.LinearLayout;
+
+import com.android.internal.widget.SubtitleView;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Vector;
+
+/** @hide */
+public class WebVttRenderer extends SubtitleController.Renderer {
+    private final Context mContext;
+
+    private WebVttRenderingWidget mRenderingWidget;
+
+    @UnsupportedAppUsage
+    public WebVttRenderer(Context context) {
+        mContext = context;
+    }
+
+    @Override
+    public boolean supports(MediaFormat format) {
+        if (format.containsKey(MediaFormat.KEY_MIME)) {
+            return format.getString(MediaFormat.KEY_MIME).equals("text/vtt");
+        }
+        return false;
+    }
+
+    @Override
+    public SubtitleTrack createTrack(MediaFormat format) {
+        if (mRenderingWidget == null) {
+            mRenderingWidget = new WebVttRenderingWidget(mContext);
+        }
+
+        return new WebVttTrack(mRenderingWidget, format);
+    }
+}
+
+/** @hide */
+class TextTrackCueSpan {
+    long mTimestampMs;
+    boolean mEnabled;
+    String mText;
+    TextTrackCueSpan(String text, long timestamp) {
+        mTimestampMs = timestamp;
+        mText = text;
+        // spans with timestamp will be enabled by Cue.onTime
+        mEnabled = (mTimestampMs < 0);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof TextTrackCueSpan)) {
+            return false;
+        }
+        TextTrackCueSpan span = (TextTrackCueSpan) o;
+        return mTimestampMs == span.mTimestampMs &&
+                mText.equals(span.mText);
+    }
+}
+
+/**
+ * @hide
+ *
+ * Extract all text without style, but with timestamp spans.
+ */
+class UnstyledTextExtractor implements Tokenizer.OnTokenListener {
+    StringBuilder mLine = new StringBuilder();
+    Vector<TextTrackCueSpan[]> mLines = new Vector<TextTrackCueSpan[]>();
+    Vector<TextTrackCueSpan> mCurrentLine = new Vector<TextTrackCueSpan>();
+    long mLastTimestamp;
+
+    UnstyledTextExtractor() {
+        init();
+    }
+
+    private void init() {
+        mLine.delete(0, mLine.length());
+        mLines.clear();
+        mCurrentLine.clear();
+        mLastTimestamp = -1;
+    }
+
+    @Override
+    public void onData(String s) {
+        mLine.append(s);
+    }
+
+    @Override
+    public void onStart(String tag, String[] classes, String annotation) { }
+
+    @Override
+    public void onEnd(String tag) { }
+
+    @Override
+    public void onTimeStamp(long timestampMs) {
+        // finish any prior span
+        if (mLine.length() > 0 && timestampMs != mLastTimestamp) {
+            mCurrentLine.add(
+                    new TextTrackCueSpan(mLine.toString(), mLastTimestamp));
+            mLine.delete(0, mLine.length());
+        }
+        mLastTimestamp = timestampMs;
+    }
+
+    @Override
+    public void onLineEnd() {
+        // finish any pending span
+        if (mLine.length() > 0) {
+            mCurrentLine.add(
+                    new TextTrackCueSpan(mLine.toString(), mLastTimestamp));
+            mLine.delete(0, mLine.length());
+        }
+
+        TextTrackCueSpan[] spans = new TextTrackCueSpan[mCurrentLine.size()];
+        mCurrentLine.toArray(spans);
+        mCurrentLine.clear();
+        mLines.add(spans);
+    }
+
+    public TextTrackCueSpan[][] getText() {
+        // for politeness, finish last cue-line if it ends abruptly
+        if (mLine.length() > 0 || mCurrentLine.size() > 0) {
+            onLineEnd();
+        }
+        TextTrackCueSpan[][] lines = new TextTrackCueSpan[mLines.size()][];
+        mLines.toArray(lines);
+        init();
+        return lines;
+    }
+}
+
+/**
+ * @hide
+ *
+ * Tokenizer tokenizes the WebVTT Cue Text into tags and data
+ */
+class Tokenizer {
+    private static final String TAG = "Tokenizer";
+    private TokenizerPhase mPhase;
+    private TokenizerPhase mDataTokenizer;
+    private TokenizerPhase mTagTokenizer;
+
+    private OnTokenListener mListener;
+    private String mLine;
+    private int mHandledLen;
+
+    interface TokenizerPhase {
+        TokenizerPhase start();
+        void tokenize();
+    }
+
+    class DataTokenizer implements TokenizerPhase {
+        // includes both WebVTT data && escape state
+        private StringBuilder mData;
+
+        public TokenizerPhase start() {
+            mData = new StringBuilder();
+            return this;
+        }
+
+        private boolean replaceEscape(String escape, String replacement, int pos) {
+            if (mLine.startsWith(escape, pos)) {
+                mData.append(mLine.substring(mHandledLen, pos));
+                mData.append(replacement);
+                mHandledLen = pos + escape.length();
+                pos = mHandledLen - 1;
+                return true;
+            }
+            return false;
+        }
+
+        @Override
+        public void tokenize() {
+            int end = mLine.length();
+            for (int pos = mHandledLen; pos < mLine.length(); pos++) {
+                if (mLine.charAt(pos) == '&') {
+                    if (replaceEscape("&amp;", "&", pos) ||
+                            replaceEscape("&lt;", "<", pos) ||
+                            replaceEscape("&gt;", ">", pos) ||
+                            replaceEscape("&lrm;", "\u200e", pos) ||
+                            replaceEscape("&rlm;", "\u200f", pos) ||
+                            replaceEscape("&nbsp;", "\u00a0", pos)) {
+                        continue;
+                    }
+                } else if (mLine.charAt(pos) == '<') {
+                    end = pos;
+                    mPhase = mTagTokenizer.start();
+                    break;
+                }
+            }
+            mData.append(mLine.substring(mHandledLen, end));
+            // yield mData
+            mListener.onData(mData.toString());
+            mData.delete(0, mData.length());
+            mHandledLen = end;
+        }
+    }
+
+    class TagTokenizer implements TokenizerPhase {
+        private boolean mAtAnnotation;
+        private String mName, mAnnotation;
+
+        public TokenizerPhase start() {
+            mName = mAnnotation = "";
+            mAtAnnotation = false;
+            return this;
+        }
+
+        @Override
+        public void tokenize() {
+            if (!mAtAnnotation)
+                mHandledLen++;
+            if (mHandledLen < mLine.length()) {
+                String[] parts;
+                /**
+                 * Collect annotations and end-tags to closing >.  Collect tag
+                 * name to closing bracket or next white-space.
+                 */
+                if (mAtAnnotation || mLine.charAt(mHandledLen) == '/') {
+                    parts = mLine.substring(mHandledLen).split(">");
+                } else {
+                    parts = mLine.substring(mHandledLen).split("[\t\f >]");
+                }
+                String part = mLine.substring(
+                            mHandledLen, mHandledLen + parts[0].length());
+                mHandledLen += parts[0].length();
+
+                if (mAtAnnotation) {
+                    mAnnotation += " " + part;
+                } else {
+                    mName = part;
+                }
+            }
+
+            mAtAnnotation = true;
+
+            if (mHandledLen < mLine.length() && mLine.charAt(mHandledLen) == '>') {
+                yield_tag();
+                mPhase = mDataTokenizer.start();
+                mHandledLen++;
+            }
+        }
+
+        private void yield_tag() {
+            if (mName.startsWith("/")) {
+                mListener.onEnd(mName.substring(1));
+            } else if (mName.length() > 0 && Character.isDigit(mName.charAt(0))) {
+                // timestamp
+                try {
+                    long timestampMs = WebVttParser.parseTimestampMs(mName);
+                    mListener.onTimeStamp(timestampMs);
+                } catch (NumberFormatException e) {
+                    Log.d(TAG, "invalid timestamp tag: <" + mName + ">");
+                }
+            } else {
+                mAnnotation = mAnnotation.replaceAll("\\s+", " ");
+                if (mAnnotation.startsWith(" ")) {
+                    mAnnotation = mAnnotation.substring(1);
+                }
+                if (mAnnotation.endsWith(" ")) {
+                    mAnnotation = mAnnotation.substring(0, mAnnotation.length() - 1);
+                }
+
+                String[] classes = null;
+                int dotAt = mName.indexOf('.');
+                if (dotAt >= 0) {
+                    classes = mName.substring(dotAt + 1).split("\\.");
+                    mName = mName.substring(0, dotAt);
+                }
+                mListener.onStart(mName, classes, mAnnotation);
+            }
+        }
+    }
+
+    Tokenizer(OnTokenListener listener) {
+        mDataTokenizer = new DataTokenizer();
+        mTagTokenizer = new TagTokenizer();
+        reset();
+        mListener = listener;
+    }
+
+    void reset() {
+        mPhase = mDataTokenizer.start();
+    }
+
+    void tokenize(String s) {
+        mHandledLen = 0;
+        mLine = s;
+        while (mHandledLen < mLine.length()) {
+            mPhase.tokenize();
+        }
+        /* we are finished with a line unless we are in the middle of a tag */
+        if (!(mPhase instanceof TagTokenizer)) {
+            // yield END-OF-LINE
+            mListener.onLineEnd();
+        }
+    }
+
+    interface OnTokenListener {
+        void onData(String s);
+        void onStart(String tag, String[] classes, String annotation);
+        void onEnd(String tag);
+        void onTimeStamp(long timestampMs);
+        void onLineEnd();
+    }
+}
+
+/** @hide */
+class TextTrackRegion {
+    final static int SCROLL_VALUE_NONE      = 300;
+    final static int SCROLL_VALUE_SCROLL_UP = 301;
+
+    String mId;
+    float mWidth;
+    int mLines;
+    float mAnchorPointX, mAnchorPointY;
+    float mViewportAnchorPointX, mViewportAnchorPointY;
+    int mScrollValue;
+
+    TextTrackRegion() {
+        mId = "";
+        mWidth = 100;
+        mLines = 3;
+        mAnchorPointX = mViewportAnchorPointX = 0.f;
+        mAnchorPointY = mViewportAnchorPointY = 100.f;
+        mScrollValue = SCROLL_VALUE_NONE;
+    }
+
+    public String toString() {
+        StringBuilder res = new StringBuilder(" {id:\"").append(mId)
+            .append("\", width:").append(mWidth)
+            .append(", lines:").append(mLines)
+            .append(", anchorPoint:(").append(mAnchorPointX)
+            .append(", ").append(mAnchorPointY)
+            .append("), viewportAnchorPoints:").append(mViewportAnchorPointX)
+            .append(", ").append(mViewportAnchorPointY)
+            .append("), scrollValue:")
+            .append(mScrollValue == SCROLL_VALUE_NONE ? "none" :
+                    mScrollValue == SCROLL_VALUE_SCROLL_UP ? "scroll_up" :
+                    "INVALID")
+            .append("}");
+        return res.toString();
+    }
+}
+
+/** @hide */
+class TextTrackCue extends SubtitleTrack.Cue {
+    final static int WRITING_DIRECTION_HORIZONTAL  = 100;
+    final static int WRITING_DIRECTION_VERTICAL_RL = 101;
+    final static int WRITING_DIRECTION_VERTICAL_LR = 102;
+
+    final static int ALIGNMENT_MIDDLE = 200;
+    final static int ALIGNMENT_START  = 201;
+    final static int ALIGNMENT_END    = 202;
+    final static int ALIGNMENT_LEFT   = 203;
+    final static int ALIGNMENT_RIGHT  = 204;
+    private static final String TAG = "TTCue";
+
+    String  mId;
+    boolean mPauseOnExit;
+    int     mWritingDirection;
+    String  mRegionId;
+    boolean mSnapToLines;
+    Integer mLinePosition;  // null means AUTO
+    boolean mAutoLinePosition;
+    int     mTextPosition;
+    int     mSize;
+    int     mAlignment;
+    // Vector<String> mText;
+    String[] mStrings;
+    TextTrackCueSpan[][] mLines;
+    TextTrackRegion mRegion;
+
+    TextTrackCue() {
+        mId = "";
+        mPauseOnExit = false;
+        mWritingDirection = WRITING_DIRECTION_HORIZONTAL;
+        mRegionId = "";
+        mSnapToLines = true;
+        mLinePosition = null /* AUTO */;
+        mTextPosition = 50;
+        mSize = 100;
+        mAlignment = ALIGNMENT_MIDDLE;
+        mLines = null;
+        mRegion = null;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof TextTrackCue)) {
+            return false;
+        }
+        if (this == o) {
+            return true;
+        }
+
+        try {
+            TextTrackCue cue = (TextTrackCue) o;
+            boolean res = mId.equals(cue.mId) &&
+                    mPauseOnExit == cue.mPauseOnExit &&
+                    mWritingDirection == cue.mWritingDirection &&
+                    mRegionId.equals(cue.mRegionId) &&
+                    mSnapToLines == cue.mSnapToLines &&
+                    mAutoLinePosition == cue.mAutoLinePosition &&
+                    (mAutoLinePosition ||
+                            ((mLinePosition != null && mLinePosition.equals(cue.mLinePosition)) ||
+                             (mLinePosition == null && cue.mLinePosition == null))) &&
+                    mTextPosition == cue.mTextPosition &&
+                    mSize == cue.mSize &&
+                    mAlignment == cue.mAlignment &&
+                    mLines.length == cue.mLines.length;
+            if (res == true) {
+                for (int line = 0; line < mLines.length; line++) {
+                    if (!Arrays.equals(mLines[line], cue.mLines[line])) {
+                        return false;
+                    }
+                }
+            }
+            return res;
+        } catch(IncompatibleClassChangeError e) {
+            return false;
+        }
+    }
+
+    public StringBuilder appendStringsToBuilder(StringBuilder builder) {
+        if (mStrings == null) {
+            builder.append("null");
+        } else {
+            builder.append("[");
+            boolean first = true;
+            for (String s: mStrings) {
+                if (!first) {
+                    builder.append(", ");
+                }
+                if (s == null) {
+                    builder.append("null");
+                } else {
+                    builder.append("\"");
+                    builder.append(s);
+                    builder.append("\"");
+                }
+                first = false;
+            }
+            builder.append("]");
+        }
+        return builder;
+    }
+
+    public StringBuilder appendLinesToBuilder(StringBuilder builder) {
+        if (mLines == null) {
+            builder.append("null");
+        } else {
+            builder.append("[");
+            boolean first = true;
+            for (TextTrackCueSpan[] spans: mLines) {
+                if (!first) {
+                    builder.append(", ");
+                }
+                if (spans == null) {
+                    builder.append("null");
+                } else {
+                    builder.append("\"");
+                    boolean innerFirst = true;
+                    long lastTimestamp = -1;
+                    for (TextTrackCueSpan span: spans) {
+                        if (!innerFirst) {
+                            builder.append(" ");
+                        }
+                        if (span.mTimestampMs != lastTimestamp) {
+                            builder.append("<")
+                                    .append(WebVttParser.timeToString(
+                                            span.mTimestampMs))
+                                    .append(">");
+                            lastTimestamp = span.mTimestampMs;
+                        }
+                        builder.append(span.mText);
+                        innerFirst = false;
+                    }
+                    builder.append("\"");
+                }
+                first = false;
+            }
+            builder.append("]");
+        }
+        return builder;
+    }
+
+    public String toString() {
+        StringBuilder res = new StringBuilder();
+
+        res.append(WebVttParser.timeToString(mStartTimeMs))
+                .append(" --> ").append(WebVttParser.timeToString(mEndTimeMs))
+                .append(" {id:\"").append(mId)
+                .append("\", pauseOnExit:").append(mPauseOnExit)
+                .append(", direction:")
+                .append(mWritingDirection == WRITING_DIRECTION_HORIZONTAL ? "horizontal" :
+                        mWritingDirection == WRITING_DIRECTION_VERTICAL_LR ? "vertical_lr" :
+                        mWritingDirection == WRITING_DIRECTION_VERTICAL_RL ? "vertical_rl" :
+                        "INVALID")
+                .append(", regionId:\"").append(mRegionId)
+                .append("\", snapToLines:").append(mSnapToLines)
+                .append(", linePosition:").append(mAutoLinePosition ? "auto" :
+                                                  mLinePosition)
+                .append(", textPosition:").append(mTextPosition)
+                .append(", size:").append(mSize)
+                .append(", alignment:")
+                .append(mAlignment == ALIGNMENT_END ? "end" :
+                        mAlignment == ALIGNMENT_LEFT ? "left" :
+                        mAlignment == ALIGNMENT_MIDDLE ? "middle" :
+                        mAlignment == ALIGNMENT_RIGHT ? "right" :
+                        mAlignment == ALIGNMENT_START ? "start" : "INVALID")
+                .append(", text:");
+        appendStringsToBuilder(res).append("}");
+        return res.toString();
+    }
+
+    @Override
+    public int hashCode() {
+        return toString().hashCode();
+    }
+
+    @Override
+    public void onTime(long timeMs) {
+        for (TextTrackCueSpan[] line: mLines) {
+            for (TextTrackCueSpan span: line) {
+                span.mEnabled = timeMs >= span.mTimestampMs;
+            }
+        }
+    }
+}
+
+/**
+ *  Supporting July 10 2013 draft version
+ *
+ *  @hide
+ */
+class WebVttParser {
+    private static final String TAG = "WebVttParser";
+    private Phase mPhase;
+    private TextTrackCue mCue;
+    private Vector<String> mCueTexts;
+    private WebVttCueListener mListener;
+    private String mBuffer;
+
+    WebVttParser(WebVttCueListener listener) {
+        mPhase = mParseStart;
+        mBuffer = "";   /* mBuffer contains up to 1 incomplete line */
+        mListener = listener;
+        mCueTexts = new Vector<String>();
+    }
+
+    /* parsePercentageString */
+    public static float parseFloatPercentage(String s)
+            throws NumberFormatException {
+        if (!s.endsWith("%")) {
+            throw new NumberFormatException("does not end in %");
+        }
+        s = s.substring(0, s.length() - 1);
+        // parseFloat allows an exponent or a sign
+        if (s.matches(".*[^0-9.].*")) {
+            throw new NumberFormatException("contains an invalid character");
+        }
+
+        try {
+            float value = Float.parseFloat(s);
+            if (value < 0.0f || value > 100.0f) {
+                throw new NumberFormatException("is out of range");
+            }
+            return value;
+        } catch (NumberFormatException e) {
+            throw new NumberFormatException("is not a number");
+        }
+    }
+
+    public static int parseIntPercentage(String s) throws NumberFormatException {
+        if (!s.endsWith("%")) {
+            throw new NumberFormatException("does not end in %");
+        }
+        s = s.substring(0, s.length() - 1);
+        // parseInt allows "-0" that returns 0, so check for non-digits
+        if (s.matches(".*[^0-9].*")) {
+            throw new NumberFormatException("contains an invalid character");
+        }
+
+        try {
+            int value = Integer.parseInt(s);
+            if (value < 0 || value > 100) {
+                throw new NumberFormatException("is out of range");
+            }
+            return value;
+        } catch (NumberFormatException e) {
+            throw new NumberFormatException("is not a number");
+        }
+    }
+
+    public static long parseTimestampMs(String s) throws NumberFormatException {
+        if (!s.matches("(\\d+:)?[0-5]\\d:[0-5]\\d\\.\\d{3}")) {
+            throw new NumberFormatException("has invalid format");
+        }
+
+        String[] parts = s.split("\\.", 2);
+        long value = 0;
+        for (String group: parts[0].split(":")) {
+            value = value * 60 + Long.parseLong(group);
+        }
+        return value * 1000 + Long.parseLong(parts[1]);
+    }
+
+    public static String timeToString(long timeMs) {
+        return String.format("%d:%02d:%02d.%03d",
+                timeMs / 3600000, (timeMs / 60000) % 60,
+                (timeMs / 1000) % 60, timeMs % 1000);
+    }
+
+    public void parse(String s) {
+        boolean trailingCR = false;
+        mBuffer = (mBuffer + s.replace("\0", "\ufffd")).replace("\r\n", "\n");
+
+        /* keep trailing '\r' in case matching '\n' arrives in next packet */
+        if (mBuffer.endsWith("\r")) {
+            trailingCR = true;
+            mBuffer = mBuffer.substring(0, mBuffer.length() - 1);
+        }
+
+        String[] lines = mBuffer.split("[\r\n]");
+        for (int i = 0; i < lines.length - 1; i++) {
+            mPhase.parse(lines[i]);
+        }
+
+        mBuffer = lines[lines.length - 1];
+        if (trailingCR)
+            mBuffer += "\r";
+    }
+
+    public void eos() {
+        if (mBuffer.endsWith("\r")) {
+            mBuffer = mBuffer.substring(0, mBuffer.length() - 1);
+        }
+
+        mPhase.parse(mBuffer);
+        mBuffer = "";
+
+        yieldCue();
+        mPhase = mParseStart;
+    }
+
+    public void yieldCue() {
+        if (mCue != null && mCueTexts.size() > 0) {
+            mCue.mStrings = new String[mCueTexts.size()];
+            mCueTexts.toArray(mCue.mStrings);
+            mCueTexts.clear();
+            mListener.onCueParsed(mCue);
+        }
+        mCue = null;
+    }
+
+    interface Phase {
+        void parse(String line);
+    }
+
+    final private Phase mSkipRest = new Phase() {
+        @Override
+        public void parse(String line) { }
+    };
+
+    final private Phase mParseStart = new Phase() { // 5-9
+        @Override
+        public void parse(String line) {
+            if (line.startsWith("\ufeff")) {
+                line = line.substring(1);
+            }
+            if (!line.equals("WEBVTT") &&
+                    !line.startsWith("WEBVTT ") &&
+                    !line.startsWith("WEBVTT\t")) {
+                log_warning("Not a WEBVTT header", line);
+                mPhase = mSkipRest;
+            } else {
+                mPhase = mParseHeader;
+            }
+        }
+    };
+
+    final private Phase mParseHeader = new Phase() { // 10-13
+        TextTrackRegion parseRegion(String s) {
+            TextTrackRegion region = new TextTrackRegion();
+            for (String setting: s.split(" +")) {
+                int equalAt = setting.indexOf('=');
+                if (equalAt <= 0 || equalAt == setting.length() - 1) {
+                    continue;
+                }
+
+                String name = setting.substring(0, equalAt);
+                String value = setting.substring(equalAt + 1);
+                if (name.equals("id")) {
+                    region.mId = value;
+                } else if (name.equals("width")) {
+                    try {
+                        region.mWidth = parseFloatPercentage(value);
+                    } catch (NumberFormatException e) {
+                        log_warning("region setting", name,
+                                "has invalid value", e.getMessage(), value);
+                    }
+                } else if (name.equals("lines")) {
+                    if (value.matches(".*[^0-9].*")) {
+                        log_warning("lines", name, "contains an invalid character", value);
+                    } else {
+                        try {
+                            region.mLines = Integer.parseInt(value);
+                            assert(region.mLines >= 0); // lines contains only digits
+                        } catch (NumberFormatException e) {
+                            log_warning("region setting", name, "is not numeric", value);
+                        }
+                    }
+                } else if (name.equals("regionanchor") ||
+                           name.equals("viewportanchor")) {
+                    int commaAt = value.indexOf(",");
+                    if (commaAt < 0) {
+                        log_warning("region setting", name, "contains no comma", value);
+                        continue;
+                    }
+
+                    String anchorX = value.substring(0, commaAt);
+                    String anchorY = value.substring(commaAt + 1);
+                    float x, y;
+
+                    try {
+                        x = parseFloatPercentage(anchorX);
+                    } catch (NumberFormatException e) {
+                        log_warning("region setting", name,
+                                "has invalid x component", e.getMessage(), anchorX);
+                        continue;
+                    }
+                    try {
+                        y = parseFloatPercentage(anchorY);
+                    } catch (NumberFormatException e) {
+                        log_warning("region setting", name,
+                                "has invalid y component", e.getMessage(), anchorY);
+                        continue;
+                    }
+
+                    if (name.charAt(0) == 'r') {
+                        region.mAnchorPointX = x;
+                        region.mAnchorPointY = y;
+                    } else {
+                        region.mViewportAnchorPointX = x;
+                        region.mViewportAnchorPointY = y;
+                    }
+                } else if (name.equals("scroll")) {
+                    if (value.equals("up")) {
+                        region.mScrollValue =
+                            TextTrackRegion.SCROLL_VALUE_SCROLL_UP;
+                    } else {
+                        log_warning("region setting", name, "has invalid value", value);
+                    }
+                }
+            }
+            return region;
+        }
+
+        @Override
+        public void parse(String line)  {
+            if (line.length() == 0) {
+                mPhase = mParseCueId;
+            } else if (line.contains("-->")) {
+                mPhase = mParseCueTime;
+                mPhase.parse(line);
+            } else {
+                int colonAt = line.indexOf(':');
+                if (colonAt <= 0 || colonAt >= line.length() - 1) {
+                    log_warning("meta data header has invalid format", line);
+                }
+                String name = line.substring(0, colonAt);
+                String value = line.substring(colonAt + 1);
+
+                if (name.equals("Region")) {
+                    TextTrackRegion region = parseRegion(value);
+                    mListener.onRegionParsed(region);
+                }
+            }
+        }
+    };
+
+    final private Phase mParseCueId = new Phase() {
+        @Override
+        public void parse(String line) {
+            if (line.length() == 0) {
+                return;
+            }
+
+            assert(mCue == null);
+
+            if (line.equals("NOTE") || line.startsWith("NOTE ")) {
+                mPhase = mParseCueText;
+            }
+
+            mCue = new TextTrackCue();
+            mCueTexts.clear();
+
+            mPhase = mParseCueTime;
+            if (line.contains("-->")) {
+                mPhase.parse(line);
+            } else {
+                mCue.mId = line;
+            }
+        }
+    };
+
+    final private Phase mParseCueTime = new Phase() {
+        @Override
+        public void parse(String line) {
+            int arrowAt = line.indexOf("-->");
+            if (arrowAt < 0) {
+                mCue = null;
+                mPhase = mParseCueId;
+                return;
+            }
+
+            String start = line.substring(0, arrowAt).trim();
+            // convert only initial and first other white-space to space
+            String rest = line.substring(arrowAt + 3)
+                    .replaceFirst("^\\s+", "").replaceFirst("\\s+", " ");
+            int spaceAt = rest.indexOf(' ');
+            String end = spaceAt > 0 ? rest.substring(0, spaceAt) : rest;
+            rest = spaceAt > 0 ? rest.substring(spaceAt + 1) : "";
+
+            mCue.mStartTimeMs = parseTimestampMs(start);
+            mCue.mEndTimeMs = parseTimestampMs(end);
+            for (String setting: rest.split(" +")) {
+                int colonAt = setting.indexOf(':');
+                if (colonAt <= 0 || colonAt == setting.length() - 1) {
+                    continue;
+                }
+                String name = setting.substring(0, colonAt);
+                String value = setting.substring(colonAt + 1);
+
+                if (name.equals("region")) {
+                    mCue.mRegionId = value;
+                } else if (name.equals("vertical")) {
+                    if (value.equals("rl")) {
+                        mCue.mWritingDirection =
+                            TextTrackCue.WRITING_DIRECTION_VERTICAL_RL;
+                    } else if (value.equals("lr")) {
+                        mCue.mWritingDirection =
+                            TextTrackCue.WRITING_DIRECTION_VERTICAL_LR;
+                    } else {
+                        log_warning("cue setting", name, "has invalid value", value);
+                    }
+                } else if (name.equals("line")) {
+                    try {
+                        /* TRICKY: we know that there are no spaces in value */
+                        assert(value.indexOf(' ') < 0);
+                        if (value.endsWith("%")) {
+                            mCue.mSnapToLines = false;
+                            mCue.mLinePosition = parseIntPercentage(value);
+                        } else if (value.matches(".*[^0-9].*")) {
+                            log_warning("cue setting", name,
+                                    "contains an invalid character", value);
+                        } else {
+                            mCue.mSnapToLines = true;
+                            mCue.mLinePosition = Integer.parseInt(value);
+                        }
+                    } catch (NumberFormatException e) {
+                        log_warning("cue setting", name,
+                                "is not numeric or percentage", value);
+                    }
+                    // TODO: add support for optional alignment value [,start|middle|end]
+                } else if (name.equals("position")) {
+                    try {
+                        mCue.mTextPosition = parseIntPercentage(value);
+                    } catch (NumberFormatException e) {
+                        log_warning("cue setting", name,
+                               "is not numeric or percentage", value);
+                    }
+                } else if (name.equals("size")) {
+                    try {
+                        mCue.mSize = parseIntPercentage(value);
+                    } catch (NumberFormatException e) {
+                        log_warning("cue setting", name,
+                               "is not numeric or percentage", value);
+                    }
+                } else if (name.equals("align")) {
+                    if (value.equals("start")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_START;
+                    } else if (value.equals("middle")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_MIDDLE;
+                    } else if (value.equals("end")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_END;
+                    } else if (value.equals("left")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_LEFT;
+                    } else if (value.equals("right")) {
+                        mCue.mAlignment = TextTrackCue.ALIGNMENT_RIGHT;
+                    } else {
+                        log_warning("cue setting", name, "has invalid value", value);
+                        continue;
+                    }
+                }
+            }
+
+            if (mCue.mLinePosition != null ||
+                    mCue.mSize != 100 ||
+                    (mCue.mWritingDirection !=
+                        TextTrackCue.WRITING_DIRECTION_HORIZONTAL)) {
+                mCue.mRegionId = "";
+            }
+
+            mPhase = mParseCueText;
+        }
+    };
+
+    /* also used for notes */
+    final private Phase mParseCueText = new Phase() {
+        @Override
+        public void parse(String line) {
+            if (line.length() == 0) {
+                yieldCue();
+                mPhase = mParseCueId;
+                return;
+            } else if (mCue != null) {
+                mCueTexts.add(line);
+            }
+        }
+    };
+
+    private void log_warning(
+            String nameType, String name, String message,
+            String subMessage, String value) {
+        Log.w(this.getClass().getName(), nameType + " '" + name + "' " +
+                message + " ('" + value + "' " + subMessage + ")");
+    }
+
+    private void log_warning(
+            String nameType, String name, String message, String value) {
+        Log.w(this.getClass().getName(), nameType + " '" + name + "' " +
+                message + " ('" + value + "')");
+    }
+
+    private void log_warning(String message, String value) {
+        Log.w(this.getClass().getName(), message + " ('" + value + "')");
+    }
+}
+
+/** @hide */
+interface WebVttCueListener {
+    void onCueParsed(TextTrackCue cue);
+    void onRegionParsed(TextTrackRegion region);
+}
+
+/** @hide */
+class WebVttTrack extends SubtitleTrack implements WebVttCueListener {
+    private static final String TAG = "WebVttTrack";
+
+    private final WebVttParser mParser = new WebVttParser(this);
+    private final UnstyledTextExtractor mExtractor =
+        new UnstyledTextExtractor();
+    private final Tokenizer mTokenizer = new Tokenizer(mExtractor);
+    private final Vector<Long> mTimestamps = new Vector<Long>();
+    private final WebVttRenderingWidget mRenderingWidget;
+
+    private final Map<String, TextTrackRegion> mRegions =
+        new HashMap<String, TextTrackRegion>();
+    private Long mCurrentRunID;
+
+    WebVttTrack(WebVttRenderingWidget renderingWidget, MediaFormat format) {
+        super(format);
+
+        mRenderingWidget = renderingWidget;
+    }
+
+    @Override
+    public WebVttRenderingWidget getRenderingWidget() {
+        return mRenderingWidget;
+    }
+
+    @Override
+    public void onData(byte[] data, boolean eos, long runID) {
+        try {
+            String str = new String(data, "UTF-8");
+
+            // implement intermixing restriction for WebVTT only for now
+            synchronized(mParser) {
+                if (mCurrentRunID != null && runID != mCurrentRunID) {
+                    throw new IllegalStateException(
+                            "Run #" + mCurrentRunID +
+                            " in progress.  Cannot process run #" + runID);
+                }
+                mCurrentRunID = runID;
+                mParser.parse(str);
+                if (eos) {
+                    finishedRun(runID);
+                    mParser.eos();
+                    mRegions.clear();
+                    mCurrentRunID = null;
+                }
+            }
+        } catch (java.io.UnsupportedEncodingException e) {
+            Log.w(TAG, "subtitle data is not UTF-8 encoded: " + e);
+        }
+    }
+
+    @Override
+    public void onCueParsed(TextTrackCue cue) {
+        synchronized (mParser) {
+            // resolve region
+            if (cue.mRegionId.length() != 0) {
+                cue.mRegion = mRegions.get(cue.mRegionId);
+            }
+
+            if (DEBUG) Log.v(TAG, "adding cue " + cue);
+
+            // tokenize text track string-lines into lines of spans
+            mTokenizer.reset();
+            for (String s: cue.mStrings) {
+                mTokenizer.tokenize(s);
+            }
+            cue.mLines = mExtractor.getText();
+            if (DEBUG) Log.v(TAG, cue.appendLinesToBuilder(
+                    cue.appendStringsToBuilder(
+                        new StringBuilder()).append(" simplified to: "))
+                            .toString());
+
+            // extract inner timestamps
+            for (TextTrackCueSpan[] line: cue.mLines) {
+                for (TextTrackCueSpan span: line) {
+                    if (span.mTimestampMs > cue.mStartTimeMs &&
+                            span.mTimestampMs < cue.mEndTimeMs &&
+                            !mTimestamps.contains(span.mTimestampMs)) {
+                        mTimestamps.add(span.mTimestampMs);
+                    }
+                }
+            }
+
+            if (mTimestamps.size() > 0) {
+                cue.mInnerTimesMs = new long[mTimestamps.size()];
+                for (int ix=0; ix < mTimestamps.size(); ++ix) {
+                    cue.mInnerTimesMs[ix] = mTimestamps.get(ix);
+                }
+                mTimestamps.clear();
+            } else {
+                cue.mInnerTimesMs = null;
+            }
+
+            cue.mRunID = mCurrentRunID;
+        }
+
+        addCue(cue);
+    }
+
+    @Override
+    public void onRegionParsed(TextTrackRegion region) {
+        synchronized(mParser) {
+            mRegions.put(region.mId, region);
+        }
+    }
+
+    @Override
+    public void updateView(Vector<SubtitleTrack.Cue> activeCues) {
+        if (!mVisible) {
+            // don't keep the state if we are not visible
+            return;
+        }
+
+        if (DEBUG && mTimeProvider != null) {
+            try {
+                Log.d(TAG, "at " +
+                        (mTimeProvider.getCurrentTimeUs(false, true) / 1000) +
+                        " ms the active cues are:");
+            } catch (IllegalStateException e) {
+                Log.d(TAG, "at (illegal state) the active cues are:");
+            }
+        }
+
+        if (mRenderingWidget != null) {
+            mRenderingWidget.setActiveCues(activeCues);
+        }
+    }
+}
+
+/**
+ * Widget capable of rendering WebVTT captions.
+ *
+ * @hide
+ */
+class WebVttRenderingWidget extends ViewGroup implements SubtitleTrack.RenderingWidget {
+    private static final boolean DEBUG = false;
+
+    private static final CaptionStyle DEFAULT_CAPTION_STYLE = CaptionStyle.DEFAULT;
+
+    private static final int DEBUG_REGION_BACKGROUND = 0x800000FF;
+    private static final int DEBUG_CUE_BACKGROUND = 0x80FF0000;
+
+    /** WebVtt specifies line height as 5.3% of the viewport height. */
+    private static final float LINE_HEIGHT_RATIO = 0.0533f;
+
+    /** Map of active regions, used to determine enter/exit. */
+    private final ArrayMap<TextTrackRegion, RegionLayout> mRegionBoxes =
+            new ArrayMap<TextTrackRegion, RegionLayout>();
+
+    /** Map of active cues, used to determine enter/exit. */
+    private final ArrayMap<TextTrackCue, CueLayout> mCueBoxes =
+            new ArrayMap<TextTrackCue, CueLayout>();
+
+    /** Captioning manager, used to obtain and track caption properties. */
+    private final CaptioningManager mManager;
+
+    /** Callback for rendering changes. */
+    private OnChangedListener mListener;
+
+    /** Current caption style. */
+    private CaptionStyle mCaptionStyle;
+
+    /** Current font size, computed from font scaling factor and height. */
+    private float mFontSize;
+
+    /** Whether a caption style change listener is registered. */
+    private boolean mHasChangeListener;
+
+    public WebVttRenderingWidget(Context context) {
+        this(context, null);
+    }
+
+    public WebVttRenderingWidget(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public WebVttRenderingWidget(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public WebVttRenderingWidget(
+            Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+        super(context, attrs, defStyleAttr, defStyleRes);
+
+        // Cannot render text over video when layer type is hardware.
+        setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+
+        mManager = (CaptioningManager) context.getSystemService(Context.CAPTIONING_SERVICE);
+        mCaptionStyle = mManager.getUserStyle();
+        mFontSize = mManager.getFontScale() * getHeight() * LINE_HEIGHT_RATIO;
+    }
+
+    @Override
+    public void setSize(int width, int height) {
+        final int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
+        final int heightSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY);
+
+        measure(widthSpec, heightSpec);
+        layout(0, 0, width, height);
+    }
+
+    @Override
+    public void onAttachedToWindow() {
+        super.onAttachedToWindow();
+
+        manageChangeListener();
+    }
+
+    @Override
+    public void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        manageChangeListener();
+    }
+
+    @Override
+    public void setOnChangedListener(OnChangedListener listener) {
+        mListener = listener;
+    }
+
+    @Override
+    public void setVisible(boolean visible) {
+        if (visible) {
+            setVisibility(View.VISIBLE);
+        } else {
+            setVisibility(View.GONE);
+        }
+
+        manageChangeListener();
+    }
+
+    /**
+     * Manages whether this renderer is listening for caption style changes.
+     */
+    private void manageChangeListener() {
+        final boolean needsListener = isAttachedToWindow() && getVisibility() == View.VISIBLE;
+        if (mHasChangeListener != needsListener) {
+            mHasChangeListener = needsListener;
+
+            if (needsListener) {
+                mManager.addCaptioningChangeListener(mCaptioningListener);
+
+                final CaptionStyle captionStyle = mManager.getUserStyle();
+                final float fontSize = mManager.getFontScale() * getHeight() * LINE_HEIGHT_RATIO;
+                setCaptionStyle(captionStyle, fontSize);
+            } else {
+                mManager.removeCaptioningChangeListener(mCaptioningListener);
+            }
+        }
+    }
+
+    public void setActiveCues(Vector<SubtitleTrack.Cue> activeCues) {
+        final Context context = getContext();
+        final CaptionStyle captionStyle = mCaptionStyle;
+        final float fontSize = mFontSize;
+
+        prepForPrune();
+
+        // Ensure we have all necessary cue and region boxes.
+        final int count = activeCues.size();
+        for (int i = 0; i < count; i++) {
+            final TextTrackCue cue = (TextTrackCue) activeCues.get(i);
+            final TextTrackRegion region = cue.mRegion;
+            if (region != null) {
+                RegionLayout regionBox = mRegionBoxes.get(region);
+                if (regionBox == null) {
+                    regionBox = new RegionLayout(context, region, captionStyle, fontSize);
+                    mRegionBoxes.put(region, regionBox);
+                    addView(regionBox, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+                }
+                regionBox.put(cue);
+            } else {
+                CueLayout cueBox = mCueBoxes.get(cue);
+                if (cueBox == null) {
+                    cueBox = new CueLayout(context, cue, captionStyle, fontSize);
+                    mCueBoxes.put(cue, cueBox);
+                    addView(cueBox, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+                }
+                cueBox.update();
+                cueBox.setOrder(i);
+            }
+        }
+
+        prune();
+
+        // Force measurement and layout.
+        final int width = getWidth();
+        final int height = getHeight();
+        setSize(width, height);
+
+        if (mListener != null) {
+            mListener.onChanged(this);
+        }
+    }
+
+    private void setCaptionStyle(CaptionStyle captionStyle, float fontSize) {
+        captionStyle = DEFAULT_CAPTION_STYLE.applyStyle(captionStyle);
+        mCaptionStyle = captionStyle;
+        mFontSize = fontSize;
+
+        final int cueCount = mCueBoxes.size();
+        for (int i = 0; i < cueCount; i++) {
+            final CueLayout cueBox = mCueBoxes.valueAt(i);
+            cueBox.setCaptionStyle(captionStyle, fontSize);
+        }
+
+        final int regionCount = mRegionBoxes.size();
+        for (int i = 0; i < regionCount; i++) {
+            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
+            regionBox.setCaptionStyle(captionStyle, fontSize);
+        }
+    }
+
+    /**
+     * Remove inactive cues and regions.
+     */
+    private void prune() {
+        int regionCount = mRegionBoxes.size();
+        for (int i = 0; i < regionCount; i++) {
+            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
+            if (regionBox.prune()) {
+                removeView(regionBox);
+                mRegionBoxes.removeAt(i);
+                regionCount--;
+                i--;
+            }
+        }
+
+        int cueCount = mCueBoxes.size();
+        for (int i = 0; i < cueCount; i++) {
+            final CueLayout cueBox = mCueBoxes.valueAt(i);
+            if (!cueBox.isActive()) {
+                removeView(cueBox);
+                mCueBoxes.removeAt(i);
+                cueCount--;
+                i--;
+            }
+        }
+    }
+
+    /**
+     * Reset active cues and regions.
+     */
+    private void prepForPrune() {
+        final int regionCount = mRegionBoxes.size();
+        for (int i = 0; i < regionCount; i++) {
+            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
+            regionBox.prepForPrune();
+        }
+
+        final int cueCount = mCueBoxes.size();
+        for (int i = 0; i < cueCount; i++) {
+            final CueLayout cueBox = mCueBoxes.valueAt(i);
+            cueBox.prepForPrune();
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        final int regionCount = mRegionBoxes.size();
+        for (int i = 0; i < regionCount; i++) {
+            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
+            regionBox.measureForParent(widthMeasureSpec, heightMeasureSpec);
+        }
+
+        final int cueCount = mCueBoxes.size();
+        for (int i = 0; i < cueCount; i++) {
+            final CueLayout cueBox = mCueBoxes.valueAt(i);
+            cueBox.measureForParent(widthMeasureSpec, heightMeasureSpec);
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        final int viewportWidth = r - l;
+        final int viewportHeight = b - t;
+
+        setCaptionStyle(mCaptionStyle,
+                mManager.getFontScale() * LINE_HEIGHT_RATIO * viewportHeight);
+
+        final int regionCount = mRegionBoxes.size();
+        for (int i = 0; i < regionCount; i++) {
+            final RegionLayout regionBox = mRegionBoxes.valueAt(i);
+            layoutRegion(viewportWidth, viewportHeight, regionBox);
+        }
+
+        final int cueCount = mCueBoxes.size();
+        for (int i = 0; i < cueCount; i++) {
+            final CueLayout cueBox = mCueBoxes.valueAt(i);
+            layoutCue(viewportWidth, viewportHeight, cueBox);
+        }
+    }
+
+    /**
+     * Lays out a region within the viewport. The region handles layout for
+     * contained cues.
+     */
+    private void layoutRegion(
+            int viewportWidth, int viewportHeight,
+            RegionLayout regionBox) {
+        final TextTrackRegion region = regionBox.getRegion();
+        final int regionHeight = regionBox.getMeasuredHeight();
+        final int regionWidth = regionBox.getMeasuredWidth();
+
+        // TODO: Account for region anchor point.
+        final float x = region.mViewportAnchorPointX;
+        final float y = region.mViewportAnchorPointY;
+        final int left = (int) (x * (viewportWidth - regionWidth) / 100);
+        final int top = (int) (y * (viewportHeight - regionHeight) / 100);
+
+        regionBox.layout(left, top, left + regionWidth, top + regionHeight);
+    }
+
+    /**
+     * Lays out a cue within the viewport.
+     */
+    private void layoutCue(
+            int viewportWidth, int viewportHeight, CueLayout cueBox) {
+        final TextTrackCue cue = cueBox.getCue();
+        final int direction = getLayoutDirection();
+        final int absAlignment = resolveCueAlignment(direction, cue.mAlignment);
+        final boolean cueSnapToLines = cue.mSnapToLines;
+
+        int size = 100 * cueBox.getMeasuredWidth() / viewportWidth;
+
+        // Determine raw x-position.
+        int xPosition;
+        switch (absAlignment) {
+            case TextTrackCue.ALIGNMENT_LEFT:
+                xPosition = cue.mTextPosition;
+                break;
+            case TextTrackCue.ALIGNMENT_RIGHT:
+                xPosition = cue.mTextPosition - size;
+                break;
+            case TextTrackCue.ALIGNMENT_MIDDLE:
+            default:
+                xPosition = cue.mTextPosition - size / 2;
+                break;
+        }
+
+        // Adjust x-position for layout.
+        if (direction == LAYOUT_DIRECTION_RTL) {
+            xPosition = 100 - xPosition;
+        }
+
+        // If the text track cue snap-to-lines flag is set, adjust
+        // x-position and size for padding. This is equivalent to placing the
+        // cue within the title-safe area.
+        if (cueSnapToLines) {
+            final int paddingLeft = 100 * getPaddingLeft() / viewportWidth;
+            final int paddingRight = 100 * getPaddingRight() / viewportWidth;
+            if (xPosition < paddingLeft && xPosition + size > paddingLeft) {
+                xPosition += paddingLeft;
+                size -= paddingLeft;
+            }
+            final float rightEdge = 100 - paddingRight;
+            if (xPosition < rightEdge && xPosition + size > rightEdge) {
+                size -= paddingRight;
+            }
+        }
+
+        // Compute absolute left position and width.
+        final int left = xPosition * viewportWidth / 100;
+        final int width = size * viewportWidth / 100;
+
+        // Determine initial y-position.
+        final int yPosition = calculateLinePosition(cueBox);
+
+        // Compute absolute final top position and height.
+        final int height = cueBox.getMeasuredHeight();
+        final int top;
+        if (yPosition < 0) {
+            // TODO: This needs to use the actual height of prior boxes.
+            top = viewportHeight + yPosition * height;
+        } else {
+            top = yPosition * (viewportHeight - height) / 100;
+        }
+
+        // Layout cue in final position.
+        cueBox.layout(left, top, left + width, top + height);
+    }
+
+    /**
+     * Calculates the line position for a cue.
+     * <p>
+     * If the resulting position is negative, it represents a bottom-aligned
+     * position relative to the number of active cues. Otherwise, it represents
+     * a percentage [0-100] of the viewport height.
+     */
+    private int calculateLinePosition(CueLayout cueBox) {
+        final TextTrackCue cue = cueBox.getCue();
+        final Integer linePosition = cue.mLinePosition;
+        final boolean snapToLines = cue.mSnapToLines;
+        final boolean autoPosition = (linePosition == null);
+
+        if (!snapToLines && !autoPosition && (linePosition < 0 || linePosition > 100)) {
+            // Invalid line position defaults to 100.
+            return 100;
+        } else if (!autoPosition) {
+            // Use the valid, supplied line position.
+            return linePosition;
+        } else if (!snapToLines) {
+            // Automatic, non-snapped line position defaults to 100.
+            return 100;
+        } else {
+            // Automatic snapped line position uses active cue order.
+            return -(cueBox.mOrder + 1);
+        }
+    }
+
+    /**
+     * Resolves cue alignment according to the specified layout direction.
+     */
+    private static int resolveCueAlignment(int layoutDirection, int alignment) {
+        switch (alignment) {
+            case TextTrackCue.ALIGNMENT_START:
+                return layoutDirection == View.LAYOUT_DIRECTION_LTR ?
+                        TextTrackCue.ALIGNMENT_LEFT : TextTrackCue.ALIGNMENT_RIGHT;
+            case TextTrackCue.ALIGNMENT_END:
+                return layoutDirection == View.LAYOUT_DIRECTION_LTR ?
+                        TextTrackCue.ALIGNMENT_RIGHT : TextTrackCue.ALIGNMENT_LEFT;
+        }
+        return alignment;
+    }
+
+    private final CaptioningChangeListener mCaptioningListener = new CaptioningChangeListener() {
+        @Override
+        public void onFontScaleChanged(float fontScale) {
+            final float fontSize = fontScale * getHeight() * LINE_HEIGHT_RATIO;
+            setCaptionStyle(mCaptionStyle, fontSize);
+        }
+
+        @Override
+        public void onUserStyleChanged(CaptionStyle userStyle) {
+            setCaptionStyle(userStyle, mFontSize);
+        }
+    };
+
+    /**
+     * A text track region represents a portion of the video viewport and
+     * provides a rendering area for text track cues.
+     */
+    private static class RegionLayout extends LinearLayout {
+        private final ArrayList<CueLayout> mRegionCueBoxes = new ArrayList<CueLayout>();
+        private final TextTrackRegion mRegion;
+
+        private CaptionStyle mCaptionStyle;
+        private float mFontSize;
+
+        public RegionLayout(Context context, TextTrackRegion region, CaptionStyle captionStyle,
+                float fontSize) {
+            super(context);
+
+            mRegion = region;
+            mCaptionStyle = captionStyle;
+            mFontSize = fontSize;
+
+            // TODO: Add support for vertical text
+            setOrientation(VERTICAL);
+
+            if (DEBUG) {
+                setBackgroundColor(DEBUG_REGION_BACKGROUND);
+            } else {
+                setBackgroundColor(captionStyle.windowColor);
+            }
+        }
+
+        public void setCaptionStyle(CaptionStyle captionStyle, float fontSize) {
+            mCaptionStyle = captionStyle;
+            mFontSize = fontSize;
+
+            final int cueCount = mRegionCueBoxes.size();
+            for (int i = 0; i < cueCount; i++) {
+                final CueLayout cueBox = mRegionCueBoxes.get(i);
+                cueBox.setCaptionStyle(captionStyle, fontSize);
+            }
+
+            setBackgroundColor(captionStyle.windowColor);
+        }
+
+        /**
+         * Performs the parent's measurement responsibilities, then
+         * automatically performs its own measurement.
+         */
+        public void measureForParent(int widthMeasureSpec, int heightMeasureSpec) {
+            final TextTrackRegion region = mRegion;
+            final int specWidth = MeasureSpec.getSize(widthMeasureSpec);
+            final int specHeight = MeasureSpec.getSize(heightMeasureSpec);
+            final int width = (int) region.mWidth;
+
+            // Determine the absolute maximum region size as the requested size.
+            final int size = width * specWidth / 100;
+
+            widthMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
+            heightMeasureSpec = MeasureSpec.makeMeasureSpec(specHeight, MeasureSpec.AT_MOST);
+            measure(widthMeasureSpec, heightMeasureSpec);
+        }
+
+        /**
+         * Prepares this region for pruning by setting all tracks as inactive.
+         * <p>
+         * Tracks that are added or updated using {@link #put(TextTrackCue)}
+         * after this calling this method will be marked as active.
+         */
+        public void prepForPrune() {
+            final int cueCount = mRegionCueBoxes.size();
+            for (int i = 0; i < cueCount; i++) {
+                final CueLayout cueBox = mRegionCueBoxes.get(i);
+                cueBox.prepForPrune();
+            }
+        }
+
+        /**
+         * Adds a {@link TextTrackCue} to this region. If the track had already
+         * been added, updates its active state.
+         *
+         * @param cue
+         */
+        public void put(TextTrackCue cue) {
+            final int cueCount = mRegionCueBoxes.size();
+            for (int i = 0; i < cueCount; i++) {
+                final CueLayout cueBox = mRegionCueBoxes.get(i);
+                if (cueBox.getCue() == cue) {
+                    cueBox.update();
+                    return;
+                }
+            }
+
+            final CueLayout cueBox = new CueLayout(getContext(), cue, mCaptionStyle, mFontSize);
+            mRegionCueBoxes.add(cueBox);
+            addView(cueBox, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+
+            if (getChildCount() > mRegion.mLines) {
+                removeViewAt(0);
+            }
+        }
+
+        /**
+         * Remove all inactive tracks from this region.
+         *
+         * @return true if this region is empty and should be pruned
+         */
+        public boolean prune() {
+            int cueCount = mRegionCueBoxes.size();
+            for (int i = 0; i < cueCount; i++) {
+                final CueLayout cueBox = mRegionCueBoxes.get(i);
+                if (!cueBox.isActive()) {
+                    mRegionCueBoxes.remove(i);
+                    removeView(cueBox);
+                    cueCount--;
+                    i--;
+                }
+            }
+
+            return mRegionCueBoxes.isEmpty();
+        }
+
+        /**
+         * @return the region data backing this layout
+         */
+        public TextTrackRegion getRegion() {
+            return mRegion;
+        }
+    }
+
+    /**
+     * A text track cue is the unit of time-sensitive data in a text track,
+     * corresponding for instance for subtitles and captions to the text that
+     * appears at a particular time and disappears at another time.
+     * <p>
+     * A single cue may contain multiple {@link SpanLayout}s, each representing a
+     * single line of text.
+     */
+    private static class CueLayout extends LinearLayout {
+        public final TextTrackCue mCue;
+
+        private CaptionStyle mCaptionStyle;
+        private float mFontSize;
+
+        private boolean mActive;
+        private int mOrder;
+
+        public CueLayout(
+                Context context, TextTrackCue cue, CaptionStyle captionStyle, float fontSize) {
+            super(context);
+
+            mCue = cue;
+            mCaptionStyle = captionStyle;
+            mFontSize = fontSize;
+
+            // TODO: Add support for vertical text.
+            final boolean horizontal = cue.mWritingDirection
+                    == TextTrackCue.WRITING_DIRECTION_HORIZONTAL;
+            setOrientation(horizontal ? VERTICAL : HORIZONTAL);
+
+            switch (cue.mAlignment) {
+                case TextTrackCue.ALIGNMENT_END:
+                    setGravity(Gravity.END);
+                    break;
+                case TextTrackCue.ALIGNMENT_LEFT:
+                    setGravity(Gravity.LEFT);
+                    break;
+                case TextTrackCue.ALIGNMENT_MIDDLE:
+                    setGravity(horizontal
+                            ? Gravity.CENTER_HORIZONTAL : Gravity.CENTER_VERTICAL);
+                    break;
+                case TextTrackCue.ALIGNMENT_RIGHT:
+                    setGravity(Gravity.RIGHT);
+                    break;
+                case TextTrackCue.ALIGNMENT_START:
+                    setGravity(Gravity.START);
+                    break;
+            }
+
+            if (DEBUG) {
+                setBackgroundColor(DEBUG_CUE_BACKGROUND);
+            }
+
+            update();
+        }
+
+        public void setCaptionStyle(CaptionStyle style, float fontSize) {
+            mCaptionStyle = style;
+            mFontSize = fontSize;
+
+            final int n = getChildCount();
+            for (int i = 0; i < n; i++) {
+                final View child = getChildAt(i);
+                if (child instanceof SpanLayout) {
+                    ((SpanLayout) child).setCaptionStyle(style, fontSize);
+                }
+            }
+        }
+
+        public void prepForPrune() {
+            mActive = false;
+        }
+
+        public void update() {
+            mActive = true;
+
+            removeAllViews();
+
+            final int cueAlignment = resolveCueAlignment(getLayoutDirection(), mCue.mAlignment);
+            final Alignment alignment;
+            switch (cueAlignment) {
+                case TextTrackCue.ALIGNMENT_LEFT:
+                    alignment = Alignment.ALIGN_LEFT;
+                    break;
+                case TextTrackCue.ALIGNMENT_RIGHT:
+                    alignment = Alignment.ALIGN_RIGHT;
+                    break;
+                case TextTrackCue.ALIGNMENT_MIDDLE:
+                default:
+                    alignment = Alignment.ALIGN_CENTER;
+            }
+
+            final CaptionStyle captionStyle = mCaptionStyle;
+            final float fontSize = mFontSize;
+            final TextTrackCueSpan[][] lines = mCue.mLines;
+            final int lineCount = lines.length;
+            for (int i = 0; i < lineCount; i++) {
+                final SpanLayout lineBox = new SpanLayout(getContext(), lines[i]);
+                lineBox.setAlignment(alignment);
+                lineBox.setCaptionStyle(captionStyle, fontSize);
+
+                addView(lineBox, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+            }
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+        }
+
+        /**
+         * Performs the parent's measurement responsibilities, then
+         * automatically performs its own measurement.
+         */
+        public void measureForParent(int widthMeasureSpec, int heightMeasureSpec) {
+            final TextTrackCue cue = mCue;
+            final int specWidth = MeasureSpec.getSize(widthMeasureSpec);
+            final int specHeight = MeasureSpec.getSize(heightMeasureSpec);
+            final int direction = getLayoutDirection();
+            final int absAlignment = resolveCueAlignment(direction, cue.mAlignment);
+
+            // Determine the maximum size of cue based on its starting position
+            // and the direction in which it grows.
+            final int maximumSize;
+            switch (absAlignment) {
+                case TextTrackCue.ALIGNMENT_LEFT:
+                    maximumSize = 100 - cue.mTextPosition;
+                    break;
+                case TextTrackCue.ALIGNMENT_RIGHT:
+                    maximumSize = cue.mTextPosition;
+                    break;
+                case TextTrackCue.ALIGNMENT_MIDDLE:
+                    if (cue.mTextPosition <= 50) {
+                        maximumSize = cue.mTextPosition * 2;
+                    } else {
+                        maximumSize = (100 - cue.mTextPosition) * 2;
+                    }
+                    break;
+                default:
+                    maximumSize = 0;
+            }
+
+            // Determine absolute maximum cue size as the smaller of the
+            // requested size and the maximum theoretical size.
+            final int size = Math.min(cue.mSize, maximumSize) * specWidth / 100;
+            widthMeasureSpec = MeasureSpec.makeMeasureSpec(size, MeasureSpec.AT_MOST);
+            heightMeasureSpec = MeasureSpec.makeMeasureSpec(specHeight, MeasureSpec.AT_MOST);
+            measure(widthMeasureSpec, heightMeasureSpec);
+        }
+
+        /**
+         * Sets the order of this cue in the list of active cues.
+         *
+         * @param order the order of this cue in the list of active cues
+         */
+        public void setOrder(int order) {
+            mOrder = order;
+        }
+
+        /**
+         * @return whether this cue is marked as active
+         */
+        public boolean isActive() {
+            return mActive;
+        }
+
+        /**
+         * @return the cue data backing this layout
+         */
+        public TextTrackCue getCue() {
+            return mCue;
+        }
+    }
+
+    /**
+     * A text track line represents a single line of text within a cue.
+     * <p>
+     * A single line may contain multiple spans, each representing a section of
+     * text that may be enabled or disabled at a particular time.
+     */
+    private static class SpanLayout extends SubtitleView {
+        private final SpannableStringBuilder mBuilder = new SpannableStringBuilder();
+        private final TextTrackCueSpan[] mSpans;
+
+        public SpanLayout(Context context, TextTrackCueSpan[] spans) {
+            super(context);
+
+            mSpans = spans;
+
+            update();
+        }
+
+        public void update() {
+            final SpannableStringBuilder builder = mBuilder;
+            final TextTrackCueSpan[] spans = mSpans;
+
+            builder.clear();
+            builder.clearSpans();
+
+            final int spanCount = spans.length;
+            for (int i = 0; i < spanCount; i++) {
+                final TextTrackCueSpan span = spans[i];
+                if (span.mEnabled) {
+                    builder.append(spans[i].mText);
+                }
+            }
+
+            setText(builder);
+        }
+
+        public void setCaptionStyle(CaptionStyle captionStyle, float fontSize) {
+            setBackgroundColor(captionStyle.backgroundColor);
+            setForegroundColor(captionStyle.foregroundColor);
+            setEdgeColor(captionStyle.edgeColor);
+            setEdgeType(captionStyle.edgeType);
+            setTypeface(captionStyle.getTypeface());
+            setTextSize(fontSize);
+        }
+    }
+}
diff --git a/android/media/audiofx/AcousticEchoCanceler.java b/android/media/audiofx/AcousticEchoCanceler.java
new file mode 100644
index 0000000..3a44df4
--- /dev/null
+++ b/android/media/audiofx/AcousticEchoCanceler.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 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.audiofx;
+
+import android.util.Log;
+
+/**
+ * Acoustic Echo Canceler (AEC).
+ * <p>Acoustic Echo Canceler (AEC) is an audio pre-processor which removes the contribution of the
+ * signal received from the remote party from the captured audio signal.
+ * <p>AEC is used by voice communication applications (voice chat, video conferencing, SIP calls)
+ * where the presence of echo with significant delay in the signal received from the remote party
+ * is highly disturbing. AEC is often used in conjunction with noise suppression (NS).
+ * <p>An application creates an AcousticEchoCanceler object to instantiate and control an AEC
+ * engine in the audio capture path.
+ * <p>To attach the AcousticEchoCanceler to a particular {@link android.media.AudioRecord},
+ * specify the audio session ID of this AudioRecord when creating the AcousticEchoCanceler.
+ * The audio session is retrieved by calling
+ * {@link android.media.AudioRecord#getAudioSessionId()} on the AudioRecord instance.
+ * <p>On some devices, an AEC can be inserted by default in the capture path by the platform
+ * according to the {@link android.media.MediaRecorder.AudioSource} used. The application should
+ * call AcousticEchoCanceler.getEnable() after creating the AEC to check the default AEC activation
+ * state on a particular AudioRecord session.
+ * <p>See {@link android.media.audiofx.AudioEffect} class for more details on
+ * controlling audio effects.
+ */
+
+public class AcousticEchoCanceler extends AudioEffect {
+
+    private final static String TAG = "AcousticEchoCanceler";
+
+    /**
+     * Checks if the device implements acoustic echo cancellation.
+     * @return true if the device implements acoustic echo cancellation, false otherwise.
+     */
+    public static boolean isAvailable() {
+        return AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_AEC);
+    }
+
+    /**
+     * Creates an AcousticEchoCanceler and attaches it to the AudioRecord on the audio
+     * session specified.
+     * @param audioSession system wide unique audio session identifier. The AcousticEchoCanceler
+     * will be applied to the AudioRecord with the same audio session.
+     * @return AcousticEchoCanceler created or null if the device does not implement AEC.
+     */
+    public static AcousticEchoCanceler create(int audioSession) {
+        AcousticEchoCanceler aec = null;
+        try {
+            aec = new AcousticEchoCanceler(audioSession);
+        } catch (IllegalArgumentException e) {
+            Log.w(TAG, "not implemented on this device"+ aec);
+        } catch (UnsupportedOperationException e) {
+            Log.w(TAG, "not enough resources");
+        } catch (RuntimeException e) {
+            Log.w(TAG, "not enough memory");
+        }
+        return aec;
+    }
+
+    /**
+     * Class constructor.
+     * <p> The constructor is not guarantied to succeed and throws the following exceptions:
+     * <ul>
+     *  <li>IllegalArgumentException is thrown if the device does not implement an AEC</li>
+     *  <li>UnsupportedOperationException is thrown is the resources allocated to audio
+     *  pre-procesing are currently exceeded.</li>
+     *  <li>RuntimeException is thrown if a memory allocation error occurs.</li>
+     * </ul>
+     *
+     * @param audioSession system wide unique audio session identifier. The AcousticEchoCanceler
+     * will be applied to the AudioRecord with the same audio session.
+     *
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    private AcousticEchoCanceler(int audioSession)
+            throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
+        super(EFFECT_TYPE_AEC, EFFECT_TYPE_NULL, 0, audioSession);
+    }
+}
diff --git a/android/media/audiofx/AudioEffect.java b/android/media/audiofx/AudioEffect.java
new file mode 100644
index 0000000..70bb960
--- /dev/null
+++ b/android/media/audiofx/AudioEffect.java
@@ -0,0 +1,1566 @@
+/*
+ * Copyright (C) 2010 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.audiofx;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
+import android.content.AttributionSource.ScopedParcelState;
+import android.media.AudioDeviceAttributes;
+import android.media.AudioDeviceInfo;
+import android.media.AudioSystem;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.lang.ref.WeakReference;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * AudioEffect is the base class for controlling audio effects provided by the android audio
+ * framework.
+ * <p>Applications should not use the AudioEffect class directly but one of its derived classes to
+ * control specific effects:
+ * <ul>
+ *   <li> {@link android.media.audiofx.Equalizer}</li>
+ *   <li> {@link android.media.audiofx.Virtualizer}</li>
+ *   <li> {@link android.media.audiofx.BassBoost}</li>
+ *   <li> {@link android.media.audiofx.PresetReverb}</li>
+ *   <li> {@link android.media.audiofx.EnvironmentalReverb}</li>
+ *   <li> {@link android.media.audiofx.DynamicsProcessing}</li>
+ *   <li> {@link android.media.audiofx.HapticGenerator}</li>
+ * </ul>
+ * <p>To apply the audio effect to a specific AudioTrack or MediaPlayer instance,
+ * the application must specify the audio session ID of that instance when creating the AudioEffect.
+ * (see {@link android.media.MediaPlayer#getAudioSessionId()} for details on audio sessions).
+ * <p>NOTE: attaching insert effects (equalizer, bass boost, virtualizer) to the global audio output
+ * mix by use of session 0 is deprecated.
+ * <p>Creating an AudioEffect object will create the corresponding effect engine in the audio
+ * framework if no instance of the same effect type exists in the specified audio session.
+ * If one exists, this instance will be used.
+ * <p>The application creating the AudioEffect object (or a derived class) will either receive
+ * control of the effect engine or not depending on the priority parameter. If priority is higher
+ * than the priority used by the current effect engine owner, the control will be transfered to the
+ * new object. Otherwise control will remain with the previous object. In this case, the new
+ * application will be notified of changes in effect engine state or control ownership by the
+ * appropriate listener.
+ */
+
+public class AudioEffect {
+    static {
+        System.loadLibrary("audioeffect_jni");
+        native_init();
+    }
+
+    private final static String TAG = "AudioEffect-JAVA";
+
+    // effect type UUIDs are taken from hardware/libhardware/include/hardware/audio_effect.h
+
+    /**
+     * The following UUIDs define effect types corresponding to standard audio
+     * effects whose implementation and interface conform to the OpenSL ES
+     * specification. The definitions match the corresponding interface IDs in
+     * OpenSLES_IID.h
+     */
+    /**
+     * UUID for environmental reverberation effect
+     */
+    public static final UUID EFFECT_TYPE_ENV_REVERB = UUID
+            .fromString("c2e5d5f0-94bd-4763-9cac-4e234d06839e");
+    /**
+     * UUID for preset reverberation effect
+     */
+    public static final UUID EFFECT_TYPE_PRESET_REVERB = UUID
+            .fromString("47382d60-ddd8-11db-bf3a-0002a5d5c51b");
+    /**
+     * UUID for equalizer effect
+     */
+    public static final UUID EFFECT_TYPE_EQUALIZER = UUID
+            .fromString("0bed4300-ddd6-11db-8f34-0002a5d5c51b");
+    /**
+     * UUID for bass boost effect
+     */
+    public static final UUID EFFECT_TYPE_BASS_BOOST = UUID
+            .fromString("0634f220-ddd4-11db-a0fc-0002a5d5c51b");
+    /**
+     * UUID for virtualizer effect
+     */
+    public static final UUID EFFECT_TYPE_VIRTUALIZER = UUID
+            .fromString("37cc2c00-dddd-11db-8577-0002a5d5c51b");
+
+    /**
+     * UUIDs for effect types not covered by OpenSL ES.
+     */
+    /**
+     * UUID for Automatic Gain Control (AGC)
+     */
+    public static final UUID EFFECT_TYPE_AGC = UUID
+            .fromString("0a8abfe0-654c-11e0-ba26-0002a5d5c51b");
+
+    /**
+     * UUID for Acoustic Echo Canceler (AEC)
+     */
+    public static final UUID EFFECT_TYPE_AEC = UUID
+            .fromString("7b491460-8d4d-11e0-bd61-0002a5d5c51b");
+
+    /**
+     * UUID for Noise Suppressor (NS)
+     */
+    public static final UUID EFFECT_TYPE_NS = UUID
+            .fromString("58b4b260-8e06-11e0-aa8e-0002a5d5c51b");
+
+    /**
+     * UUID for Loudness Enhancer
+     */
+    public static final UUID EFFECT_TYPE_LOUDNESS_ENHANCER = UUID
+              .fromString("fe3199be-aed0-413f-87bb-11260eb63cf1");
+
+    /**
+     * UUID for Dynamics Processing
+     */
+    public static final UUID EFFECT_TYPE_DYNAMICS_PROCESSING = UUID
+              .fromString("7261676f-6d75-7369-6364-28e2fd3ac39e");
+
+    /**
+     * UUID for Haptic Generator.
+     */
+    // This is taken from system/media/audio/include/system/audio_effects/effect_hapticgenerator.h
+    @NonNull
+    public static final UUID EFFECT_TYPE_HAPTIC_GENERATOR = UUID
+              .fromString("1411e6d6-aecd-4021-a1cf-a6aceb0d71e5");
+
+    /**
+     * Null effect UUID. See {@link AudioEffect(UUID, UUID, int, int)} for use.
+     * @hide
+     */
+    @TestApi
+    public static final UUID EFFECT_TYPE_NULL = UUID
+            .fromString("ec7178ec-e5e1-4432-a3f4-4657e6795210");
+
+    /**
+     * State of an AudioEffect object that was not successfully initialized upon
+     * creation
+     * @hide
+     */
+    public static final int STATE_UNINITIALIZED = 0;
+    /**
+     * State of an AudioEffect object that is ready to be used.
+     * @hide
+     */
+    public static final int STATE_INITIALIZED = 1;
+
+    // to keep in sync with
+    // frameworks/base/include/media/AudioEffect.h
+    /**
+     * Event id for engine control ownership change notification.
+     * @hide
+     */
+    public static final int NATIVE_EVENT_CONTROL_STATUS = 0;
+    /**
+     * Event id for engine state change notification.
+     * @hide
+     */
+    public static final int NATIVE_EVENT_ENABLED_STATUS = 1;
+    /**
+     * Event id for engine parameter change notification.
+     * @hide
+     */
+    public static final int NATIVE_EVENT_PARAMETER_CHANGED = 2;
+
+    /**
+     * Successful operation.
+     */
+    public static final int SUCCESS = 0;
+    /**
+     * Unspecified error.
+     */
+    public static final int ERROR = -1;
+    /**
+     * Internal operation status. Not returned by any method.
+     */
+    public static final int ALREADY_EXISTS = -2;
+    /**
+     * Operation failed due to bad object initialization.
+     */
+    public static final int ERROR_NO_INIT = -3;
+    /**
+     * Operation failed due to bad parameter value.
+     */
+    public static final int ERROR_BAD_VALUE = -4;
+    /**
+     * Operation failed because it was requested in wrong state.
+     */
+    public static final int ERROR_INVALID_OPERATION = -5;
+    /**
+     * Operation failed due to lack of memory.
+     */
+    public static final int ERROR_NO_MEMORY = -6;
+    /**
+     * Operation failed due to dead remote object.
+     */
+    public static final int ERROR_DEAD_OBJECT = -7;
+
+    /**
+     * The effect descriptor contains information on a particular effect implemented in the
+     * audio framework:<br>
+     * <ul>
+     *  <li>type: UUID identifying the effect type. May be one of:
+     * {@link AudioEffect#EFFECT_TYPE_AEC}, {@link AudioEffect#EFFECT_TYPE_AGC},
+     * {@link AudioEffect#EFFECT_TYPE_BASS_BOOST}, {@link AudioEffect#EFFECT_TYPE_ENV_REVERB},
+     * {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS},
+     * {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}, {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER},
+     * {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING},
+     * {@link AudioEffect#EFFECT_TYPE_HAPTIC_GENERATOR}.
+     *  </li>
+     *  <li>uuid: UUID for this particular implementation</li>
+     *  <li>connectMode: {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}</li>
+     *  <li>name: human readable effect name</li>
+     *  <li>implementor: human readable effect implementor name</li>
+     * </ul>
+     * The method {@link #queryEffects()} returns an array of Descriptors to facilitate effects
+     * enumeration.
+     */
+    public static class Descriptor {
+
+        public Descriptor() {
+        }
+
+        /**
+         *  Indicates the generic type of the effect (Equalizer, Bass boost ...).
+         *  One of {@link AudioEffect#EFFECT_TYPE_AEC},
+         *  {@link AudioEffect#EFFECT_TYPE_AGC}, {@link AudioEffect#EFFECT_TYPE_BASS_BOOST},
+         *  {@link AudioEffect#EFFECT_TYPE_ENV_REVERB}, {@link AudioEffect#EFFECT_TYPE_EQUALIZER},
+         *  {@link AudioEffect#EFFECT_TYPE_NS}, {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB}
+         *  {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER},
+         *  {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING},
+         *  or {@link AudioEffect#EFFECT_TYPE_HAPTIC_GENERATOR}.<br>
+         *  For reverberation, bass boost, EQ and virtualizer, the UUID
+         *  corresponds to the OpenSL ES Interface ID.
+         */
+        public UUID type;
+        /**
+         *  Indicates the particular implementation of the effect in that type. Several effects
+         *  can have the same type but this uuid is unique to a given implementation.
+         */
+        public UUID uuid;
+        /**
+         *  Indicates if the effect is of insert category {@link #EFFECT_INSERT} or auxiliary
+         *  category {@link #EFFECT_AUXILIARY}.
+         *  Insert effects (typically an {@link Equalizer}) are applied
+         *  to the entire audio source and usually not shared by several sources. Auxiliary effects
+         *  (typically a reverberator) are applied to part of the signal (wet) and the effect output
+         *  is added to the original signal (dry).
+         *  Audio pre processing are applied to audio captured on a particular
+         * {@link android.media.AudioRecord}.
+         */
+        public String connectMode;
+        /**
+         * Human readable effect name
+         */
+        public String name;
+        /**
+         * Human readable effect implementor name
+         */
+        public String implementor;
+
+        /**
+         * @param type          UUID identifying the effect type. May be one of:
+         * {@link AudioEffect#EFFECT_TYPE_AEC}, {@link AudioEffect#EFFECT_TYPE_AGC},
+         * {@link AudioEffect#EFFECT_TYPE_BASS_BOOST}, {@link AudioEffect#EFFECT_TYPE_ENV_REVERB},
+         * {@link AudioEffect#EFFECT_TYPE_EQUALIZER}, {@link AudioEffect#EFFECT_TYPE_NS},
+         * {@link AudioEffect#EFFECT_TYPE_PRESET_REVERB},
+         * {@link AudioEffect#EFFECT_TYPE_VIRTUALIZER},
+         * {@link AudioEffect#EFFECT_TYPE_DYNAMICS_PROCESSING},
+         * {@link AudioEffect#EFFECT_TYPE_HAPTIC_GENERATOR}.
+         * @param uuid         UUID for this particular implementation
+         * @param connectMode  {@link #EFFECT_INSERT} or {@link #EFFECT_AUXILIARY}
+         * @param name         human readable effect name
+         * @param implementor  human readable effect implementor name
+        *
+        */
+        public Descriptor(String type, String uuid, String connectMode,
+                String name, String implementor) {
+            this.type = UUID.fromString(type);
+            this.uuid = UUID.fromString(uuid);
+            this.connectMode = connectMode;
+            this.name = name;
+            this.implementor = implementor;
+        }
+
+        /** @hide */
+        @TestApi
+        public Descriptor(Parcel in) {
+            type = UUID.fromString(in.readString());
+            uuid = UUID.fromString(in.readString());
+            connectMode = in.readString();
+            name = in.readString();
+            implementor = in.readString();
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(type, uuid, connectMode, name, implementor);
+        }
+
+        /** @hide */
+        @TestApi
+        public void writeToParcel(Parcel dest) {
+            dest.writeString(type.toString());
+            dest.writeString(uuid.toString());
+            dest.writeString(connectMode);
+            dest.writeString(name);
+            dest.writeString(implementor);
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (o == null || !(o instanceof Descriptor)) return false;
+
+            Descriptor that = (Descriptor) o;
+
+            return (type.equals(that.type)
+                    && uuid.equals(that.uuid)
+                    && connectMode.equals(that.connectMode)
+                    && name.equals(that.name)
+                    && implementor.equals(that.implementor));
+        }
+    }
+
+    /**
+     * Effect connection mode is insert. Specifying an audio session ID when creating the effect
+     * will insert this effect after all players in the same audio session.
+     */
+    public static final String EFFECT_INSERT = "Insert";
+    /**
+     * Effect connection mode is auxiliary.
+     * <p>Auxiliary effects must be created on session 0 (global output mix). In order for a
+     * MediaPlayer or AudioTrack to be fed into this effect, they must be explicitely attached to
+     * this effect and a send level must be specified.
+     * <p>Use the effect ID returned by {@link #getId()} to designate this particular effect when
+     * attaching it to the MediaPlayer or AudioTrack.
+     */
+    public static final String EFFECT_AUXILIARY = "Auxiliary";
+    /**
+     * Effect connection mode is pre processing.
+     * The audio pre processing effects are attached to an audio input stream or device
+     */
+    public static final String EFFECT_PRE_PROCESSING = "Pre Processing";
+    /**
+     * Effect connection mode is post processing.
+     * The audio post processing effects are attached to an audio output stream or device
+     */
+    public static final String EFFECT_POST_PROCESSING = "Post Processing";
+
+    // --------------------------------------------------------------------------
+    // Member variables
+    // --------------------
+    /**
+     * Indicates the state of the AudioEffect instance
+     */
+    private int mState = STATE_UNINITIALIZED;
+    /**
+     * Lock to synchronize access to mState
+     */
+    private final Object mStateLock = new Object();
+    /**
+     * System wide unique effect ID
+     */
+    private int mId;
+
+    // accessed by native methods
+    private long mNativeAudioEffect;
+    private long mJniData;
+
+    /**
+     * Effect descriptor
+     */
+    private Descriptor mDescriptor;
+
+    /**
+     * Listener for effect engine state change notifications.
+     *
+     * @see #setEnableStatusListener(OnEnableStatusChangeListener)
+     */
+    private OnEnableStatusChangeListener mEnableStatusChangeListener = null;
+    /**
+     * Listener for effect engine control ownership change notifications.
+     *
+     * @see #setControlStatusListener(OnControlStatusChangeListener)
+     */
+    private OnControlStatusChangeListener mControlChangeStatusListener = null;
+    /**
+     * Listener for effect engine control ownership change notifications.
+     *
+     * @see #setParameterListener(OnParameterChangeListener)
+     */
+    private OnParameterChangeListener mParameterChangeListener = null;
+    /**
+     * Lock to protect listeners updates against event notifications
+     * @hide
+     */
+    public final Object mListenerLock = new Object();
+    /**
+     * Handler for events coming from the native code
+     * @hide
+     */
+    public NativeEventHandler mNativeEventHandler = null;
+
+    // --------------------------------------------------------------------------
+    // Constructor, Finalize
+    // --------------------
+    /**
+     * Class constructor.
+     *
+     * @param type type of effect engine created. See {@link #EFFECT_TYPE_ENV_REVERB},
+     *            {@link #EFFECT_TYPE_EQUALIZER} ... Types corresponding to
+     *            built-in effects are defined by AudioEffect class. Other types
+     *            can be specified provided they correspond an existing OpenSL
+     *            ES interface ID and the corresponsing effect is available on
+     *            the platform. If an unspecified effect type is requested, the
+     *            constructor with throw the IllegalArgumentException. This
+     *            parameter can be set to {@link #EFFECT_TYPE_NULL} in which
+     *            case only the uuid will be used to select the effect.
+     * @param uuid unique identifier of a particular effect implementation.
+     *            Must be specified if the caller wants to use a particular
+     *            implementation of an effect type. This parameter can be set to
+     *            {@link #EFFECT_TYPE_NULL} in which case only the type will
+     *            be used to select the effect.
+     * @param priority the priority level requested by the application for
+     *            controlling the effect engine. As the same effect engine can
+     *            be shared by several applications, this parameter indicates
+     *            how much the requesting application needs control of effect
+     *            parameters. The normal priority is 0, above normal is a
+     *            positive number, below normal a negative number.
+     * @param audioSession system wide unique audio session identifier.
+     *            The effect will be attached to the MediaPlayer or AudioTrack in
+     *            the same audio session.
+     *
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     * @hide
+     */
+
+    @UnsupportedAppUsage
+    public AudioEffect(UUID type, UUID uuid, int priority, int audioSession)
+            throws IllegalArgumentException, UnsupportedOperationException,
+            RuntimeException {
+        this(type, uuid, priority, audioSession, null);
+    }
+
+    /**
+     * Constructs an AudioEffect attached to a particular audio device.
+     * The device does not have to be attached when the effect is created. The effect will only
+     * be applied when the device is actually selected for playback or capture.
+     * @param uuid unique identifier of a particular effect implementation.
+     * @param device the device the effect must be attached to.
+     *
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
+    public AudioEffect(@NonNull UUID uuid, @NonNull AudioDeviceAttributes device) {
+        this(EFFECT_TYPE_NULL, Objects.requireNonNull(uuid),
+                0, -2, Objects.requireNonNull(device));
+    }
+
+    private AudioEffect(UUID type, UUID uuid, int priority,
+            int audioSession, @Nullable AudioDeviceAttributes device)
+            throws IllegalArgumentException, UnsupportedOperationException,
+            RuntimeException {
+        this(type, uuid, priority, audioSession, device, false);
+    }
+
+    private AudioEffect(UUID type, UUID uuid, int priority,
+            int audioSession, @Nullable AudioDeviceAttributes device, boolean probe)
+            throws IllegalArgumentException, UnsupportedOperationException,
+            RuntimeException {
+        int[] id = new int[1];
+        Descriptor[] desc = new Descriptor[1];
+
+        int deviceType = AudioSystem.DEVICE_NONE;
+        String deviceAddress = "";
+        if (device != null) {
+            deviceType = AudioDeviceInfo.convertDeviceTypeToInternalDevice(device.getType());
+            deviceAddress = device.getAddress();
+        }
+
+        // native initialization
+        // TODO b/182469354: Make consistent with AudioRecord
+        int initResult;
+        try (ScopedParcelState attributionSourceState =  AttributionSource.myAttributionSource()
+                .asScopedParcelState()) {
+            initResult = native_setup(new WeakReference<>(this), type.toString(), uuid.toString(),
+                    priority, audioSession, deviceType, deviceAddress, id, desc,
+                    attributionSourceState.getParcel(), probe);
+        }
+        if (initResult != SUCCESS && initResult != ALREADY_EXISTS) {
+            Log.e(TAG, "Error code " + initResult
+                    + " when initializing AudioEffect.");
+            switch (initResult) {
+            case ERROR_BAD_VALUE:
+                throw (new IllegalArgumentException("Effect type: " + type
+                        + " not supported."));
+            case ERROR_INVALID_OPERATION:
+                throw (new UnsupportedOperationException(
+                        "Effect library not loaded"));
+            default:
+                throw (new RuntimeException(
+                        "Cannot initialize effect engine for type: " + type
+                                + " Error: " + initResult));
+            }
+        }
+        mId = id[0];
+        mDescriptor = desc[0];
+        if (!probe) {
+            synchronized (mStateLock) {
+                mState = STATE_INITIALIZED;
+            }
+        }
+    }
+
+    /**
+     * Checks if an AudioEffect identified by the supplied uuid can be attached
+     * to an audio device described by the supplied AudioDeviceAttributes.
+     * @param uuid unique identifier of a particular effect implementation.
+     * @param device the device the effect would be attached to.
+     * @return true if possible, false otherwise.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS)
+    public static boolean isEffectSupportedForDevice(
+            @NonNull UUID uuid, @NonNull AudioDeviceAttributes device) {
+        try {
+            AudioEffect fx = new AudioEffect(
+                    EFFECT_TYPE_NULL, Objects.requireNonNull(uuid),
+                    0, -2, Objects.requireNonNull(device), true);
+            fx.release();
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * Releases the native AudioEffect resources. It is a good practice to
+     * release the effect engine when not in use as control can be returned to
+     * other applications or the native resources released.
+     */
+    public void release() {
+        synchronized (mStateLock) {
+            native_release();
+            mState = STATE_UNINITIALIZED;
+        }
+    }
+
+    @Override
+    protected void finalize() {
+        native_finalize();
+    }
+
+    /**
+     * Get the effect descriptor.
+     *
+     * @see android.media.audiofx.AudioEffect.Descriptor
+     * @throws IllegalStateException
+     */
+    public Descriptor getDescriptor() throws IllegalStateException {
+        checkState("getDescriptor()");
+        return mDescriptor;
+    }
+
+    // --------------------------------------------------------------------------
+    // Effects Enumeration
+    // --------------------
+
+    /**
+     * Query all effects available on the platform. Returns an array of
+     * {@link android.media.audiofx.AudioEffect.Descriptor} objects
+     *
+     * @throws IllegalStateException
+     */
+
+    static public Descriptor[] queryEffects() {
+        return (Descriptor[]) native_query_effects();
+    }
+
+    /**
+     * Query all audio pre-processing effects applied to the AudioRecord with the supplied
+     * audio session ID. Returns an array of {@link android.media.audiofx.AudioEffect.Descriptor}
+     * objects.
+     * @param audioSession system wide unique audio session identifier.
+     * @throws IllegalStateException
+     * @hide
+     */
+
+    static public Descriptor[] queryPreProcessings(int audioSession) {
+        return (Descriptor[]) native_query_pre_processing(audioSession);
+    }
+
+    /**
+     * Checks if the device implements the specified effect type.
+     * @param type the requested effect type.
+     * @return true if the device implements the specified effect type, false otherwise.
+     * @hide
+     */
+    @TestApi
+    public static boolean isEffectTypeAvailable(UUID type) {
+        AudioEffect.Descriptor[] desc = AudioEffect.queryEffects();
+        if (desc == null) {
+            return false;
+        }
+
+        for (int i = 0; i < desc.length; i++) {
+            if (desc[i].type.equals(type)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    // --------------------------------------------------------------------------
+    // Control methods
+    // --------------------
+
+    /**
+     * Enable or disable the effect.
+     * Creating an audio effect does not automatically apply this effect on the audio source. It
+     * creates the resources necessary to process this effect but the audio signal is still bypassed
+     * through the effect engine. Calling this method will make that the effect is actually applied
+     * or not to the audio content being played in the corresponding audio session.
+     *
+     * @param enabled the requested enable state
+     * @return {@link #SUCCESS} in case of success, {@link #ERROR_INVALID_OPERATION}
+     *         or {@link #ERROR_DEAD_OBJECT} in case of failure.
+     * @throws IllegalStateException
+     */
+    public int setEnabled(boolean enabled) throws IllegalStateException {
+        checkState("setEnabled()");
+        return native_setEnabled(enabled);
+    }
+
+    /**
+     * Set effect parameter. The setParameter method is provided in several
+     * forms addressing most common parameter formats. This form is the most
+     * generic one where the parameter and its value are both specified as an
+     * array of bytes. The parameter and value type and length are therefore
+     * totally free. For standard effect defined by OpenSL ES, the parameter
+     * format and values must match the definitions in the corresponding OpenSL
+     * ES interface.
+     *
+     * @param param the identifier of the parameter to set
+     * @param value the new value for the specified parameter
+     * @return {@link #SUCCESS} in case of success, {@link #ERROR_BAD_VALUE},
+     *         {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or
+     *         {@link #ERROR_DEAD_OBJECT} in case of failure
+     * @throws IllegalStateException
+     * @hide
+     */
+    @TestApi
+    public int setParameter(byte[] param, byte[] value)
+            throws IllegalStateException {
+        checkState("setParameter()");
+        return native_setParameter(param.length, param, value.length, value);
+    }
+
+    /**
+     * Set effect parameter. The parameter and its value are integers.
+     *
+     * @see #setParameter(byte[], byte[])
+     * @hide
+     */
+    @TestApi
+    public int setParameter(int param, int value) throws IllegalStateException {
+        byte[] p = intToByteArray(param);
+        byte[] v = intToByteArray(value);
+        return setParameter(p, v);
+    }
+
+    /**
+     * Set effect parameter. The parameter is an integer and the value is a
+     * short integer.
+     *
+     * @see #setParameter(byte[], byte[])
+     * @hide
+     */
+    @TestApi
+    public int setParameter(int param, short value)
+            throws IllegalStateException {
+        byte[] p = intToByteArray(param);
+        byte[] v = shortToByteArray(value);
+        return setParameter(p, v);
+    }
+
+    /**
+     * Set effect parameter. The parameter is an integer and the value is an
+     * array of bytes.
+     *
+     * @see #setParameter(byte[], byte[])
+     * @hide
+     */
+    @TestApi
+    public int setParameter(int param, byte[] value)
+            throws IllegalStateException {
+        byte[] p = intToByteArray(param);
+        return setParameter(p, value);
+    }
+
+    /**
+     * Set effect parameter. The parameter is an array of 1 or 2 integers and
+     * the value is also an array of 1 or 2 integers
+     *
+     * @see #setParameter(byte[], byte[])
+     * @hide
+     */
+    @TestApi
+    public int setParameter(int[] param, int[] value)
+            throws IllegalStateException {
+        if (param.length > 2 || value.length > 2) {
+            return ERROR_BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param[0]);
+        if (param.length > 1) {
+            byte[] p2 = intToByteArray(param[1]);
+            p = concatArrays(p, p2);
+        }
+        byte[] v = intToByteArray(value[0]);
+        if (value.length > 1) {
+            byte[] v2 = intToByteArray(value[1]);
+            v = concatArrays(v, v2);
+        }
+        return setParameter(p, v);
+    }
+
+    /**
+     * Set effect parameter. The parameter is an array of 1 or 2 integers and
+     * the value is an array of 1 or 2 short integers
+     *
+     * @see #setParameter(byte[], byte[])
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public int setParameter(int[] param, short[] value)
+            throws IllegalStateException {
+        if (param.length > 2 || value.length > 2) {
+            return ERROR_BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param[0]);
+        if (param.length > 1) {
+            byte[] p2 = intToByteArray(param[1]);
+            p = concatArrays(p, p2);
+        }
+
+        byte[] v = shortToByteArray(value[0]);
+        if (value.length > 1) {
+            byte[] v2 = shortToByteArray(value[1]);
+            v = concatArrays(v, v2);
+        }
+        return setParameter(p, v);
+    }
+
+    /**
+     * Set effect parameter. The parameter is an array of 1 or 2 integers and
+     * the value is an array of bytes
+     *
+     * @see #setParameter(byte[], byte[])
+     * @hide
+     */
+    @TestApi
+    public int setParameter(int[] param, byte[] value)
+            throws IllegalStateException {
+        if (param.length > 2) {
+            return ERROR_BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param[0]);
+        if (param.length > 1) {
+            byte[] p2 = intToByteArray(param[1]);
+            p = concatArrays(p, p2);
+        }
+        return setParameter(p, value);
+    }
+
+    /**
+     * Get effect parameter. The getParameter method is provided in several
+     * forms addressing most common parameter formats. This form is the most
+     * generic one where the parameter and its value are both specified as an
+     * array of bytes. The parameter and value type and length are therefore
+     * totally free.
+     *
+     * @param param the identifier of the parameter to set
+     * @param value the new value for the specified parameter
+     * @return the number of meaningful bytes in value array in case of success or
+     *  {@link #ERROR_BAD_VALUE}, {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION}
+     *  or {@link #ERROR_DEAD_OBJECT} in case of failure.
+     * @throws IllegalStateException
+     * @hide
+     */
+    @TestApi
+    public int getParameter(byte[] param, byte[] value)
+            throws IllegalStateException {
+        checkState("getParameter()");
+        return native_getParameter(param.length, param, value.length, value);
+    }
+
+    /**
+     * Get effect parameter. The parameter is an integer and the value is an
+     * array of bytes.
+     *
+     * @see #getParameter(byte[], byte[])
+     * @hide
+     */
+    @TestApi
+    public int getParameter(int param, byte[] value)
+            throws IllegalStateException {
+        byte[] p = intToByteArray(param);
+
+        return getParameter(p, value);
+    }
+
+    /**
+     * Get effect parameter. The parameter is an integer and the value is an
+     * array of 1 or 2 integers
+     *
+     * @see #getParameter(byte[], byte[])
+     * In case of success, returns the number of meaningful integers in value array.
+     * @hide
+     */
+    @TestApi
+    public int getParameter(int param, int[] value)
+            throws IllegalStateException {
+        if (value.length > 2) {
+            return ERROR_BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param);
+
+        byte[] v = new byte[value.length * 4];
+
+        int status = getParameter(p, v);
+
+        if (status == 4 || status == 8) {
+            value[0] = byteArrayToInt(v);
+            if (status == 8) {
+                value[1] = byteArrayToInt(v, 4);
+            }
+            status /= 4;
+        } else {
+            status = ERROR;
+        }
+        return status;
+    }
+
+    /**
+     * Get effect parameter. The parameter is an integer and the value is an
+     * array of 1 or 2 short integers
+     *
+     * @see #getParameter(byte[], byte[])
+     * In case of success, returns the number of meaningful short integers in value array.
+     * @hide
+     */
+    @TestApi
+    public int getParameter(int param, short[] value)
+            throws IllegalStateException {
+        if (value.length > 2) {
+            return ERROR_BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param);
+
+        byte[] v = new byte[value.length * 2];
+
+        int status = getParameter(p, v);
+
+        if (status == 2 || status == 4) {
+            value[0] = byteArrayToShort(v);
+            if (status == 4) {
+                value[1] = byteArrayToShort(v, 2);
+            }
+            status /= 2;
+        } else {
+            status = ERROR;
+        }
+        return status;
+    }
+
+    /**
+     * Get effect parameter. The parameter is an array of 1 or 2 integers and
+     * the value is also an array of 1 or 2 integers
+     *
+     * @see #getParameter(byte[], byte[])
+     * In case of success, the returns the number of meaningful integers in value array.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public int getParameter(int[] param, int[] value)
+            throws IllegalStateException {
+        if (param.length > 2 || value.length > 2) {
+            return ERROR_BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param[0]);
+        if (param.length > 1) {
+            byte[] p2 = intToByteArray(param[1]);
+            p = concatArrays(p, p2);
+        }
+        byte[] v = new byte[value.length * 4];
+
+        int status = getParameter(p, v);
+
+        if (status == 4 || status == 8) {
+            value[0] = byteArrayToInt(v);
+            if (status == 8) {
+                value[1] = byteArrayToInt(v, 4);
+            }
+            status /= 4;
+        } else {
+            status = ERROR;
+        }
+        return status;
+    }
+
+    /**
+     * Get effect parameter. The parameter is an array of 1 or 2 integers and
+     * the value is an array of 1 or 2 short integers
+     *
+     * @see #getParameter(byte[], byte[])
+     * In case of success, returns the number of meaningful short integers in value array.
+     * @hide
+     */
+    @TestApi
+    public int getParameter(int[] param, short[] value)
+            throws IllegalStateException {
+        if (param.length > 2 || value.length > 2) {
+            return ERROR_BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param[0]);
+        if (param.length > 1) {
+            byte[] p2 = intToByteArray(param[1]);
+            p = concatArrays(p, p2);
+        }
+        byte[] v = new byte[value.length * 2];
+
+        int status = getParameter(p, v);
+
+        if (status == 2 || status == 4) {
+            value[0] = byteArrayToShort(v);
+            if (status == 4) {
+                value[1] = byteArrayToShort(v, 2);
+            }
+            status /= 2;
+        } else {
+            status = ERROR;
+        }
+        return status;
+    }
+
+    /**
+     * Get effect parameter. The parameter is an array of 1 or 2 integers and
+     * the value is an array of bytes
+     *
+     * @see #getParameter(byte[], byte[])
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public int getParameter(int[] param, byte[] value)
+            throws IllegalStateException {
+        if (param.length > 2) {
+            return ERROR_BAD_VALUE;
+        }
+        byte[] p = intToByteArray(param[0]);
+        if (param.length > 1) {
+            byte[] p2 = intToByteArray(param[1]);
+            p = concatArrays(p, p2);
+        }
+
+        return getParameter(p, value);
+    }
+
+    /**
+     * Send a command to the effect engine. This method is intended to send
+     * proprietary commands to a particular effect implementation.
+     * In case of success, returns the number of meaningful bytes in reply array.
+     * In case of failure, the returned value is negative and implementation specific.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
+    public int command(int cmdCode, byte[] command, byte[] reply)
+            throws IllegalStateException {
+        checkState("command()");
+        return native_command(cmdCode, command.length, command, reply.length, reply);
+    }
+
+    // --------------------------------------------------------------------------
+    // Getters
+    // --------------------
+
+    /**
+     * Returns effect unique identifier. This system wide unique identifier can
+     * be used to attach this effect to a MediaPlayer or an AudioTrack when the
+     * effect is an auxiliary effect (Reverb)
+     *
+     * @return the effect identifier.
+     * @throws IllegalStateException
+     */
+    public int getId() throws IllegalStateException {
+        checkState("getId()");
+        return mId;
+    }
+
+    /**
+     * Returns effect enabled state
+     *
+     * @return true if the effect is enabled, false otherwise.
+     * @throws IllegalStateException
+     */
+    public boolean getEnabled() throws IllegalStateException {
+        checkState("getEnabled()");
+        return native_getEnabled();
+    }
+
+    /**
+     * Checks if this AudioEffect object is controlling the effect engine.
+     *
+     * @return true if this instance has control of effect engine, false
+     *         otherwise.
+     * @throws IllegalStateException
+     */
+    public boolean hasControl() throws IllegalStateException {
+        checkState("hasControl()");
+        return native_hasControl();
+    }
+
+    // --------------------------------------------------------------------------
+    // Initialization / configuration
+    // --------------------
+    /**
+     * Sets the listener AudioEffect notifies when the effect engine is enabled
+     * or disabled.
+     *
+     * @param listener
+     */
+    public void setEnableStatusListener(OnEnableStatusChangeListener listener) {
+        synchronized (mListenerLock) {
+            mEnableStatusChangeListener = listener;
+        }
+        if ((listener != null) && (mNativeEventHandler == null)) {
+            createNativeEventHandler();
+        }
+    }
+
+    /**
+     * Sets the listener AudioEffect notifies when the effect engine control is
+     * taken or returned.
+     *
+     * @param listener
+     */
+    public void setControlStatusListener(OnControlStatusChangeListener listener) {
+        synchronized (mListenerLock) {
+            mControlChangeStatusListener = listener;
+        }
+        if ((listener != null) && (mNativeEventHandler == null)) {
+            createNativeEventHandler();
+        }
+    }
+
+    /**
+     * Sets the listener AudioEffect notifies when a parameter is changed.
+     *
+     * @param listener
+     * @hide
+     */
+    @TestApi
+    public void setParameterListener(OnParameterChangeListener listener) {
+        synchronized (mListenerLock) {
+            mParameterChangeListener = listener;
+        }
+        if ((listener != null) && (mNativeEventHandler == null)) {
+            createNativeEventHandler();
+        }
+    }
+
+    // Convenience method for the creation of the native event handler
+    // It is called only when a non-null event listener is set.
+    // precondition:
+    // mNativeEventHandler is null
+    private void createNativeEventHandler() {
+        Looper looper;
+        if ((looper = Looper.myLooper()) != null) {
+            mNativeEventHandler = new NativeEventHandler(this, looper);
+        } else if ((looper = Looper.getMainLooper()) != null) {
+            mNativeEventHandler = new NativeEventHandler(this, looper);
+        } else {
+            mNativeEventHandler = null;
+        }
+    }
+
+    // ---------------------------------------------------------
+    // Interface definitions
+    // --------------------
+    /**
+     * The OnEnableStatusChangeListener interface defines a method called by the AudioEffect
+     * when the enabled state of the effect engine was changed by the controlling application.
+     */
+    public interface OnEnableStatusChangeListener {
+        /**
+         * Called on the listener to notify it that the effect engine has been
+         * enabled or disabled.
+         * @param effect the effect on which the interface is registered.
+         * @param enabled new effect state.
+         */
+        void onEnableStatusChange(AudioEffect effect, boolean enabled);
+    }
+
+    /**
+     * The OnControlStatusChangeListener interface defines a method called by the AudioEffect
+     * when control of the effect engine is gained or lost by the application
+     */
+    public interface OnControlStatusChangeListener {
+        /**
+         * Called on the listener to notify it that the effect engine control
+         * has been taken or returned.
+         * @param effect the effect on which the interface is registered.
+         * @param controlGranted true if the application has been granted control of the effect
+         * engine, false otherwise.
+         */
+        void onControlStatusChange(AudioEffect effect, boolean controlGranted);
+    }
+
+    /**
+     * The OnParameterChangeListener interface defines a method called by the AudioEffect
+     * when a parameter is changed in the effect engine by the controlling application.
+     * @hide
+     */
+    @TestApi
+    public interface OnParameterChangeListener {
+        /**
+         * Called on the listener to notify it that a parameter value has changed.
+         * @param effect the effect on which the interface is registered.
+         * @param status status of the set parameter operation.
+         * @param param ID of the modified parameter.
+         * @param value the new parameter value.
+         */
+        void onParameterChange(AudioEffect effect, int status, byte[] param,
+                byte[] value);
+    }
+
+
+    // -------------------------------------------------------------------------
+    // Audio Effect Control panel intents
+    // -------------------------------------------------------------------------
+
+    /**
+     *  Intent to launch an audio effect control panel UI.
+     *  <p>The goal of this intent is to enable separate implementations of music/media player
+     *  applications and audio effect control application or services.
+     *  This will allow platform vendors to offer more advanced control options for standard effects
+     *  or control for platform specific effects.
+     *  <p>The intent carries a number of extras used by the player application to communicate
+     *  necessary pieces of information to the control panel application.
+     *  <p>The calling application must use the
+     *  {@link android.app.Activity#startActivityForResult(Intent, int)} method to launch the
+     *  control panel so that its package name is indicated and used by the control panel
+     *  application to keep track of changes for this particular application.
+     *  <p>The {@link #EXTRA_AUDIO_SESSION} extra will indicate an audio session to which the
+     *  audio effects should be applied. If no audio session is specified, either one of the
+     *  follownig will happen:
+     *  <p>- If an audio session was previously opened by the calling application with
+     *  {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} intent, the effect changes will
+     *  be applied to that session.
+     *  <p>- If no audio session is opened, the changes will be stored in the package specific
+     *  storage area and applied whenever a new audio session is opened by this application.
+     *  <p>The {@link #EXTRA_CONTENT_TYPE} extra will help the control panel application
+     *  customize both the UI layout and the default audio effect settings if none are already
+     *  stored for the calling application.
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL =
+        "android.media.action.DISPLAY_AUDIO_EFFECT_CONTROL_PANEL";
+
+    /**
+     *  Intent to signal to the effect control application or service that a new audio session
+     *  is opened and requires audio effects to be applied.
+     *  <p>This is different from {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL} in that no
+     *  UI should be displayed in this case. Music player applications can broadcast this intent
+     *  before starting playback to make sure that any audio effect settings previously selected
+     *  by the user are applied.
+     *  <p>The effect control application receiving this intent will look for previously stored
+     *  settings for the calling application, create all required audio effects and apply the
+     *  effect settings to the specified audio session.
+     *  <p>The calling package name is indicated by the {@link #EXTRA_PACKAGE_NAME} extra and the
+     *  audio session ID by the {@link #EXTRA_AUDIO_SESSION} extra. Both extras are mandatory.
+     *  <p>If no stored settings are found for the calling application, default settings for the
+     *  content type indicated by {@link #EXTRA_CONTENT_TYPE} will be applied. The default settings
+     *  for a given content type are platform specific.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION =
+        "android.media.action.OPEN_AUDIO_EFFECT_CONTROL_SESSION";
+
+    /**
+     *  Intent to signal to the effect control application or service that an audio session
+     *  is closed and that effects should not be applied anymore.
+     *  <p>The effect control application receiving this intent will delete all effects on
+     *  this session and store current settings in package specific storage.
+     *  <p>The calling package name is indicated by the {@link #EXTRA_PACKAGE_NAME} extra and the
+     *  audio session ID by the {@link #EXTRA_AUDIO_SESSION} extra. Both extras are mandatory.
+     *  <p>It is good practice for applications to broadcast this intent when music playback stops
+     *  and/or when exiting to free system resources consumed by audio effect engines.
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION =
+        "android.media.action.CLOSE_AUDIO_EFFECT_CONTROL_SESSION";
+
+    /**
+     * Contains the ID of the audio session the effects should be applied to.
+     * <p>This extra is for use with {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL},
+     * {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} and
+     * {@link #ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION} intents.
+     * <p>The extra value is of type int and is the audio session ID.
+     *  @see android.media.MediaPlayer#getAudioSessionId() for details on audio sessions.
+     */
+     public static final String EXTRA_AUDIO_SESSION = "android.media.extra.AUDIO_SESSION";
+
+    /**
+     * Contains the package name of the calling application.
+     * <p>This extra is for use with {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} and
+     * {@link #ACTION_CLOSE_AUDIO_EFFECT_CONTROL_SESSION} intents.
+     * <p>The extra value is a string containing the full package name.
+     */
+    public static final String EXTRA_PACKAGE_NAME = "android.media.extra.PACKAGE_NAME";
+
+    /**
+     * Indicates which type of content is played by the application.
+     * <p>This extra is for use with {@link #ACTION_DISPLAY_AUDIO_EFFECT_CONTROL_PANEL} and
+     * {@link #ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION} intents.
+     * <p>This information is used by the effect control application to customize UI and select
+     * appropriate default effect settings. The content type is one of the following:
+     * <ul>
+     *   <li>{@link #CONTENT_TYPE_MUSIC}</li>
+     *   <li>{@link #CONTENT_TYPE_MOVIE}</li>
+     *   <li>{@link #CONTENT_TYPE_GAME}</li>
+     *   <li>{@link #CONTENT_TYPE_VOICE}</li>
+     * </ul>
+     * If omitted, the content type defaults to {@link #CONTENT_TYPE_MUSIC}.
+     */
+    public static final String EXTRA_CONTENT_TYPE = "android.media.extra.CONTENT_TYPE";
+
+    /**
+     * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is music
+     */
+    public static final int  CONTENT_TYPE_MUSIC = 0;
+    /**
+     * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is video or movie
+     */
+    public static final int  CONTENT_TYPE_MOVIE = 1;
+    /**
+     * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is game audio
+     */
+    public static final int  CONTENT_TYPE_GAME = 2;
+    /**
+     * Value for {@link #EXTRA_CONTENT_TYPE} when the type of content played is voice audio
+     */
+    public static final int  CONTENT_TYPE_VOICE = 3;
+
+
+    // ---------------------------------------------------------
+    // Inner classes
+    // --------------------
+    /**
+     * Helper class to handle the forwarding of native events to the appropriate
+     * listeners
+     */
+    private class NativeEventHandler extends Handler {
+        private AudioEffect mAudioEffect;
+
+        public NativeEventHandler(AudioEffect ae, Looper looper) {
+            super(looper);
+            mAudioEffect = ae;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (mAudioEffect == null) {
+                return;
+            }
+            switch (msg.what) {
+            case NATIVE_EVENT_ENABLED_STATUS:
+                OnEnableStatusChangeListener enableStatusChangeListener = null;
+                synchronized (mListenerLock) {
+                    enableStatusChangeListener = mAudioEffect.mEnableStatusChangeListener;
+                }
+                if (enableStatusChangeListener != null) {
+                    enableStatusChangeListener.onEnableStatusChange(
+                            mAudioEffect, (boolean) (msg.arg1 != 0));
+                }
+                break;
+            case NATIVE_EVENT_CONTROL_STATUS:
+                OnControlStatusChangeListener controlStatusChangeListener = null;
+                synchronized (mListenerLock) {
+                    controlStatusChangeListener = mAudioEffect.mControlChangeStatusListener;
+                }
+                if (controlStatusChangeListener != null) {
+                    controlStatusChangeListener.onControlStatusChange(
+                            mAudioEffect, (boolean) (msg.arg1 != 0));
+                }
+                break;
+            case NATIVE_EVENT_PARAMETER_CHANGED:
+                OnParameterChangeListener parameterChangeListener = null;
+                synchronized (mListenerLock) {
+                    parameterChangeListener = mAudioEffect.mParameterChangeListener;
+                }
+                if (parameterChangeListener != null) {
+                    // arg1 contains offset of parameter value from start of
+                    // byte array
+                    int vOffset = msg.arg1;
+                    byte[] p = (byte[]) msg.obj;
+                    // See effect_param_t in EffectApi.h for psize and vsize
+                    // fields offsets
+                    int status = byteArrayToInt(p, 0);
+                    int psize = byteArrayToInt(p, 4);
+                    int vsize = byteArrayToInt(p, 8);
+                    byte[] param = new byte[psize];
+                    byte[] value = new byte[vsize];
+                    System.arraycopy(p, 12, param, 0, psize);
+                    System.arraycopy(p, vOffset, value, 0, vsize);
+
+                    parameterChangeListener.onParameterChange(mAudioEffect,
+                            status, param, value);
+                }
+                break;
+
+            default:
+                Log.e(TAG, "handleMessage() Unknown event type: " + msg.what);
+                break;
+            }
+        }
+    }
+
+    // ---------------------------------------------------------
+    // Java methods called from the native side
+    // --------------------
+    @SuppressWarnings("unused")
+    private static void postEventFromNative(Object effect_ref, int what,
+            int arg1, int arg2, Object obj) {
+        AudioEffect effect = (AudioEffect) ((WeakReference) effect_ref).get();
+        if (effect == null) {
+            return;
+        }
+        if (effect.mNativeEventHandler != null) {
+            Message m = effect.mNativeEventHandler.obtainMessage(what, arg1,
+                    arg2, obj);
+            effect.mNativeEventHandler.sendMessage(m);
+        }
+
+    }
+
+    // ---------------------------------------------------------
+    // Native methods called from the Java side
+    // --------------------
+
+    private static native final void native_init();
+
+    private native final int native_setup(Object audioeffect_this, String type,
+            String uuid, int priority, int audioSession,
+            int deviceType, String deviceAddress, int[] id, Object[] desc,
+            @NonNull Parcel attributionSource, boolean probe);
+
+    private native final void native_finalize();
+
+    private native final void native_release();
+
+    private native final int native_setEnabled(boolean enabled);
+
+    private native final boolean native_getEnabled();
+
+    private native final boolean native_hasControl();
+
+    private native final int native_setParameter(int psize, byte[] param,
+            int vsize, byte[] value);
+
+    private native final int native_getParameter(int psize, byte[] param,
+            int vsize, byte[] value);
+
+    private native final int native_command(int cmdCode, int cmdSize,
+            byte[] cmdData, int repSize, byte[] repData);
+
+    private static native Object[] native_query_effects();
+
+    private static native Object[] native_query_pre_processing(int audioSession);
+
+    // ---------------------------------------------------------
+    // Utility methods
+    // ------------------
+
+    /**
+    * @hide
+    */
+    @UnsupportedAppUsage
+    public void checkState(String methodName) throws IllegalStateException {
+        synchronized (mStateLock) {
+            if (mState != STATE_INITIALIZED) {
+                throw (new IllegalStateException(methodName
+                        + " called on uninitialized AudioEffect."));
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public void checkStatus(int status) {
+        if (isError(status)) {
+            switch (status) {
+            case AudioEffect.ERROR_BAD_VALUE:
+                throw (new IllegalArgumentException(
+                        "AudioEffect: bad parameter value"));
+            case AudioEffect.ERROR_INVALID_OPERATION:
+                throw (new UnsupportedOperationException(
+                        "AudioEffect: invalid parameter operation"));
+            default:
+                throw (new RuntimeException("AudioEffect: set/get parameter error"));
+            }
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public static boolean isError(int status) {
+        return (status < 0);
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public static int byteArrayToInt(byte[] valueBuf) {
+        return byteArrayToInt(valueBuf, 0);
+
+    }
+
+    /**
+     * @hide
+     */
+    public static int byteArrayToInt(byte[] valueBuf, int offset) {
+        ByteBuffer converter = ByteBuffer.wrap(valueBuf);
+        converter.order(ByteOrder.nativeOrder());
+        return converter.getInt(offset);
+
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public static byte[] intToByteArray(int value) {
+        ByteBuffer converter = ByteBuffer.allocate(4);
+        converter.order(ByteOrder.nativeOrder());
+        converter.putInt(value);
+        return converter.array();
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public static short byteArrayToShort(byte[] valueBuf) {
+        return byteArrayToShort(valueBuf, 0);
+    }
+
+    /**
+     * @hide
+     */
+    public static short byteArrayToShort(byte[] valueBuf, int offset) {
+        ByteBuffer converter = ByteBuffer.wrap(valueBuf);
+        converter.order(ByteOrder.nativeOrder());
+        return converter.getShort(offset);
+
+    }
+
+    /**
+     * @hide
+     */
+    @TestApi
+    public static byte[] shortToByteArray(short value) {
+        ByteBuffer converter = ByteBuffer.allocate(2);
+        converter.order(ByteOrder.nativeOrder());
+        short sValue = (short) value;
+        converter.putShort(sValue);
+        return converter.array();
+    }
+
+    /**
+     * @hide
+     */
+    public static float byteArrayToFloat(byte[] valueBuf) {
+        return byteArrayToFloat(valueBuf, 0);
+
+    }
+
+    /**
+     * @hide
+     */
+    public static float byteArrayToFloat(byte[] valueBuf, int offset) {
+        ByteBuffer converter = ByteBuffer.wrap(valueBuf);
+        converter.order(ByteOrder.nativeOrder());
+        return converter.getFloat(offset);
+
+    }
+
+    /**
+     * @hide
+     */
+    public static byte[] floatToByteArray(float value) {
+        ByteBuffer converter = ByteBuffer.allocate(4);
+        converter.order(ByteOrder.nativeOrder());
+        converter.putFloat(value);
+        return converter.array();
+    }
+
+    /**
+     * @hide
+     */
+    public static byte[] concatArrays(byte[]... arrays) {
+        int len = 0;
+        for (byte[] a : arrays) {
+            len += a.length;
+        }
+        byte[] b = new byte[len];
+
+        int offs = 0;
+        for (byte[] a : arrays) {
+            System.arraycopy(a, 0, b, offs, a.length);
+            offs += a.length;
+        }
+        return b;
+    }
+}
diff --git a/android/media/audiofx/AutomaticGainControl.java b/android/media/audiofx/AutomaticGainControl.java
new file mode 100644
index 0000000..a76b4de
--- /dev/null
+++ b/android/media/audiofx/AutomaticGainControl.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 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.audiofx;
+
+import android.util.Log;
+
+/**
+ * Automatic Gain Control (AGC).
+ * <p>Automatic Gain Control (AGC) is an audio pre-processor which automatically normalizes the
+ * output of the captured signal by boosting or lowering input from the microphone to match a preset
+ * level so that the output signal level is virtually constant.
+ * AGC can be used by applications where the input signal dynamic range is not important but where
+ * a constant strong capture level is desired.
+ * <p>An application creates a AutomaticGainControl object to instantiate and control an AGC
+ * engine in the audio framework.
+ * <p>To attach the AutomaticGainControl to a particular {@link android.media.AudioRecord},
+ * specify the audio session ID of this AudioRecord when creating the AutomaticGainControl.
+ * The audio session is retrieved by calling
+ * {@link android.media.AudioRecord#getAudioSessionId()} on the AudioRecord instance.
+ * <p>On some devices, an AGC can be inserted by default in the capture path by the platform
+ * according to the {@link android.media.MediaRecorder.AudioSource} used. The application should
+ * call AutomaticGainControl.getEnable() after creating the AGC to check the default AGC activation
+ * state on a particular AudioRecord session.
+ * <p>See {@link android.media.audiofx.AudioEffect} class for more details on
+ * controlling audio effects.
+ */
+
+public class AutomaticGainControl extends AudioEffect {
+
+    private final static String TAG = "AutomaticGainControl";
+
+    /**
+     * Checks if the device implements automatic gain control.
+     * @return true if the device implements automatic gain control, false otherwise.
+     */
+    public static boolean isAvailable() {
+        return AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_AGC);
+    }
+
+    /**
+     * Creates an AutomaticGainControl and attaches it to the AudioRecord on the audio
+     * session specified.
+     * @param audioSession system wide unique audio session identifier. The AutomaticGainControl
+     * will be applied to the AudioRecord with the same audio session.
+     * @return AutomaticGainControl created or null if the device does not implement AGC.
+     */
+    public static AutomaticGainControl create(int audioSession) {
+        AutomaticGainControl agc = null;
+        try {
+            agc = new AutomaticGainControl(audioSession);
+        } catch (IllegalArgumentException e) {
+            Log.w(TAG, "not implemented on this device "+agc);
+        } catch (UnsupportedOperationException e) {
+            Log.w(TAG, "not enough resources");
+        } catch (RuntimeException e) {
+            Log.w(TAG, "not enough memory");
+        }
+        return agc;
+    }
+
+    /**
+     * Class constructor.
+     * <p> The constructor is not guarantied to succeed and throws the following exceptions:
+     * <ul>
+     *  <li>IllegalArgumentException is thrown if the device does not implement an AGC</li>
+     *  <li>UnsupportedOperationException is thrown is the resources allocated to audio
+     *  pre-procesing are currently exceeded.</li>
+     *  <li>RuntimeException is thrown if a memory allocation error occurs.</li>
+     * </ul>
+     *
+     * @param audioSession system wide unique audio session identifier. The AutomaticGainControl
+     * will be applied to the AudioRecord with the same audio session.
+     *
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    private AutomaticGainControl(int audioSession)
+            throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
+        super(EFFECT_TYPE_AGC, EFFECT_TYPE_NULL, 0, audioSession);
+    }
+}
diff --git a/android/media/audiofx/BassBoost.java b/android/media/audiofx/BassBoost.java
new file mode 100644
index 0000000..a46cc22
--- /dev/null
+++ b/android/media/audiofx/BassBoost.java
@@ -0,0 +1,287 @@
+/*
+ * Copyright (C) 2010 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.audiofx;
+
+import android.media.audiofx.AudioEffect;
+import android.util.Log;
+
+import java.util.StringTokenizer;
+
+
+/**
+ * Bass boost is an audio effect to boost or amplify low frequencies of the sound. It is comparable
+ * to a simple equalizer but limited to one band amplification in the low frequency range.
+ * <p>An application creates a BassBoost object to instantiate and control a bass boost engine in
+ * the audio framework.
+ * <p>The methods, parameter types and units exposed by the BassBoost implementation are directly
+ * mapping those defined by the OpenSL ES 1.0.1 Specification (http://www.khronos.org/opensles/)
+ * for the SLBassBoostItf interface. Please refer to this specification for more details.
+ * <p>To attach the BassBoost to a particular AudioTrack or MediaPlayer, specify the audio session
+ * ID of this AudioTrack or MediaPlayer when constructing the BassBoost.
+ * <p>NOTE: attaching a BassBoost to the global audio output mix by use of session 0 is deprecated.
+ * <p>See {@link android.media.MediaPlayer#getAudioSessionId()} for details on audio sessions.
+ * <p>See {@link android.media.audiofx.AudioEffect} class for more details on
+ * controlling audio effects.
+ */
+
+public class BassBoost extends AudioEffect {
+
+    private final static String TAG = "BassBoost";
+
+    // These constants must be synchronized with those in
+    // frameworks/base/include/media/EffectBassBoostApi.h
+    /**
+     * Is strength parameter supported by bass boost engine. Parameter ID for getParameter().
+     */
+    public static final int PARAM_STRENGTH_SUPPORTED = 0;
+    /**
+     * Bass boost effect strength. Parameter ID for
+     * {@link android.media.audiofx.BassBoost.OnParameterChangeListener}
+     */
+    public static final int PARAM_STRENGTH = 1;
+
+    /**
+     * Indicates if strength parameter is supported by the bass boost engine
+     */
+    private boolean mStrengthSupported = false;
+
+    /**
+     * Registered listener for parameter changes.
+     */
+    private OnParameterChangeListener mParamListener = null;
+
+    /**
+     * Listener used internally to to receive raw parameter change event from AudioEffect super class
+     */
+    private BaseParameterListener mBaseParamListener = null;
+
+    /**
+     * Lock for access to mParamListener
+     */
+    private final Object mParamListenerLock = new Object();
+
+    /**
+     * Class constructor.
+     * @param priority the priority level requested by the application for controlling the BassBoost
+     * engine. As the same engine can be shared by several applications, this parameter indicates
+     * how much the requesting application needs control of effect parameters. The normal priority
+     * is 0, above normal is a positive number, below normal a negative number.
+     * @param audioSession system wide unique audio session identifier. The BassBoost will be
+     * attached to the MediaPlayer or AudioTrack in the same audio session.
+     *
+     * @throws java.lang.IllegalStateException
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    public BassBoost(int priority, int audioSession)
+    throws IllegalStateException, IllegalArgumentException,
+           UnsupportedOperationException, RuntimeException {
+        super(EFFECT_TYPE_BASS_BOOST, EFFECT_TYPE_NULL, priority, audioSession);
+
+        if (audioSession == 0) {
+            Log.w(TAG, "WARNING: attaching a BassBoost to global output mix is deprecated!");
+        }
+
+        int[] value = new int[1];
+        checkStatus(getParameter(PARAM_STRENGTH_SUPPORTED, value));
+        mStrengthSupported = (value[0] != 0);
+    }
+
+    /**
+     * Indicates whether setting strength is supported. If this method returns false, only one
+     * strength is supported and the setStrength() method always rounds to that value.
+     * @return true is strength parameter is supported, false otherwise
+     */
+    public boolean getStrengthSupported() {
+       return mStrengthSupported;
+    }
+
+    /**
+     * Sets the strength of the bass boost effect. If the implementation does not support per mille
+     * accuracy for setting the strength, it is allowed to round the given strength to the nearest
+     * supported value. You can use the {@link #getRoundedStrength()} method to query the
+     * (possibly rounded) value that was actually set.
+     * @param strength strength of the effect. The valid range for strength strength is [0, 1000],
+     * where 0 per mille designates the mildest effect and 1000 per mille designates the strongest.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setStrength(short strength)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_STRENGTH, strength));
+    }
+
+    /**
+     * Gets the current strength of the effect.
+     * @return the strength of the effect. The valid range for strength is [0, 1000], where 0 per
+     * mille designates the mildest effect and 1000 per mille the strongest
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getRoundedStrength()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        short[] value = new short[1];
+        checkStatus(getParameter(PARAM_STRENGTH, value));
+        return value[0];
+    }
+
+    /**
+     * The OnParameterChangeListener interface defines a method called by the BassBoost when a
+     * parameter value has changed.
+     */
+    public interface OnParameterChangeListener  {
+        /**
+         * Method called when a parameter value has changed. The method is called only if the
+         * parameter was changed by another application having the control of the same
+         * BassBoost engine.
+         * @param effect the BassBoost on which the interface is registered.
+         * @param status status of the set parameter operation.
+         * @param param ID of the modified parameter. See {@link #PARAM_STRENGTH} ...
+         * @param value the new parameter value.
+         */
+        void onParameterChange(BassBoost effect, int status, int param, short value);
+    }
+
+    /**
+     * Listener used internally to receive unformatted parameter change events from AudioEffect
+     * super class.
+     */
+    private class BaseParameterListener implements AudioEffect.OnParameterChangeListener {
+        private BaseParameterListener() {
+
+        }
+        public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) {
+            OnParameterChangeListener l = null;
+
+            synchronized (mParamListenerLock) {
+                if (mParamListener != null) {
+                    l = mParamListener;
+                }
+            }
+            if (l != null) {
+                int p = -1;
+                short v = -1;
+
+                if (param.length == 4) {
+                    p = byteArrayToInt(param, 0);
+                }
+                if (value.length == 2) {
+                    v = byteArrayToShort(value, 0);
+                }
+                if (p != -1 && v != -1) {
+                    l.onParameterChange(BassBoost.this, status, p, v);
+                }
+            }
+        }
+    }
+
+    /**
+     * Registers an OnParameterChangeListener interface.
+     * @param listener OnParameterChangeListener interface registered
+     */
+    public void setParameterListener(OnParameterChangeListener listener) {
+        synchronized (mParamListenerLock) {
+            if (mParamListener == null) {
+                mParamListener = listener;
+                mBaseParamListener = new BaseParameterListener();
+                super.setParameterListener(mBaseParamListener);
+            }
+        }
+    }
+
+    /**
+     * The Settings class regroups all bass boost parameters. It is used in
+     * conjuntion with getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+    public static class Settings {
+        public short strength;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            int tokens = st.countTokens();
+            if (st.countTokens() != 3) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("BassBoost")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for BassBoost: " + key);
+            }
+            try {
+                key = st.nextToken();
+                if (!key.equals("strength")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                strength = Short.parseShort(st.nextToken());
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+            String str = new String (
+                    "BassBoost"+
+                    ";strength="+Short.toString(strength)
+                    );
+            return str;
+        }
+    };
+
+
+    /**
+     * Gets the bass boost properties. This method is useful when a snapshot of current
+     * bass boost settings must be saved by the application.
+     * @return a BassBoost.Settings object containing all current parameters values
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public BassBoost.Settings getProperties()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        Settings settings = new Settings();
+        short[] value = new short[1];
+        checkStatus(getParameter(PARAM_STRENGTH, value));
+        settings.strength = value[0];
+        return settings;
+    }
+
+    /**
+     * Sets the bass boost properties. This method is useful when bass boost settings have to
+     * be applied from a previous backup.
+     * @param settings a BassBoost.Settings object containing the properties to apply
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setProperties(BassBoost.Settings settings)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_STRENGTH, settings.strength));
+    }
+}
diff --git a/android/media/audiofx/DefaultEffect.java b/android/media/audiofx/DefaultEffect.java
new file mode 100644
index 0000000..ce087ad
--- /dev/null
+++ b/android/media/audiofx/DefaultEffect.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 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.audiofx;
+
+/**
+ * DefaultEffect is the base class for controlling default audio effects linked into the
+ * Android audio framework.
+ * <p>DefaultEffects are effects that get attached automatically to all AudioTracks,
+ * AudioRecords, and MediaPlayer instances meeting some criteria.
+ * <p>Applications should not use the DefaultEffect class directly but one of its derived classes
+ * to control specific types of defaults:
+ * <ul>
+ *   <li> {@link android.media.audiofx.SourceDefaultEffect}</li>
+ *   <li> {@link android.media.audiofx.StreamDefaultEffect}</li>
+ * </ul>
+ * <p>Creating a DefaultEffect object will register the corresponding effect engine as a default
+ * for the specified criteria. Whenever an audio session meets the criteria, an AudioEffect will
+ * be created and attached to it using the specified priority.
+ * @hide
+ */
+
+public abstract class DefaultEffect {
+    /**
+     * System wide unique default effect ID.
+     */
+    int mId;
+}
diff --git a/android/media/audiofx/DynamicsProcessing.java b/android/media/audiofx/DynamicsProcessing.java
new file mode 100644
index 0000000..1c3cff9
--- /dev/null
+++ b/android/media/audiofx/DynamicsProcessing.java
@@ -0,0 +1,2402 @@
+/*
+ * Copyright (C) 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.audiofx;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.media.AudioTrack;
+import android.media.MediaPlayer;
+import android.media.audiofx.AudioEffect;
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.StringTokenizer;
+
+/**
+ * DynamicsProcessing is an audio effect for equalizing and changing dynamic range properties of the
+ * sound. It is composed of multiple stages including equalization, multi-band compression and
+ * limiter.
+ * <p>The number of bands and active stages is configurable, and most parameters can be controlled
+ * in realtime, such as gains, attack/release times, thresholds, etc.
+ * <p>The effect is instantiated and controlled by channels. Each channel has the same basic
+ * architecture, but all of their parameters are independent from other channels.
+ * <p>The basic channel configuration is:
+ * <pre>
+ *
+ *    Channel 0          Channel 1       ....       Channel N-1
+ *      Input              Input                       Input
+ *        |                  |                           |
+ *   +----v----+        +----v----+                 +----v----+
+ *   |inputGain|        |inputGain|                 |inputGain|
+ *   +---------+        +---------+                 +---------+
+ *        |                  |                           |
+ *  +-----v-----+      +-----v-----+               +-----v-----+
+ *  |   PreEQ   |      |   PreEQ   |               |   PreEQ   |
+ *  +-----------+      +-----------+               +-----------+
+ *        |                  |                           |
+ *  +-----v-----+      +-----v-----+               +-----v-----+
+ *  |    MBC    |      |    MBC    |               |    MBC    |
+ *  +-----------+      +-----------+               +-----------+
+ *        |                  |                           |
+ *  +-----v-----+      +-----v-----+               +-----v-----+
+ *  |  PostEQ   |      |  PostEQ   |               |  PostEQ   |
+ *  +-----------+      +-----------+               +-----------+
+ *        |                  |                           |
+ *  +-----v-----+      +-----v-----+               +-----v-----+
+ *  |  Limiter  |      |  Limiter  |               |  Limiter  |
+ *  +-----------+      +-----------+               +-----------+
+ *        |                  |                           |
+ *     Output             Output                      Output
+ * </pre>
+ *
+ * <p>Where the stages are:
+ * inputGain: input gain factor in decibels (dB). 0 dB means no change in level.
+ * PreEQ:  Multi-band Equalizer.
+ * MBC:    Multi-band Compressor
+ * PostEQ: Multi-band Equalizer
+ * Limiter: Single band compressor/limiter.
+ *
+ * <p>An application creates a DynamicsProcessing object to instantiate and control this audio
+ * effect in the audio framework. A DynamicsProcessor.Config and DynamicsProcessor.Config.Builder
+ * are available to help configure the multiple stages and each band parameters if desired.
+ * <p>See each stage documentation for further details.
+ * <p>If no Config is specified during creation, a default configuration is chosen.
+ * <p>To attach the DynamicsProcessing to a particular AudioTrack or MediaPlayer,
+ * specify the audio session ID of this AudioTrack or MediaPlayer when constructing the effect
+ * (see {@link AudioTrack#getAudioSessionId()} and {@link MediaPlayer#getAudioSessionId()}).
+ *
+ * <p>To attach the DynamicsProcessing to a particular AudioTrack or MediaPlayer, specify the audio
+ * session ID of this AudioTrack or MediaPlayer when constructing the DynamicsProcessing.
+ * <p>See {@link android.media.MediaPlayer#getAudioSessionId()} for details on audio sessions.
+ * <p>See {@link android.media.audiofx.AudioEffect} class for more details on controlling audio
+ * effects.
+ */
+
+public final class DynamicsProcessing extends AudioEffect {
+
+    private final static String TAG = "DynamicsProcessing";
+
+    // These parameter constants must be synchronized with those in
+    // /system/media/audio_effects/include/audio_effects/effect_dynamicsprocessing.h
+    private static final int PARAM_GET_CHANNEL_COUNT = 0x10;
+    private static final int PARAM_INPUT_GAIN = 0x20;
+    private static final int PARAM_ENGINE_ARCHITECTURE = 0x30;
+    private static final int PARAM_PRE_EQ = 0x40;
+    private static final int PARAM_PRE_EQ_BAND = 0x45;
+    private static final int PARAM_MBC = 0x50;
+    private static final int PARAM_MBC_BAND = 0x55;
+    private static final int PARAM_POST_EQ = 0x60;
+    private static final int PARAM_POST_EQ_BAND = 0x65;
+    private static final int PARAM_LIMITER = 0x70;
+
+    /**
+     * Index of variant that favors frequency resolution. Frequency domain based implementation.
+     */
+    public static final int VARIANT_FAVOR_FREQUENCY_RESOLUTION  = 0;
+
+    /**
+     * Index of variant that favors time resolution resolution. Time domain based implementation.
+     */
+    public static final int VARIANT_FAVOR_TIME_RESOLUTION       = 1;
+
+    /**
+     * Maximum expected channels to be reported by effect
+     */
+    private static final int CHANNEL_COUNT_MAX = 32;
+
+    /**
+     * Number of channels in effect architecture
+     */
+    private int mChannelCount = 0;
+
+    /**
+     * Registered listener for parameter changes.
+     */
+    private OnParameterChangeListener mParamListener = null;
+
+    /**
+     * Listener used internally to to receive raw parameter change events
+     * from AudioEffect super class
+     */
+    private BaseParameterListener mBaseParamListener = null;
+
+    /**
+     * Lock for access to mParamListener
+     */
+    private final Object mParamListenerLock = new Object();
+
+    /**
+     * Class constructor.
+     * @param audioSession system-wide unique audio session identifier. The DynamicsProcessing
+     * will be attached to the MediaPlayer or AudioTrack in the same audio session.
+     */
+    public DynamicsProcessing(int audioSession) {
+        this(0 /*priority*/, audioSession);
+    }
+
+    /**
+     * @hide
+     * Class constructor for the DynamicsProcessing audio effect.
+     * @param priority the priority level requested by the application for controlling the
+     * DynamicsProcessing engine. As the same engine can be shared by several applications,
+     * this parameter indicates how much the requesting application needs control of effect
+     * parameters. The normal priority is 0, above normal is a positive number, below normal a
+     * negative number.
+     * @param audioSession system-wide unique audio session identifier. The DynamicsProcessing
+     * will be attached to the MediaPlayer or AudioTrack in the same audio session.
+     */
+    public DynamicsProcessing(int priority, int audioSession) {
+        this(priority, audioSession, null);
+    }
+
+    /**
+     * Class constructor for the DynamicsProcessing audio effect
+     * @param priority the priority level requested by the application for controlling the
+     * DynamicsProcessing engine. As the same engine can be shared by several applications,
+     * this parameter indicates how much the requesting application needs control of effect
+     * parameters. The normal priority is 0, above normal is a positive number, below normal a
+     * negative number.
+     * @param audioSession system-wide unique audio session identifier. The DynamicsProcessing
+     * will be attached to the MediaPlayer or AudioTrack in the same audio session.
+     * @param cfg Config object used to setup the audio effect, including bands per stage, and
+     * specific parameters for each stage/band. Use
+     * {@link android.media.audiofx.DynamicsProcessing.Config.Builder} to create a
+     * Config object that suits your needs. A null cfg parameter will create and use a default
+     * configuration for the effect
+     */
+    public DynamicsProcessing(int priority, int audioSession, @Nullable Config cfg) {
+        super(EFFECT_TYPE_DYNAMICS_PROCESSING, EFFECT_TYPE_NULL, priority, audioSession);
+        if (audioSession == 0) {
+            Log.w(TAG, "WARNING: attaching a DynamicsProcessing to global output mix is"
+                    + "deprecated!");
+        }
+        final Config config;
+        mChannelCount = getChannelCount();
+        if (cfg == null) {
+            //create a default configuration and effect, with the number of channels this effect has
+            DynamicsProcessing.Config.Builder builder =
+                    new DynamicsProcessing.Config.Builder(
+                            CONFIG_DEFAULT_VARIANT,
+                            mChannelCount,
+                            CONFIG_DEFAULT_USE_PREEQ,
+                            CONFIG_DEFAULT_PREEQ_BANDS,
+                            CONFIG_DEFAULT_USE_MBC,
+                            CONFIG_DEFAULT_MBC_BANDS,
+                            CONFIG_DEFAULT_USE_POSTEQ,
+                            CONFIG_DEFAULT_POSTEQ_BANDS,
+                            CONFIG_DEFAULT_USE_LIMITER);
+            config = builder.build();
+        } else {
+            //validate channels are ok. decide what to do: replicate channels if more
+            config = new DynamicsProcessing.Config(mChannelCount, cfg);
+        }
+
+        //configure engine
+        setEngineArchitecture(config.getVariant(),
+                config.getPreferredFrameDuration(),
+                config.isPreEqInUse(),
+                config.getPreEqBandCount(),
+                config.isMbcInUse(),
+                config.getMbcBandCount(),
+                config.isPostEqInUse(),
+                config.getPostEqBandCount(),
+                config.isLimiterInUse());
+        //update all the parameters
+        for (int ch = 0; ch < mChannelCount; ch++) {
+            updateEngineChannelByChannelIndex(ch, config.getChannelByChannelIndex(ch));
+        }
+    }
+
+    /**
+     * Returns the Config object used to setup this effect.
+     * @return Config Current Config object used to setup this DynamicsProcessing effect.
+     */
+    public Config getConfig() {
+        //Query engine architecture to create config object
+        Number[] params = { PARAM_ENGINE_ARCHITECTURE };
+        Number[] values = { 0 /*0 variant */,
+                0.0f /* 1 preferredFrameDuration */,
+                0 /*2 preEqInUse */,
+                0 /*3 preEqBandCount */,
+                0 /*4 mbcInUse */,
+                0 /*5 mbcBandCount*/,
+                0 /*6 postEqInUse */,
+                0 /*7 postEqBandCount */,
+                0 /*8 limiterInUse */};
+        byte[] paramBytes = numberArrayToByteArray(params);
+        byte[] valueBytes = numberArrayToByteArray(values); //just interest in the byte size.
+        getParameter(paramBytes, valueBytes);
+        byteArrayToNumberArray(valueBytes, values);
+        DynamicsProcessing.Config.Builder builder =
+                new DynamicsProcessing.Config.Builder(
+                        values[0].intValue(),
+                        mChannelCount,
+                        values[2].intValue() > 0 /*use preEQ*/,
+                        values[3].intValue() /*pre eq bands*/,
+                        values[4].intValue() > 0 /*use mbc*/,
+                        values[5].intValue() /*mbc bands*/,
+                        values[6].intValue() > 0 /*use postEQ*/,
+                        values[7].intValue()/*postEq bands*/,
+                        values[8].intValue() > 0 /*use Limiter*/).
+                setPreferredFrameDuration(values[1].floatValue());
+        Config config = builder.build();
+        for (int ch = 0; ch < mChannelCount; ch++) {
+            Channel channel = queryEngineByChannelIndex(ch);
+            config.setChannelTo(ch, channel);
+        }
+        return config;
+    }
+
+
+    private static final int CONFIG_DEFAULT_VARIANT = VARIANT_FAVOR_FREQUENCY_RESOLUTION;
+    private static final boolean CONFIG_DEFAULT_USE_PREEQ = true;
+    private static final int CONFIG_DEFAULT_PREEQ_BANDS = 6;
+    private static final boolean CONFIG_DEFAULT_USE_MBC = true;
+    private static final int CONFIG_DEFAULT_MBC_BANDS = 6;
+    private static final boolean CONFIG_DEFAULT_USE_POSTEQ = true;
+    private static final int CONFIG_DEFAULT_POSTEQ_BANDS = 6;
+    private static final boolean CONFIG_DEFAULT_USE_LIMITER = true;
+
+    private static final float CHANNEL_DEFAULT_INPUT_GAIN = 0; // dB
+    private static final float CONFIG_PREFERRED_FRAME_DURATION_MS = 10.0f; //milliseconds
+
+    private static final float EQ_DEFAULT_GAIN = 0; // dB
+    private static final boolean PREEQ_DEFAULT_ENABLED = true;
+    private static final boolean POSTEQ_DEFAULT_ENABLED = true;
+
+    private static final boolean MBC_DEFAULT_ENABLED = true;
+    private static final float MBC_DEFAULT_ATTACK_TIME = 3; // ms
+    private static final float MBC_DEFAULT_RELEASE_TIME = 80; // ms
+    private static final float MBC_DEFAULT_RATIO = 1; // N:1
+    private static final float MBC_DEFAULT_THRESHOLD = -45; // dB
+    private static final float MBC_DEFAULT_KNEE_WIDTH = 0; // dB
+    private static final float MBC_DEFAULT_NOISE_GATE_THRESHOLD = -90; // dB
+    private static final float MBC_DEFAULT_EXPANDER_RATIO = 1; // 1:N
+    private static final float MBC_DEFAULT_PRE_GAIN = 0; // dB
+    private static final float MBC_DEFAULT_POST_GAIN = 0; // dB
+
+    private static final boolean LIMITER_DEFAULT_ENABLED = true;
+    private static final int LIMITER_DEFAULT_LINK_GROUP = 0;//;
+    private static final float LIMITER_DEFAULT_ATTACK_TIME = 1; // ms
+    private static final float LIMITER_DEFAULT_RELEASE_TIME = 60; // ms
+    private static final float LIMITER_DEFAULT_RATIO = 10; // N:1
+    private static final float LIMITER_DEFAULT_THRESHOLD = -2; // dB
+    private static final float LIMITER_DEFAULT_POST_GAIN = 0; // dB
+
+    private static final float DEFAULT_MIN_FREQUENCY = 220; // Hz
+    private static final float DEFAULT_MAX_FREQUENCY = 20000; // Hz
+    private static final float mMinFreqLog = (float)Math.log10(DEFAULT_MIN_FREQUENCY);
+    private static final float mMaxFreqLog = (float)Math.log10(DEFAULT_MAX_FREQUENCY);
+
+    /**
+     * base class for the different stages.
+     */
+    public static class Stage {
+        private boolean mInUse;
+        private boolean mEnabled;
+        /**
+         * Class constructor for stage
+         * @param inUse true if this stage is set to be used. False otherwise. Stages that are not
+         * set "inUse" at initialization time are not available to be used at any time.
+         * @param enabled true if this stage is currently used to process sound. When disabled,
+         * the stage is bypassed and the sound is copied unaltered from input to output.
+         */
+        public Stage(boolean inUse, boolean enabled) {
+            mInUse = inUse;
+            mEnabled = enabled;
+        }
+
+        /**
+         * returns enabled state of the stage
+         * @return true if stage is enabled for processing, false otherwise
+         */
+        public boolean isEnabled() {
+            return mEnabled;
+        }
+        /**
+         * sets enabled state of the stage
+         * @param enabled true for enabled, false otherwise
+         */
+        public void setEnabled(boolean enabled) {
+            mEnabled = enabled;
+        }
+
+        /**
+         * returns inUse state of the stage.
+         * @return inUse state of the stage. True if this stage is currently used to process sound.
+         * When false, the stage is bypassed and the sound is copied unaltered from input to output.
+         */
+        public boolean isInUse() {
+            return mInUse;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(String.format(" Stage InUse: %b\n", isInUse()));
+            if (isInUse()) {
+                sb.append(String.format(" Stage Enabled: %b\n", mEnabled));
+            }
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Base class for stages that hold bands
+     */
+    public static class BandStage extends Stage{
+        private int mBandCount;
+        /**
+         * Class constructor for BandStage
+         * @param inUse true if this stage is set to be used. False otherwise. Stages that are not
+         * set "inUse" at initialization time are not available to be used at any time.
+         * @param enabled true if this stage is currently used to process sound. When disabled,
+         * the stage is bypassed and the sound is copied unaltered from input to output.
+         * @param bandCount number of bands this stage will handle. If stage is not inUse, bandcount
+         * is set to 0
+         */
+        public BandStage(boolean inUse, boolean enabled, int bandCount) {
+            super(inUse, enabled);
+            mBandCount = isInUse() ? bandCount : 0;
+        }
+
+        /**
+         * gets number of bands held in this stage
+         * @return number of bands held in this stage
+         */
+        public int getBandCount() {
+            return mBandCount;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(super.toString());
+            if (isInUse()) {
+                sb.append(String.format(" Band Count: %d\n", mBandCount));
+            }
+            return sb.toString();
+        }
+    }
+
+    /**
+     * Base class for bands
+     */
+    public static class BandBase {
+        private boolean mEnabled;
+        private float mCutoffFrequency;
+        /**
+         * Class constructor for BandBase
+         * @param enabled true if this band is currently used to process sound. When false,
+         * the band is effectively muted and sound set to zero.
+         * @param cutoffFrequency topmost frequency number (in Hz) this band will process. The
+         * effective bandwidth for the band is then computed using this and the previous band
+         * topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with
+         * band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on.
+         */
+        public BandBase(boolean enabled, float cutoffFrequency) {
+            mEnabled = enabled;
+            mCutoffFrequency = cutoffFrequency;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(String.format(" Enabled: %b\n", mEnabled));
+            sb.append(String.format(" CutoffFrequency: %f\n", mCutoffFrequency));
+            return sb.toString();
+        }
+
+        /**
+         * returns enabled state of the band
+         * @return true if bands is enabled for processing, false otherwise
+         */
+        public boolean isEnabled() {
+            return mEnabled;
+        }
+        /**
+         * sets enabled state of the band
+         * @param enabled true for enabled, false otherwise
+         */
+        public void setEnabled(boolean enabled) {
+            mEnabled = enabled;
+        }
+
+        /**
+         * gets cutoffFrequency for this band in Hertz (Hz)
+         * @return cutoffFrequency for this band in Hertz (Hz)
+         */
+        public float getCutoffFrequency() {
+            return mCutoffFrequency;
+        }
+
+        /**
+         * sets topmost frequency number (in Hz) this band will process. The
+         * effective bandwidth for the band is then computed using this and the previous band
+         * topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with
+         * band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on.
+         * @param frequency
+         */
+        public void setCutoffFrequency(float frequency) {
+            mCutoffFrequency = frequency;
+        }
+    }
+
+    /**
+     * Class for Equalizer Bands
+     * Equalizer bands have three controllable parameters: enabled/disabled, cutoffFrequency and
+     * gain
+     */
+    public final static class EqBand extends BandBase {
+        private float mGain;
+        /**
+         * Class constructor for EqBand
+         * @param enabled true if this band is currently used to process sound. When false,
+         * the band is effectively muted and sound set to zero.
+         * @param cutoffFrequency topmost frequency number (in Hz) this band will process. The
+         * effective bandwidth for the band is then computed using this and the previous band
+         * topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with
+         * band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on.
+         * @param gain of equalizer band in decibels (dB). A gain of 0 dB means no change in level.
+         */
+        public EqBand(boolean enabled, float cutoffFrequency, float gain) {
+            super(enabled, cutoffFrequency);
+            mGain = gain;
+        }
+
+        /**
+         * Class constructor for EqBand
+         * @param cfg copy constructor
+         */
+        public EqBand(EqBand cfg) {
+            super(cfg.isEnabled(), cfg.getCutoffFrequency());
+            mGain = cfg.mGain;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(super.toString());
+            sb.append(String.format(" Gain: %f\n", mGain));
+            return sb.toString();
+        }
+
+        /**
+         * gets current gain of band in decibels (dB)
+         * @return current gain of band in decibels (dB)
+         */
+        public float getGain() {
+            return mGain;
+        }
+
+        /**
+         * sets current gain of band in decibels (dB)
+         * @param gain desired in decibels (db)
+         */
+        public void setGain(float gain) {
+            mGain = gain;
+        }
+    }
+
+    /**
+     * Class for Multi-Band compressor bands
+     * MBC bands have multiple controllable parameters: enabled/disabled, cutoffFrequency,
+     * attackTime, releaseTime, ratio, threshold, kneeWidth, noiseGateThreshold, expanderRatio,
+     * preGain and postGain.
+     */
+    public final static class MbcBand extends BandBase{
+        private float mAttackTime;
+        private float mReleaseTime;
+        private float mRatio;
+        private float mThreshold;
+        private float mKneeWidth;
+        private float mNoiseGateThreshold;
+        private float mExpanderRatio;
+        private float mPreGain;
+        private float mPostGain;
+        /**
+         * Class constructor for MbcBand
+         * @param enabled true if this band is currently used to process sound. When false,
+         * the band is effectively muted and sound set to zero.
+         * @param cutoffFrequency topmost frequency number (in Hz) this band will process. The
+         * effective bandwidth for the band is then computed using this and the previous band
+         * topmost frequency (or 0 Hz for band number 0). Frequencies are expected to increase with
+         * band number, thus band 0 cutoffFrequency <= band 1 cutoffFrequency, and so on.
+         * @param attackTime Attack Time for compressor in milliseconds (ms)
+         * @param releaseTime Release Time for compressor in milliseconds (ms)
+         * @param ratio Compressor ratio (N:1) (input:output)
+         * @param threshold Compressor threshold measured in decibels (dB) from 0 dB Full Scale
+         * (dBFS).
+         * @param kneeWidth Width in decibels (dB) around compressor threshold point.
+         * @param noiseGateThreshold Noise gate threshold in decibels (dB) from 0 dB Full Scale
+         * (dBFS).
+         * @param expanderRatio Expander ratio (1:N) (input:output) for signals below the Noise Gate
+         * Threshold.
+         * @param preGain Gain applied to the signal BEFORE the compression.
+         * @param postGain Gain applied to the signal AFTER compression.
+         */
+        public MbcBand(boolean enabled, float cutoffFrequency, float attackTime, float releaseTime,
+                float ratio, float threshold, float kneeWidth, float noiseGateThreshold,
+                float expanderRatio, float preGain, float postGain) {
+            super(enabled, cutoffFrequency);
+            mAttackTime = attackTime;
+            mReleaseTime = releaseTime;
+            mRatio = ratio;
+            mThreshold = threshold;
+            mKneeWidth = kneeWidth;
+            mNoiseGateThreshold = noiseGateThreshold;
+            mExpanderRatio = expanderRatio;
+            mPreGain = preGain;
+            mPostGain = postGain;
+        }
+
+        /**
+         * Class constructor for MbcBand
+         * @param cfg copy constructor
+         */
+        public MbcBand(MbcBand cfg) {
+            super(cfg.isEnabled(), cfg.getCutoffFrequency());
+            mAttackTime = cfg.mAttackTime;
+            mReleaseTime = cfg.mReleaseTime;
+            mRatio = cfg.mRatio;
+            mThreshold = cfg.mThreshold;
+            mKneeWidth = cfg.mKneeWidth;
+            mNoiseGateThreshold = cfg.mNoiseGateThreshold;
+            mExpanderRatio = cfg.mExpanderRatio;
+            mPreGain = cfg.mPreGain;
+            mPostGain = cfg.mPostGain;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(super.toString());
+            sb.append(String.format(" AttackTime: %f (ms)\n", mAttackTime));
+            sb.append(String.format(" ReleaseTime: %f (ms)\n", mReleaseTime));
+            sb.append(String.format(" Ratio: 1:%f\n", mRatio));
+            sb.append(String.format(" Threshold: %f (dB)\n", mThreshold));
+            sb.append(String.format(" NoiseGateThreshold: %f(dB)\n", mNoiseGateThreshold));
+            sb.append(String.format(" ExpanderRatio: %f:1\n", mExpanderRatio));
+            sb.append(String.format(" PreGain: %f (dB)\n", mPreGain));
+            sb.append(String.format(" PostGain: %f (dB)\n", mPostGain));
+            return sb.toString();
+        }
+
+        /**
+         * gets attack time for compressor in milliseconds (ms)
+         * @return attack time for compressor in milliseconds (ms)
+         */
+        public float getAttackTime() { return mAttackTime; }
+        /**
+         * sets attack time for compressor in milliseconds (ms)
+         * @param attackTime desired for compressor in milliseconds (ms)
+         */
+        public void setAttackTime(float attackTime) { mAttackTime = attackTime; }
+        /**
+         * gets release time for compressor in milliseconds (ms)
+         * @return release time for compressor in milliseconds (ms)
+         */
+        public float getReleaseTime() { return mReleaseTime; }
+        /**
+         * sets release time for compressor in milliseconds (ms)
+         * @param releaseTime desired for compressor in milliseconds (ms)
+         */
+        public void setReleaseTime(float releaseTime) { mReleaseTime = releaseTime; }
+        /**
+         * gets the compressor ratio (N:1)
+         * @return compressor ratio (N:1)
+         */
+        public float getRatio() { return mRatio; }
+        /**
+         * sets compressor ratio (N:1)
+         * @param ratio desired for the compressor (N:1)
+         */
+        public void setRatio(float ratio) { mRatio = ratio; }
+        /**
+         * gets the compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS).
+         * Thresholds are negative. A threshold of 0 dB means no compression will take place.
+         * @return compressor threshold in decibels (dB)
+         */
+        public float getThreshold() { return mThreshold; }
+        /**
+         * sets the compressor threshold measured in decibels (dB) from 0 dB Full Scale (dBFS).
+         * Thresholds are negative. A threshold of 0 dB means no compression will take place.
+         * @param threshold desired for compressor in decibels(dB)
+         */
+        public void setThreshold(float threshold) { mThreshold = threshold; }
+        /**
+         * get Knee Width in decibels (dB) around compressor threshold point. Widths are always
+         * positive, with higher values representing a wider area of transition from the linear zone
+         * to the compression zone. A knee of 0 dB means a more abrupt transition.
+         * @return Knee Width in decibels (dB)
+         */
+        public float getKneeWidth() { return mKneeWidth; }
+        /**
+         * sets knee width in decibels (dB). See
+         * {@link android.media.audiofx.DynamicsProcessing.MbcBand#getKneeWidth} for more
+         * information.
+         * @param kneeWidth desired in decibels (dB)
+         */
+        public void setKneeWidth(float kneeWidth) { mKneeWidth = kneeWidth; }
+        /**
+         * gets the noise gate threshold in decibels (dB) from 0 dB Full Scale (dBFS). Noise gate
+         * thresholds are negative. Signals below this level will be expanded according the
+         * expanderRatio parameter. A Noise Gate Threshold of -75 dB means very quiet signals might
+         * be effectively removed from the signal.
+         * @return Noise Gate Threshold in decibels (dB)
+         */
+        public float getNoiseGateThreshold() { return mNoiseGateThreshold; }
+        /**
+         * sets noise gate threshod in decibels (dB). See
+         * {@link android.media.audiofx.DynamicsProcessing.MbcBand#getNoiseGateThreshold} for more
+         * information.
+         * @param noiseGateThreshold desired in decibels (dB)
+         */
+        public void setNoiseGateThreshold(float noiseGateThreshold) {
+            mNoiseGateThreshold = noiseGateThreshold; }
+        /**
+         * gets Expander ratio (1:N) for signals below the Noise Gate Threshold.
+         * @return Expander ratio (1:N)
+         */
+        public float getExpanderRatio() { return mExpanderRatio; }
+        /**
+         * sets Expander ratio (1:N) for signals below the Noise Gate Threshold.
+         * @param expanderRatio desired expander ratio (1:N)
+         */
+        public void setExpanderRatio(float expanderRatio) { mExpanderRatio = expanderRatio; }
+        /**
+         * gets the gain applied to the signal BEFORE the compression. Measured in decibels (dB)
+         * where 0 dB means no level change.
+         * @return preGain value in decibels (dB)
+         */
+        public float getPreGain() { return mPreGain; }
+        /**
+         * sets the gain to be applied to the signal BEFORE the compression, measured in decibels
+         * (dB), where 0 dB means no level change.
+         * @param preGain desired in decibels (dB)
+         */
+        public void setPreGain(float preGain) { mPreGain = preGain; }
+        /**
+         * gets the gain applied to the signal AFTER compression. Measured in decibels (dB) where 0
+         * dB means no level change
+         * @return postGain value in decibels (dB)
+         */
+        public float getPostGain() { return mPostGain; }
+        /**
+         * sets the gain to be applied to the siganl AFTER the compression. Measured in decibels
+         * (dB), where 0 dB means no level change.
+         * @param postGain desired value in decibels (dB)
+         */
+        public void setPostGain(float postGain) { mPostGain = postGain; }
+    }
+
+    /**
+     * Class for Equalizer stage
+     */
+    public final static class Eq extends BandStage {
+        private final EqBand[] mBands;
+        /**
+         * Class constructor for Equalizer (Eq) stage
+         * @param inUse true if Eq stage will be used, false otherwise.
+         * @param enabled true if Eq stage is enabled/disabled. This can be changed while effect is
+         * running
+         * @param bandCount number of bands for this Equalizer stage. Can't be changed while effect
+         * is running
+         */
+        public Eq(boolean inUse, boolean enabled, int bandCount) {
+            super(inUse, enabled, bandCount);
+            if (isInUse()) {
+                mBands = new EqBand[bandCount];
+                for (int b = 0; b < bandCount; b++) {
+                    float freq = DEFAULT_MAX_FREQUENCY;
+                    if (bandCount > 1) {
+                        freq = (float)Math.pow(10, mMinFreqLog +
+                                b * (mMaxFreqLog - mMinFreqLog)/(bandCount -1));
+                    }
+                    mBands[b] = new EqBand(true, freq, EQ_DEFAULT_GAIN);
+                }
+            } else {
+                mBands = null;
+            }
+        }
+        /**
+         * Class constructor for Eq stage
+         * @param cfg copy constructor
+         */
+        public Eq(Eq cfg) {
+            super(cfg.isInUse(), cfg.isEnabled(), cfg.getBandCount());
+            if (isInUse()) {
+                mBands = new EqBand[cfg.mBands.length];
+                for (int b = 0; b < mBands.length; b++) {
+                    mBands[b] = new EqBand(cfg.mBands[b]);
+                }
+            } else {
+                mBands = null;
+            }
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(super.toString());
+            if (isInUse()) {
+                sb.append("--->EqBands: " + mBands.length + "\n");
+                for (int b = 0; b < mBands.length; b++) {
+                    sb.append(String.format("  Band %d\n", b));
+                    sb.append(mBands[b].toString());
+                }
+            }
+            return sb.toString();
+        }
+        /**
+         * Helper function to check if band index is within range
+         * @param band index to check
+         */
+        private void checkBand(int band) {
+            if (mBands == null || band < 0 || band >= mBands.length) {
+                throw new IllegalArgumentException("band index " + band +" out of bounds");
+            }
+        }
+        /**
+         * Sets EqBand object for given band index
+         * @param band index of band to be modified
+         * @param bandCfg EqBand object.
+         */
+        public void setBand(int band, EqBand bandCfg) {
+            checkBand(band);
+            mBands[band] = new EqBand(bandCfg);
+        }
+        /**
+         * Gets EqBand object for band of interest.
+         * @param band index of band of interest
+         * @return EqBand Object
+         */
+        public EqBand getBand(int band) {
+            checkBand(band);
+            return mBands[band];
+        }
+    }
+
+    /**
+     * Class for Multi-Band Compressor (MBC) stage
+     */
+    public final static class Mbc extends BandStage {
+        private final MbcBand[] mBands;
+        /**
+         * Constructor for Multi-Band Compressor (MBC) stage
+         * @param inUse true if MBC stage will be used, false otherwise.
+         * @param enabled true if MBC stage is enabled/disabled. This can be changed while effect
+         * is running
+         * @param bandCount number of bands for this MBC stage. Can't be changed while effect is
+         * running
+         */
+        public Mbc(boolean inUse, boolean enabled, int bandCount) {
+            super(inUse, enabled, bandCount);
+            if (isInUse()) {
+                mBands = new MbcBand[bandCount];
+                for (int b = 0; b < bandCount; b++) {
+                    float freq = DEFAULT_MAX_FREQUENCY;
+                    if (bandCount > 1) {
+                        freq = (float)Math.pow(10, mMinFreqLog +
+                                b * (mMaxFreqLog - mMinFreqLog)/(bandCount -1));
+                    }
+                    mBands[b] = new MbcBand(true, freq, MBC_DEFAULT_ATTACK_TIME,
+                            MBC_DEFAULT_RELEASE_TIME, MBC_DEFAULT_RATIO,
+                            MBC_DEFAULT_THRESHOLD, MBC_DEFAULT_KNEE_WIDTH,
+                            MBC_DEFAULT_NOISE_GATE_THRESHOLD, MBC_DEFAULT_EXPANDER_RATIO,
+                            MBC_DEFAULT_PRE_GAIN, MBC_DEFAULT_POST_GAIN);
+                }
+            } else {
+                mBands = null;
+            }
+        }
+        /**
+         * Class constructor for MBC stage
+         * @param cfg copy constructor
+         */
+        public Mbc(Mbc cfg) {
+            super(cfg.isInUse(), cfg.isEnabled(), cfg.getBandCount());
+            if (isInUse()) {
+                mBands = new MbcBand[cfg.mBands.length];
+                for (int b = 0; b < mBands.length; b++) {
+                    mBands[b] = new MbcBand(cfg.mBands[b]);
+                }
+            } else {
+                mBands = null;
+            }
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(super.toString());
+            if (isInUse()) {
+                sb.append("--->MbcBands: " + mBands.length + "\n");
+                for (int b = 0; b < mBands.length; b++) {
+                    sb.append(String.format("  Band %d\n", b));
+                    sb.append(mBands[b].toString());
+                }
+            }
+            return sb.toString();
+        }
+        /**
+         * Helper function to check if band index is within range
+         * @param band index to check
+         */
+        private void checkBand(int band) {
+            if (mBands == null || band < 0 || band >= mBands.length) {
+                throw new IllegalArgumentException("band index " + band +" out of bounds");
+            }
+        }
+        /**
+         * Sets MbcBand object for given band index
+         * @param band index of band to be modified
+         * @param bandCfg MbcBand object.
+         */
+        public void setBand(int band, MbcBand bandCfg) {
+            checkBand(band);
+            mBands[band] = new MbcBand(bandCfg);
+        }
+        /**
+         * Gets MbcBand object for band of interest.
+         * @param band index of band of interest
+         * @return MbcBand Object
+         */
+        public MbcBand getBand(int band) {
+            checkBand(band);
+            return mBands[band];
+        }
+    }
+
+    /**
+     * Class for Limiter Stage
+     * Limiter is a single band compressor at the end of the processing chain, commonly used to
+     * protect the signal from overloading and distortion. Limiters have multiple controllable
+     * parameters: enabled/disabled, linkGroup, attackTime, releaseTime, ratio, threshold, and
+     * postGain.
+     * <p>Limiters can be linked in groups across multiple channels. Linked limiters will trigger
+     * the same limiting if any of the linked limiters starts compressing.
+     */
+    public final static class Limiter extends Stage {
+        private int mLinkGroup;
+        private float mAttackTime;
+        private float mReleaseTime;
+        private float mRatio;
+        private float mThreshold;
+        private float mPostGain;
+
+        /**
+         * Class constructor for Limiter Stage
+         * @param inUse true if MBC stage will be used, false otherwise.
+         * @param enabled true if MBC stage is enabled/disabled. This can be changed while effect
+         * is running
+         * @param linkGroup index of group assigned to this Limiter. Only limiters that share the
+         * same linkGroup index will react together.
+         * @param attackTime Attack Time for limiter compressor in milliseconds (ms)
+         * @param releaseTime Release Time for limiter compressor in milliseconds (ms)
+         * @param ratio Limiter Compressor ratio (N:1) (input:output)
+         * @param threshold Limiter Compressor threshold measured in decibels (dB) from 0 dB Full
+         * Scale (dBFS).
+         * @param postGain Gain applied to the signal AFTER compression.
+         */
+        public Limiter(boolean inUse, boolean enabled, int linkGroup, float attackTime,
+                float releaseTime, float ratio, float threshold, float postGain) {
+            super(inUse, enabled);
+            mLinkGroup = linkGroup;
+            mAttackTime = attackTime;
+            mReleaseTime = releaseTime;
+            mRatio = ratio;
+            mThreshold = threshold;
+            mPostGain = postGain;
+        }
+
+        /**
+         * Class Constructor for Limiter
+         * @param cfg copy constructor
+         */
+        public Limiter(Limiter cfg) {
+            super(cfg.isInUse(), cfg.isEnabled());
+            mLinkGroup = cfg.mLinkGroup;
+            mAttackTime = cfg.mAttackTime;
+            mReleaseTime = cfg.mReleaseTime;
+            mRatio = cfg.mRatio;
+            mThreshold = cfg.mThreshold;
+            mPostGain = cfg.mPostGain;
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(super.toString());
+            if (isInUse()) {
+                sb.append(String.format(" LinkGroup: %d (group)\n", mLinkGroup));
+                sb.append(String.format(" AttackTime: %f (ms)\n", mAttackTime));
+                sb.append(String.format(" ReleaseTime: %f (ms)\n", mReleaseTime));
+                sb.append(String.format(" Ratio: 1:%f\n", mRatio));
+                sb.append(String.format(" Threshold: %f (dB)\n", mThreshold));
+                sb.append(String.format(" PostGain: %f (dB)\n", mPostGain));
+            }
+            return sb.toString();
+        }
+        /**
+         * Gets the linkGroup index for this Limiter Stage. Only limiters that share the same
+         * linkGroup index will react together.
+         * @return linkGroup index.
+         */
+        public int getLinkGroup() { return mLinkGroup; }
+        /**
+         * Sets the linkGroup index for this limiter Stage.
+         * @param linkGroup desired linkGroup index
+         */
+        public void setLinkGroup(int linkGroup) { mLinkGroup = linkGroup; }
+        /**
+         * gets attack time for limiter compressor in milliseconds (ms)
+         * @return attack time for limiter compressor in milliseconds (ms)
+         */
+        public float getAttackTime() { return mAttackTime; }
+        /**
+         * sets attack time for limiter compressor in milliseconds (ms)
+         * @param attackTime desired for limiter compressor in milliseconds (ms)
+         */
+        public void setAttackTime(float attackTime) { mAttackTime = attackTime; }
+        /**
+         * gets release time for limiter compressor in milliseconds (ms)
+         * @return release time for limiter compressor in milliseconds (ms)
+         */
+        public float getReleaseTime() { return mReleaseTime; }
+        /**
+         * sets release time for limiter compressor in milliseconds (ms)
+         * @param releaseTime desired for limiter compressor in milliseconds (ms)
+         */
+        public void setReleaseTime(float releaseTime) { mReleaseTime = releaseTime; }
+        /**
+         * gets the limiter compressor ratio (N:1)
+         * @return limiter compressor ratio (N:1)
+         */
+        public float getRatio() { return mRatio; }
+        /**
+         * sets limiter compressor ratio (N:1)
+         * @param ratio desired for the limiter compressor (N:1)
+         */
+        public void setRatio(float ratio) { mRatio = ratio; }
+        /**
+         * gets the limiter compressor threshold measured in decibels (dB) from 0 dB Full Scale
+         * (dBFS). Thresholds are negative. A threshold of 0 dB means no limiting will take place.
+         * @return limiter compressor threshold in decibels (dB)
+         */
+        public float getThreshold() { return mThreshold; }
+        /**
+         * sets the limiter compressor threshold measured in decibels (dB) from 0 dB Full Scale
+         * (dBFS). Thresholds are negative. A threshold of 0 dB means no limiting will take place.
+         * @param threshold desired for limiter compressor in decibels(dB)
+         */
+        public void setThreshold(float threshold) { mThreshold = threshold; }
+        /**
+         * gets the gain applied to the signal AFTER limiting. Measured in decibels (dB) where 0
+         * dB means no level change
+         * @return postGain value in decibels (dB)
+         */
+        public float getPostGain() { return mPostGain; }
+        /**
+         * sets the gain to be applied to the siganl AFTER the limiter. Measured in decibels
+         * (dB), where 0 dB means no level change.
+         * @param postGain desired value in decibels (dB)
+         */
+        public void setPostGain(float postGain) { mPostGain = postGain; }
+    }
+
+    /**
+     * Class for Channel configuration parameters. It is composed of multiple stages, which can be
+     * used/enabled independently. Stages not used or disabled will be bypassed and the sound would
+     * be unaffected by them.
+     */
+    public final static class Channel {
+        private float   mInputGain;
+        private Eq      mPreEq;
+        private Mbc     mMbc;
+        private Eq      mPostEq;
+        private Limiter mLimiter;
+
+        /**
+         * Class constructor for Channel configuration.
+         * @param inputGain value in decibels (dB) of level change applied to the audio before
+         * processing. A value of 0 dB means no change.
+         * @param preEqInUse true if PreEq stage will be used, false otherwise. This can't be
+         * changed later.
+         * @param preEqBandCount number of bands for PreEq stage. This can't be changed later.
+         * @param mbcInUse true if Mbc stage will be used, false otherwise. This can't be changed
+         * later.
+         * @param mbcBandCount number of bands for Mbc stage. This can't be changed later.
+         * @param postEqInUse true if PostEq stage will be used, false otherwise. This can't be
+         * changed later.
+         * @param postEqBandCount number of bands for PostEq stage. This can't be changed later.
+         * @param limiterInUse true if Limiter stage will be used, false otherwise. This can't be
+         * changed later.
+         */
+        public Channel (float inputGain,
+                boolean preEqInUse, int preEqBandCount,
+                boolean mbcInUse, int mbcBandCount,
+                boolean postEqInUse, int postEqBandCount,
+                boolean limiterInUse) {
+            mInputGain = inputGain;
+            mPreEq = new Eq(preEqInUse, PREEQ_DEFAULT_ENABLED, preEqBandCount);
+            mMbc = new Mbc(mbcInUse, MBC_DEFAULT_ENABLED, mbcBandCount);
+            mPostEq = new Eq(postEqInUse, POSTEQ_DEFAULT_ENABLED,
+                    postEqBandCount);
+            mLimiter = new Limiter(limiterInUse,
+                    LIMITER_DEFAULT_ENABLED, LIMITER_DEFAULT_LINK_GROUP,
+                    LIMITER_DEFAULT_ATTACK_TIME, LIMITER_DEFAULT_RELEASE_TIME,
+                    LIMITER_DEFAULT_RATIO, LIMITER_DEFAULT_THRESHOLD, LIMITER_DEFAULT_POST_GAIN);
+        }
+
+        /**
+         * Class constructor for Channel configuration
+         * @param cfg copy constructor
+         */
+        public Channel(Channel cfg) {
+            mInputGain = cfg.mInputGain;
+            mPreEq = new Eq(cfg.mPreEq);
+            mMbc = new Mbc(cfg.mMbc);
+            mPostEq = new Eq(cfg.mPostEq);
+            mLimiter = new Limiter(cfg.mLimiter);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(String.format(" InputGain: %f\n", mInputGain));
+            sb.append("-->PreEq\n");
+            sb.append(mPreEq.toString());
+            sb.append("-->MBC\n");
+            sb.append(mMbc.toString());
+            sb.append("-->PostEq\n");
+            sb.append(mPostEq.toString());
+            sb.append("-->Limiter\n");
+            sb.append(mLimiter.toString());
+            return sb.toString();
+        }
+        /**
+         * Gets inputGain value in decibels (dB). 0 dB means no change;
+         * @return gain value in decibels (dB)
+         */
+        public float getInputGain() {
+            return mInputGain;
+        }
+        /**
+         * Sets inputGain value in decibels (dB). 0 dB means no change;
+         * @param inputGain desired gain value in decibels (dB)
+         */
+        public void setInputGain(float inputGain) {
+            mInputGain = inputGain;
+        }
+
+        /**
+         * Gets PreEq configuration stage
+         * @return PreEq configuration stage
+         */
+        public Eq getPreEq() {
+            return mPreEq;
+        }
+        /**
+         * Sets PreEq configuration stage. New PreEq stage must have the same number of bands than
+         * original PreEq stage.
+         * @param preEq configuration
+         */
+        public void setPreEq(Eq preEq) {
+            if (preEq.getBandCount() != mPreEq.getBandCount()) {
+                throw new IllegalArgumentException("PreEqBandCount changed from " +
+                        mPreEq.getBandCount() + " to " + preEq.getBandCount());
+            }
+            mPreEq = new Eq(preEq);
+        }
+        /**
+         * Gets EqBand for PreEq stage for given band index.
+         * @param band index of band of interest from PreEq stage
+         * @return EqBand configuration
+         */
+        public EqBand getPreEqBand(int band) {
+            return mPreEq.getBand(band);
+        }
+        /**
+         * Sets EqBand for PreEq stage for given band index
+         * @param band index of band of interest from PreEq stage
+         * @param preEqBand configuration to be set.
+         */
+        public void setPreEqBand(int band, EqBand preEqBand) {
+            mPreEq.setBand(band, preEqBand);
+        }
+
+        /**
+         * Gets Mbc configuration stage
+         * @return Mbc configuration stage
+         */
+        public Mbc getMbc() {
+            return mMbc;
+        }
+        /**
+         * Sets Mbc configuration stage. New Mbc stage must have the same number of bands than
+         * original Mbc stage.
+         * @param mbc
+         */
+        public void setMbc(Mbc mbc) {
+            if (mbc.getBandCount() != mMbc.getBandCount()) {
+                throw new IllegalArgumentException("MbcBandCount changed from " +
+                        mMbc.getBandCount() + " to " + mbc.getBandCount());
+            }
+            mMbc = new Mbc(mbc);
+        }
+        /**
+         * Gets MbcBand configuration for Mbc stage, for given band index.
+         * @param band index of band of interest from Mbc stage
+         * @return MbcBand configuration
+         */
+        public MbcBand getMbcBand(int band) {
+            return mMbc.getBand(band);
+        }
+        /**
+         * Sets MbcBand for Mbc stage for given band index
+         * @param band index of band of interest from Mbc Stage
+         * @param mbcBand configuration to be set
+         */
+        public void setMbcBand(int band, MbcBand mbcBand) {
+            mMbc.setBand(band, mbcBand);
+        }
+
+        /**
+         * Gets PostEq configuration stage
+         * @return PostEq configuration stage
+         */
+        public Eq getPostEq() {
+            return mPostEq;
+        }
+        /**
+         * Sets PostEq configuration stage. New PostEq stage must have the same number of bands than
+         * original PostEq stage.
+         * @param postEq configuration
+         */
+        public void setPostEq(Eq postEq) {
+            if (postEq.getBandCount() != mPostEq.getBandCount()) {
+                throw new IllegalArgumentException("PostEqBandCount changed from " +
+                        mPostEq.getBandCount() + " to " + postEq.getBandCount());
+            }
+            mPostEq = new Eq(postEq);
+        }
+        /**
+         * Gets EqBand for PostEq stage for given band index.
+         * @param band index of band of interest from PostEq stage
+         * @return EqBand configuration
+         */
+        public EqBand getPostEqBand(int band) {
+            return mPostEq.getBand(band);
+        }
+        /**
+         * Sets EqBand for PostEq stage for given band index
+         * @param band index of band of interest from PostEq stage
+         * @param postEqBand configuration to be set.
+         */
+        public void setPostEqBand(int band, EqBand postEqBand) {
+            mPostEq.setBand(band, postEqBand);
+        }
+
+        /**
+         * Gets Limiter configuration stage
+         * @return Limiter configuration stage
+         */
+        public Limiter getLimiter() {
+            return mLimiter;
+        }
+        /**
+         * Sets Limiter configuration stage.
+         * @param limiter configuration stage.
+         */
+        public void setLimiter(Limiter limiter) {
+            mLimiter = new Limiter(limiter);
+        }
+    }
+
+    /**
+     * Class for Config object, used by DynamicsProcessing to configure and update the audio effect.
+     * use Builder to instantiate objects of this type.
+     */
+    public final static class Config {
+        private final int mVariant;
+        private final int mChannelCount;
+        private final boolean mPreEqInUse;
+        private final int mPreEqBandCount;
+        private final boolean mMbcInUse;
+        private final int mMbcBandCount;
+        private final boolean mPostEqInUse;
+        private final int mPostEqBandCount;
+        private final boolean mLimiterInUse;
+        private final float mPreferredFrameDuration;
+        private final Channel[] mChannel;
+
+        /**
+         * @hide
+         * Class constructor for config. None of these parameters can be changed later.
+         * @param variant index of variant used for effect engine. See
+         * {@link #VARIANT_FAVOR_FREQUENCY_RESOLUTION} and {@link #VARIANT_FAVOR_TIME_RESOLUTION}.
+         * @param frameDurationMs preferred frame duration in milliseconds (ms).
+         * @param channelCount Number of channels to be configured.
+         * @param preEqInUse true if PreEq stage will be used, false otherwise.
+         * @param preEqBandCount number of bands for PreEq stage.
+         * @param mbcInUse true if Mbc stage will be used, false otherwise.
+         * @param mbcBandCount number of bands for Mbc stage.
+         * @param postEqInUse true if PostEq stage will be used, false otherwise.
+         * @param postEqBandCount number of bands for PostEq stage.
+         * @param limiterInUse true if Limiter stage will be used, false otherwise.
+         * @param channel array of Channel objects to be used for this configuration.
+         */
+        public Config(int variant, float frameDurationMs, int channelCount,
+                boolean preEqInUse, int preEqBandCount,
+                boolean mbcInUse, int mbcBandCount,
+                boolean postEqInUse, int postEqBandCount,
+                boolean limiterInUse,
+                Channel[] channel) {
+            mVariant = variant;
+            mPreferredFrameDuration = frameDurationMs;
+            mChannelCount = channelCount;
+            mPreEqInUse = preEqInUse;
+            mPreEqBandCount = preEqBandCount;
+            mMbcInUse = mbcInUse;
+            mMbcBandCount = mbcBandCount;
+            mPostEqInUse = postEqInUse;
+            mPostEqBandCount = postEqBandCount;
+            mLimiterInUse = limiterInUse;
+
+            mChannel = new Channel[mChannelCount];
+            //check if channelconfig is null or has less channels than channel count.
+            //options: fill the missing with default options.
+            // or fail?
+            for (int ch = 0; ch < mChannelCount; ch++) {
+                if (ch < channel.length) {
+                    mChannel[ch] = new Channel(channel[ch]); //copy create
+                } else {
+                    //create a new one from scratch? //fail?
+                }
+            }
+        }
+        //a version that will scale to necessary number of channels
+        /**
+         * @hide
+         * Class constructor for Configuration.
+         * @param channelCount limit configuration to this number of channels. if channelCount is
+         * greater than number of channels in cfg, the constructor will duplicate the last channel
+         * found as many times as necessary to create a Config with channelCount number of channels.
+         * If channelCount is less than channels in cfg, the extra channels in cfg will be ignored.
+         * @param cfg copy constructor paremter.
+         */
+        public Config(int channelCount, Config cfg) {
+            mVariant = cfg.mVariant;
+            mPreferredFrameDuration = cfg.mPreferredFrameDuration;
+            mChannelCount = cfg.mChannelCount;
+            mPreEqInUse = cfg.mPreEqInUse;
+            mPreEqBandCount = cfg.mPreEqBandCount;
+            mMbcInUse = cfg.mMbcInUse;
+            mMbcBandCount = cfg.mMbcBandCount;
+            mPostEqInUse = cfg.mPostEqInUse;
+            mPostEqBandCount = cfg.mPostEqBandCount;
+            mLimiterInUse = cfg.mLimiterInUse;
+
+            if (mChannelCount != cfg.mChannel.length) {
+                throw new IllegalArgumentException("configuration channel counts differ " +
+                        mChannelCount + " !=" + cfg.mChannel.length);
+            }
+            if (channelCount < 1) {
+                throw new IllegalArgumentException("channel resizing less than 1 not allowed");
+            }
+
+            mChannel = new Channel[channelCount];
+            for (int ch = 0; ch < channelCount; ch++) {
+                if (ch < mChannelCount) {
+                    mChannel[ch] = new Channel(cfg.mChannel[ch]);
+                } else {
+                    //duplicate last
+                    mChannel[ch] = new Channel(cfg.mChannel[mChannelCount-1]);
+                }
+            }
+        }
+
+        /**
+         * @hide
+         * Class constructor for Config
+         * @param cfg Configuration object copy constructor
+         */
+        public Config(@NonNull Config cfg) {
+            this(cfg.mChannelCount, cfg);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(String.format("Variant: %d\n", mVariant));
+            sb.append(String.format("PreferredFrameDuration: %f\n", mPreferredFrameDuration));
+            sb.append(String.format("ChannelCount: %d\n", mChannelCount));
+            sb.append(String.format("PreEq inUse: %b, bandCount:%d\n",mPreEqInUse,
+                    mPreEqBandCount));
+            sb.append(String.format("Mbc inUse: %b, bandCount: %d\n",mMbcInUse, mMbcBandCount));
+            sb.append(String.format("PostEq inUse: %b, bandCount: %d\n", mPostEqInUse,
+                    mPostEqBandCount));
+            sb.append(String.format("Limiter inUse: %b\n", mLimiterInUse));
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                sb.append(String.format("==Channel %d\n", ch));
+                sb.append(mChannel[ch].toString());
+            }
+            return sb.toString();
+        }
+        private void checkChannel(int channelIndex) {
+            if (channelIndex < 0 || channelIndex >= mChannel.length) {
+                throw new IllegalArgumentException("ChannelIndex out of bounds");
+            }
+        }
+
+        //getters and setters
+        /**
+         * Gets variant for effect engine See {@link #VARIANT_FAVOR_FREQUENCY_RESOLUTION} and
+         * {@link #VARIANT_FAVOR_TIME_RESOLUTION}.
+         * @return variant of effect engine
+         */
+        public int getVariant() {
+            return mVariant;
+        }
+        /**
+         * Gets preferred frame duration in milliseconds (ms).
+         * @return preferred frame duration in milliseconds (ms)
+         */
+        public float getPreferredFrameDuration() {
+            return mPreferredFrameDuration;
+        }
+        /**
+         * Gets if preEq stage is in use
+         * @return true if preEq stage is in use;
+         */
+        public boolean isPreEqInUse() {
+            return mPreEqInUse;
+        }
+        /**
+         * Gets number of bands configured for the PreEq stage.
+         * @return number of bands configured for the PreEq stage.
+         */
+        public int getPreEqBandCount() {
+            return mPreEqBandCount;
+        }
+        /**
+         * Gets if Mbc stage is in use
+         * @return true if Mbc stage is in use;
+         */
+        public boolean isMbcInUse() {
+            return mMbcInUse;
+        }
+        /**
+         * Gets number of bands configured for the Mbc stage.
+         * @return number of bands configured for the Mbc stage.
+         */
+        public int getMbcBandCount() {
+            return mMbcBandCount;
+        }
+        /**
+         * Gets if PostEq stage is in use
+         * @return true if PostEq stage is in use;
+         */
+        public boolean isPostEqInUse() {
+            return mPostEqInUse;
+        }
+        /**
+         * Gets number of bands configured for the PostEq stage.
+         * @return number of bands configured for the PostEq stage.
+         */
+        public int getPostEqBandCount() {
+            return mPostEqBandCount;
+        }
+        /**
+         * Gets if Limiter stage is in use
+         * @return true if Limiter stage is in use;
+         */
+        public boolean isLimiterInUse() {
+            return mLimiterInUse;
+        }
+
+        //channel
+        /**
+         * Gets the Channel configuration object by using the channel index
+         * @param channelIndex of desired Channel object
+         * @return Channel configuration object
+         */
+        public Channel getChannelByChannelIndex(int channelIndex) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex];
+        }
+
+        /**
+         * Sets the chosen Channel object in the selected channelIndex
+         * Note that all the stages should have the same number of bands than the existing Channel
+         * object.
+         * @param channelIndex index of channel to be replaced
+         * @param channel Channel configuration object to be set
+         */
+        public void setChannelTo(int channelIndex, Channel channel) {
+            checkChannel(channelIndex);
+            //check all things are compatible
+            if (mMbcBandCount != channel.getMbc().getBandCount()) {
+                throw new IllegalArgumentException("MbcBandCount changed from " +
+                        mMbcBandCount + " to " + channel.getPreEq().getBandCount());
+            }
+            if (mPreEqBandCount != channel.getPreEq().getBandCount()) {
+                throw new IllegalArgumentException("PreEqBandCount changed from " +
+                        mPreEqBandCount + " to " + channel.getPreEq().getBandCount());
+            }
+            if (mPostEqBandCount != channel.getPostEq().getBandCount()) {
+                throw new IllegalArgumentException("PostEqBandCount changed from " +
+                        mPostEqBandCount + " to " + channel.getPostEq().getBandCount());
+            }
+            mChannel[channelIndex] = new Channel(channel);
+        }
+
+        /**
+         * Sets ALL channels to the chosen Channel object. Note that all the stages should have the
+         * same number of bands than the existing ones.
+         * @param channel Channel configuration object to be set.
+         */
+        public void setAllChannelsTo(Channel channel) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                setChannelTo(ch, channel);
+            }
+        }
+
+        //===channel params
+        /**
+         * Gets inputGain value in decibels (dB) for channel indicated by channelIndex
+         * @param channelIndex index of channel of interest
+         * @return inputGain value in decibels (dB). 0 dB means no change.
+         */
+        public float getInputGainByChannelIndex(int channelIndex) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getInputGain();
+        }
+        /**
+         * Sets the inputGain value in decibels (dB) for the channel indicated by channelIndex.
+         * @param channelIndex index of channel of interest
+         * @param inputGain desired value in decibels (dB).
+         */
+        public void setInputGainByChannelIndex(int channelIndex, float inputGain) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setInputGain(inputGain);
+        }
+        /**
+         * Sets the inputGain value in decibels (dB) for ALL channels
+         * @param inputGain desired value in decibels (dB)
+         */
+        public void setInputGainAllChannelsTo(float inputGain) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setInputGain(inputGain);
+            }
+        }
+
+        //=== PreEQ
+        /**
+         * Gets PreEq stage from channel indicated by channelIndex
+         * @param channelIndex index of channel of interest
+         * @return PreEq stage configuration object
+         */
+        public Eq getPreEqByChannelIndex(int channelIndex) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getPreEq();
+        }
+        /**
+         * Sets the PreEq stage configuration for the channel indicated by channelIndex. Note that
+         * new preEq stage must have the same number of bands than original preEq stage
+         * @param channelIndex index of channel to be set
+         * @param preEq desired PreEq configuration to be set
+         */
+        public void setPreEqByChannelIndex(int channelIndex, Eq preEq) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setPreEq(preEq);
+        }
+        /**
+         * Sets the PreEq stage configuration for ALL channels. Note that new preEq stage must have
+         * the same number of bands than original preEq stages.
+         * @param preEq desired PreEq configuration to be set
+         */
+        public void setPreEqAllChannelsTo(Eq preEq) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setPreEq(preEq);
+            }
+        }
+        public EqBand getPreEqBandByChannelIndex(int channelIndex, int band) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getPreEqBand(band);
+        }
+        public void setPreEqBandByChannelIndex(int channelIndex, int band, EqBand preEqBand) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setPreEqBand(band, preEqBand);
+        }
+        public void setPreEqBandAllChannelsTo(int band, EqBand preEqBand) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setPreEqBand(band, preEqBand);
+            }
+        }
+
+        //=== MBC
+        public Mbc getMbcByChannelIndex(int channelIndex) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getMbc();
+        }
+        public void setMbcByChannelIndex(int channelIndex, Mbc mbc) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setMbc(mbc);
+        }
+        public void setMbcAllChannelsTo(Mbc mbc) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setMbc(mbc);
+            }
+        }
+        public MbcBand getMbcBandByChannelIndex(int channelIndex, int band) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getMbcBand(band);
+        }
+        public void setMbcBandByChannelIndex(int channelIndex, int band, MbcBand mbcBand) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setMbcBand(band, mbcBand);
+        }
+        public void setMbcBandAllChannelsTo(int band, MbcBand mbcBand) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setMbcBand(band, mbcBand);
+            }
+        }
+
+        //=== PostEQ
+        public Eq getPostEqByChannelIndex(int channelIndex) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getPostEq();
+        }
+        public void setPostEqByChannelIndex(int channelIndex, Eq postEq) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setPostEq(postEq);
+        }
+        public void setPostEqAllChannelsTo(Eq postEq) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setPostEq(postEq);
+            }
+        }
+        public EqBand getPostEqBandByChannelIndex(int channelIndex, int band) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getPostEqBand(band);
+        }
+        public void setPostEqBandByChannelIndex(int channelIndex, int band, EqBand postEqBand) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setPostEqBand(band, postEqBand);
+        }
+        public void setPostEqBandAllChannelsTo(int band, EqBand postEqBand) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setPostEqBand(band, postEqBand);
+            }
+        }
+
+        //Limiter
+        public Limiter getLimiterByChannelIndex(int channelIndex) {
+            checkChannel(channelIndex);
+            return mChannel[channelIndex].getLimiter();
+        }
+        public void setLimiterByChannelIndex(int channelIndex, Limiter limiter) {
+            checkChannel(channelIndex);
+            mChannel[channelIndex].setLimiter(limiter);
+        }
+        public void setLimiterAllChannelsTo(Limiter limiter) {
+            for (int ch = 0; ch < mChannel.length; ch++) {
+                mChannel[ch].setLimiter(limiter);
+            }
+        }
+
+        public final static class Builder {
+            private int mVariant;
+            private int mChannelCount;
+            private boolean mPreEqInUse;
+            private int mPreEqBandCount;
+            private boolean mMbcInUse;
+            private int mMbcBandCount;
+            private boolean mPostEqInUse;
+            private int mPostEqBandCount;
+            private boolean mLimiterInUse;
+            private float mPreferredFrameDuration = CONFIG_PREFERRED_FRAME_DURATION_MS;
+            private Channel[] mChannel;
+
+            public Builder(int variant, int channelCount,
+                    boolean preEqInUse, int preEqBandCount,
+                    boolean mbcInUse, int mbcBandCount,
+                    boolean postEqInUse, int postEqBandCount,
+                    boolean limiterInUse) {
+                mVariant = variant;
+                mChannelCount = channelCount;
+                mPreEqInUse = preEqInUse;
+                mPreEqBandCount = preEqBandCount;
+                mMbcInUse = mbcInUse;
+                mMbcBandCount = mbcBandCount;
+                mPostEqInUse = postEqInUse;
+                mPostEqBandCount = postEqBandCount;
+                mLimiterInUse = limiterInUse;
+                mChannel = new Channel[mChannelCount];
+                for (int ch = 0; ch < mChannelCount; ch++) {
+                    this.mChannel[ch] = new Channel(CHANNEL_DEFAULT_INPUT_GAIN,
+                            this.mPreEqInUse, this.mPreEqBandCount,
+                            this.mMbcInUse, this.mMbcBandCount,
+                            this.mPostEqInUse, this.mPostEqBandCount,
+                            this.mLimiterInUse);
+                }
+            }
+
+            private void checkChannel(int channelIndex) {
+                if (channelIndex < 0 || channelIndex >= mChannel.length) {
+                    throw new IllegalArgumentException("ChannelIndex out of bounds");
+                }
+            }
+
+            public Builder setPreferredFrameDuration(float frameDuration) {
+                if (frameDuration < 0) {
+                    throw new IllegalArgumentException("Expected positive frameDuration");
+                }
+                mPreferredFrameDuration = frameDuration;
+                return this;
+            }
+
+            public Builder setInputGainByChannelIndex(int channelIndex, float inputGain) {
+                checkChannel(channelIndex);
+                mChannel[channelIndex].setInputGain(inputGain);
+                return this;
+            }
+            public Builder setInputGainAllChannelsTo(float inputGain) {
+                for (int ch = 0; ch < mChannel.length; ch++) {
+                    mChannel[ch].setInputGain(inputGain);
+                }
+                return this;
+            }
+
+            public Builder setChannelTo(int channelIndex, Channel channel) {
+                checkChannel(channelIndex);
+                //check all things are compatible
+                if (mMbcBandCount != channel.getMbc().getBandCount()) {
+                    throw new IllegalArgumentException("MbcBandCount changed from " +
+                            mMbcBandCount + " to " + channel.getPreEq().getBandCount());
+                }
+                if (mPreEqBandCount != channel.getPreEq().getBandCount()) {
+                    throw new IllegalArgumentException("PreEqBandCount changed from " +
+                            mPreEqBandCount + " to " + channel.getPreEq().getBandCount());
+                }
+                if (mPostEqBandCount != channel.getPostEq().getBandCount()) {
+                    throw new IllegalArgumentException("PostEqBandCount changed from " +
+                            mPostEqBandCount + " to " + channel.getPostEq().getBandCount());
+                }
+                mChannel[channelIndex] = new Channel(channel);
+                return this;
+            }
+            public Builder setAllChannelsTo(Channel channel) {
+                for (int ch = 0; ch < mChannel.length; ch++) {
+                    setChannelTo(ch, channel);
+                }
+                return this;
+            }
+
+            public Builder setPreEqByChannelIndex(int channelIndex, Eq preEq) {
+                checkChannel(channelIndex);
+                mChannel[channelIndex].setPreEq(preEq);
+                return this;
+            }
+            public Builder setPreEqAllChannelsTo(Eq preEq) {
+                for (int ch = 0; ch < mChannel.length; ch++) {
+                    setPreEqByChannelIndex(ch, preEq);
+                }
+                return this;
+            }
+
+            public Builder setMbcByChannelIndex(int channelIndex, Mbc mbc) {
+                checkChannel(channelIndex);
+                mChannel[channelIndex].setMbc(mbc);
+                return this;
+            }
+            public Builder setMbcAllChannelsTo(Mbc mbc) {
+                for (int ch = 0; ch < mChannel.length; ch++) {
+                    setMbcByChannelIndex(ch, mbc);
+                }
+                return this;
+            }
+
+            public Builder setPostEqByChannelIndex(int channelIndex, Eq postEq) {
+                checkChannel(channelIndex);
+                mChannel[channelIndex].setPostEq(postEq);
+                return this;
+            }
+            public Builder setPostEqAllChannelsTo(Eq postEq) {
+                for (int ch = 0; ch < mChannel.length; ch++) {
+                    setPostEqByChannelIndex(ch, postEq);
+                }
+                return this;
+            }
+
+            public Builder setLimiterByChannelIndex(int channelIndex, Limiter limiter) {
+                checkChannel(channelIndex);
+                mChannel[channelIndex].setLimiter(limiter);
+                return this;
+            }
+            public Builder setLimiterAllChannelsTo(Limiter limiter) {
+                for (int ch = 0; ch < mChannel.length; ch++) {
+                    setLimiterByChannelIndex(ch, limiter);
+                }
+                return this;
+            }
+
+            public Config build() {
+                return new Config(mVariant, mPreferredFrameDuration, mChannelCount,
+                        mPreEqInUse, mPreEqBandCount,
+                        mMbcInUse, mMbcBandCount,
+                        mPostEqInUse, mPostEqBandCount,
+                        mLimiterInUse, mChannel);
+            }
+        }
+    }
+    //=== CHANNEL
+    public Channel getChannelByChannelIndex(int channelIndex) {
+        return queryEngineByChannelIndex(channelIndex);
+    }
+
+    public void setChannelTo(int channelIndex, Channel channel) {
+        updateEngineChannelByChannelIndex(channelIndex, channel);
+    }
+
+    public void setAllChannelsTo(Channel channel) {
+        for (int ch = 0; ch < mChannelCount; ch++) {
+            setChannelTo(ch, channel);
+        }
+    }
+
+    //=== channel params
+    public float getInputGainByChannelIndex(int channelIndex) {
+        return getTwoFloat(PARAM_INPUT_GAIN, channelIndex);
+    }
+    public void setInputGainbyChannel(int channelIndex, float inputGain) {
+        setTwoFloat(PARAM_INPUT_GAIN, channelIndex, inputGain);
+    }
+    public void setInputGainAllChannelsTo(float inputGain) {
+        for (int ch = 0; ch < mChannelCount; ch++) {
+            setInputGainbyChannel(ch, inputGain);
+        }
+    }
+
+    //=== PreEQ
+    public Eq getPreEqByChannelIndex(int channelIndex) {
+        return queryEngineEqByChannelIndex(PARAM_PRE_EQ, channelIndex);
+    }
+    public void setPreEqByChannelIndex(int channelIndex, Eq preEq) {
+        updateEngineEqByChannelIndex(PARAM_PRE_EQ, channelIndex, preEq);
+    }
+    public void setPreEqAllChannelsTo(Eq preEq) {
+        for (int ch = 0; ch < mChannelCount; ch++) {
+            setPreEqByChannelIndex(ch, preEq);
+        }
+    }
+    public EqBand getPreEqBandByChannelIndex(int channelIndex, int band) {
+        return queryEngineEqBandByChannelIndex(PARAM_PRE_EQ_BAND, channelIndex, band);
+    }
+    public void setPreEqBandByChannelIndex(int channelIndex, int band, EqBand preEqBand) {
+        updateEngineEqBandByChannelIndex(PARAM_PRE_EQ_BAND, channelIndex, band, preEqBand);
+    }
+    public void setPreEqBandAllChannelsTo(int band, EqBand preEqBand) {
+        for (int ch = 0; ch < mChannelCount; ch++) {
+            setPreEqBandByChannelIndex(ch, band, preEqBand);
+        }
+    }
+
+    //=== MBC
+    public Mbc getMbcByChannelIndex(int channelIndex) {
+        return queryEngineMbcByChannelIndex(channelIndex);
+    }
+    public void setMbcByChannelIndex(int channelIndex, Mbc mbc) {
+        updateEngineMbcByChannelIndex(channelIndex, mbc);
+    }
+    public void setMbcAllChannelsTo(Mbc mbc) {
+        for (int ch = 0; ch < mChannelCount; ch++) {
+            setMbcByChannelIndex(ch, mbc);
+        }
+    }
+    public MbcBand getMbcBandByChannelIndex(int channelIndex, int band) {
+        return queryEngineMbcBandByChannelIndex(channelIndex, band);
+    }
+    public void setMbcBandByChannelIndex(int channelIndex, int band, MbcBand mbcBand) {
+        updateEngineMbcBandByChannelIndex(channelIndex, band, mbcBand);
+    }
+    public void setMbcBandAllChannelsTo(int band, MbcBand mbcBand) {
+        for (int ch = 0; ch < mChannelCount; ch++) {
+            setMbcBandByChannelIndex(ch, band, mbcBand);
+        }
+    }
+
+    //== PostEq
+    public Eq getPostEqByChannelIndex(int channelIndex) {
+        return queryEngineEqByChannelIndex(PARAM_POST_EQ, channelIndex);
+    }
+    public void setPostEqByChannelIndex(int channelIndex, Eq postEq) {
+        updateEngineEqByChannelIndex(PARAM_POST_EQ, channelIndex, postEq);
+    }
+    public void setPostEqAllChannelsTo(Eq postEq) {
+        for (int ch = 0; ch < mChannelCount; ch++) {
+            setPostEqByChannelIndex(ch, postEq);
+        }
+    }
+    public EqBand getPostEqBandByChannelIndex(int channelIndex, int band) {
+        return queryEngineEqBandByChannelIndex(PARAM_POST_EQ_BAND, channelIndex, band);
+    }
+    public void setPostEqBandByChannelIndex(int channelIndex, int band, EqBand postEqBand) {
+        updateEngineEqBandByChannelIndex(PARAM_POST_EQ_BAND, channelIndex, band, postEqBand);
+    }
+    public void setPostEqBandAllChannelsTo(int band, EqBand postEqBand) {
+        for (int ch = 0; ch < mChannelCount; ch++) {
+            setPostEqBandByChannelIndex(ch, band, postEqBand);
+        }
+    }
+
+    //==== Limiter
+    public Limiter getLimiterByChannelIndex(int channelIndex) {
+        return queryEngineLimiterByChannelIndex(channelIndex);
+    }
+    public void setLimiterByChannelIndex(int channelIndex, Limiter limiter) {
+        updateEngineLimiterByChannelIndex(channelIndex, limiter);
+    }
+    public void setLimiterAllChannelsTo(Limiter limiter) {
+        for (int ch = 0; ch < mChannelCount; ch++) {
+            setLimiterByChannelIndex(ch, limiter);
+        }
+    }
+
+    /**
+     * Gets the number of channels in the effect engine
+     * @return number of channels currently in use by the effect engine
+     */
+    public int getChannelCount() {
+        return getOneInt(PARAM_GET_CHANNEL_COUNT);
+    }
+
+    //=== Engine calls
+    private void setEngineArchitecture(int variant, float preferredFrameDuration,
+            boolean preEqInUse, int preEqBandCount, boolean mbcInUse, int mbcBandCount,
+            boolean postEqInUse, int postEqBandCount, boolean limiterInUse) {
+
+        Number[] params = { PARAM_ENGINE_ARCHITECTURE };
+        Number[] values = { variant /* variant */,
+                preferredFrameDuration,
+                (preEqInUse ? 1 : 0),
+                preEqBandCount,
+                (mbcInUse ? 1 : 0),
+                mbcBandCount,
+                (postEqInUse ? 1 : 0),
+                postEqBandCount,
+                (limiterInUse ? 1 : 0)};
+        setNumberArray(params, values);
+    }
+
+    private void updateEngineEqBandByChannelIndex(int param, int channelIndex, int bandIndex,
+            @NonNull EqBand eqBand) {
+        Number[] params = {param,
+                channelIndex,
+                bandIndex};
+        Number[] values = {(eqBand.isEnabled() ? 1 : 0),
+                eqBand.getCutoffFrequency(),
+                eqBand.getGain()};
+        setNumberArray(params, values);
+    }
+    private Eq queryEngineEqByChannelIndex(int param, int channelIndex) {
+
+        Number[] params = {param == PARAM_PRE_EQ ? PARAM_PRE_EQ : PARAM_POST_EQ,
+                channelIndex};
+        Number[] values = {0 /*0 in use */,
+                            0 /*1 enabled*/,
+                            0 /*2 band count */};
+        byte[] paramBytes = numberArrayToByteArray(params);
+        byte[] valueBytes = numberArrayToByteArray(values); //just interest in the byte size.
+        getParameter(paramBytes, valueBytes);
+        byteArrayToNumberArray(valueBytes, values);
+        int bandCount = values[2].intValue();
+        Eq eq = new Eq(values[0].intValue() > 0 /* in use */,
+                values[1].intValue() > 0 /* enabled */,
+                bandCount /*band count*/);
+        for (int b = 0; b < bandCount; b++) {
+            EqBand eqBand = queryEngineEqBandByChannelIndex(param == PARAM_PRE_EQ ?
+                    PARAM_PRE_EQ_BAND : PARAM_POST_EQ_BAND, channelIndex, b);
+            eq.setBand(b, eqBand);
+        }
+        return eq;
+    }
+    private EqBand queryEngineEqBandByChannelIndex(int param, int channelIndex, int bandIndex) {
+        Number[] params = {param,
+                channelIndex,
+                bandIndex};
+        Number[] values = {0 /*0 enabled*/,
+                            0.0f /*1 cutoffFrequency */,
+                            0.0f /*2 gain */};
+
+        byte[] paramBytes = numberArrayToByteArray(params);
+        byte[] valueBytes = numberArrayToByteArray(values); //just interest in the byte size.
+        getParameter(paramBytes, valueBytes);
+
+        byteArrayToNumberArray(valueBytes, values);
+
+        return new EqBand(values[0].intValue() > 0 /* enabled */,
+                values[1].floatValue() /* cutoffFrequency */,
+                values[2].floatValue() /* gain*/);
+    }
+    private void updateEngineEqByChannelIndex(int param, int channelIndex, @NonNull Eq eq) {
+        int bandCount = eq.getBandCount();
+        Number[] params = {param,
+                channelIndex};
+        Number[] values = { (eq.isInUse() ? 1 : 0),
+                (eq.isEnabled() ? 1 : 0),
+                bandCount};
+        setNumberArray(params, values);
+        for (int b = 0; b < bandCount; b++) {
+            EqBand eqBand = eq.getBand(b);
+            updateEngineEqBandByChannelIndex(param == PARAM_PRE_EQ ?
+                    PARAM_PRE_EQ_BAND : PARAM_POST_EQ_BAND, channelIndex, b, eqBand);
+        }
+    }
+
+    private Mbc queryEngineMbcByChannelIndex(int channelIndex) {
+        Number[] params = {PARAM_MBC,
+                channelIndex};
+        Number[] values = {0 /*0 in use */,
+                            0 /*1 enabled*/,
+                            0 /*2 band count */};
+        byte[] paramBytes = numberArrayToByteArray(params);
+        byte[] valueBytes = numberArrayToByteArray(values); //just interest in the byte size.
+        getParameter(paramBytes, valueBytes);
+        byteArrayToNumberArray(valueBytes, values);
+        int bandCount = values[2].intValue();
+        Mbc mbc = new Mbc(values[0].intValue() > 0 /* in use */,
+                values[1].intValue() > 0 /* enabled */,
+                bandCount /*band count*/);
+        for (int b = 0; b < bandCount; b++) {
+            MbcBand mbcBand = queryEngineMbcBandByChannelIndex(channelIndex, b);
+            mbc.setBand(b, mbcBand);
+        }
+        return mbc;
+    }
+    private MbcBand queryEngineMbcBandByChannelIndex(int channelIndex, int bandIndex) {
+        Number[] params = {PARAM_MBC_BAND,
+                channelIndex,
+                bandIndex};
+        Number[] values = {0 /*0 enabled */,
+                0.0f /*1 cutoffFrequency */,
+                0.0f /*2 AttackTime */,
+                0.0f /*3 ReleaseTime */,
+                0.0f /*4 Ratio */,
+                0.0f /*5 Threshold */,
+                0.0f /*6 KneeWidth */,
+                0.0f /*7 NoiseGateThreshold */,
+                0.0f /*8 ExpanderRatio */,
+                0.0f /*9 PreGain */,
+                0.0f /*10 PostGain*/};
+
+        byte[] paramBytes = numberArrayToByteArray(params);
+        byte[] valueBytes = numberArrayToByteArray(values); //just interest in the byte size.
+        getParameter(paramBytes, valueBytes);
+
+        byteArrayToNumberArray(valueBytes, values);
+
+        return new MbcBand(values[0].intValue() > 0 /* enabled */,
+                values[1].floatValue() /* cutoffFrequency */,
+                values[2].floatValue()/*2 AttackTime */,
+                values[3].floatValue()/*3 ReleaseTime */,
+                values[4].floatValue()/*4 Ratio */,
+                values[5].floatValue()/*5 Threshold */,
+                values[6].floatValue()/*6 KneeWidth */,
+                values[7].floatValue()/*7 NoiseGateThreshold */,
+                values[8].floatValue()/*8 ExpanderRatio */,
+                values[9].floatValue()/*9 PreGain */,
+                values[10].floatValue()/*10 PostGain*/);
+    }
+    private void updateEngineMbcBandByChannelIndex(int channelIndex, int bandIndex,
+            @NonNull MbcBand mbcBand) {
+        Number[] params = { PARAM_MBC_BAND,
+                channelIndex,
+                bandIndex};
+        Number[] values = {(mbcBand.isEnabled() ? 1 : 0),
+                mbcBand.getCutoffFrequency(),
+                mbcBand.getAttackTime(),
+                mbcBand.getReleaseTime(),
+                mbcBand.getRatio(),
+                mbcBand.getThreshold(),
+                mbcBand.getKneeWidth(),
+                mbcBand.getNoiseGateThreshold(),
+                mbcBand.getExpanderRatio(),
+                mbcBand.getPreGain(),
+                mbcBand.getPostGain()};
+        setNumberArray(params, values);
+    }
+
+    private void updateEngineMbcByChannelIndex(int channelIndex, @NonNull Mbc mbc) {
+        int bandCount = mbc.getBandCount();
+        Number[] params = { PARAM_MBC,
+                channelIndex};
+        Number[] values = {(mbc.isInUse() ? 1 : 0),
+                (mbc.isEnabled() ? 1 : 0),
+                bandCount};
+        setNumberArray(params, values);
+        for (int b = 0; b < bandCount; b++) {
+            MbcBand mbcBand = mbc.getBand(b);
+            updateEngineMbcBandByChannelIndex(channelIndex, b, mbcBand);
+        }
+    }
+
+    private void updateEngineLimiterByChannelIndex(int channelIndex, @NonNull Limiter limiter) {
+        Number[] params = { PARAM_LIMITER,
+                channelIndex};
+        Number[] values = {(limiter.isInUse() ? 1 : 0),
+                (limiter.isEnabled() ? 1 : 0),
+                limiter.getLinkGroup(),
+                limiter.getAttackTime(),
+                limiter.getReleaseTime(),
+                limiter.getRatio(),
+                limiter.getThreshold(),
+                limiter.getPostGain()};
+        setNumberArray(params, values);
+    }
+
+    private Limiter queryEngineLimiterByChannelIndex(int channelIndex) {
+        Number[] params = {PARAM_LIMITER,
+                channelIndex};
+        Number[] values = {0 /*0 in use (int)*/,
+                0 /*1 enabled (int)*/,
+                0 /*2 link group (int)*/,
+                0.0f /*3 attack time (float)*/,
+                0.0f /*4 release time (float)*/,
+                0.0f /*5 ratio (float)*/,
+                0.0f /*6 threshold (float)*/,
+                0.0f /*7 post gain(float)*/};
+
+        byte[] paramBytes = numberArrayToByteArray(params);
+        byte[] valueBytes = numberArrayToByteArray(values); //just interest in the byte size.
+        getParameter(paramBytes, valueBytes);
+        byteArrayToNumberArray(valueBytes, values);
+
+        return new Limiter(values[0].intValue() > 0 /*in use*/,
+                values[1].intValue() > 0 /*enabled*/,
+                values[2].intValue() /*linkGroup*/,
+                values[3].floatValue() /*attackTime*/,
+                values[4].floatValue() /*releaseTime*/,
+                values[5].floatValue() /*ratio*/,
+                values[6].floatValue() /*threshold*/,
+                values[7].floatValue() /*postGain*/);
+    }
+
+    private Channel queryEngineByChannelIndex(int channelIndex) {
+        float inputGain = getTwoFloat(PARAM_INPUT_GAIN, channelIndex);
+        Eq preEq = queryEngineEqByChannelIndex(PARAM_PRE_EQ, channelIndex);
+        Mbc mbc = queryEngineMbcByChannelIndex(channelIndex);
+        Eq postEq = queryEngineEqByChannelIndex(PARAM_POST_EQ, channelIndex);
+        Limiter limiter = queryEngineLimiterByChannelIndex(channelIndex);
+
+        Channel channel = new Channel(inputGain,
+                preEq.isInUse(), preEq.getBandCount(),
+                mbc.isInUse(), mbc.getBandCount(),
+                postEq.isInUse(), postEq.getBandCount(),
+                limiter.isInUse());
+        channel.setInputGain(inputGain);
+        channel.setPreEq(preEq);
+        channel.setMbc(mbc);
+        channel.setPostEq(postEq);
+        channel.setLimiter(limiter);
+        return channel;
+    }
+
+    private void updateEngineChannelByChannelIndex(int channelIndex, @NonNull Channel channel) {
+        //send things with as few calls as possible
+        setTwoFloat(PARAM_INPUT_GAIN, channelIndex, channel.getInputGain());
+        Eq preEq = channel.getPreEq();
+        updateEngineEqByChannelIndex(PARAM_PRE_EQ, channelIndex, preEq);
+        Mbc mbc = channel.getMbc();
+        updateEngineMbcByChannelIndex(channelIndex, mbc);
+        Eq postEq = channel.getPostEq();
+        updateEngineEqByChannelIndex(PARAM_POST_EQ, channelIndex, postEq);
+        Limiter limiter = channel.getLimiter();
+        updateEngineLimiterByChannelIndex(channelIndex, limiter);
+    }
+
+    //****** convenience methods:
+    //
+    private int getOneInt(int param) {
+        final int[] params = { param };
+        final int[] result = new int[1];
+
+        checkStatus(getParameter(params, result));
+        return result[0];
+    }
+
+    private void setTwoFloat(int param, int paramA, float valueSet) {
+        final int[] params = { param, paramA };
+        final byte[] value;
+
+        value = floatToByteArray(valueSet);
+        checkStatus(setParameter(params, value));
+    }
+
+    private byte[] numberArrayToByteArray(Number[] values) {
+        int expectedBytes = 0;
+        for (int i = 0; i < values.length; i++) {
+            if (values[i] instanceof Integer) {
+                expectedBytes += Integer.BYTES;
+            } else if (values[i] instanceof Float) {
+                expectedBytes += Float.BYTES;
+            } else {
+                throw new IllegalArgumentException("unknown value type " +
+                        values[i].getClass());
+            }
+        }
+        ByteBuffer converter = ByteBuffer.allocate(expectedBytes);
+        converter.order(ByteOrder.nativeOrder());
+        for (int i = 0; i < values.length; i++) {
+            if (values[i] instanceof Integer) {
+                converter.putInt(values[i].intValue());
+            } else if (values[i] instanceof Float) {
+                converter.putFloat(values[i].floatValue());
+            }
+        }
+        return converter.array();
+    }
+
+    private void byteArrayToNumberArray(byte[] valuesIn, Number[] valuesOut) {
+        int inIndex = 0;
+        int outIndex = 0;
+        while (inIndex < valuesIn.length && outIndex < valuesOut.length) {
+            if (valuesOut[outIndex] instanceof Integer) {
+                valuesOut[outIndex++] = byteArrayToInt(valuesIn, inIndex);
+                inIndex += Integer.BYTES;
+            } else if (valuesOut[outIndex] instanceof Float) {
+                valuesOut[outIndex++] = byteArrayToFloat(valuesIn, inIndex);
+                inIndex += Float.BYTES;
+            } else {
+                throw new IllegalArgumentException("can't convert " +
+                        valuesOut[outIndex].getClass());
+            }
+        }
+        if (outIndex != valuesOut.length) {
+            throw new IllegalArgumentException("only converted " + outIndex +
+                    " values out of "+ valuesOut.length + " expected");
+        }
+    }
+
+    private void setNumberArray(Number[] params, Number[] values) {
+        byte[] paramBytes = numberArrayToByteArray(params);
+        byte[] valueBytes = numberArrayToByteArray(values);
+        checkStatus(setParameter(paramBytes, valueBytes));
+    }
+
+    private float getTwoFloat(int param, int paramA) {
+        final int[] params = { param, paramA };
+        final byte[] result = new byte[4];
+
+        checkStatus(getParameter(params, result));
+        return byteArrayToFloat(result);
+    }
+
+    /**
+     * @hide
+     * The OnParameterChangeListener interface defines a method called by the DynamicsProcessing
+     * when a parameter value has changed.
+     */
+    public interface OnParameterChangeListener {
+        /**
+         * Method called when a parameter value has changed. The method is called only if the
+         * parameter was changed by another application having the control of the same
+         * DynamicsProcessing engine.
+         * @param effect the DynamicsProcessing on which the interface is registered.
+         * @param param ID of the modified parameter. See {@link #PARAM_GENERIC_PARAM1} ...
+         * @param value the new parameter value.
+         */
+        void onParameterChange(DynamicsProcessing effect, int param, int value);
+    }
+
+    /**
+     * helper method to update effect architecture parameters
+     */
+    private void updateEffectArchitecture() {
+        mChannelCount = getChannelCount();
+    }
+
+    /**
+     * Listener used internally to receive unformatted parameter change events from AudioEffect
+     * super class.
+     */
+    private class BaseParameterListener implements AudioEffect.OnParameterChangeListener {
+        private BaseParameterListener() {
+
+        }
+        public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) {
+            // only notify when the parameter was successfully change
+            if (status != AudioEffect.SUCCESS) {
+                return;
+            }
+            OnParameterChangeListener l = null;
+            synchronized (mParamListenerLock) {
+                if (mParamListener != null) {
+                    l = mParamListener;
+                }
+            }
+            if (l != null) {
+                int p = -1;
+                int v = Integer.MIN_VALUE;
+
+                if (param.length == 4) {
+                    p = byteArrayToInt(param, 0);
+                }
+                if (value.length == 4) {
+                    v = byteArrayToInt(value, 0);
+                }
+                if (p != -1 && v != Integer.MIN_VALUE) {
+                    l.onParameterChange(DynamicsProcessing.this, p, v);
+                }
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Registers an OnParameterChangeListener interface.
+     * @param listener OnParameterChangeListener interface registered
+     */
+    public void setParameterListener(OnParameterChangeListener listener) {
+        synchronized (mParamListenerLock) {
+            if (mParamListener == null) {
+                mBaseParamListener = new BaseParameterListener();
+                super.setParameterListener(mBaseParamListener);
+            }
+            mParamListener = listener;
+        }
+    }
+
+    /**
+     * @hide
+     * The Settings class regroups the DynamicsProcessing parameters. It is used in
+     * conjunction with the getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+
+    public static class Settings {
+        public int channelCount;
+        public float[] inputGain;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            //int tokens = st.countTokens();
+            if (st.countTokens() != 3) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("DynamicsProcessing")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for DynamicsProcessing: " + key);
+            }
+            try {
+                key = st.nextToken();
+                if (!key.equals("channelCount")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                channelCount = Short.parseShort(st.nextToken());
+                if (channelCount > CHANNEL_COUNT_MAX) {
+                    throw new IllegalArgumentException("too many channels Settings:" + settings);
+                }
+                if (st.countTokens() != channelCount*1) { //check expected parameters.
+                    throw new IllegalArgumentException("settings: " + settings);
+                }
+                //check to see it is ok the size
+                inputGain = new float[channelCount];
+                for (int ch = 0; ch < channelCount; ch++) {
+                    key = st.nextToken();
+                    if (!key.equals(ch +"_inputGain")) {
+                        throw new IllegalArgumentException("invalid key name: " + key);
+                    }
+                    inputGain[ch] = Float.parseFloat(st.nextToken());
+                }
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+            String str = new String (
+                    "DynamicsProcessing"+
+                    ";channelCount="+Integer.toString(channelCount));
+                    for (int ch = 0; ch < channelCount; ch++) {
+                        str = str.concat(";"+ch+"_inputGain="+Float.toString(inputGain[ch]));
+                    }
+            return str;
+        }
+    };
+
+
+    /**
+     * @hide
+     * Gets the DynamicsProcessing properties. This method is useful when a snapshot of current
+     * effect settings must be saved by the application.
+     * @return a DynamicsProcessing.Settings object containing all current parameters values
+     */
+    public DynamicsProcessing.Settings getProperties() {
+        Settings settings = new Settings();
+
+        //TODO: just for testing, we are calling the getters one by one, this is
+        // supposed to be done in a single (or few calls) and get all the parameters at once.
+
+        settings.channelCount = getChannelCount();
+
+        if (settings.channelCount > CHANNEL_COUNT_MAX) {
+            throw new IllegalArgumentException("too many channels Settings:" + settings);
+        }
+
+        { // get inputGainmB per channel
+            settings.inputGain = new float [settings.channelCount];
+            for (int ch = 0; ch < settings.channelCount; ch++) {
+//TODO:with config                settings.inputGain[ch] = getInputGain(ch);
+            }
+        }
+        return settings;
+    }
+
+    /**
+     * @hide
+     * Sets the DynamicsProcessing properties. This method is useful when bass boost settings
+     * have to be applied from a previous backup.
+     * @param settings a DynamicsProcessing.Settings object containing the properties to apply
+     */
+    public void setProperties(DynamicsProcessing.Settings settings) {
+
+        if (settings.channelCount != settings.inputGain.length ||
+                settings.channelCount != mChannelCount) {
+                throw new IllegalArgumentException("settings invalid channel count: "
+                + settings.channelCount);
+            }
+
+        //TODO: for now calling multiple times.
+        for (int ch = 0; ch < mChannelCount; ch++) {
+//TODO: use config            setInputGain(ch, settings.inputGain[ch]);
+        }
+    }
+}
diff --git a/android/media/audiofx/EnvironmentalReverb.java b/android/media/audiofx/EnvironmentalReverb.java
new file mode 100644
index 0000000..ef1c4c3
--- /dev/null
+++ b/android/media/audiofx/EnvironmentalReverb.java
@@ -0,0 +1,661 @@
+/*
+ * Copyright (C) 2010 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.audiofx;
+
+import android.media.audiofx.AudioEffect;
+import java.util.StringTokenizer;
+
+/**
+ * A sound generated within a room travels in many directions. The listener first hears the direct
+ * sound from the source itself. Later, he or she hears discrete echoes caused by sound bouncing off
+ * nearby walls, the ceiling and the floor. As sound waves arrive after undergoing more and more
+ * reflections, individual reflections become indistinguishable and the listener hears continuous
+ * reverberation that decays over time.
+ * Reverb is vital for modeling a listener's environment. It can be used in music applications
+ * to simulate music being played back in various environments, or in games to immerse the
+ * listener within the game's environment.
+ * The EnvironmentalReverb class allows an application to control each reverb engine property in a
+ * global reverb environment and is more suitable for games. For basic control, more suitable for
+ * music applications, it is recommended to use the
+ * {@link android.media.audiofx.PresetReverb} class.
+ * <p>An application creates a EnvironmentalReverb object to instantiate and control a reverb engine
+ * in the audio framework.
+ * <p>The methods, parameter types and units exposed by the EnvironmentalReverb implementation are
+ * directly mapping those defined by the OpenSL ES 1.0.1 Specification
+ * (http://www.khronos.org/opensles/) for the SLEnvironmentalReverbItf interface.
+ * Please refer to this specification for more details.
+ * <p>The EnvironmentalReverb is an output mix auxiliary effect and should be created on
+ * Audio session 0. In order for a MediaPlayer or AudioTrack to be fed into this effect,
+ * they must be explicitely attached to it and a send level must be specified. Use the effect ID
+ * returned by getId() method to designate this particular effect when attaching it to the
+ * MediaPlayer or AudioTrack.
+ * <p>Creating a reverb on the output mix (audio session 0) requires permission
+ * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}
+ * <p>See {@link android.media.audiofx.AudioEffect} class for more details on controlling
+ * audio effects.
+ */
+
+public class EnvironmentalReverb extends AudioEffect {
+
+    private final static String TAG = "EnvironmentalReverb";
+
+    // These constants must be synchronized with those in
+    // frameworks/base/include/media/EffectEnvironmentalReverbApi.h
+
+    /**
+     * Room level. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_ROOM_LEVEL = 0;
+    /**
+     * Room HF level. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_ROOM_HF_LEVEL = 1;
+    /**
+     * Decay time. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_DECAY_TIME = 2;
+    /**
+     * Decay HF ratio. Parameter ID for
+     * {@link android.media.audiofx.EnvironmentalReverb.OnParameterChangeListener}
+     */
+    public static final int PARAM_DECAY_HF_RATIO = 3;
+    /**
+     * Early reflections level. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_REFLECTIONS_LEVEL = 4;
+    /**
+     * Early reflections delay. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_REFLECTIONS_DELAY = 5;
+    /**
+     * Reverb level. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_REVERB_LEVEL = 6;
+    /**
+     * Reverb delay. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_REVERB_DELAY = 7;
+    /**
+     * Diffusion. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_DIFFUSION = 8;
+    /**
+     * Density. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_DENSITY = 9;
+
+    // used by setProperties()/getProperties
+    private static final int PARAM_PROPERTIES = 10;
+
+    /**
+     * Registered listener for parameter changes
+     */
+    private OnParameterChangeListener mParamListener = null;
+
+    /**
+     * Listener used internally to to receive raw parameter change event from AudioEffect super
+     * class
+     */
+    private BaseParameterListener mBaseParamListener = null;
+
+    /**
+     * Lock for access to mParamListener
+     */
+    private final Object mParamListenerLock = new Object();
+
+    /**
+     * Class constructor.
+     * @param priority the priority level requested by the application for controlling the
+     * EnvironmentalReverb engine. As the same engine can be shared by several applications, this
+     * parameter indicates how much the requesting application needs control of effect parameters.
+     * The normal priority is 0, above normal is a positive number, below normal a negative number.
+     * @param audioSession  system wide unique audio session identifier. If audioSession
+     *  is not 0, the EnvironmentalReverb will be attached to the MediaPlayer or AudioTrack in the
+     *  same audio session. Otherwise, the EnvironmentalReverb will apply to the output mix.
+     *  As the EnvironmentalReverb is an auxiliary effect it is recommended to instantiate it on
+     *  audio session 0 and to attach it to the MediaPLayer auxiliary output.
+     *
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    public EnvironmentalReverb(int priority, int audioSession)
+    throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
+        super(EFFECT_TYPE_ENV_REVERB, EFFECT_TYPE_NULL, priority, audioSession);
+    }
+
+    /**
+     * Sets the master volume level of the environmental reverb effect.
+     * @param room room level in millibels. The valid range is [-9000, 0].
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setRoomLevel(short room)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = shortToByteArray(room);
+        checkStatus(setParameter(PARAM_ROOM_LEVEL, param));
+    }
+
+    /**
+     * Gets the master volume level of the environmental reverb effect.
+     * @return the room level in millibels.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getRoomLevel()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[2];
+        checkStatus(getParameter(PARAM_ROOM_LEVEL, param));
+        return byteArrayToShort(param);
+    }
+
+    /**
+     * Sets the volume level at 5 kHz relative to the volume level at low frequencies of the
+     * overall reverb effect.
+     * <p>This controls a low-pass filter that will reduce the level of the high-frequency.
+     * @param roomHF high frequency attenuation level in millibels. The valid range is [-9000, 0].
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setRoomHFLevel(short roomHF)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = shortToByteArray(roomHF);
+        checkStatus(setParameter(PARAM_ROOM_HF_LEVEL, param));
+    }
+
+    /**
+     * Gets the room HF level.
+     * @return the room HF level in millibels.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getRoomHFLevel()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[2];
+        checkStatus(getParameter(PARAM_ROOM_HF_LEVEL, param));
+        return byteArrayToShort(param);
+    }
+
+    /**
+     * Sets the time taken for the level of reverberation to decay by 60 dB.
+     * @param decayTime decay time in milliseconds. The valid range is [100, 20000].
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setDecayTime(int decayTime)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = intToByteArray(decayTime);
+        checkStatus(setParameter(PARAM_DECAY_TIME, param));
+    }
+
+    /**
+     * Gets the decay time.
+     * @return the decay time in milliseconds.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public int getDecayTime()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[4];
+        checkStatus(getParameter(PARAM_DECAY_TIME, param));
+        return byteArrayToInt(param);
+    }
+
+    /**
+     * Sets the ratio of high frequency decay time (at 5 kHz) relative to the decay time at low
+     * frequencies.
+     * @param decayHFRatio high frequency decay ratio using a permille scale. The valid range is
+     * [100, 2000]. A ratio of 1000 indicates that all frequencies decay at the same rate.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setDecayHFRatio(short decayHFRatio)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = shortToByteArray(decayHFRatio);
+        checkStatus(setParameter(PARAM_DECAY_HF_RATIO, param));
+    }
+
+    /**
+     * Gets the ratio of high frequency decay time (at 5 kHz) relative to low frequencies.
+     * @return the decay HF ration. See {@link #setDecayHFRatio(short)} for units.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getDecayHFRatio()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[2];
+        checkStatus(getParameter(PARAM_DECAY_HF_RATIO, param));
+        return byteArrayToShort(param);
+    }
+
+    /**
+     * Sets the volume level of the early reflections.
+     * <p>This level is combined with the overall room level
+     * (set using {@link #setRoomLevel(short)}).
+     * @param reflectionsLevel reflection level in millibels. The valid range is [-9000, 1000].
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setReflectionsLevel(short reflectionsLevel)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = shortToByteArray(reflectionsLevel);
+        checkStatus(setParameter(PARAM_REFLECTIONS_LEVEL, param));
+    }
+
+    /**
+     * Gets the volume level of the early reflections.
+     * @return the early reflections level in millibels.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getReflectionsLevel()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[2];
+        checkStatus(getParameter(PARAM_REFLECTIONS_LEVEL, param));
+        return byteArrayToShort(param);
+    }
+
+    /**
+     * Sets the delay time for the early reflections.
+     * <p>This method sets the time between when the direct path is heard and when the first
+     * reflection is heard.
+     * @param reflectionsDelay reflections delay in milliseconds. The valid range is [0, 300].
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setReflectionsDelay(int reflectionsDelay)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = intToByteArray(reflectionsDelay);
+        checkStatus(setParameter(PARAM_REFLECTIONS_DELAY, param));
+    }
+
+    /**
+     * Gets the reflections delay.
+     * @return the early reflections delay in milliseconds.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public int getReflectionsDelay()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[4];
+        checkStatus(getParameter(PARAM_REFLECTIONS_DELAY, param));
+        return byteArrayToInt(param);
+    }
+
+    /**
+     * Sets the volume level of the late reverberation.
+     * <p>This level is combined with the overall room level (set using {@link #setRoomLevel(short)}).
+     * @param reverbLevel reverb level in millibels. The valid range is [-9000, 2000].
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setReverbLevel(short reverbLevel)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = shortToByteArray(reverbLevel);
+        checkStatus(setParameter(PARAM_REVERB_LEVEL, param));
+    }
+
+    /**
+     * Gets the reverb level.
+     * @return the reverb level in millibels.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getReverbLevel()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[2];
+        checkStatus(getParameter(PARAM_REVERB_LEVEL, param));
+        return byteArrayToShort(param);
+    }
+
+    /**
+     * Sets the time between the first reflection and the reverberation.
+     * @param reverbDelay reverb delay in milliseconds. The valid range is [0, 100].
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setReverbDelay(int reverbDelay)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = intToByteArray(reverbDelay);
+        checkStatus(setParameter(PARAM_REVERB_DELAY, param));
+    }
+
+    /**
+     * Gets the reverb delay.
+     * @return the reverb delay in milliseconds.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public int getReverbDelay()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[4];
+        checkStatus(getParameter(PARAM_REVERB_DELAY, param));
+        return byteArrayToInt(param);
+    }
+
+    /**
+     * Sets the echo density in the late reverberation decay.
+     * <p>The scale should approximately map linearly to the perceived change in reverberation.
+     * @param diffusion diffusion specified using a permille scale. The diffusion valid range is
+     * [0, 1000]. A value of 1000 o/oo indicates a smooth reverberation decay.
+     * Values below this level give a more <i>grainy</i> character.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setDiffusion(short diffusion)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = shortToByteArray(diffusion);
+        checkStatus(setParameter(PARAM_DIFFUSION, param));
+    }
+
+    /**
+     * Gets diffusion level.
+     * @return the diffusion level. See {@link #setDiffusion(short)} for units.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getDiffusion()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[2];
+        checkStatus(getParameter(PARAM_DIFFUSION, param));
+        return byteArrayToShort(param);
+    }
+
+
+    /**
+     * Controls the modal density of the late reverberation decay.
+     * <p> The scale should approximately map linearly to the perceived change in reverberation.
+     * A lower density creates a hollow sound that is useful for simulating small reverberation
+     * spaces such as bathrooms.
+     * @param density density specified using a permille scale. The valid range is [0, 1000].
+     * A value of 1000 o/oo indicates a natural sounding reverberation. Values below this level
+     * produce a more colored effect.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setDensity(short density)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = shortToByteArray(density);
+        checkStatus(setParameter(PARAM_DENSITY, param));
+    }
+
+    /**
+     * Gets the density level.
+     * @return the density level. See {@link #setDiffusion(short)} for units.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getDensity()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[2];
+        checkStatus(getParameter(PARAM_DENSITY, param));
+        return byteArrayToShort(param);
+    }
+
+
+    /**
+     * The OnParameterChangeListener interface defines a method called by the EnvironmentalReverb
+     * when a parameter value has changed.
+     */
+    public interface OnParameterChangeListener  {
+        /**
+         * Method called when a parameter value has changed. The method is called only if the
+         * parameter was changed by another application having the control of the same
+         * EnvironmentalReverb engine.
+         * @param effect the EnvironmentalReverb on which the interface is registered.
+         * @param status status of the set parameter operation.
+         * @param param ID of the modified parameter. See {@link #PARAM_ROOM_LEVEL} ...
+         * @param value the new parameter value.
+         */
+        void onParameterChange(EnvironmentalReverb effect, int status, int param, int value);
+    }
+
+    /**
+     * Listener used internally to receive unformatted parameter change events from AudioEffect
+     * super class.
+     */
+    private class BaseParameterListener implements AudioEffect.OnParameterChangeListener {
+        private BaseParameterListener() {
+
+        }
+        public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) {
+            OnParameterChangeListener l = null;
+
+            synchronized (mParamListenerLock) {
+                if (mParamListener != null) {
+                    l = mParamListener;
+                }
+            }
+            if (l != null) {
+                int p = -1;
+                int v = -1;
+
+                if (param.length == 4) {
+                    p = byteArrayToInt(param, 0);
+                }
+                if (value.length == 2) {
+                    v = (int)byteArrayToShort(value, 0);
+                } else if (value.length == 4) {
+                    v = byteArrayToInt(value, 0);
+                }
+                if (p != -1 && v != -1) {
+                    l.onParameterChange(EnvironmentalReverb.this, status, p, v);
+                }
+            }
+        }
+    }
+
+    /**
+     * Registers an OnParameterChangeListener interface.
+     * @param listener OnParameterChangeListener interface registered
+     */
+    public void setParameterListener(OnParameterChangeListener listener) {
+        synchronized (mParamListenerLock) {
+            if (mParamListener == null) {
+                mParamListener = listener;
+                mBaseParamListener = new BaseParameterListener();
+                super.setParameterListener(mBaseParamListener);
+            }
+        }
+    }
+
+    /**
+     * The Settings class regroups all environmental reverb parameters. It is used in
+     * conjuntion with getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+    public static class Settings {
+        public short roomLevel;
+        public short roomHFLevel;
+        public int decayTime;
+        public short decayHFRatio;
+        public short reflectionsLevel;
+        public int reflectionsDelay;
+        public short reverbLevel;
+        public int reverbDelay;
+        public short diffusion;
+        public short density;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            int tokens = st.countTokens();
+            if (st.countTokens() != 21) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("EnvironmentalReverb")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for EnvironmentalReverb: " + key);
+            }
+
+            try {
+                key = st.nextToken();
+                if (!key.equals("roomLevel")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                roomLevel = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("roomHFLevel")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                roomHFLevel = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("decayTime")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                decayTime = Integer.parseInt(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("decayHFRatio")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                decayHFRatio = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("reflectionsLevel")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                reflectionsLevel = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("reflectionsDelay")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                reflectionsDelay = Integer.parseInt(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("reverbLevel")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                reverbLevel = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("reverbDelay")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                reverbDelay = Integer.parseInt(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("diffusion")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                diffusion = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("density")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                density = Short.parseShort(st.nextToken());
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return new String (
+                    "EnvironmentalReverb"+
+                    ";roomLevel="+Short.toString(roomLevel)+
+                    ";roomHFLevel="+Short.toString(roomHFLevel)+
+                    ";decayTime="+Integer.toString(decayTime)+
+                    ";decayHFRatio="+Short.toString(decayHFRatio)+
+                    ";reflectionsLevel="+Short.toString(reflectionsLevel)+
+                    ";reflectionsDelay="+Integer.toString(reflectionsDelay)+
+                    ";reverbLevel="+Short.toString(reverbLevel)+
+                    ";reverbDelay="+Integer.toString(reverbDelay)+
+                    ";diffusion="+Short.toString(diffusion)+
+                    ";density="+Short.toString(density)
+                    );
+        }
+    };
+
+    // Keep this in sync with sizeof(s_reverb_settings) defined in
+    // frameworks/base/include/media/EffectEnvironmentalReverbApi.h
+    static private int PROPERTY_SIZE = 26;
+
+    /**
+     * Gets the environmental reverb properties. This method is useful when a snapshot of current
+     * reverb settings must be saved by the application.
+     * @return an EnvironmentalReverb.Settings object containing all current parameters values
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public EnvironmentalReverb.Settings getProperties()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[PROPERTY_SIZE];
+        checkStatus(getParameter(PARAM_PROPERTIES, param));
+        Settings settings = new Settings();
+        settings.roomLevel = byteArrayToShort(param, 0);
+        settings.roomHFLevel = byteArrayToShort(param, 2);
+        settings.decayTime = byteArrayToInt(param, 4);
+        settings.decayHFRatio = byteArrayToShort(param, 8);
+        settings.reflectionsLevel = byteArrayToShort(param, 10);
+        settings.reflectionsDelay = byteArrayToInt(param, 12);
+        settings.reverbLevel = byteArrayToShort(param, 16);
+        settings.reverbDelay = byteArrayToInt(param, 18);
+        settings.diffusion = byteArrayToShort(param, 22);
+        settings.density = byteArrayToShort(param, 24);
+        return settings;
+    }
+
+    /**
+     * Sets the environmental reverb properties. This method is useful when reverb settings have to
+     * be applied from a previous backup.
+     * @param settings a EnvironmentalReverb.Settings object containing the properties to apply
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setProperties(EnvironmentalReverb.Settings settings)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+
+        byte[] param = concatArrays(shortToByteArray(settings.roomLevel),
+                                    shortToByteArray(settings.roomHFLevel),
+                                    intToByteArray(settings.decayTime),
+                                    shortToByteArray(settings.decayHFRatio),
+                                    shortToByteArray(settings.reflectionsLevel),
+                                    intToByteArray(settings.reflectionsDelay),
+                                    shortToByteArray(settings.reverbLevel),
+                                    intToByteArray(settings.reverbDelay),
+                                    shortToByteArray(settings.diffusion),
+                                    shortToByteArray(settings.density));
+
+        checkStatus(setParameter(PARAM_PROPERTIES, param));
+    }
+}
diff --git a/android/media/audiofx/Equalizer.java b/android/media/audiofx/Equalizer.java
new file mode 100644
index 0000000..7abada0
--- /dev/null
+++ b/android/media/audiofx/Equalizer.java
@@ -0,0 +1,559 @@
+/*
+ * Copyright (C) 2010 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.audiofx;
+
+import android.media.audiofx.AudioEffect;
+import android.util.Log;
+
+import java.util.StringTokenizer;
+
+
+/**
+ * An Equalizer is used to alter the frequency response of a particular music source or of the main
+ * output mix.
+ * <p>An application creates an Equalizer object to instantiate and control an Equalizer engine
+ * in the audio framework. The application can either simply use predefined presets or have a more
+ * precise control of the gain in each frequency band controlled by the equalizer.
+ * <p>The methods, parameter types and units exposed by the Equalizer implementation are directly
+ * mapping those defined by the OpenSL ES 1.0.1 Specification (http://www.khronos.org/opensles/)
+ * for the SLEqualizerItf interface. Please refer to this specification for more details.
+ * <p>To attach the Equalizer to a particular AudioTrack or MediaPlayer, specify the audio session
+ * ID of this AudioTrack or MediaPlayer when constructing the Equalizer.
+ * <p>NOTE: attaching an Equalizer to the global audio output mix by use of session 0 is deprecated.
+ * <p>See {@link android.media.MediaPlayer#getAudioSessionId()} for details on audio sessions.
+ * <p>See {@link android.media.audiofx.AudioEffect} class for more details on controlling audio
+ * effects.
+ */
+
+public class Equalizer extends AudioEffect {
+
+    private final static String TAG = "Equalizer";
+
+    // These constants must be synchronized with those in
+    // frameworks/base/include/media/EffectEqualizerApi.h
+    /**
+     * Number of bands. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_NUM_BANDS = 0;
+    /**
+     * Band level range. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_LEVEL_RANGE = 1;
+    /**
+     * Band level. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_BAND_LEVEL = 2;
+    /**
+     * Band center frequency. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_CENTER_FREQ = 3;
+    /**
+     * Band frequency range. Parameter ID for
+     * {@link android.media.audiofx.Equalizer.OnParameterChangeListener}
+     */
+    public static final int PARAM_BAND_FREQ_RANGE = 4;
+    /**
+     * Band for a given frequency. Parameter ID for OnParameterChangeListener
+     *
+     */
+    public static final int PARAM_GET_BAND = 5;
+    /**
+     * Current preset. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_CURRENT_PRESET = 6;
+    /**
+     * Request number of presets. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_GET_NUM_OF_PRESETS = 7;
+    /**
+     * Request preset name. Parameter ID for OnParameterChangeListener
+     */
+    public static final int PARAM_GET_PRESET_NAME = 8;
+    // used by setProperties()/getProperties
+    private static final int PARAM_PROPERTIES = 9;
+    /**
+     * Maximum size for preset name
+     */
+    public static final int PARAM_STRING_SIZE_MAX = 32;
+
+    /**
+     * Number of bands implemented by Equalizer engine
+     */
+    private short mNumBands = 0;
+
+    /**
+     * Number of presets implemented by Equalizer engine
+     */
+    private int mNumPresets;
+    /**
+     * Names of presets implemented by Equalizer engine
+     */
+    private String[] mPresetNames;
+
+    /**
+     * Registered listener for parameter changes.
+     */
+    private OnParameterChangeListener mParamListener = null;
+
+    /**
+     * Listener used internally to to receive raw parameter change event from AudioEffect super class
+     */
+    private BaseParameterListener mBaseParamListener = null;
+
+    /**
+     * Lock for access to mParamListener
+     */
+    private final Object mParamListenerLock = new Object();
+
+    /**
+     * Class constructor.
+     * @param priority the priority level requested by the application for controlling the Equalizer
+     * engine. As the same engine can be shared by several applications, this parameter indicates
+     * how much the requesting application needs control of effect parameters. The normal priority
+     * is 0, above normal is a positive number, below normal a negative number.
+     * @param audioSession  system wide unique audio session identifier. The Equalizer will be
+     * attached to the MediaPlayer or AudioTrack in the same audio session.
+     *
+     * @throws java.lang.IllegalStateException
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    public Equalizer(int priority, int audioSession)
+    throws IllegalStateException, IllegalArgumentException,
+           UnsupportedOperationException, RuntimeException {
+        super(EFFECT_TYPE_EQUALIZER, EFFECT_TYPE_NULL, priority, audioSession);
+
+        if (audioSession == 0) {
+            Log.w(TAG, "WARNING: attaching an Equalizer to global output mix is deprecated!");
+        }
+
+        getNumberOfBands();
+
+        mNumPresets = (int)getNumberOfPresets();
+
+        if (mNumPresets != 0) {
+            mPresetNames = new String[mNumPresets];
+            byte[] value = new byte[PARAM_STRING_SIZE_MAX];
+            int[] param = new int[2];
+            param[0] = PARAM_GET_PRESET_NAME;
+            for (int i = 0; i < mNumPresets; i++) {
+                param[1] = i;
+                checkStatus(getParameter(param, value));
+                int length = 0;
+                while (value[length] != 0) length++;
+                try {
+                    mPresetNames[i] = new String(value, 0, length, "ISO-8859-1");
+                } catch (java.io.UnsupportedEncodingException e) {
+                    Log.e(TAG, "preset name decode error");
+                }
+            }
+        }
+    }
+
+    /**
+     * Gets the number of frequency bands supported by the Equalizer engine.
+     * @return the number of bands
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getNumberOfBands()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        if (mNumBands != 0) {
+            return mNumBands;
+        }
+        int[] param = new int[1];
+        param[0] = PARAM_NUM_BANDS;
+        short[] result = new short[1];
+        checkStatus(getParameter(param, result));
+        mNumBands = result[0];
+        return mNumBands;
+    }
+
+    /**
+     * Gets the level range for use by {@link #setBandLevel(short,short)}. The level is expressed in
+     * milliBel.
+     * @return the band level range in an array of short integers. The first element is the lower
+     * limit of the range, the second element the upper limit.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short[] getBandLevelRange()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        short[] result = new short[2];
+        checkStatus(getParameter(PARAM_LEVEL_RANGE, result));
+        return result;
+    }
+
+    /**
+     * Sets the given equalizer band to the given gain value.
+     * @param band frequency band that will have the new gain. The numbering of the bands starts
+     * from 0 and ends at (number of bands - 1).
+     * @param level new gain in millibels that will be set to the given band. getBandLevelRange()
+     * will define the maximum and minimum values.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     * @see #getNumberOfBands()
+     */
+    public void setBandLevel(short band, short level)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        int[] param = new int[2];
+        short[] value = new short[1];
+
+        param[0] = PARAM_BAND_LEVEL;
+        param[1] = (int)band;
+        value[0] = level;
+        checkStatus(setParameter(param, value));
+    }
+
+    /**
+     * Gets the gain set for the given equalizer band.
+     * @param band frequency band whose gain is requested. The numbering of the bands starts
+     * from 0 and ends at (number of bands - 1).
+     * @return the gain in millibels of the given band.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getBandLevel(short band)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        int[] param = new int[2];
+        short[] result = new short[1];
+
+        param[0] = PARAM_BAND_LEVEL;
+        param[1] = (int)band;
+        checkStatus(getParameter(param, result));
+
+        return result[0];
+    }
+
+
+    /**
+     * Gets the center frequency of the given band.
+     * @param band frequency band whose center frequency is requested. The numbering of the bands
+     * starts from 0 and ends at (number of bands - 1).
+     * @return the center frequency in milliHertz
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public int getCenterFreq(short band)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        int[] param = new int[2];
+        int[] result = new int[1];
+
+        param[0] = PARAM_CENTER_FREQ;
+        param[1] = (int)band;
+        checkStatus(getParameter(param, result));
+
+        return result[0];
+    }
+
+    /**
+     * Gets the frequency range of the given frequency band.
+     * @param band frequency band whose frequency range is requested. The numbering of the bands
+     * starts from 0 and ends at (number of bands - 1).
+     * @return the frequency range in millHertz in an array of integers. The first element is the
+     * lower limit of the range, the second element the upper limit.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public int[] getBandFreqRange(short band)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        int[] param = new int[2];
+        int[] result = new int[2];
+        param[0] = PARAM_BAND_FREQ_RANGE;
+        param[1] = (int)band;
+        checkStatus(getParameter(param, result));
+
+        return result;
+    }
+
+    /**
+     * Gets the band that has the most effect on the given frequency.
+     * @param frequency frequency in milliHertz which is to be equalized via the returned band.
+     * @return the frequency band that has most effect on the given frequency.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getBand(int frequency)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        int[] param = new int[2];
+        short[] result = new short[1];
+
+        param[0] = PARAM_GET_BAND;
+        param[1] = frequency;
+        checkStatus(getParameter(param, result));
+
+        return result[0];
+    }
+
+    /**
+     * Gets current preset.
+     * @return the preset that is set at the moment.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getCurrentPreset()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        short[] result = new short[1];
+        checkStatus(getParameter(PARAM_CURRENT_PRESET, result));
+        return result[0];
+    }
+
+    /**
+     * Sets the equalizer according to the given preset.
+     * @param preset new preset that will be taken into use. The valid range is [0,
+     * number of presets-1].
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     * @see #getNumberOfPresets()
+     */
+    public void usePreset(short preset)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_CURRENT_PRESET, preset));
+    }
+
+    /**
+     * Gets the total number of presets the equalizer supports. The presets will have indices
+     * [0, number of presets-1].
+     * @return the number of presets the equalizer supports.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getNumberOfPresets()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        short[] result = new short[1];
+        checkStatus(getParameter(PARAM_GET_NUM_OF_PRESETS, result));
+        return result[0];
+    }
+
+    /**
+     * Gets the preset name based on the index.
+     * @param preset index of the preset. The valid range is [0, number of presets-1].
+     * @return a string containing the name of the given preset.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public String getPresetName(short preset)
+    {
+        if (preset >= 0 && preset < mNumPresets) {
+            return mPresetNames[preset];
+        } else {
+            return "";
+        }
+    }
+
+    /**
+     * The OnParameterChangeListener interface defines a method called by the Equalizer when a
+     * parameter value has changed.
+     */
+    public interface OnParameterChangeListener  {
+        /**
+         * Method called when a parameter value has changed. The method is called only if the
+         * parameter was changed by another application having the control of the same
+         * Equalizer engine.
+         * @param effect the Equalizer on which the interface is registered.
+         * @param status status of the set parameter operation.
+         * @param param1 ID of the modified parameter. See {@link #PARAM_BAND_LEVEL} ...
+         * @param param2 additional parameter qualifier (e.g the band for band level parameter).
+         * @param value the new parameter value.
+         */
+        void onParameterChange(Equalizer effect, int status, int param1, int param2, int value);
+    }
+
+    /**
+     * Listener used internally to receive unformatted parameter change events from AudioEffect
+     * super class.
+     */
+    private class BaseParameterListener implements AudioEffect.OnParameterChangeListener {
+        private BaseParameterListener() {
+
+        }
+        public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) {
+            OnParameterChangeListener l = null;
+
+            synchronized (mParamListenerLock) {
+                if (mParamListener != null) {
+                    l = mParamListener;
+                }
+            }
+            if (l != null) {
+                int p1 = -1;
+                int p2 = -1;
+                int v = -1;
+
+                if (param.length >= 4) {
+                    p1 = byteArrayToInt(param, 0);
+                    if (param.length >= 8) {
+                        p2 = byteArrayToInt(param, 4);
+                    }
+                }
+                if (value.length == 2) {
+                    v = (int)byteArrayToShort(value, 0);;
+                } else if (value.length == 4) {
+                    v = byteArrayToInt(value, 0);
+                }
+
+                if (p1 != -1 && v != -1) {
+                    l.onParameterChange(Equalizer.this, status, p1, p2, v);
+                }
+            }
+        }
+    }
+
+    /**
+     * Registers an OnParameterChangeListener interface.
+     * @param listener OnParameterChangeListener interface registered
+     */
+    public void setParameterListener(OnParameterChangeListener listener) {
+        synchronized (mParamListenerLock) {
+            if (mParamListener == null) {
+                mParamListener = listener;
+                mBaseParamListener = new BaseParameterListener();
+                super.setParameterListener(mBaseParamListener);
+            }
+        }
+    }
+
+    /**
+     * The Settings class regroups all equalizer parameters. It is used in
+     * conjuntion with getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+    public static class Settings {
+        public short curPreset;
+        public short numBands = 0;
+        public short[] bandLevels = null;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            int tokens = st.countTokens();
+            if (st.countTokens() < 5) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("Equalizer")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for Equalizer: " + key);
+            }
+            try {
+                key = st.nextToken();
+                if (!key.equals("curPreset")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                curPreset = Short.parseShort(st.nextToken());
+                key = st.nextToken();
+                if (!key.equals("numBands")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                numBands = Short.parseShort(st.nextToken());
+                if (st.countTokens() != numBands*2) {
+                    throw new IllegalArgumentException("settings: " + settings);
+                }
+                bandLevels = new short[numBands];
+                for (int i = 0; i < numBands; i++) {
+                    key = st.nextToken();
+                    if (!key.equals("band"+(i+1)+"Level")) {
+                        throw new IllegalArgumentException("invalid key name: " + key);
+                    }
+                    bandLevels[i] = Short.parseShort(st.nextToken());
+                }
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+
+            String str = new String (
+                    "Equalizer"+
+                    ";curPreset="+Short.toString(curPreset)+
+                    ";numBands="+Short.toString(numBands)
+                    );
+            for (int i = 0; i < numBands; i++) {
+                str = str.concat(";band"+(i+1)+"Level="+Short.toString(bandLevels[i]));
+            }
+            return str;
+        }
+    };
+
+
+    /**
+     * Gets the equalizer properties. This method is useful when a snapshot of current
+     * equalizer settings must be saved by the application.
+     * @return an Equalizer.Settings object containing all current parameters values
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public Equalizer.Settings getProperties()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        byte[] param = new byte[4 + mNumBands * 2];
+        checkStatus(getParameter(PARAM_PROPERTIES, param));
+        Settings settings = new Settings();
+        settings.curPreset = byteArrayToShort(param, 0);
+        settings.numBands = byteArrayToShort(param, 2);
+        settings.bandLevels = new short[mNumBands];
+        for (int i = 0; i < mNumBands; i++) {
+            settings.bandLevels[i] = byteArrayToShort(param, 4 + 2*i);
+        }
+        return settings;
+    }
+
+    /**
+     * Sets the equalizer properties. This method is useful when equalizer settings have to
+     * be applied from a previous backup.
+     * @param settings an Equalizer.Settings object containing the properties to apply
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setProperties(Equalizer.Settings settings)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        if (settings.numBands != settings.bandLevels.length ||
+            settings.numBands != mNumBands) {
+            throw new IllegalArgumentException("settings invalid band count: " +settings.numBands);
+        }
+
+        byte[] param = concatArrays(shortToByteArray(settings.curPreset),
+                                    shortToByteArray(mNumBands));
+        for (int i = 0; i < mNumBands; i++) {
+            param = concatArrays(param,
+                                 shortToByteArray(settings.bandLevels[i]));
+        }
+        checkStatus(setParameter(PARAM_PROPERTIES, param));
+    }
+}
diff --git a/android/media/audiofx/HapticGenerator.java b/android/media/audiofx/HapticGenerator.java
new file mode 100644
index 0000000..fe7f29e
--- /dev/null
+++ b/android/media/audiofx/HapticGenerator.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2020 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.audiofx;
+
+import android.annotation.NonNull;
+import android.media.AudioManager;
+import android.util.Log;
+
+import java.util.UUID;
+
+/**
+ * Haptic Generator(HG).
+ * <p>HG is an audio post-processor which generates haptic data based on the audio channels. The
+ * generated haptic data is sent along with audio data down to the audio HAL, which will require the
+ * device to support audio-coupled-haptic playback. In that case, the effect will only be created on
+ * device supporting audio-coupled-haptic playback. Call {@link HapticGenerator#isAvailable()} to
+ * check if the device supports this effect.
+ * <p>An application can create a HapticGenerator object to initiate and control this audio effect
+ * in the audio framework.
+ * <p>To attach the HapticGenerator to a particular AudioTrack or MediaPlayer, specify the audio
+ * session ID of this AudioTrack or MediaPlayer when constructing the HapticGenerator.
+ * <p>See {@link android.media.MediaPlayer#getAudioSessionId()} for details on audio sessions.
+ * <p>See {@link android.media.audiofx.AudioEffect} class for more details on controlling audio
+ * effects.
+ */
+public class HapticGenerator extends AudioEffect implements AutoCloseable {
+
+    private static final String TAG = "HapticGenerator";
+
+    // For every HapticGenerator, it contains a volume control effect so that the volume control
+    // will always be handled in the effect chain. In that case, the HapticGenerator can generate
+    // haptic data based on the raw audio data.
+    private AudioEffect mVolumeControlEffect;
+
+    /**
+     * @return true if the HapticGenerator is available on the device.
+     */
+    public static boolean isAvailable() {
+        return AudioManager.isHapticPlaybackSupported()
+                && AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_HAPTIC_GENERATOR);
+    }
+
+    /**
+     * Creates a HapticGenerator and attaches it to the given audio session.
+     * Use {@link android.media.AudioTrack#getAudioSessionId()} or
+     * {@link android.media.MediaPlayer#getAudioSessionId()} to
+     * apply this effect on specific AudioTrack or MediaPlayer instance.
+     *
+     * @param audioSession system wide unique audio session identifier. The HapticGenerator will be
+     *                     applied to the players with the same audio session.
+     * @return HapticGenerator created or null if the device does not support HapticGenerator or
+     *                         the audio session is invalid.
+     * @throws java.lang.IllegalArgumentException when HapticGenerator is not supported
+     * @throws java.lang.UnsupportedOperationException when the effect library is not loaded.
+     * @throws java.lang.RuntimeException for all other error
+     */
+    public static @NonNull HapticGenerator create(int audioSession) {
+        return new HapticGenerator(audioSession);
+    }
+
+    /**
+     * Class constructor.
+     *
+     * @param audioSession system wide unique audio session identifier. The HapticGenerator will be
+     *                     attached to the MediaPlayer or AudioTrack in the same audio session.
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    private HapticGenerator(int audioSession) {
+        super(EFFECT_TYPE_HAPTIC_GENERATOR, EFFECT_TYPE_NULL, 0, audioSession);
+        mVolumeControlEffect = new AudioEffect(
+                AudioEffect.EFFECT_TYPE_NULL,
+                UUID.fromString("119341a0-8469-11df-81f9-0002a5d5c51b"),
+                0,
+                audioSession);
+    }
+
+    /**
+     * Enable or disable the effect.
+     *
+     * @param enabled the requested enable state
+     * @return {@link #SUCCESS} in case of success, {@link #ERROR_INVALID_OPERATION}
+     *         or {@link #ERROR_DEAD_OBJECT} in case of failure.
+     */
+    @Override
+    public int setEnabled(boolean enabled) {
+        int ret = super.setEnabled(enabled);
+        if (ret == SUCCESS) {
+            if (mVolumeControlEffect == null
+                    || mVolumeControlEffect.setEnabled(enabled) != SUCCESS) {
+                Log.w(TAG, "Failed to enable volume control effect for HapticGenerator");
+            }
+        }
+        return ret;
+    }
+
+    /**
+     * Releases the native AudioEffect resources.
+     */
+    @Override
+    public void release() {
+        if (mVolumeControlEffect != null) {
+            mVolumeControlEffect.release();
+        }
+        super.release();
+    }
+
+    /**
+     * Release the resources that are held by the effect.
+     */
+    @Override
+    public void close() {
+        release();
+    }
+}
diff --git a/android/media/audiofx/LoudnessEnhancer.java b/android/media/audiofx/LoudnessEnhancer.java
new file mode 100644
index 0000000..7dc4175
--- /dev/null
+++ b/android/media/audiofx/LoudnessEnhancer.java
@@ -0,0 +1,290 @@
+/*
+ * Copyright (C) 2013 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.audiofx;
+
+import android.media.AudioTrack;
+import android.media.MediaPlayer;
+import android.media.audiofx.AudioEffect;
+import android.util.Log;
+
+import java.util.StringTokenizer;
+
+
+/**
+ * LoudnessEnhancer is an audio effect for increasing audio loudness.
+ * The processing is parametrized by a target gain value, which determines the maximum amount
+ * by which an audio signal will be amplified; signals amplified outside of the sample
+ * range supported by the platform are compressed.
+ * An application creates a LoudnessEnhancer object to instantiate and control a
+ * this audio effect in the audio framework.
+ * To attach the LoudnessEnhancer to a particular AudioTrack or MediaPlayer,
+ * specify the audio session ID of this AudioTrack or MediaPlayer when constructing the effect
+ * (see {@link AudioTrack#getAudioSessionId()} and {@link MediaPlayer#getAudioSessionId()}).
+ */
+
+public class LoudnessEnhancer extends AudioEffect {
+
+    private final static String TAG = "LoudnessEnhancer";
+
+    // These parameter constants must be synchronized with those in
+    // /system/media/audio_effects/include/audio_effects/effect_loudnessenhancer.h
+    /**
+     * The maximum gain applied applied to the signal to process.
+     * It is expressed in millibels (100mB = 1dB) where 0mB corresponds to no amplification.
+     */
+    public static final int PARAM_TARGET_GAIN_MB = 0;
+
+    /**
+     * Registered listener for parameter changes.
+     */
+    private OnParameterChangeListener mParamListener = null;
+
+    /**
+     * Listener used internally to to receive raw parameter change events
+     * from AudioEffect super class
+     */
+    private BaseParameterListener mBaseParamListener = null;
+
+    /**
+     * Lock for access to mParamListener
+     */
+    private final Object mParamListenerLock = new Object();
+
+    /**
+     * Class constructor.
+     * @param audioSession system-wide unique audio session identifier. The LoudnessEnhancer
+     * will be attached to the MediaPlayer or AudioTrack in the same audio session.
+     *
+     * @throws java.lang.IllegalStateException
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    public LoudnessEnhancer(int audioSession)
+            throws IllegalStateException, IllegalArgumentException,
+                UnsupportedOperationException, RuntimeException {
+        super(EFFECT_TYPE_LOUDNESS_ENHANCER, EFFECT_TYPE_NULL, 0, audioSession);
+
+        if (audioSession == 0) {
+            Log.w(TAG, "WARNING: attaching a LoudnessEnhancer to global output mix is deprecated!");
+        }
+    }
+
+    /**
+     * @hide
+     * Class constructor for the LoudnessEnhancer audio effect.
+     * @param priority the priority level requested by the application for controlling the
+     * LoudnessEnhancer engine. As the same engine can be shared by several applications,
+     * this parameter indicates how much the requesting application needs control of effect
+     * parameters. The normal priority is 0, above normal is a positive number, below normal a
+     * negative number.
+     * @param audioSession system-wide unique audio session identifier. The LoudnessEnhancer
+     * will be attached to the MediaPlayer or AudioTrack in the same audio session.
+     *
+     * @throws java.lang.IllegalStateException
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    public LoudnessEnhancer(int priority, int audioSession)
+            throws IllegalStateException, IllegalArgumentException,
+                UnsupportedOperationException, RuntimeException {
+        super(EFFECT_TYPE_LOUDNESS_ENHANCER, EFFECT_TYPE_NULL, priority, audioSession);
+
+        if (audioSession == 0) {
+            Log.w(TAG, "WARNING: attaching a LoudnessEnhancer to global output mix is deprecated!");
+        }
+    }
+
+    /**
+     * Set the target gain for the audio effect.
+     * The target gain is the maximum value by which a sample value will be amplified when the
+     * effect is enabled.
+     * @param gainmB the effect target gain expressed in mB. 0mB corresponds to no amplification.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setTargetGain(int gainmB)
+            throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_TARGET_GAIN_MB, gainmB));
+    }
+
+    /**
+     * Return the target gain.
+     * @return the effect target gain expressed in mB.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public float getTargetGain()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        int[] value = new int[1];
+        checkStatus(getParameter(PARAM_TARGET_GAIN_MB, value));
+        return value[0];
+    }
+
+    /**
+     * @hide
+     * The OnParameterChangeListener interface defines a method called by the LoudnessEnhancer
+     * when a parameter value has changed.
+     */
+    public interface OnParameterChangeListener  {
+        /**
+         * Method called when a parameter value has changed. The method is called only if the
+         * parameter was changed by another application having the control of the same
+         * LoudnessEnhancer engine.
+         * @param effect the LoudnessEnhancer on which the interface is registered.
+         * @param param ID of the modified parameter. See {@link #PARAM_GENERIC_PARAM1} ...
+         * @param value the new parameter value.
+         */
+        void onParameterChange(LoudnessEnhancer effect, int param, int value);
+    }
+
+    /**
+     * Listener used internally to receive unformatted parameter change events from AudioEffect
+     * super class.
+     */
+    private class BaseParameterListener implements AudioEffect.OnParameterChangeListener {
+        private BaseParameterListener() {
+
+        }
+        public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) {
+            // only notify when the parameter was successfully change
+            if (status != AudioEffect.SUCCESS) {
+                return;
+            }
+            OnParameterChangeListener l = null;
+            synchronized (mParamListenerLock) {
+                if (mParamListener != null) {
+                    l = mParamListener;
+                }
+            }
+            if (l != null) {
+                int p = -1;
+                int v = Integer.MIN_VALUE;
+
+                if (param.length == 4) {
+                    p = byteArrayToInt(param, 0);
+                }
+                if (value.length == 4) {
+                    v = byteArrayToInt(value, 0);
+                }
+                if (p != -1 && v != Integer.MIN_VALUE) {
+                    l.onParameterChange(LoudnessEnhancer.this, p, v);
+                }
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Registers an OnParameterChangeListener interface.
+     * @param listener OnParameterChangeListener interface registered
+     */
+    public void setParameterListener(OnParameterChangeListener listener) {
+        synchronized (mParamListenerLock) {
+            if (mParamListener == null) {
+                mBaseParamListener = new BaseParameterListener();
+                super.setParameterListener(mBaseParamListener);
+            }
+            mParamListener = listener;
+        }
+    }
+
+    /**
+     * @hide
+     * The Settings class regroups the LoudnessEnhancer parameters. It is used in
+     * conjunction with the getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+    public static class Settings {
+        public int targetGainmB;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            //int tokens = st.countTokens();
+            if (st.countTokens() != 3) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("LoudnessEnhancer")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for LoudnessEnhancer: " + key);
+            }
+            try {
+                key = st.nextToken();
+                if (!key.equals("targetGainmB")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                targetGainmB = Integer.parseInt(st.nextToken());
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+            String str = new String (
+                    "LoudnessEnhancer"+
+                    ";targetGainmB="+Integer.toString(targetGainmB)
+                    );
+            return str;
+        }
+    };
+
+
+    /**
+     * @hide
+     * Gets the LoudnessEnhancer properties. This method is useful when a snapshot of current
+     * effect settings must be saved by the application.
+     * @return a LoudnessEnhancer.Settings object containing all current parameters values
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public LoudnessEnhancer.Settings getProperties()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        Settings settings = new Settings();
+        int[] value = new int[1];
+        checkStatus(getParameter(PARAM_TARGET_GAIN_MB, value));
+        settings.targetGainmB = value[0];
+        return settings;
+    }
+
+    /**
+     * @hide
+     * Sets the LoudnessEnhancer properties. This method is useful when bass boost settings
+     * have to be applied from a previous backup.
+     * @param settings a LoudnessEnhancer.Settings object containing the properties to apply
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setProperties(LoudnessEnhancer.Settings settings)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_TARGET_GAIN_MB, settings.targetGainmB));
+    }
+}
diff --git a/android/media/audiofx/NoiseSuppressor.java b/android/media/audiofx/NoiseSuppressor.java
new file mode 100644
index 0000000..70cc87c
--- /dev/null
+++ b/android/media/audiofx/NoiseSuppressor.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2011 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.audiofx;
+
+import android.util.Log;
+
+/**
+ * Noise Suppressor (NS).
+ * <p>Noise suppression (NS) is an audio pre-processor which removes background noise from the
+ * captured signal. The component of the signal considered as noise can be either stationary
+ * (car/airplane engine, AC system) or non-stationary (other peoples conversations, car horn) for
+ * more advanced implementations.
+ * <p>NS is mostly used by voice communication applications (voice chat, video conferencing,
+ * SIP calls).
+ * <p>An application creates a NoiseSuppressor object to instantiate and control an NS
+ * engine in the audio framework.
+ * <p>To attach the NoiseSuppressor to a particular {@link android.media.AudioRecord},
+ * specify the audio session ID of this AudioRecord when creating the NoiseSuppressor.
+ * The audio session is retrieved by calling
+ * {@link android.media.AudioRecord#getAudioSessionId()} on the AudioRecord instance.
+ * <p>On some devices, NS can be inserted by default in the capture path by the platform
+ * according to the {@link android.media.MediaRecorder.AudioSource} used. The application should
+ * call NoiseSuppressor.getEnable() after creating the NS to check the default NS activation
+ * state on a particular AudioRecord session.
+ * <p>See {@link android.media.audiofx.AudioEffect} class for more details on
+ * controlling audio effects.
+ */
+
+public class NoiseSuppressor extends AudioEffect {
+
+    private final static String TAG = "NoiseSuppressor";
+
+    /**
+     * Checks if the device implements noise suppression.
+     * @return true if the device implements noise suppression, false otherwise.
+     */
+    public static boolean isAvailable() {
+        return AudioEffect.isEffectTypeAvailable(AudioEffect.EFFECT_TYPE_NS);
+    }
+
+    /**
+     * Creates a NoiseSuppressor and attaches it to the AudioRecord on the audio
+     * session specified.
+     * @param audioSession system wide unique audio session identifier. The NoiseSuppressor
+     * will be applied to the AudioRecord with the same audio session.
+     * @return NoiseSuppressor created or null if the device does not implement noise
+     * suppression.
+     */
+    public static NoiseSuppressor create(int audioSession) {
+        NoiseSuppressor ns = null;
+        try {
+            ns = new NoiseSuppressor(audioSession);
+        } catch (IllegalArgumentException e) {
+            Log.w(TAG, "not implemented on this device "+ns);
+        } catch (UnsupportedOperationException e) {
+            Log.w(TAG, "not enough resources");
+        } catch (RuntimeException e) {
+            Log.w(TAG, "not enough memory");
+        }
+        return ns;
+    }
+
+    /**
+     * Class constructor.
+     * <p> The constructor is not guarantied to succeed and throws the following exceptions:
+     * <ul>
+     *  <li>IllegalArgumentException is thrown if the device does not implement an NS</li>
+     *  <li>UnsupportedOperationException is thrown is the resources allocated to audio
+     *  pre-procesing are currently exceeded.</li>
+     *  <li>RuntimeException is thrown if a memory allocation error occurs.</li>
+     * </ul>
+     *
+     * @param audioSession system wide unique audio session identifier. The NoiseSuppressor
+     * will be applied to the AudioRecord with the same audio session.
+     *
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    private NoiseSuppressor(int audioSession)
+            throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
+        super(EFFECT_TYPE_NS, EFFECT_TYPE_NULL, 0, audioSession);
+    }
+}
diff --git a/android/media/audiofx/PresetReverb.java b/android/media/audiofx/PresetReverb.java
new file mode 100644
index 0000000..ef91667
--- /dev/null
+++ b/android/media/audiofx/PresetReverb.java
@@ -0,0 +1,303 @@
+/*
+ * Copyright (C) 2010 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.audiofx;
+
+import android.media.audiofx.AudioEffect;
+import java.util.StringTokenizer;
+
+
+/**
+ * A sound generated within a room travels in many directions. The listener first hears the
+ * direct sound from the source itself. Later, he or she hears discrete echoes caused by sound
+ * bouncing off nearby walls, the ceiling and the floor. As sound waves arrive after
+ * undergoing more and more reflections, individual reflections become indistinguishable and
+ * the listener hears continuous reverberation that decays over time.
+ * Reverb is vital for modeling a listener's environment. It can be used in music applications
+ * to simulate music being played back in various environments, or in games to immerse the
+ * listener within the game's environment.
+ * The PresetReverb class allows an application to configure the global reverb using a reverb preset.
+ * This is primarily used for adding some reverb in a music playback context. Applications
+ * requiring control over a more advanced environmental reverb are advised to use the
+ * {@link android.media.audiofx.EnvironmentalReverb} class.
+ * <p>An application creates a PresetReverb object to instantiate and control a reverb engine in the
+ * audio framework.
+ * <p>The methods, parameter types and units exposed by the PresetReverb implementation are
+ * directly mapping those defined by the OpenSL ES 1.0.1 Specification
+ * (http://www.khronos.org/opensles/) for the SLPresetReverbItf interface.
+ * Please refer to this specification for more details.
+ * <p>The PresetReverb is an output mix auxiliary effect and should be created on
+ * Audio session 0. In order for a MediaPlayer or AudioTrack to be fed into this effect,
+ * they must be explicitely attached to it and a send level must be specified. Use the effect ID
+ * returned by getId() method to designate this particular effect when attaching it to the
+ * MediaPlayer or AudioTrack.
+ * <p>Creating a reverb on the output mix (audio session 0) requires permission
+ * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}
+ * <p>See {@link android.media.audiofx.AudioEffect} class for more details on controlling
+ * audio effects.
+ */
+
+public class PresetReverb extends AudioEffect {
+
+    private final static String TAG = "PresetReverb";
+
+    // These constants must be synchronized with those in
+    // frameworks/base/include/media/EffectPresetReverbApi.h
+
+    /**
+     * Preset. Parameter ID for
+     * {@link android.media.audiofx.PresetReverb.OnParameterChangeListener}
+     */
+    public static final int PARAM_PRESET = 0;
+
+    /**
+     * No reverb or reflections
+     */
+    public static final short PRESET_NONE        = 0;
+    /**
+     * Reverb preset representing a small room less than five meters in length
+     */
+    public static final short PRESET_SMALLROOM   = 1;
+    /**
+     * Reverb preset representing a medium room with a length of ten meters or less
+     */
+    public static final short PRESET_MEDIUMROOM  = 2;
+    /**
+     * Reverb preset representing a large-sized room suitable for live performances
+     */
+    public static final short PRESET_LARGEROOM   = 3;
+    /**
+     * Reverb preset representing a medium-sized hall
+     */
+    public static final short PRESET_MEDIUMHALL  = 4;
+    /**
+     * Reverb preset representing a large-sized hall suitable for a full orchestra
+     */
+    public static final short PRESET_LARGEHALL   = 5;
+    /**
+     * Reverb preset representing a synthesis of the traditional plate reverb
+     */
+    public static final short PRESET_PLATE       = 6;
+
+    /**
+     * Registered listener for parameter changes.
+     */
+    private OnParameterChangeListener mParamListener = null;
+
+    /**
+     * Listener used internally to to receive raw parameter change event from AudioEffect super class
+     */
+    private BaseParameterListener mBaseParamListener = null;
+
+    /**
+     * Lock for access to mParamListener
+     */
+    private final Object mParamListenerLock = new Object();
+
+    /**
+     * Class constructor.
+     * @param priority the priority level requested by the application for controlling the
+     * PresetReverb engine. As the same engine can be shared by several applications, this
+     * parameter indicates how much the requesting application needs control of effect parameters.
+     * The normal priority is 0, above normal is a positive number, below normal a negative number.
+     * @param audioSession  system wide unique audio session identifier. If audioSession
+     *  is not 0, the PresetReverb will be attached to the MediaPlayer or AudioTrack in the
+     *  same audio session. Otherwise, the PresetReverb will apply to the output mix.
+     *  As the PresetReverb is an auxiliary effect it is recommended to instantiate it on
+     *  audio session 0 and to attach it to the MediaPLayer auxiliary output.
+     *
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    public PresetReverb(int priority, int audioSession)
+    throws IllegalArgumentException, UnsupportedOperationException, RuntimeException {
+        super(EFFECT_TYPE_PRESET_REVERB, EFFECT_TYPE_NULL, priority, audioSession);
+    }
+
+    /**
+     *  Enables a preset on the reverb.
+     *  <p>The reverb PRESET_NONE disables any reverb from the current output but does not free the
+     *  resources associated with the reverb. For an application to signal to the implementation
+     *  to free the resources, it must call the release() method.
+     * @param preset this must be one of the the preset constants defined in this class.
+     * e.g. {@link #PRESET_SMALLROOM}
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setPreset(short preset)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_PRESET, preset));
+    }
+
+    /**
+     * Gets current reverb preset.
+     * @return the preset that is set at the moment.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getPreset()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        short[] value = new short[1];
+        checkStatus(getParameter(PARAM_PRESET, value));
+        return value[0];
+    }
+
+    /**
+     * The OnParameterChangeListener interface defines a method called by the PresetReverb
+     * when a parameter value has changed.
+     */
+    public interface OnParameterChangeListener  {
+        /**
+         * Method called when a parameter value has changed. The method is called only if the
+         * parameter was changed by another application having the control of the same
+         * PresetReverb engine.
+         * @param effect the PresetReverb on which the interface is registered.
+         * @param status status of the set parameter operation.
+         * @param param ID of the modified parameter. See {@link #PARAM_PRESET} ...
+         * @param value the new parameter value.
+         */
+        void onParameterChange(PresetReverb effect, int status, int param, short value);
+    }
+
+    /**
+     * Listener used internally to receive unformatted parameter change events from AudioEffect
+     * super class.
+     */
+    private class BaseParameterListener implements AudioEffect.OnParameterChangeListener {
+        private BaseParameterListener() {
+
+        }
+        public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) {
+            OnParameterChangeListener l = null;
+
+            synchronized (mParamListenerLock) {
+                if (mParamListener != null) {
+                    l = mParamListener;
+                }
+            }
+            if (l != null) {
+                int p = -1;
+                short v = -1;
+
+                if (param.length == 4) {
+                    p = byteArrayToInt(param, 0);
+                }
+                if (value.length == 2) {
+                    v = byteArrayToShort(value, 0);
+                }
+                if (p != -1 && v != -1) {
+                    l.onParameterChange(PresetReverb.this, status, p, v);
+                }
+            }
+        }
+    }
+
+    /**
+     * Registers an OnParameterChangeListener interface.
+     * @param listener OnParameterChangeListener interface registered
+     */
+    public void setParameterListener(OnParameterChangeListener listener) {
+        synchronized (mParamListenerLock) {
+            if (mParamListener == null) {
+                mParamListener = listener;
+                mBaseParamListener = new BaseParameterListener();
+                super.setParameterListener(mBaseParamListener);
+            }
+        }
+    }
+
+    /**
+     * The Settings class regroups all preset reverb parameters. It is used in
+     * conjuntion with getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+    public static class Settings {
+        public short preset;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            int tokens = st.countTokens();
+            if (st.countTokens() != 3) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("PresetReverb")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for PresetReverb: " + key);
+            }
+            try {
+                key = st.nextToken();
+                if (!key.equals("preset")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                preset = Short.parseShort(st.nextToken());
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+            String str = new String (
+                    "PresetReverb"+
+                    ";preset="+Short.toString(preset)
+                    );
+            return str;
+        }
+    };
+
+
+    /**
+     * Gets the preset reverb properties. This method is useful when a snapshot of current
+     * preset reverb settings must be saved by the application.
+     * @return a PresetReverb.Settings object containing all current parameters values
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public PresetReverb.Settings getProperties()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        Settings settings = new Settings();
+        short[] value = new short[1];
+        checkStatus(getParameter(PARAM_PRESET, value));
+        settings.preset = value[0];
+        return settings;
+    }
+
+    /**
+     * Sets the preset reverb properties. This method is useful when preset reverb settings have to
+     * be applied from a previous backup.
+     * @param settings a PresetReverb.Settings object containing the properties to apply
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setProperties(PresetReverb.Settings settings)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_PRESET, settings.preset));
+    }
+}
diff --git a/android/media/audiofx/SourceDefaultEffect.java b/android/media/audiofx/SourceDefaultEffect.java
new file mode 100644
index 0000000..d7a292e
--- /dev/null
+++ b/android/media/audiofx/SourceDefaultEffect.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 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.audiofx;
+
+import android.annotation.RequiresPermission;
+import android.app.ActivityThread;
+import android.util.Log;
+import java.util.UUID;
+
+/**
+ * SourceDefaultEffect is a default effect that attaches automatically to all AudioRecord and
+ * MediaRecorder instances of a given source type.
+ * <p>see {@link android.media.audiofx.DefaultEffect} class for more details on default effects.
+ * @hide
+ */
+
+public class SourceDefaultEffect extends DefaultEffect {
+    static {
+        System.loadLibrary("audioeffect_jni");
+    }
+
+    private final static String TAG = "SourceDefaultEffect-JAVA";
+
+    /**
+     * Class constructor.
+     *
+     * @param type type of effect engine to be default. This parameter is ignored if uuid is set,
+     *             and can be set to {@link android.media.audiofx.AudioEffect#EFFECT_TYPE_NULL}
+     *             in that case.
+     * @param uuid unique identifier of a particular effect implementation to be default. This
+     *             parameter can be set to
+     *             {@link android.media.audiofx.AudioEffect#EFFECT_TYPE_NULL}, in which case only
+     *             the type will be used to select the effect.
+     * @param priority the priority level requested by the application for controlling the effect
+     *             engine. As the same engine can be shared by several applications, this parameter
+     *             indicates how much the requesting application needs control of effect parameters.
+     *             The normal priority is 0, above normal is a positive number, below normal a
+     *             negative number.
+     * @param source a MediaRecorder.AudioSource.* constant from
+     *             {@link android.media.MediaRecorder.AudioSource} indicating
+     *             what sources the given effect should attach to by default. Note that similar
+     *             sources may share defaults.
+     *
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    @RequiresPermission(value = android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS,
+                        conditional = true)  // Android Things uses an alternate permission.
+    public SourceDefaultEffect(UUID type, UUID uuid, int priority, int source) {
+        int[] id = new int[1];
+        int initResult = native_setup(type.toString(),
+                                      uuid.toString(),
+                                      priority,
+                                      source,
+                                      ActivityThread.currentOpPackageName(),
+                                      id);
+        if (initResult != AudioEffect.SUCCESS) {
+            Log.e(TAG, "Error code " + initResult + " when initializing SourceDefaultEffect");
+            switch (initResult) {
+                case AudioEffect.ERROR_BAD_VALUE:
+                    throw (new IllegalArgumentException(
+                            "Source, type uuid, or implementation uuid not supported."));
+                case AudioEffect.ERROR_INVALID_OPERATION:
+                    throw (new UnsupportedOperationException(
+                            "Effect library not loaded"));
+                default:
+                    throw (new RuntimeException(
+                            "Cannot initialize effect engine for type: " + type
+                            + " Error: " + initResult));
+            }
+        }
+
+        mId = id[0];
+    }
+
+
+    /**
+     * Releases the native SourceDefaultEffect resources. It is a good practice to
+     * release the default effect when done with use as control can be returned to
+     * other applications or the native resources released.
+     */
+    public void release() {
+        native_release(mId);
+    }
+
+    @Override
+    protected void finalize() {
+        release();
+    }
+
+    // ---------------------------------------------------------
+    // Native methods called from the Java side
+    // --------------------
+
+    private native final int native_setup(String type,
+                                          String uuid,
+                                          int priority,
+                                          int source,
+                                          String opPackageName,
+                                          int[] id);
+
+    private native final void native_release(int id);
+}
diff --git a/android/media/audiofx/StreamDefaultEffect.java b/android/media/audiofx/StreamDefaultEffect.java
new file mode 100644
index 0000000..9b1a21a
--- /dev/null
+++ b/android/media/audiofx/StreamDefaultEffect.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 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.audiofx;
+
+import android.annotation.RequiresPermission;
+import android.app.ActivityThread;
+import android.util.Log;
+import java.util.UUID;
+
+/**
+ * StreamDefaultEffect is a default effect that attaches automatically to all AudioTracks and
+ * MediaPlayer instances of a given stream type.
+ * <p>see {@link android.media.audiofx.DefaultEffect} class for more details on default effects.
+ * @hide
+ */
+
+public class StreamDefaultEffect extends DefaultEffect {
+    static {
+        System.loadLibrary("audioeffect_jni");
+    }
+
+    private final static String TAG = "StreamDefaultEffect-JAVA";
+
+    /**
+     * Class constructor.
+     *
+     * @param type type of effect engine to be default. This parameter is ignored if uuid is set,
+     *             and can be set to {@link android.media.audiofx.AudioEffect#EFFECT_TYPE_NULL}
+     *             in that case.
+     * @param uuid unique identifier of a particular effect implementation to be default. This
+     *             parameter can be set to
+     *             {@link android.media.audiofx.AudioEffect#EFFECT_TYPE_NULL}, in which case only
+     *             the type will be used to select the effect.
+     * @param priority the priority level requested by the application for controlling the effect
+     *             engine. As the same engine can be shared by several applications, this parameter
+     *             indicates how much the requesting application needs control of effect parameters.
+     *             The normal priority is 0, above normal is a positive number, below normal a
+     *             negative number.
+     * @param streamUsage a USAGE_* constant from {@link android.media.AudioAttributes} indicating
+     *             what streams the given effect should attach to by default. Note that similar
+     *             usages may share defaults.
+     *
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    @RequiresPermission(value = android.Manifest.permission.MODIFY_DEFAULT_AUDIO_EFFECTS,
+                        conditional = true)  // Android Things uses an alternate permission.
+    public StreamDefaultEffect(UUID type, UUID uuid, int priority, int streamUsage) {
+        int[] id = new int[1];
+        int initResult = native_setup(type.toString(),
+                                      uuid.toString(),
+                                      priority,
+                                      streamUsage,
+                                      ActivityThread.currentOpPackageName(),
+                                      id);
+        if (initResult != AudioEffect.SUCCESS) {
+            Log.e(TAG, "Error code " + initResult + " when initializing StreamDefaultEffect");
+            switch (initResult) {
+                case AudioEffect.ERROR_BAD_VALUE:
+                    throw (new IllegalArgumentException(
+                            "Stream usage, type uuid, or implementation uuid not supported."));
+                case AudioEffect.ERROR_INVALID_OPERATION:
+                    throw (new UnsupportedOperationException(
+                            "Effect library not loaded"));
+                default:
+                    throw (new RuntimeException(
+                            "Cannot initialize effect engine for type: " + type
+                            + " Error: " + initResult));
+            }
+        }
+
+        mId = id[0];
+    }
+
+
+    /**
+     * Releases the native StreamDefaultEffect resources. It is a good practice to
+     * release the default effect when done with use as control can be returned to
+     * other applications or the native resources released.
+     */
+    public void release() {
+        native_release(mId);
+    }
+
+    @Override
+    protected void finalize() {
+        release();
+    }
+
+    // ---------------------------------------------------------
+    // Native methods called from the Java side
+    // --------------------
+
+    private native final int native_setup(String type,
+                                          String uuid,
+                                          int priority,
+                                          int streamUsage,
+                                          String opPackageName,
+                                          int[] id);
+
+    private native final void native_release(int id);
+}
diff --git a/android/media/audiofx/Virtualizer.java b/android/media/audiofx/Virtualizer.java
new file mode 100644
index 0000000..74b6fc1
--- /dev/null
+++ b/android/media/audiofx/Virtualizer.java
@@ -0,0 +1,629 @@
+/*
+ * Copyright (C) 2010 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.audiofx;
+
+import android.annotation.IntDef;
+import android.media.AudioDeviceInfo;
+import android.media.AudioFormat;
+import android.media.audiofx.AudioEffect;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.StringTokenizer;
+
+
+/**
+ * An audio virtualizer is a general name for an effect to spatialize audio channels. The exact
+ * behavior of this effect is dependent on the number of audio input channels and the types and
+ * number of audio output channels of the device. For example, in the case of a stereo input and
+ * stereo headphone output, a stereo widening effect is used when this effect is turned on.
+ * <p>An application creates a Virtualizer object to instantiate and control a virtualizer engine
+ * in the audio framework.
+ * <p>The methods, parameter types and units exposed by the Virtualizer implementation are directly
+ * mapping those defined by the OpenSL ES 1.0.1 Specification (http://www.khronos.org/opensles/)
+ * for the SLVirtualizerItf interface. Please refer to this specification for more details.
+ * <p>To attach the Virtualizer to a particular AudioTrack or MediaPlayer, specify the audio session
+ * ID of this AudioTrack or MediaPlayer when constructing the Virtualizer.
+ * <p>NOTE: attaching a Virtualizer to the global audio output mix by use of session 0 is
+ * deprecated.
+ * <p>See {@link android.media.MediaPlayer#getAudioSessionId()} for details on audio sessions.
+ * <p>See {@link android.media.audiofx.AudioEffect} class for more details on controlling
+ * audio effects.
+ */
+
+public class Virtualizer extends AudioEffect {
+
+    private final static String TAG = "Virtualizer";
+    private final static boolean DEBUG = false;
+
+    // These constants must be synchronized with those in
+    //        system/media/audio_effects/include/audio_effects/effect_virtualizer.h
+    /**
+     * Is strength parameter supported by virtualizer engine. Parameter ID for getParameter().
+     */
+    public static final int PARAM_STRENGTH_SUPPORTED = 0;
+    /**
+     * Virtualizer effect strength. Parameter ID for
+     * {@link android.media.audiofx.Virtualizer.OnParameterChangeListener}
+     */
+    public static final int PARAM_STRENGTH = 1;
+    /**
+     * @hide
+     * Parameter ID to query the virtual speaker angles for a channel mask / device configuration.
+     */
+    public static final int PARAM_VIRTUAL_SPEAKER_ANGLES = 2;
+    /**
+     * @hide
+     * Parameter ID to force the virtualization mode to be that of a specific device
+     */
+    public static final int PARAM_FORCE_VIRTUALIZATION_MODE = 3;
+    /**
+     * @hide
+     * Parameter ID to query the current virtualization mode.
+     */
+    public static final int PARAM_VIRTUALIZATION_MODE = 4;
+
+    /**
+     * Indicates if strength parameter is supported by the virtualizer engine
+     */
+    private boolean mStrengthSupported = false;
+
+    /**
+     * Registered listener for parameter changes.
+     */
+    private OnParameterChangeListener mParamListener = null;
+
+    /**
+     * Listener used internally to to receive raw parameter change event from AudioEffect super class
+     */
+    private BaseParameterListener mBaseParamListener = null;
+
+    /**
+     * Lock for access to mParamListener
+     */
+    private final Object mParamListenerLock = new Object();
+
+    /**
+     * Class constructor.
+     * @param priority the priority level requested by the application for controlling the Virtualizer
+     * engine. As the same engine can be shared by several applications, this parameter indicates
+     * how much the requesting application needs control of effect parameters. The normal priority
+     * is 0, above normal is a positive number, below normal a negative number.
+     * @param audioSession  system wide unique audio session identifier. The Virtualizer will
+     * be attached to the MediaPlayer or AudioTrack in the same audio session.
+     *
+     * @throws java.lang.IllegalStateException
+     * @throws java.lang.IllegalArgumentException
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+    public Virtualizer(int priority, int audioSession)
+    throws IllegalStateException, IllegalArgumentException,
+           UnsupportedOperationException, RuntimeException {
+        super(EFFECT_TYPE_VIRTUALIZER, EFFECT_TYPE_NULL, priority, audioSession);
+
+        if (audioSession == 0) {
+            Log.w(TAG, "WARNING: attaching a Virtualizer to global output mix is deprecated!");
+        }
+
+        int[] value = new int[1];
+        checkStatus(getParameter(PARAM_STRENGTH_SUPPORTED, value));
+        mStrengthSupported = (value[0] != 0);
+    }
+
+    /**
+     * Indicates whether setting strength is supported. If this method returns false, only one
+     * strength is supported and the setStrength() method always rounds to that value.
+     * @return true is strength parameter is supported, false otherwise
+     */
+    public boolean getStrengthSupported() {
+       return mStrengthSupported;
+    }
+
+    /**
+     * Sets the strength of the virtualizer effect. If the implementation does not support per mille
+     * accuracy for setting the strength, it is allowed to round the given strength to the nearest
+     * supported value. You can use the {@link #getRoundedStrength()} method to query the
+     * (possibly rounded) value that was actually set.
+     * @param strength strength of the effect. The valid range for strength strength is [0, 1000],
+     * where 0 per mille designates the mildest effect and 1000 per mille designates the strongest.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setStrength(short strength)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_STRENGTH, strength));
+    }
+
+    /**
+     * Gets the current strength of the effect.
+     * @return the strength of the effect. The valid range for strength is [0, 1000], where 0 per
+     * mille designates the mildest effect and 1000 per mille the strongest
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public short getRoundedStrength()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        short[] value = new short[1];
+        checkStatus(getParameter(PARAM_STRENGTH, value));
+        return value[0];
+    }
+
+    /**
+     * Checks if a configuration is supported, and query the virtual speaker angles.
+     * @param inputChannelMask
+     * @param deviceType
+     * @param angles if non-null: array in which the angles will be written. If null, no angles
+     *    are returned
+     * @return true if the combination of channel mask and output device type is supported, false
+     *    otherwise
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    private boolean getAnglesInt(int inputChannelMask, int deviceType, int[] angles)
+            throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        // parameter check
+        if (inputChannelMask == AudioFormat.CHANNEL_INVALID) {
+            throw (new IllegalArgumentException(
+                    "Virtualizer: illegal CHANNEL_INVALID channel mask"));
+        }
+        int channelMask = inputChannelMask == AudioFormat.CHANNEL_OUT_DEFAULT ?
+                AudioFormat.CHANNEL_OUT_STEREO : inputChannelMask;
+        int nbChannels = AudioFormat.channelCountFromOutChannelMask(channelMask);
+        if ((angles != null) && (angles.length < (nbChannels * 3))) {
+            Log.e(TAG, "Size of array for angles cannot accomodate number of channels in mask ("
+                    + nbChannels + ")");
+            throw (new IllegalArgumentException(
+                    "Virtualizer: array for channel / angle pairs is too small: is " + angles.length
+                    + ", should be " + (nbChannels * 3)));
+        }
+
+        ByteBuffer paramsConverter = ByteBuffer.allocate(3 /* param + mask + device*/ * 4);
+        paramsConverter.order(ByteOrder.nativeOrder());
+        paramsConverter.putInt(PARAM_VIRTUAL_SPEAKER_ANGLES);
+        // convert channel mask to internal native representation
+        paramsConverter.putInt(AudioFormat.convertChannelOutMaskToNativeMask(channelMask));
+        // convert Java device type to internal representation
+        paramsConverter.putInt(AudioDeviceInfo.convertDeviceTypeToInternalDevice(deviceType));
+        // allocate an array to store the results
+        byte[] result = new byte[nbChannels * 4/*int to byte*/ * 3/*for mask, azimuth, elevation*/];
+
+        // call into the effect framework
+        int status = getParameter(paramsConverter.array(), result);
+        if (DEBUG) {
+            Log.v(TAG, "getAngles(0x" + Integer.toHexString(inputChannelMask) + ", 0x"
+                    + Integer.toHexString(deviceType) + ") returns " + status);
+        }
+
+        if (status >= 0) {
+            if (angles != null) {
+                // convert and copy the results
+                ByteBuffer resultConverter = ByteBuffer.wrap(result);
+                resultConverter.order(ByteOrder.nativeOrder());
+                for (int i = 0 ; i < nbChannels ; i++) {
+                    // write the channel mask
+                    angles[3 * i] = AudioFormat.convertNativeChannelMaskToOutMask(
+                            resultConverter.getInt((i * 4 * 3)));
+                    // write the azimuth
+                    angles[3 * i + 1] = resultConverter.getInt(i * 4 * 3 + 4);
+                    // write the elevation
+                    angles[3 * i + 2] = resultConverter.getInt(i * 4 * 3 + 8);
+                    if (DEBUG) {
+                        Log.v(TAG, "channel 0x" + Integer.toHexString(angles[3*i]).toUpperCase()
+                                + " at az=" + angles[3*i+1] + "deg"
+                                + " elev="  + angles[3*i+2] + "deg");
+                    }
+                }
+            }
+            return true;
+        } else if (status == AudioEffect.ERROR_BAD_VALUE) {
+            // a BAD_VALUE return from getParameter indicates the configuration is not supported
+            // don't throw an exception, just return false
+            return false;
+        } else {
+            // something wrong may have happened
+            checkStatus(status);
+        }
+        // unexpected virtualizer behavior
+        Log.e(TAG, "unexpected status code " + status
+                + " after getParameter(PARAM_VIRTUAL_SPEAKER_ANGLES)");
+        return false;
+    }
+
+    /**
+     * A virtualization mode indicating virtualization processing is not active.
+     * See {@link #getVirtualizationMode()} as one of the possible return value.
+     */
+    public static final int VIRTUALIZATION_MODE_OFF = 0;
+
+    /**
+     * A virtualization mode used to indicate the virtualizer effect must stop forcing the
+     * processing to a particular mode in {@link #forceVirtualizationMode(int)}.
+     */
+    public static final int VIRTUALIZATION_MODE_AUTO = 1;
+    /**
+     * A virtualization mode typically used over headphones.
+     * Binaural virtualization describes an audio processing configuration for virtualization
+     * where the left and right channels are respectively reaching the left and right ear of the
+     * user, without also feeding the opposite ear (as is the case when listening over speakers).
+     * <p>Such a mode is therefore meant to be used when audio is playing over stereo wired
+     * headphones or headsets, but also stereo headphones through a wireless A2DP Bluetooth link.
+     * <p>See {@link #canVirtualize(int, int)} to verify this mode is supported by this Virtualizer.
+     */
+    public final static int VIRTUALIZATION_MODE_BINAURAL = 2;
+
+    /**
+     * A virtualization mode typically used over speakers.
+     * Transaural virtualization describes an audio processing configuration that differs from
+     * binaural (as described in {@link #VIRTUALIZATION_MODE_BINAURAL} in that cross-talk is
+     * present, i.e. audio played from the left channel also reaches the right ear of the user,
+     * and vice-versa.
+     * <p>When supported, such a mode is therefore meant to be used when audio is playing over the
+     * built-in stereo speakers of a device, if they are featured.
+     * <p>See {@link #canVirtualize(int, int)} to verify this mode is supported by this Virtualizer.
+     */
+    public final static int VIRTUALIZATION_MODE_TRANSAURAL = 3;
+
+    /** @hide */
+    @IntDef( {
+        VIRTUALIZATION_MODE_BINAURAL,
+        VIRTUALIZATION_MODE_TRANSAURAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface VirtualizationMode {}
+
+    /** @hide */
+    @IntDef( {
+        VIRTUALIZATION_MODE_AUTO,
+        VIRTUALIZATION_MODE_BINAURAL,
+        VIRTUALIZATION_MODE_TRANSAURAL
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ForceVirtualizationMode {}
+
+    private static int getDeviceForModeQuery(@VirtualizationMode int virtualizationMode)
+            throws IllegalArgumentException {
+        switch (virtualizationMode) {
+            case VIRTUALIZATION_MODE_BINAURAL:
+                return AudioDeviceInfo.TYPE_WIRED_HEADPHONES;
+            case VIRTUALIZATION_MODE_TRANSAURAL:
+                return AudioDeviceInfo.TYPE_BUILTIN_SPEAKER;
+            default:
+                throw (new IllegalArgumentException(
+                        "Virtualizer: illegal virtualization mode " + virtualizationMode));
+        }
+    }
+
+    private static int getDeviceForModeForce(@ForceVirtualizationMode int virtualizationMode)
+            throws IllegalArgumentException {
+        if (virtualizationMode == VIRTUALIZATION_MODE_AUTO) {
+            return AudioDeviceInfo.TYPE_UNKNOWN;
+        } else {
+            return getDeviceForModeQuery(virtualizationMode);
+        }
+    }
+
+    private static int deviceToMode(int deviceType) {
+        switch (deviceType) {
+            case AudioDeviceInfo.TYPE_WIRED_HEADSET:
+            case AudioDeviceInfo.TYPE_WIRED_HEADPHONES:
+            case AudioDeviceInfo.TYPE_BLUETOOTH_SCO:
+            case AudioDeviceInfo.TYPE_BUILTIN_EARPIECE:
+            case AudioDeviceInfo.TYPE_USB_HEADSET:
+                return VIRTUALIZATION_MODE_BINAURAL;
+            case AudioDeviceInfo.TYPE_BUILTIN_SPEAKER:
+            case AudioDeviceInfo.TYPE_LINE_ANALOG:
+            case AudioDeviceInfo.TYPE_LINE_DIGITAL:
+            case AudioDeviceInfo.TYPE_BLUETOOTH_A2DP:
+            case AudioDeviceInfo.TYPE_HDMI:
+            case AudioDeviceInfo.TYPE_HDMI_ARC:
+            case AudioDeviceInfo.TYPE_USB_DEVICE:
+            case AudioDeviceInfo.TYPE_USB_ACCESSORY:
+            case AudioDeviceInfo.TYPE_DOCK:
+            case AudioDeviceInfo.TYPE_FM:
+            case AudioDeviceInfo.TYPE_AUX_LINE:
+                return VIRTUALIZATION_MODE_TRANSAURAL;
+            case AudioDeviceInfo.TYPE_UNKNOWN:
+            default:
+                return VIRTUALIZATION_MODE_OFF;
+        }
+    }
+
+    /**
+     * Checks if the combination of a channel mask and virtualization mode is supported by this
+     * virtualizer.
+     * Some virtualizer implementations may only support binaural processing (i.e. only support
+     * headphone output, see {@link #VIRTUALIZATION_MODE_BINAURAL}), some may support transaural
+     * processing (i.e. for speaker output, see {@link #VIRTUALIZATION_MODE_TRANSAURAL}) for the
+     * built-in speakers. Use this method to query the virtualizer implementation capabilities.
+     * @param inputChannelMask the channel mask of the content to virtualize.
+     * @param virtualizationMode the mode for which virtualization processing is to be performed,
+     *    one of {@link #VIRTUALIZATION_MODE_BINAURAL}, {@link #VIRTUALIZATION_MODE_TRANSAURAL}.
+     * @return true if the combination of channel mask and virtualization mode is supported, false
+     *    otherwise.
+     *    <br>An indication that a certain channel mask is not supported doesn't necessarily mean
+     *    you cannot play content with that channel mask, it more likely implies the content will
+     *    be downmixed before being virtualized. For instance a virtualizer that only supports a
+     *    mask such as {@link AudioFormat#CHANNEL_OUT_STEREO}
+     *    will still be able to process content with a mask of
+     *    {@link AudioFormat#CHANNEL_OUT_5POINT1}, but will downmix the content to stereo first, and
+     *    then will virtualize, as opposed to virtualizing each channel individually.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public boolean canVirtualize(int inputChannelMask, @VirtualizationMode int virtualizationMode)
+            throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        return getAnglesInt(inputChannelMask, getDeviceForModeQuery(virtualizationMode), null);
+    }
+
+    /**
+     * Queries the virtual speaker angles (azimuth and elevation) for a combination of a channel
+     * mask and virtualization mode.
+     * If the virtualization configuration (mask and mode) is supported (see
+     * {@link #canVirtualize(int, int)}, the array angles will contain upon return the
+     * definition of each virtual speaker and its azimuth and elevation angles relative to the
+     * listener.
+     * <br>Note that in some virtualizer implementations, the angles may be strength-dependent.
+     * @param inputChannelMask the channel mask of the content to virtualize.
+     * @param virtualizationMode the mode for which virtualization processing is to be performed,
+     *    one of {@link #VIRTUALIZATION_MODE_BINAURAL}, {@link #VIRTUALIZATION_MODE_TRANSAURAL}.
+     * @param angles a non-null array whose length is 3 times the number of channels in the channel
+     *    mask.
+     *    If the method indicates the configuration is supported, the array will contain upon return
+     *    triplets of values: for each channel <code>i</code> among the channels of the mask:
+     *    <ul>
+     *      <li>the element at index <code>3*i</code> in the array contains the speaker
+     *          identification (e.g. {@link AudioFormat#CHANNEL_OUT_FRONT_LEFT}),</li>
+     *      <li>the element at index <code>3*i+1</code> contains its corresponding azimuth angle
+     *          expressed in degrees, where 0 is the direction the listener faces, 180 is behind
+     *          the listener, and -90 is to her/his left,</li>
+     *      <li>the element at index <code>3*i+2</code> contains its corresponding elevation angle
+     *          where +90 is directly above the listener, 0 is the horizontal plane, and -90 is
+     *          directly below the listener.</li>
+     * @return true if the combination of channel mask and virtualization mode is supported, false
+     *    otherwise.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public boolean getSpeakerAngles(int inputChannelMask,
+            @VirtualizationMode int virtualizationMode, int[] angles)
+            throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        if (angles == null) {
+            throw (new IllegalArgumentException(
+                    "Virtualizer: illegal null channel / angle array"));
+        }
+
+        return getAnglesInt(inputChannelMask, getDeviceForModeQuery(virtualizationMode), angles);
+    }
+
+    /**
+     * Forces the virtualizer effect to use the given processing mode.
+     * The effect must be enabled for the forced mode to be applied.
+     * @param virtualizationMode one of {@link #VIRTUALIZATION_MODE_BINAURAL},
+     *     {@link #VIRTUALIZATION_MODE_TRANSAURAL} to force a particular processing mode, or
+     *     {@value #VIRTUALIZATION_MODE_AUTO} to stop forcing a mode.
+     * @return true if the processing mode is supported, and it is successfully set, or
+     *     forcing was successfully disabled, false otherwise.
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public boolean forceVirtualizationMode(@ForceVirtualizationMode int virtualizationMode)
+            throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        // convert Java device type to internal representation
+        int deviceType = getDeviceForModeForce(virtualizationMode);
+        int internalDevice = AudioDeviceInfo.convertDeviceTypeToInternalDevice(deviceType);
+
+        int status = setParameter(PARAM_FORCE_VIRTUALIZATION_MODE, internalDevice);
+
+        if (status >= 0) {
+            return true;
+        } else if (status == AudioEffect.ERROR_BAD_VALUE) {
+            // a BAD_VALUE return from setParameter indicates the mode can't be forced
+            // don't throw an exception, just return false
+            return false;
+        } else {
+            // something wrong may have happened
+            checkStatus(status);
+        }
+        // unexpected virtualizer behavior
+        Log.e(TAG, "unexpected status code " + status
+                + " after setParameter(PARAM_FORCE_VIRTUALIZATION_MODE)");
+        return false;
+    }
+
+    /**
+     * Return the virtualization mode being used, if any.
+     * @return the virtualization mode being used.
+     *     If virtualization is not active, the virtualization mode will be
+     *     {@link #VIRTUALIZATION_MODE_OFF}. Otherwise the value will be
+     *     {@link #VIRTUALIZATION_MODE_BINAURAL} or {@link #VIRTUALIZATION_MODE_TRANSAURAL}.
+     *     Virtualization may not be active either because the effect is not enabled or
+     *     because the current output device is not compatible with this virtualization
+     *     implementation.
+     * @throws IllegalStateException
+     * @throws UnsupportedOperationException
+     */
+    public int getVirtualizationMode()
+            throws IllegalStateException, UnsupportedOperationException {
+        int[] value = new int[1];
+        int status = getParameter(PARAM_VIRTUALIZATION_MODE, value);
+        if (status >= 0) {
+            return deviceToMode(AudioDeviceInfo.convertInternalDeviceToDeviceType(value[0]));
+        } else if (status == AudioEffect.ERROR_BAD_VALUE) {
+            return VIRTUALIZATION_MODE_OFF;
+        } else {
+            // something wrong may have happened
+            checkStatus(status);
+        }
+        // unexpected virtualizer behavior
+        Log.e(TAG, "unexpected status code " + status
+                + " after getParameter(PARAM_VIRTUALIZATION_MODE)");
+        return VIRTUALIZATION_MODE_OFF;
+    }
+
+    /**
+     * The OnParameterChangeListener interface defines a method called by the Virtualizer when a
+     * parameter value has changed.
+     */
+    public interface OnParameterChangeListener  {
+        /**
+         * Method called when a parameter value has changed. The method is called only if the
+         * parameter was changed by another application having the control of the same
+         * Virtualizer engine.
+         * @param effect the Virtualizer on which the interface is registered.
+         * @param status status of the set parameter operation.
+         * @param param ID of the modified parameter. See {@link #PARAM_STRENGTH} ...
+         * @param value the new parameter value.
+         */
+        void onParameterChange(Virtualizer effect, int status, int param, short value);
+    }
+
+    /**
+     * Listener used internally to receive unformatted parameter change events from AudioEffect
+     * super class.
+     */
+    private class BaseParameterListener implements AudioEffect.OnParameterChangeListener {
+        private BaseParameterListener() {
+
+        }
+        public void onParameterChange(AudioEffect effect, int status, byte[] param, byte[] value) {
+            OnParameterChangeListener l = null;
+
+            synchronized (mParamListenerLock) {
+                if (mParamListener != null) {
+                    l = mParamListener;
+                }
+            }
+            if (l != null) {
+                int p = -1;
+                short v = -1;
+
+                if (param.length == 4) {
+                    p = byteArrayToInt(param, 0);
+                }
+                if (value.length == 2) {
+                    v = byteArrayToShort(value, 0);
+                }
+                if (p != -1 && v != -1) {
+                    l.onParameterChange(Virtualizer.this, status, p, v);
+                }
+            }
+        }
+    }
+
+    /**
+     * Registers an OnParameterChangeListener interface.
+     * @param listener OnParameterChangeListener interface registered
+     */
+    public void setParameterListener(OnParameterChangeListener listener) {
+        synchronized (mParamListenerLock) {
+            if (mParamListener == null) {
+                mParamListener = listener;
+                mBaseParamListener = new BaseParameterListener();
+                super.setParameterListener(mBaseParamListener);
+            }
+        }
+    }
+
+    /**
+     * The Settings class regroups all virtualizer parameters. It is used in
+     * conjuntion with getProperties() and setProperties() methods to backup and restore
+     * all parameters in a single call.
+     */
+    public static class Settings {
+        public short strength;
+
+        public Settings() {
+        }
+
+        /**
+         * Settings class constructor from a key=value; pairs formatted string. The string is
+         * typically returned by Settings.toString() method.
+         * @throws IllegalArgumentException if the string is not correctly formatted.
+         */
+        public Settings(String settings) {
+            StringTokenizer st = new StringTokenizer(settings, "=;");
+            int tokens = st.countTokens();
+            if (st.countTokens() != 3) {
+                throw new IllegalArgumentException("settings: " + settings);
+            }
+            String key = st.nextToken();
+            if (!key.equals("Virtualizer")) {
+                throw new IllegalArgumentException(
+                        "invalid settings for Virtualizer: " + key);
+            }
+            try {
+                key = st.nextToken();
+                if (!key.equals("strength")) {
+                    throw new IllegalArgumentException("invalid key name: " + key);
+                }
+                strength = Short.parseShort(st.nextToken());
+             } catch (NumberFormatException nfe) {
+                throw new IllegalArgumentException("invalid value for key: " + key);
+            }
+        }
+
+        @Override
+        public String toString() {
+            String str = new String (
+                    "Virtualizer"+
+                    ";strength="+Short.toString(strength)
+                    );
+            return str;
+        }
+    };
+
+
+    /**
+     * Gets the virtualizer properties. This method is useful when a snapshot of current
+     * virtualizer settings must be saved by the application.
+     * @return a Virtualizer.Settings object containing all current parameters values
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public Virtualizer.Settings getProperties()
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        Settings settings = new Settings();
+        short[] value = new short[1];
+        checkStatus(getParameter(PARAM_STRENGTH, value));
+        settings.strength = value[0];
+        return settings;
+    }
+
+    /**
+     * Sets the virtualizer properties. This method is useful when virtualizer settings have to
+     * be applied from a previous backup.
+     * @param settings a Virtualizer.Settings object containing the properties to apply
+     * @throws IllegalStateException
+     * @throws IllegalArgumentException
+     * @throws UnsupportedOperationException
+     */
+    public void setProperties(Virtualizer.Settings settings)
+    throws IllegalStateException, IllegalArgumentException, UnsupportedOperationException {
+        checkStatus(setParameter(PARAM_STRENGTH, settings.strength));
+    }
+}
diff --git a/android/media/audiofx/Visualizer.java b/android/media/audiofx/Visualizer.java
new file mode 100644
index 0000000..3349277
--- /dev/null
+++ b/android/media/audiofx/Visualizer.java
@@ -0,0 +1,793 @@
+/*
+ * Copyright (C) 2010 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.audiofx;
+
+import android.annotation.NonNull;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.AttributionSource;
+import android.content.AttributionSource.ScopedParcelState;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Parcel;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.lang.ref.WeakReference;
+
+/**
+ * The Visualizer class enables application to retrieve part of the currently playing audio for
+ * visualization purpose. It is not an audio recording interface and only returns partial and low
+ * quality audio content. However, to protect privacy of certain audio data (e.g voice mail) the use
+ * of the visualizer requires the permission android.permission.RECORD_AUDIO.
+ * <p>The audio session ID passed to the constructor indicates which audio content should be
+ * visualized:<br>
+ * <ul>
+ *   <li>If the session is 0, the audio output mix is visualized</li>
+ *   <li>If the session is not 0, the audio from a particular {@link android.media.MediaPlayer} or
+ *   {@link android.media.AudioTrack}
+ *   using this audio session is visualized </li>
+ * </ul>
+ * <p>Two types of representation of audio content can be captured: <br>
+ * <ul>
+ *   <li>Waveform data: consecutive 8-bit (unsigned) mono samples by using the
+ *   {@link #getWaveForm(byte[])} method</li>
+ *   <li>Frequency data: 8-bit magnitude FFT by using the {@link #getFft(byte[])} method</li>
+ * </ul>
+ * <p>The length of the capture can be retrieved or specified by calling respectively
+ * {@link #getCaptureSize()} and {@link #setCaptureSize(int)} methods. The capture size must be a
+ * power of 2 in the range returned by {@link #getCaptureSizeRange()}.
+ * <p>In addition to the polling capture mode described above with {@link #getWaveForm(byte[])} and
+ *  {@link #getFft(byte[])} methods, a callback mode is also available by installing a listener by
+ *  use of the {@link #setDataCaptureListener(OnDataCaptureListener, int, boolean, boolean)} method.
+ *  The rate at which the listener capture method is called as well as the type of data returned is
+ *  specified.
+ * <p>Before capturing data, the Visualizer must be enabled by calling the
+ * {@link #setEnabled(boolean)} method.
+ * When data capture is not needed any more, the Visualizer should be disabled.
+ * <p>It is good practice to call the {@link #release()} method when the Visualizer is not used
+ * anymore to free up native resources associated to the Visualizer instance.
+ * <p>Creating a Visualizer on the output mix (audio session 0) requires permission
+ * {@link android.Manifest.permission#MODIFY_AUDIO_SETTINGS}
+ * <p>The Visualizer class can also be used to perform measurements on the audio being played back.
+ * The measurements to perform are defined by setting a mask of the requested measurement modes with
+ * {@link #setMeasurementMode(int)}. Supported values are {@link #MEASUREMENT_MODE_NONE} to cancel
+ * any measurement, and {@link #MEASUREMENT_MODE_PEAK_RMS} for peak and RMS monitoring.
+ * Measurements can be retrieved through {@link #getMeasurementPeakRms(MeasurementPeakRms)}.
+ */
+
+public class Visualizer {
+
+    static {
+        System.loadLibrary("audioeffect_jni");
+        native_init();
+    }
+
+    private final static String TAG = "Visualizer-JAVA";
+
+    /**
+     * State of a Visualizer object that was not successfully initialized upon creation
+     */
+    public static final int STATE_UNINITIALIZED = 0;
+    /**
+     * State of a Visualizer object that is ready to be used.
+     */
+    public static final int STATE_INITIALIZED   = 1;
+    /**
+     * State of a Visualizer object that is active.
+     */
+    public static final int STATE_ENABLED   = 2;
+
+    // to keep in sync with system/media/audio_effects/include/audio_effects/effect_visualizer.h
+    /**
+     * Defines a capture mode where amplification is applied based on the content of the captured
+     * data. This is the default Visualizer mode, and is suitable for music visualization.
+     */
+    public static final int SCALING_MODE_NORMALIZED = 0;
+    /**
+     * Defines a capture mode where the playback volume will affect (scale) the range of the
+     * captured data. A low playback volume will lead to low sample and fft values, and vice-versa.
+     */
+    public static final int SCALING_MODE_AS_PLAYED = 1;
+
+    /**
+     * Defines a measurement mode in which no measurements are performed.
+     */
+    public static final int MEASUREMENT_MODE_NONE = 0;
+
+    /**
+     * Defines a measurement mode which computes the peak and RMS value in mB, where 0mB is the
+     * maximum sample value, and -9600mB is the minimum value.
+     * Values for peak and RMS can be retrieved with
+     * {@link #getMeasurementPeakRms(MeasurementPeakRms)}.
+     */
+    public static final int MEASUREMENT_MODE_PEAK_RMS = 1 << 0;
+
+    // to keep in sync with frameworks/base/media/jni/audioeffect/android_media_Visualizer.cpp
+    private static final int NATIVE_EVENT_PCM_CAPTURE = 0;
+    private static final int NATIVE_EVENT_FFT_CAPTURE = 1;
+    private static final int NATIVE_EVENT_SERVER_DIED = 2;
+
+    // Error codes:
+    /**
+     * Successful operation.
+     */
+    public  static final int SUCCESS              = 0;
+    /**
+     * Unspecified error.
+     */
+    public  static final int ERROR                = -1;
+    /**
+     * Internal operation status. Not returned by any method.
+     */
+    public  static final int ALREADY_EXISTS       = -2;
+    /**
+     * Operation failed due to bad object initialization.
+     */
+    public  static final int ERROR_NO_INIT              = -3;
+    /**
+     * Operation failed due to bad parameter value.
+     */
+    public  static final int ERROR_BAD_VALUE            = -4;
+    /**
+     * Operation failed because it was requested in wrong state.
+     */
+    public  static final int ERROR_INVALID_OPERATION    = -5;
+    /**
+     * Operation failed due to lack of memory.
+     */
+    public  static final int ERROR_NO_MEMORY            = -6;
+    /**
+     * Operation failed due to dead remote object.
+     */
+    public  static final int ERROR_DEAD_OBJECT          = -7;
+
+    //--------------------------------------------------------------------------
+    // Member variables
+    //--------------------
+    /**
+     * Indicates the state of the Visualizer instance
+     */
+    @GuardedBy("mStateLock")
+    private int mState = STATE_UNINITIALIZED;
+    /**
+     * Lock to synchronize access to mState
+     */
+    private final Object mStateLock = new Object();
+    /**
+     * System wide unique Identifier of the visualizer engine used by this Visualizer instance
+     */
+    @GuardedBy("mStateLock")
+    @UnsupportedAppUsage
+    private int mId;
+
+    /**
+     * Lock to protect listeners updates against event notifications
+     */
+    private final Object mListenerLock = new Object();
+    /**
+     * Handler for events coming from the native code
+     */
+    @GuardedBy("mListenerLock")
+    private Handler mNativeEventHandler = null;
+    /**
+     *  PCM and FFT capture listener registered by client
+     */
+    @GuardedBy("mListenerLock")
+    private OnDataCaptureListener mCaptureListener = null;
+    /**
+     *  Server Died listener registered by client
+     */
+    @GuardedBy("mListenerLock")
+    private OnServerDiedListener mServerDiedListener = null;
+
+    // accessed by native methods
+    private long mNativeVisualizer;  // guarded by a static lock in native code
+    private long mJniData;  // set in native_setup, _release;
+                            // get in native_release, _setEnabled, _setPeriodicCapture
+                            // thus, effectively guarded by mStateLock
+
+    //--------------------------------------------------------------------------
+    // Constructor, Finalize
+    //--------------------
+    /**
+     * Class constructor.
+     * @param audioSession system wide unique audio session identifier. If audioSession
+     *  is not 0, the visualizer will be attached to the MediaPlayer or AudioTrack in the
+     *  same audio session. Otherwise, the Visualizer will apply to the output mix.
+     *
+     * @throws java.lang.UnsupportedOperationException
+     * @throws java.lang.RuntimeException
+     */
+
+    public Visualizer(int audioSession)
+    throws UnsupportedOperationException, RuntimeException {
+        int[] id = new int[1];
+
+        synchronized (mStateLock) {
+            mState = STATE_UNINITIALIZED;
+
+            // native initialization
+            // TODO b/182469354: make consistent with AudioRecord
+            int result;
+            try (ScopedParcelState attributionSourceState = AttributionSource.myAttributionSource()
+                    .asScopedParcelState()) {
+                result = native_setup(new WeakReference<>(this), audioSession, id,
+                        attributionSourceState.getParcel());
+            }
+            if (result != SUCCESS && result != ALREADY_EXISTS) {
+                Log.e(TAG, "Error code "+result+" when initializing Visualizer.");
+                switch (result) {
+                case ERROR_INVALID_OPERATION:
+                    throw (new UnsupportedOperationException("Effect library not loaded"));
+                default:
+                    throw (new RuntimeException("Cannot initialize Visualizer engine, error: "
+                            +result));
+                }
+            }
+            mId = id[0];
+            if (native_getEnabled()) {
+                mState = STATE_ENABLED;
+            } else {
+                mState = STATE_INITIALIZED;
+            }
+        }
+    }
+
+    /**
+     * Releases the native Visualizer resources. It is a good practice to release the
+     * visualization engine when not in use.
+     */
+    public void release() {
+        synchronized (mStateLock) {
+            native_release();
+            mState = STATE_UNINITIALIZED;
+        }
+    }
+
+    @Override
+    protected void finalize() {
+        synchronized (mStateLock) {
+            native_finalize();
+        }
+    }
+
+    /**
+     * Enable or disable the visualization engine.
+     * @param enabled requested enable state
+     * @return {@link #SUCCESS} in case of success,
+     * {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT} in case of failure.
+     * @throws IllegalStateException
+     */
+    public int setEnabled(boolean enabled)
+    throws IllegalStateException {
+        synchronized (mStateLock) {
+            if (mState == STATE_UNINITIALIZED) {
+                throw(new IllegalStateException("setEnabled() called in wrong state: "+mState));
+            }
+            int status = SUCCESS;
+            if ((enabled && (mState == STATE_INITIALIZED)) ||
+                    (!enabled && (mState == STATE_ENABLED))) {
+                status = native_setEnabled(enabled);
+                if (status == SUCCESS) {
+                    mState = enabled ? STATE_ENABLED : STATE_INITIALIZED;
+                }
+            }
+            return status;
+        }
+    }
+
+    /**
+     * Get current activation state of the visualizer.
+     * @return true if the visualizer is active, false otherwise
+     */
+    public boolean getEnabled()
+    {
+        synchronized (mStateLock) {
+            if (mState == STATE_UNINITIALIZED) {
+                throw(new IllegalStateException("getEnabled() called in wrong state: "+mState));
+            }
+            return native_getEnabled();
+        }
+    }
+
+    /**
+     * Returns the capture size range.
+     * @return the mininum capture size is returned in first array element and the maximum in second
+     * array element.
+     */
+    public static native int[] getCaptureSizeRange();
+
+    /**
+     * Returns the maximum capture rate for the callback capture method. This is the maximum value
+     * for the rate parameter of the
+     * {@link #setDataCaptureListener(OnDataCaptureListener, int, boolean, boolean)} method.
+     * @return the maximum capture rate expressed in milliHertz
+     */
+    public static native int getMaxCaptureRate();
+
+    /**
+     * Sets the capture size, i.e. the number of bytes returned by {@link #getWaveForm(byte[])} and
+     * {@link #getFft(byte[])} methods. The capture size must be a power of 2 in the range returned
+     * by {@link #getCaptureSizeRange()}.
+     * This method must not be called when the Visualizer is enabled.
+     * @param size requested capture size
+     * @return {@link #SUCCESS} in case of success,
+     * {@link #ERROR_BAD_VALUE} in case of failure.
+     * @throws IllegalStateException
+     */
+    public int setCaptureSize(int size)
+    throws IllegalStateException {
+        synchronized (mStateLock) {
+            if (mState != STATE_INITIALIZED) {
+                throw(new IllegalStateException("setCaptureSize() called in wrong state: "+mState));
+            }
+            return native_setCaptureSize(size);
+        }
+    }
+
+    /**
+     * Returns current capture size.
+     * @return the capture size in bytes.
+     */
+    public int getCaptureSize()
+    throws IllegalStateException {
+        synchronized (mStateLock) {
+            if (mState == STATE_UNINITIALIZED) {
+                throw(new IllegalStateException("getCaptureSize() called in wrong state: "+mState));
+            }
+            return native_getCaptureSize();
+        }
+    }
+
+    /**
+     * Set the type of scaling applied on the captured visualization data.
+     * @param mode see {@link #SCALING_MODE_NORMALIZED}
+     *     and {@link #SCALING_MODE_AS_PLAYED}
+     * @return {@link #SUCCESS} in case of success,
+     *     {@link #ERROR_BAD_VALUE} in case of failure.
+     * @throws IllegalStateException
+     */
+    public int setScalingMode(int mode)
+    throws IllegalStateException {
+        synchronized (mStateLock) {
+            if (mState == STATE_UNINITIALIZED) {
+                throw(new IllegalStateException("setScalingMode() called in wrong state: "
+                        + mState));
+            }
+            return native_setScalingMode(mode);
+        }
+    }
+
+    /**
+     * Returns the current scaling mode on the captured visualization data.
+     * @return the scaling mode, see {@link #SCALING_MODE_NORMALIZED}
+     *     and {@link #SCALING_MODE_AS_PLAYED}.
+     * @throws IllegalStateException
+     */
+    public int getScalingMode()
+    throws IllegalStateException {
+        synchronized (mStateLock) {
+            if (mState == STATE_UNINITIALIZED) {
+                throw(new IllegalStateException("getScalingMode() called in wrong state: "
+                        + mState));
+            }
+            return native_getScalingMode();
+        }
+    }
+
+    /**
+     * Sets the combination of measurement modes to be performed by this audio effect.
+     * @param mode a mask of the measurements to perform. The valid values are
+     *     {@link #MEASUREMENT_MODE_NONE} (to cancel any measurement)
+     *     or {@link #MEASUREMENT_MODE_PEAK_RMS}.
+     * @return {@link #SUCCESS} in case of success, {@link #ERROR_BAD_VALUE} in case of failure.
+     * @throws IllegalStateException
+     */
+    public int setMeasurementMode(int mode)
+            throws IllegalStateException {
+        synchronized (mStateLock) {
+            if (mState == STATE_UNINITIALIZED) {
+                throw(new IllegalStateException("setMeasurementMode() called in wrong state: "
+                        + mState));
+            }
+            return native_setMeasurementMode(mode);
+        }
+    }
+
+    /**
+     * Returns the current measurement modes performed by this audio effect
+     * @return the mask of the measurements,
+     *     {@link #MEASUREMENT_MODE_NONE} (when no measurements are performed)
+     *     or {@link #MEASUREMENT_MODE_PEAK_RMS}.
+     * @throws IllegalStateException
+     */
+    public int getMeasurementMode()
+            throws IllegalStateException {
+        synchronized (mStateLock) {
+            if (mState == STATE_UNINITIALIZED) {
+                throw(new IllegalStateException("getMeasurementMode() called in wrong state: "
+                        + mState));
+            }
+            return native_getMeasurementMode();
+        }
+    }
+
+    /**
+     * Returns the sampling rate of the captured audio.
+     * @return the sampling rate in milliHertz.
+     */
+    public int getSamplingRate()
+    throws IllegalStateException {
+        synchronized (mStateLock) {
+            if (mState == STATE_UNINITIALIZED) {
+                throw(new IllegalStateException("getSamplingRate() called in wrong state: "+mState));
+            }
+            return native_getSamplingRate();
+        }
+    }
+
+    /**
+     * Returns a waveform capture of currently playing audio content. The capture consists in
+     * a number of consecutive 8-bit (unsigned) mono PCM samples equal to the capture size returned
+     * by {@link #getCaptureSize()}.
+     * <p>This method must be called when the Visualizer is enabled.
+     * @param waveform array of bytes where the waveform should be returned
+     * @return {@link #SUCCESS} in case of success,
+     * {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT}
+     * in case of failure.
+     * @throws IllegalStateException
+     */
+    public int getWaveForm(byte[] waveform)
+    throws IllegalStateException {
+        synchronized (mStateLock) {
+            if (mState != STATE_ENABLED) {
+                throw(new IllegalStateException("getWaveForm() called in wrong state: "+mState));
+            }
+            return native_getWaveForm(waveform);
+        }
+    }
+    /**
+     * Returns a frequency capture of currently playing audio content.
+     * <p>This method must be called when the Visualizer is enabled.
+     * <p>The capture is an 8-bit magnitude FFT, the frequency range covered being 0 (DC) to half of
+     * the sampling rate returned by {@link #getSamplingRate()}. The capture returns the real and
+     * imaginary parts of a number of frequency points equal to half of the capture size plus one.
+     * <p>Note: only the real part is returned for the first point (DC) and the last point
+     * (sampling frequency / 2).
+     * <p>The layout in the returned byte array is as follows:
+     * <ul>
+     *   <li> n is the capture size returned by getCaptureSize()</li>
+     *   <li> Rfk, Ifk are respectively  the real and imaginary parts of the kth frequency
+     *   component</li>
+     *   <li> If Fs is the sampling frequency retuned by getSamplingRate() the kth frequency is:
+     *   k * Fs / n </li>
+     * </ul>
+     * <table border="0" cellspacing="0" cellpadding="0">
+     * <tr><td>Index </p></td>
+     *     <td>0 </p></td>
+     *     <td>1 </p></td>
+     *     <td>2 </p></td>
+     *     <td>3 </p></td>
+     *     <td>4 </p></td>
+     *     <td>5 </p></td>
+     *     <td>... </p></td>
+     *     <td>n - 2 </p></td>
+     *     <td>n - 1 </p></td></tr>
+     * <tr><td>Data </p></td>
+     *     <td>Rf0 </p></td>
+     *     <td>Rf(n/2) </p></td>
+     *     <td>Rf1 </p></td>
+     *     <td>If1 </p></td>
+     *     <td>Rf2 </p></td>
+     *     <td>If2 </p></td>
+     *     <td>... </p></td>
+     *     <td>Rf(n/2-1) </p></td>
+     *     <td>If(n/2-1) </p></td></tr>
+     * </table>
+     * <p>In order to obtain magnitude and phase values the following code can
+     * be used:
+     *    <pre class="prettyprint">
+     *       int n = fft.size();
+     *       float[] magnitudes = new float[n / 2 + 1];
+     *       float[] phases = new float[n / 2 + 1];
+     *       magnitudes[0] = (float)Math.abs(fft[0]);      // DC
+     *       magnitudes[n / 2] = (float)Math.abs(fft[1]);  // Nyquist
+     *       phases[0] = phases[n / 2] = 0;
+     *       for (int k = 1; k &lt; n / 2; k++) {
+     *           int i = k * 2;
+     *           magnitudes[k] = (float)Math.hypot(fft[i], fft[i + 1]);
+     *           phases[k] = (float)Math.atan2(fft[i + 1], fft[i]);
+     *       }</pre>
+     * @param fft array of bytes where the FFT should be returned
+     * @return {@link #SUCCESS} in case of success,
+     * {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT}
+     * in case of failure.
+     * @throws IllegalStateException
+     */
+    public int getFft(byte[] fft)
+    throws IllegalStateException {
+        synchronized (mStateLock) {
+            if (mState != STATE_ENABLED) {
+                throw(new IllegalStateException("getFft() called in wrong state: "+mState));
+            }
+            return native_getFft(fft);
+        }
+    }
+
+    /**
+     * A class to store peak and RMS values.
+     * Peak and RMS are expressed in mB, as described in the
+     * {@link Visualizer#MEASUREMENT_MODE_PEAK_RMS} measurement mode.
+     */
+    public static final class MeasurementPeakRms {
+        /**
+         * The peak value in mB.
+         */
+        public int mPeak;
+        /**
+         * The RMS value in mB.
+         */
+        public int mRms;
+    }
+
+    /**
+     * Retrieves the latest peak and RMS measurement.
+     * Sets the peak and RMS fields of the supplied {@link Visualizer.MeasurementPeakRms} to the
+     * latest measured values.
+     * @param measurement a non-null {@link Visualizer.MeasurementPeakRms} instance to store
+     *    the measurement values.
+     * @return {@link #SUCCESS} in case of success, {@link #ERROR_BAD_VALUE},
+     *    {@link #ERROR_NO_MEMORY}, {@link #ERROR_INVALID_OPERATION} or {@link #ERROR_DEAD_OBJECT}
+     *    in case of failure.
+     */
+    public int getMeasurementPeakRms(MeasurementPeakRms measurement) {
+        if (measurement == null) {
+            Log.e(TAG, "Cannot store measurements in a null object");
+            return ERROR_BAD_VALUE;
+        }
+        synchronized (mStateLock) {
+            if (mState != STATE_ENABLED) {
+                throw (new IllegalStateException("getMeasurementPeakRms() called in wrong state: "
+                        + mState));
+            }
+            return native_getPeakRms(measurement);
+        }
+    }
+
+    //---------------------------------------------------------
+    // Interface definitions
+    //--------------------
+    /**
+     * The OnDataCaptureListener interface defines methods called by the Visualizer to periodically
+     * update the audio visualization capture.
+     * The client application can implement this interface and register the listener with the
+     * {@link #setDataCaptureListener(OnDataCaptureListener, int, boolean, boolean)} method.
+     */
+    public interface OnDataCaptureListener  {
+        /**
+         * Method called when a new waveform capture is available.
+         * <p>Data in the waveform buffer is valid only within the scope of the callback.
+         * Applications which need access to the waveform data after returning from the callback
+         * should make a copy of the data instead of holding a reference.
+         * @param visualizer Visualizer object on which the listener is registered.
+         * @param waveform array of bytes containing the waveform representation.
+         * @param samplingRate sampling rate of the visualized audio.
+         */
+        void onWaveFormDataCapture(Visualizer visualizer, byte[] waveform, int samplingRate);
+
+        /**
+         * Method called when a new frequency capture is available.
+         * <p>Data in the fft buffer is valid only within the scope of the callback.
+         * Applications which need access to the fft data after returning from the callback
+         * should make a copy of the data instead of holding a reference.
+         * <p>For the explanation of the fft data array layout, and the example
+         * code for processing it, please see the documentation for {@link #getFft(byte[])} method.
+         *
+         * @param visualizer Visualizer object on which the listener is registered.
+         * @param fft array of bytes containing the frequency representation.
+         * @param samplingRate sampling rate of the visualized audio.
+         */
+        void onFftDataCapture(Visualizer visualizer, byte[] fft, int samplingRate);
+    }
+
+    /**
+     * Registers an OnDataCaptureListener interface and specifies the rate at which the capture
+     * should be updated as well as the type of capture requested.
+     * <p>Call this method with a null listener to stop receiving the capture updates.
+     * @param listener OnDataCaptureListener registered
+     * @param rate rate in milliHertz at which the capture should be updated
+     * @param waveform true if a waveform capture is requested: the onWaveFormDataCapture()
+     * method will be called on the OnDataCaptureListener interface.
+     * @param fft true if a frequency capture is requested: the onFftDataCapture() method will be
+     * called on the OnDataCaptureListener interface.
+     * @return {@link #SUCCESS} in case of success,
+     * {@link #ERROR_NO_INIT} or {@link #ERROR_BAD_VALUE} in case of failure.
+     */
+    public int setDataCaptureListener(OnDataCaptureListener listener,
+            int rate, boolean waveform, boolean fft) {
+        if (listener == null) {
+            // make sure capture callback is stopped in native code
+            waveform = false;
+            fft = false;
+        }
+        int status;
+        synchronized (mStateLock) {
+            status = native_setPeriodicCapture(rate, waveform, fft);
+        }
+        if (status == SUCCESS) {
+            synchronized (mListenerLock) {
+                mCaptureListener = listener;
+                if ((listener != null) && (mNativeEventHandler == null)) {
+                    Looper looper;
+                    if ((looper = Looper.myLooper()) != null) {
+                        mNativeEventHandler = new Handler(looper);
+                    } else if ((looper = Looper.getMainLooper()) != null) {
+                        mNativeEventHandler = new Handler(looper);
+                    } else {
+                        mNativeEventHandler = null;
+                        status = ERROR_NO_INIT;
+                    }
+                }
+            }
+        }
+        return status;
+    }
+
+    /**
+     * @hide
+     *
+     * The OnServerDiedListener interface defines a method called by the Visualizer to indicate that
+     * the connection to the native media server has been broken and that the Visualizer object will
+     * need to be released and re-created.
+     * The client application can implement this interface and register the listener with the
+     * {@link #setServerDiedListener(OnServerDiedListener)} method.
+     */
+    public interface OnServerDiedListener  {
+        /**
+         * @hide
+         *
+         * Method called when the native media server has died.
+         * <p>If the native media server encounters a fatal error and needs to restart, the binder
+         * connection from the {@link #Visualizer} to the media server will be broken.  Data capture
+         * callbacks will stop happening, and client initiated calls to the {@link #Visualizer}
+         * instance will fail with the error code {@link #DEAD_OBJECT}.  To restore functionality,
+         * clients should {@link #release()} their old visualizer and create a new instance.
+         */
+        void onServerDied();
+    }
+
+    /**
+     * @hide
+     *
+     * Registers an OnServerDiedListener interface.
+     * <p>Call this method with a null listener to stop receiving server death notifications.
+     * @return {@link #SUCCESS} in case of success,
+     */
+    public int setServerDiedListener(OnServerDiedListener listener) {
+        synchronized (mListenerLock) {
+            mServerDiedListener = listener;
+        }
+        return SUCCESS;
+    }
+
+    //---------------------------------------------------------
+    // Interface definitions
+    //--------------------
+
+    private static native final void native_init();
+
+    @GuardedBy("mStateLock")
+    private native final int native_setup(Object audioeffect_this,
+                                          int audioSession,
+                                          int[] id,
+                                          @NonNull Parcel attributionSource);
+
+    @GuardedBy("mStateLock")
+    private native final void native_finalize();
+
+    @GuardedBy("mStateLock")
+    private native final void native_release();
+
+    @GuardedBy("mStateLock")
+    private native final int native_setEnabled(boolean enabled);
+
+    @GuardedBy("mStateLock")
+    private native final boolean native_getEnabled();
+
+    @GuardedBy("mStateLock")
+    private native final int native_setCaptureSize(int size);
+
+    @GuardedBy("mStateLock")
+    private native final int native_getCaptureSize();
+
+    @GuardedBy("mStateLock")
+    private native final int native_setScalingMode(int mode);
+
+    @GuardedBy("mStateLock")
+    private native final int native_getScalingMode();
+
+    @GuardedBy("mStateLock")
+    private native final int native_setMeasurementMode(int mode);
+
+    @GuardedBy("mStateLock")
+    private native final int native_getMeasurementMode();
+
+    @GuardedBy("mStateLock")
+    private native final int native_getSamplingRate();
+
+    @GuardedBy("mStateLock")
+    private native final int native_getWaveForm(byte[] waveform);
+
+    @GuardedBy("mStateLock")
+    private native final int native_getFft(byte[] fft);
+
+    @GuardedBy("mStateLock")
+    private native final int native_getPeakRms(MeasurementPeakRms measurement);
+
+    @GuardedBy("mStateLock")
+    private native final int native_setPeriodicCapture(int rate, boolean waveForm, boolean fft);
+
+    //---------------------------------------------------------
+    // Java methods called from the native side
+    //--------------------
+    @SuppressWarnings("unused")
+    private static void postEventFromNative(Object effect_ref,
+            int what, int samplingRate, byte[] data) {
+        final Visualizer visualizer = (Visualizer) ((WeakReference) effect_ref).get();
+        if (visualizer == null) return;
+
+        final Handler handler;
+        synchronized (visualizer.mListenerLock) {
+            handler = visualizer.mNativeEventHandler;
+        }
+        if (handler == null) return;
+
+        switch (what) {
+            case NATIVE_EVENT_PCM_CAPTURE:
+            case NATIVE_EVENT_FFT_CAPTURE:
+                handler.post(() -> {
+                    final OnDataCaptureListener l;
+                    synchronized (visualizer.mListenerLock) {
+                        l = visualizer.mCaptureListener;
+                    }
+                    if (l != null) {
+                        if (what == NATIVE_EVENT_PCM_CAPTURE) {
+                            l.onWaveFormDataCapture(visualizer, data, samplingRate);
+                        } else { // what == NATIVE_EVENT_FFT_CAPTURE
+                            l.onFftDataCapture(visualizer, data, samplingRate);
+                        }
+                    }
+                });
+                break;
+            case NATIVE_EVENT_SERVER_DIED:
+                handler.post(() -> {
+                    final OnServerDiedListener l;
+                    synchronized (visualizer.mListenerLock) {
+                        l = visualizer.mServerDiedListener;
+                    }
+                    if (l != null) {
+                        l.onServerDied();
+                    }
+                });
+                break;
+            default:
+                Log.e(TAG, "Unknown native event in postEventFromNative: " + what);
+                break;
+        }
+    }
+}
diff --git a/android/media/audiopolicy/AudioMix.java b/android/media/audiopolicy/AudioMix.java
new file mode 100644
index 0000000..0c73348
--- /dev/null
+++ b/android/media/audiopolicy/AudioMix.java
@@ -0,0 +1,461 @@
+/*
+ * Copyright (C) 2014 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.audiopolicy;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.media.AudioDeviceInfo;
+import android.media.AudioFormat;
+import android.media.AudioSystem;
+import android.os.Build;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * @hide
+ */
+@SystemApi
+public class AudioMix {
+
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private AudioMixingRule mRule;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private AudioFormat mFormat;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private int mRouteFlags;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private int mMixType = MIX_TYPE_INVALID;
+
+    // written by AudioPolicy
+    int mMixState = MIX_STATE_DISABLED;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    int mCallbackFlags;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    String mDeviceAddress;
+
+    // initialized in constructor, read by AudioPolicyConfig
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    final int mDeviceSystemType; // an AudioSystem.DEVICE_* value, not AudioDeviceInfo.TYPE_*
+
+    /**
+     * All parameters are guaranteed valid through the Builder.
+     */
+    private AudioMix(AudioMixingRule rule, AudioFormat format, int routeFlags, int callbackFlags,
+            int deviceType, String deviceAddress) {
+        mRule = rule;
+        mFormat = format;
+        mRouteFlags = routeFlags;
+        mMixType = rule.getTargetMixType();
+        mCallbackFlags = callbackFlags;
+        mDeviceSystemType = deviceType;
+        mDeviceAddress = (deviceAddress == null) ? new String("") : deviceAddress;
+    }
+
+    // CALLBACK_FLAG_* values: keep in sync with AudioMix::kCbFlag* values defined
+    // in frameworks/av/include/media/AudioPolicy.h
+    /** @hide */
+    public final static int CALLBACK_FLAG_NOTIFY_ACTIVITY = 0x1;
+    // when adding new MIX_FLAG_* flags, add them to this mask of authorized masks:
+    private final static int CALLBACK_FLAGS_ALL = CALLBACK_FLAG_NOTIFY_ACTIVITY;
+
+    // ROUTE_FLAG_* values: keep in sync with MIX_ROUTE_FLAG_* values defined
+    // in frameworks/av/include/media/AudioPolicy.h
+    /**
+     * An audio mix behavior where the output of the mix is sent to the original destination of
+     * the audio signal, i.e. an output device for an output mix, or a recording for an input mix.
+     */
+    public static final int ROUTE_FLAG_RENDER    = 0x1;
+    /**
+     * An audio mix behavior where the output of the mix is rerouted back to the framework and
+     * is accessible for injection or capture through the {@link AudioTrack} and {@link AudioRecord}
+     * APIs.
+     */
+    public static final int ROUTE_FLAG_LOOP_BACK = 0x1 << 1;
+
+    /**
+     * An audio mix behavior where the targeted audio is played unaffected but a copy is
+     * accessible for capture through {@link AudioRecord}.
+     *
+     * Only capture of playback is supported, not capture of capture.
+     * Use concurrent capture instead to capture what is captured by other apps.
+     *
+     * The captured audio is an approximation of the played audio.
+     * Effects and volume are not applied, and track are mixed with different delay then in the HAL.
+     * As a result, this API is not suitable for echo cancelling.
+     * @hide
+     */
+    public static final int ROUTE_FLAG_LOOP_BACK_RENDER = ROUTE_FLAG_LOOP_BACK | ROUTE_FLAG_RENDER;
+
+    private static final int ROUTE_FLAG_SUPPORTED = ROUTE_FLAG_RENDER | ROUTE_FLAG_LOOP_BACK;
+
+    // MIX_TYPE_* values to keep in sync with frameworks/av/include/media/AudioPolicy.h
+    /**
+     * @hide
+     * Invalid mix type, default value.
+     */
+    public static final int MIX_TYPE_INVALID = -1;
+    /**
+     * @hide
+     * Mix type indicating playback streams are mixed.
+     */
+    public static final int MIX_TYPE_PLAYERS = 0;
+    /**
+     * @hide
+     * Mix type indicating recording streams are mixed.
+     */
+    public static final int MIX_TYPE_RECORDERS = 1;
+
+
+    // MIX_STATE_* values to keep in sync with frameworks/av/include/media/AudioPolicy.h
+    /**
+     * State of a mix before its policy is enabled.
+     */
+    public static final int MIX_STATE_DISABLED = -1;
+    /**
+     * State of a mix when there is no audio to mix.
+     */
+    public static final int MIX_STATE_IDLE = 0;
+    /**
+     * State of a mix that is actively mixing audio.
+     */
+    public static final int MIX_STATE_MIXING = 1;
+
+    /** Maximum sampling rate for privileged playback capture*/
+    private static final int PRIVILEDGED_CAPTURE_MAX_SAMPLE_RATE = 16000;
+
+    /** Maximum channel number for privileged playback capture*/
+    private static final int PRIVILEDGED_CAPTURE_MAX_CHANNEL_NUMBER = 1;
+
+    /** Maximum channel number for privileged playback capture*/
+    private static final int PRIVILEDGED_CAPTURE_MAX_BYTES_PER_SAMPLE = 2;
+
+    /**
+     * The current mixing state.
+     * @return one of {@link #MIX_STATE_DISABLED}, {@link #MIX_STATE_IDLE},
+     *          {@link #MIX_STATE_MIXING}.
+     */
+    public int getMixState() {
+        return mMixState;
+    }
+
+
+    /** @hide */
+    public int getRouteFlags() {
+        return mRouteFlags;
+    }
+
+    /** @hide */
+    public AudioFormat getFormat() {
+        return mFormat;
+    }
+
+    /** @hide */
+    public AudioMixingRule getRule() {
+        return mRule;
+    }
+
+    /** @hide */
+    public int getMixType() {
+        return mMixType;
+    }
+
+    void setRegistration(String regId) {
+        mDeviceAddress = regId;
+    }
+
+    /** @hide */
+    public String getRegistration() {
+        return mDeviceAddress;
+    }
+
+    /** @hide */
+    public boolean isAffectingUsage(int usage) {
+        return mRule.isAffectingUsage(usage);
+    }
+
+    /**
+      * Returns {@code true} if the rule associated with this mix contains a
+      * RULE_MATCH_ATTRIBUTE_USAGE criterion for the given usage
+      *
+      * @hide
+      */
+    public boolean containsMatchAttributeRuleForUsage(int usage) {
+        return mRule.containsMatchAttributeRuleForUsage(usage);
+    }
+
+    /** @hide */
+    public boolean isRoutedToDevice(int deviceType, @NonNull String deviceAddress) {
+        if ((mRouteFlags & ROUTE_FLAG_RENDER) != ROUTE_FLAG_RENDER) {
+            return false;
+        }
+        if (deviceType != mDeviceSystemType) {
+            return false;
+        }
+        if (!deviceAddress.equals(mDeviceAddress)) {
+            return false;
+        }
+        return true;
+    }
+
+    /** @return an error string if the format would not allow Privileged playbackCapture
+     *          null otherwise
+     * @hide */
+    public static String canBeUsedForPrivilegedMediaCapture(AudioFormat format) {
+        int sampleRate = format.getSampleRate();
+        if (sampleRate > PRIVILEDGED_CAPTURE_MAX_SAMPLE_RATE || sampleRate <= 0) {
+            return "Privileged audio capture sample rate " + sampleRate
+                   + " can not be over " + PRIVILEDGED_CAPTURE_MAX_SAMPLE_RATE + "kHz";
+        }
+        int channelCount = format.getChannelCount();
+        if (channelCount > PRIVILEDGED_CAPTURE_MAX_CHANNEL_NUMBER || channelCount <= 0) {
+            return "Privileged audio capture channel count " + channelCount + " can not be over "
+                   + PRIVILEDGED_CAPTURE_MAX_CHANNEL_NUMBER;
+        }
+        int encoding = format.getEncoding();
+        if (!format.isPublicEncoding(encoding) || !format.isEncodingLinearPcm(encoding)) {
+            return "Privileged audio capture encoding " + encoding + "is not linear";
+        }
+        if (format.getBytesPerSample(encoding) > PRIVILEDGED_CAPTURE_MAX_BYTES_PER_SAMPLE) {
+            return "Privileged audio capture encoding " + encoding + " can not be over "
+                   + PRIVILEDGED_CAPTURE_MAX_BYTES_PER_SAMPLE + " bytes per sample";
+        }
+        return null;
+    }
+
+    /** @hide */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        final AudioMix that = (AudioMix) o;
+        return (this.mRouteFlags == that.mRouteFlags)
+                && (this.mRule == that.mRule)
+                && (this.mMixType == that.mMixType)
+                && (this.mFormat == that.mFormat);
+    }
+
+    /** @hide */
+    @Override
+    public int hashCode() {
+        return Objects.hash(mRouteFlags, mRule, mMixType, mFormat);
+    }
+
+    /** @hide */
+    @IntDef(flag = true,
+            value = { ROUTE_FLAG_RENDER, ROUTE_FLAG_LOOP_BACK } )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RouteFlags {}
+
+    /**
+     * Builder class for {@link AudioMix} objects
+     */
+    public static class Builder {
+        private AudioMixingRule mRule = null;
+        private AudioFormat mFormat = null;
+        private int mRouteFlags = 0;
+        private int mCallbackFlags = 0;
+        // an AudioSystem.DEVICE_* value, not AudioDeviceInfo.TYPE_*
+        private int mDeviceSystemType = AudioSystem.DEVICE_NONE;
+        private String mDeviceAddress = null;
+
+        /**
+         * @hide
+         * Only used by AudioPolicyConfig, not a public API.
+         */
+        Builder() { }
+
+        /**
+         * Construct an instance for the given {@link AudioMixingRule}.
+         * @param rule a non-null {@link AudioMixingRule} instance.
+         * @throws IllegalArgumentException
+         */
+        public Builder(AudioMixingRule rule)
+                throws IllegalArgumentException {
+            if (rule == null) {
+                throw new IllegalArgumentException("Illegal null AudioMixingRule argument");
+            }
+            mRule = rule;
+        }
+
+        /**
+         * @hide
+         * Only used by AudioPolicyConfig, not a public API.
+         * @param rule
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        Builder setMixingRule(AudioMixingRule rule)
+                throws IllegalArgumentException {
+            if (rule == null) {
+                throw new IllegalArgumentException("Illegal null AudioMixingRule argument");
+            }
+            mRule = rule;
+            return this;
+        }
+
+        /**
+         * @hide
+         * Only used by AudioPolicyConfig, not a public API.
+         * @param callbackFlags which callbacks are called from native
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        Builder setCallbackFlags(int flags) throws IllegalArgumentException {
+            if ((flags != 0) && ((flags & CALLBACK_FLAGS_ALL) == 0)) {
+                throw new IllegalArgumentException("Illegal callback flags 0x"
+                        + Integer.toHexString(flags).toUpperCase());
+            }
+            mCallbackFlags = flags;
+            return this;
+        }
+
+        /**
+         * @hide
+         * Only used by AudioPolicyConfig, not a public API.
+         * @param deviceType an AudioSystem.DEVICE_* value, not AudioDeviceInfo.TYPE_*
+         * @param address
+         * @return the same Builder instance.
+         */
+        Builder setDevice(int deviceType, String address) {
+            mDeviceSystemType = deviceType;
+            mDeviceAddress = address;
+            return this;
+        }
+
+        /**
+         * Sets the {@link AudioFormat} for the mix.
+         * @param format a non-null {@link AudioFormat} instance.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        public Builder setFormat(AudioFormat format)
+                throws IllegalArgumentException {
+            if (format == null) {
+                throw new IllegalArgumentException("Illegal null AudioFormat argument");
+            }
+            mFormat = format;
+            return this;
+        }
+
+        /**
+         * Sets the routing behavior for the mix. If not set, routing behavior will default to
+         * {@link AudioMix#ROUTE_FLAG_LOOP_BACK}.
+         * @param routeFlags one of {@link AudioMix#ROUTE_FLAG_LOOP_BACK},
+         *     {@link AudioMix#ROUTE_FLAG_RENDER}
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        public Builder setRouteFlags(@RouteFlags int routeFlags)
+                throws IllegalArgumentException {
+            if (routeFlags == 0) {
+                throw new IllegalArgumentException("Illegal empty route flags");
+            }
+            if ((routeFlags & ROUTE_FLAG_SUPPORTED) == 0) {
+                throw new IllegalArgumentException("Invalid route flags 0x"
+                        + Integer.toHexString(routeFlags) + "when configuring an AudioMix");
+            }
+            if ((routeFlags & ~ROUTE_FLAG_SUPPORTED) != 0) {
+                throw new IllegalArgumentException("Unknown route flags 0x"
+                        + Integer.toHexString(routeFlags) + "when configuring an AudioMix");
+            }
+            mRouteFlags = routeFlags;
+            return this;
+        }
+
+        /**
+         * Sets the audio device used for playback. Cannot be used in the context of an audio
+         * policy used to inject audio to be recorded, or in a mix whose route flags doesn't
+         * specify {@link AudioMix#ROUTE_FLAG_RENDER}.
+         * @param device a non-null AudioDeviceInfo describing the audio device to play the output
+         *     of this mix.
+         * @return the same Builder instance
+         * @throws IllegalArgumentException
+         */
+        public Builder setDevice(@NonNull AudioDeviceInfo device) throws IllegalArgumentException {
+            if (device == null) {
+                throw new IllegalArgumentException("Illegal null AudioDeviceInfo argument");
+            }
+            if (!device.isSink()) {
+                throw new IllegalArgumentException("Unsupported device type on mix, not a sink");
+            }
+            mDeviceSystemType = AudioDeviceInfo.convertDeviceTypeToInternalDevice(device.getType());
+            mDeviceAddress = device.getAddress();
+            return this;
+        }
+
+        /**
+         * Combines all of the settings and return a new {@link AudioMix} object.
+         * @return a new {@link AudioMix} object
+         * @throws IllegalArgumentException if no {@link AudioMixingRule} has been set.
+         */
+        public AudioMix build() throws IllegalArgumentException {
+            if (mRule == null) {
+                throw new IllegalArgumentException("Illegal null AudioMixingRule");
+            }
+            if (mRouteFlags == 0) {
+                // no route flags set, use default as described in Builder.setRouteFlags(int)
+                mRouteFlags = ROUTE_FLAG_LOOP_BACK;
+            }
+            if (mFormat == null) {
+                // FIXME Can we eliminate this?  Will AudioMix work with an unspecified sample rate?
+                int rate = AudioSystem.getPrimaryOutputSamplingRate();
+                if (rate <= 0) {
+                    rate = 44100;
+                }
+                mFormat = new AudioFormat.Builder().setSampleRate(rate).build();
+            }
+            if ((mDeviceSystemType != AudioSystem.DEVICE_NONE)
+                    && (mDeviceSystemType != AudioSystem.DEVICE_OUT_REMOTE_SUBMIX)
+                    && (mDeviceSystemType != AudioSystem.DEVICE_IN_REMOTE_SUBMIX)) {
+                if ((mRouteFlags & ROUTE_FLAG_RENDER) == 0) {
+                    throw new IllegalArgumentException(
+                            "Can't have audio device without flag ROUTE_FLAG_RENDER");
+                }
+                if (mRule.getTargetMixType() != AudioMix.MIX_TYPE_PLAYERS) {
+                    throw new IllegalArgumentException("Unsupported device on non-playback mix");
+                }
+            } else {
+                if ((mRouteFlags & ROUTE_FLAG_SUPPORTED) == ROUTE_FLAG_RENDER) {
+                    throw new IllegalArgumentException(
+                            "Can't have flag ROUTE_FLAG_RENDER without an audio device");
+                }
+                if ((mRouteFlags & ROUTE_FLAG_LOOP_BACK) == ROUTE_FLAG_LOOP_BACK) {
+                    if (mRule.getTargetMixType() == MIX_TYPE_PLAYERS) {
+                        mDeviceSystemType = AudioSystem.DEVICE_OUT_REMOTE_SUBMIX;
+                    } else if (mRule.getTargetMixType() == MIX_TYPE_RECORDERS) {
+                        mDeviceSystemType = AudioSystem.DEVICE_IN_REMOTE_SUBMIX;
+                    } else {
+                        throw new IllegalArgumentException("Unknown mixing rule type");
+                    }
+                }
+            }
+            if (mRule.allowPrivilegedMediaPlaybackCapture()) {
+                String error = AudioMix.canBeUsedForPrivilegedMediaCapture(mFormat);
+                if (error != null) {
+                    throw new IllegalArgumentException(error);
+                }
+            }
+            return new AudioMix(mRule, mFormat, mRouteFlags, mCallbackFlags, mDeviceSystemType,
+                    mDeviceAddress);
+        }
+    }
+}
diff --git a/android/media/audiopolicy/AudioMixingRule.java b/android/media/audiopolicy/AudioMixingRule.java
new file mode 100644
index 0000000..abbcc66
--- /dev/null
+++ b/android/media/audiopolicy/AudioMixingRule.java
@@ -0,0 +1,684 @@
+/*
+ * Copyright (C) 2014 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.audiopolicy;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.media.AudioAttributes;
+import android.os.Build;
+import android.os.Parcel;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Objects;
+
+
+/**
+ * @hide
+ *
+ * Here's an example of creating a mixing rule for all media playback:
+ * <pre>
+ * AudioAttributes mediaAttr = new AudioAttributes.Builder()
+ *         .setUsage(AudioAttributes.USAGE_MEDIA)
+ *         .build();
+ * AudioMixingRule mediaRule = new AudioMixingRule.Builder()
+ *         .addRule(mediaAttr, AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE)
+ *         .build();
+ * </pre>
+ */
+@SystemApi
+public class AudioMixingRule {
+
+    private AudioMixingRule(int mixType, ArrayList<AudioMixMatchCriterion> criteria,
+                            boolean allowPrivilegedMediaPlaybackCapture,
+                            boolean voiceCommunicationCaptureAllowed) {
+        mCriteria = criteria;
+        mTargetMixType = mixType;
+        mAllowPrivilegedPlaybackCapture = allowPrivilegedMediaPlaybackCapture;
+        mVoiceCommunicationCaptureAllowed = voiceCommunicationCaptureAllowed;
+    }
+
+    /**
+     * A rule requiring the usage information of the {@link AudioAttributes} to match.
+     * This mixing rule can be added with {@link Builder#addRule(AudioAttributes, int)} or
+     * {@link Builder#addMixRule(int, Object)} where the Object parameter is an instance of
+     * {@link AudioAttributes}.
+     */
+    public static final int RULE_MATCH_ATTRIBUTE_USAGE = 0x1;
+    /**
+     * A rule requiring the capture preset information of the {@link AudioAttributes} to match.
+     * This mixing rule can be added with {@link Builder#addRule(AudioAttributes, int)} or
+     * {@link Builder#addMixRule(int, Object)} where the Object parameter is an instance of
+     * {@link AudioAttributes}.
+     */
+    public static final int RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET = 0x1 << 1;
+    /**
+     * A rule requiring the UID of the audio stream to match that specified.
+     * This mixing rule can be added with {@link Builder#addMixRule(int, Object)} where the Object
+     * parameter is an instance of {@link java.lang.Integer}.
+     */
+    public static final int RULE_MATCH_UID = 0x1 << 2;
+    /**
+     * A rule requiring the userId of the audio stream to match that specified.
+     * This mixing rule can be added with {@link Builder#addMixRule(int, Object)} where the Object
+     * parameter is an instance of {@link java.lang.Integer}.
+     */
+    public static final int RULE_MATCH_USERID = 0x1 << 3;
+
+    private final static int RULE_EXCLUSION_MASK = 0x8000;
+    /**
+     * @hide
+     * A rule requiring the usage information of the {@link AudioAttributes} to differ.
+     */
+    public static final int RULE_EXCLUDE_ATTRIBUTE_USAGE =
+            RULE_EXCLUSION_MASK | RULE_MATCH_ATTRIBUTE_USAGE;
+    /**
+     * @hide
+     * A rule requiring the capture preset information of the {@link AudioAttributes} to differ.
+     */
+    public static final int RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET =
+            RULE_EXCLUSION_MASK | RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET;
+    /**
+     * @hide
+     * A rule requiring the UID information to differ.
+     */
+    public static final int RULE_EXCLUDE_UID =
+            RULE_EXCLUSION_MASK | RULE_MATCH_UID;
+
+    /**
+     * @hide
+     * A rule requiring the userId information to differ.
+     */
+    public static final int RULE_EXCLUDE_USERID =
+            RULE_EXCLUSION_MASK | RULE_MATCH_USERID;
+
+    /** @hide */
+    public static final class AudioMixMatchCriterion {
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        final AudioAttributes mAttr;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        final int mIntProp;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        final int mRule;
+
+        /** input parameters must be valid */
+        AudioMixMatchCriterion(AudioAttributes attributes, int rule) {
+            mAttr = attributes;
+            mIntProp = Integer.MIN_VALUE;
+            mRule = rule;
+        }
+        /** input parameters must be valid */
+        AudioMixMatchCriterion(Integer intProp, int rule) {
+            mAttr = null;
+            mIntProp = intProp.intValue();
+            mRule = rule;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mAttr, mIntProp, mRule);
+        }
+
+        void writeToParcel(Parcel dest) {
+            dest.writeInt(mRule);
+            final int match_rule = mRule & ~RULE_EXCLUSION_MASK;
+            switch (match_rule) {
+                case RULE_MATCH_ATTRIBUTE_USAGE:
+                    dest.writeInt(mAttr.getSystemUsage());
+                    break;
+                case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+                    dest.writeInt(mAttr.getCapturePreset());
+                    break;
+                case RULE_MATCH_UID:
+                case RULE_MATCH_USERID:
+                    dest.writeInt(mIntProp);
+                    break;
+                default:
+                    Log.e("AudioMixMatchCriterion", "Unknown match rule" + match_rule
+                            + " when writing to Parcel");
+                    dest.writeInt(-1);
+            }
+        }
+
+        public AudioAttributes getAudioAttributes() { return mAttr; }
+        public int getIntProp() { return mIntProp; }
+        public int getRule() { return mRule; }
+    }
+
+    boolean isAffectingUsage(int usage) {
+        for (AudioMixMatchCriterion criterion : mCriteria) {
+            if ((criterion.mRule & RULE_MATCH_ATTRIBUTE_USAGE) != 0
+                    && criterion.mAttr != null
+                    && criterion.mAttr.getSystemUsage() == usage) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+      * Returns {@code true} if this rule contains a RULE_MATCH_ATTRIBUTE_USAGE criterion for
+      * the given usage
+      *
+      * @hide
+      */
+    boolean containsMatchAttributeRuleForUsage(int usage) {
+        for (AudioMixMatchCriterion criterion : mCriteria) {
+            if (criterion.mRule == RULE_MATCH_ATTRIBUTE_USAGE
+                    && criterion.mAttr != null
+                    && criterion.mAttr.getSystemUsage() == usage) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private static boolean areCriteriaEquivalent(ArrayList<AudioMixMatchCriterion> cr1,
+            ArrayList<AudioMixMatchCriterion> cr2) {
+        if (cr1 == null || cr2 == null) return false;
+        if (cr1 == cr2) return true;
+        if (cr1.size() != cr2.size()) return false;
+        //TODO iterate over rules to check they contain the same criterion
+        return (cr1.hashCode() == cr2.hashCode());
+    }
+
+    private final int mTargetMixType;
+    int getTargetMixType() { return mTargetMixType; }
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private final ArrayList<AudioMixMatchCriterion> mCriteria;
+    /** @hide */
+    public ArrayList<AudioMixMatchCriterion> getCriteria() { return mCriteria; }
+    /** Indicates that this rule is intended to capture media or game playback by a system component
+      * with permission CAPTURE_MEDIA_OUTPUT or CAPTURE_AUDIO_OUTPUT.
+      */
+    //TODO b/177061175: rename to mAllowPrivilegedMediaPlaybackCapture
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private boolean mAllowPrivilegedPlaybackCapture = false;
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    private boolean mVoiceCommunicationCaptureAllowed = false;
+
+    /** @hide */
+    public boolean allowPrivilegedMediaPlaybackCapture() {
+        return mAllowPrivilegedPlaybackCapture;
+    }
+
+    /** @hide */
+    public boolean voiceCommunicationCaptureAllowed() {
+        return mVoiceCommunicationCaptureAllowed;
+    }
+
+    /** @hide */
+    public void setVoiceCommunicationCaptureAllowed(boolean allowed) {
+        mVoiceCommunicationCaptureAllowed = allowed;
+    }
+
+    /** @hide */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        final AudioMixingRule that = (AudioMixingRule) o;
+        return (this.mTargetMixType == that.mTargetMixType)
+                && (areCriteriaEquivalent(this.mCriteria, that.mCriteria)
+                && this.mAllowPrivilegedPlaybackCapture == that.mAllowPrivilegedPlaybackCapture
+                && this.mVoiceCommunicationCaptureAllowed
+                    == that.mVoiceCommunicationCaptureAllowed);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+            mTargetMixType,
+            mCriteria,
+            mAllowPrivilegedPlaybackCapture,
+            mVoiceCommunicationCaptureAllowed);
+    }
+
+    private static boolean isValidSystemApiRule(int rule) {
+        // API rules only expose the RULE_MATCH_* rules
+        switch (rule) {
+            case RULE_MATCH_ATTRIBUTE_USAGE:
+            case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+            case RULE_MATCH_UID:
+            case RULE_MATCH_USERID:
+                return true;
+            default:
+                return false;
+        }
+    }
+    private static boolean isValidAttributesSystemApiRule(int rule) {
+        // API rules only expose the RULE_MATCH_* rules
+        switch (rule) {
+            case RULE_MATCH_ATTRIBUTE_USAGE:
+            case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private static boolean isValidRule(int rule) {
+        final int match_rule = rule & ~RULE_EXCLUSION_MASK;
+        switch (match_rule) {
+            case RULE_MATCH_ATTRIBUTE_USAGE:
+            case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+            case RULE_MATCH_UID:
+            case RULE_MATCH_USERID:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private static boolean isPlayerRule(int rule) {
+        final int match_rule = rule & ~RULE_EXCLUSION_MASK;
+        switch (match_rule) {
+            case RULE_MATCH_ATTRIBUTE_USAGE:
+            case RULE_MATCH_USERID:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private static boolean isRecorderRule(int rule) {
+        final int match_rule = rule & ~RULE_EXCLUSION_MASK;
+        switch (match_rule) {
+            case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    private static boolean isAudioAttributeRule(int match_rule) {
+        switch(match_rule) {
+            case RULE_MATCH_ATTRIBUTE_USAGE:
+            case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+                return true;
+            default:
+                return false;
+        }
+    }
+
+    /**
+     * Builder class for {@link AudioMixingRule} objects
+     */
+    public static class Builder {
+        private ArrayList<AudioMixMatchCriterion> mCriteria;
+        private int mTargetMixType = AudioMix.MIX_TYPE_INVALID;
+        private boolean mAllowPrivilegedMediaPlaybackCapture = false;
+        // This value should be set internally according to a permission check
+        private boolean mVoiceCommunicationCaptureAllowed = false;
+
+        /**
+         * Constructs a new Builder with no rules.
+         */
+        public Builder() {
+            mCriteria = new ArrayList<AudioMixMatchCriterion>();
+        }
+
+        /**
+         * Add a rule for the selection of which streams are mixed together.
+         * @param attrToMatch a non-null AudioAttributes instance for which a contradictory
+         *     rule hasn't been set yet.
+         * @param rule {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_USAGE} or
+         *     {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET}.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         * @see #excludeRule(AudioAttributes, int)
+         */
+        public Builder addRule(AudioAttributes attrToMatch, int rule)
+                throws IllegalArgumentException {
+            if (!isValidAttributesSystemApiRule(rule)) {
+                throw new IllegalArgumentException("Illegal rule value " + rule);
+            }
+            return checkAddRuleObjInternal(rule, attrToMatch);
+        }
+
+        /**
+         * Add a rule by exclusion for the selection of which streams are mixed together.
+         * <br>For instance the following code
+         * <br><pre>
+         * AudioAttributes mediaAttr = new AudioAttributes.Builder()
+         *         .setUsage(AudioAttributes.USAGE_MEDIA)
+         *         .build();
+         * AudioMixingRule noMediaRule = new AudioMixingRule.Builder()
+         *         .excludeRule(mediaAttr, AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE)
+         *         .build();
+         * </pre>
+         * <br>will create a rule which maps to any usage value, except USAGE_MEDIA.
+         * @param attrToMatch a non-null AudioAttributes instance for which a contradictory
+         *     rule hasn't been set yet.
+         * @param rule {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_USAGE} or
+         *     {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET}.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         * @see #addRule(AudioAttributes, int)
+         */
+        public Builder excludeRule(AudioAttributes attrToMatch, int rule)
+                throws IllegalArgumentException {
+            if (!isValidAttributesSystemApiRule(rule)) {
+                throw new IllegalArgumentException("Illegal rule value " + rule);
+            }
+            return checkAddRuleObjInternal(rule | RULE_EXCLUSION_MASK, attrToMatch);
+        }
+
+        /**
+         * Add a rule for the selection of which streams are mixed together.
+         * The rule defines what the matching will be made on. It also determines the type of the
+         * property to match against.
+         * @param rule one of {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_USAGE},
+         *     {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET} or
+         *     {@link AudioMixingRule#RULE_MATCH_UID} or
+         *     {@link AudioMixingRule#RULE_MATCH_USERID}.
+         * @param property see the definition of each rule for the type to use (either an
+         *     {@link AudioAttributes} or an {@link java.lang.Integer}).
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         * @see #excludeMixRule(int, Object)
+         */
+        public Builder addMixRule(int rule, Object property) throws IllegalArgumentException {
+            if (!isValidSystemApiRule(rule)) {
+                throw new IllegalArgumentException("Illegal rule value " + rule);
+            }
+            return checkAddRuleObjInternal(rule, property);
+        }
+
+        /**
+         * Add a rule by exclusion for the selection of which streams are mixed together.
+         * <br>For instance the following code
+         * <br><pre>
+         * AudioAttributes mediaAttr = new AudioAttributes.Builder()
+         *         .setUsage(AudioAttributes.USAGE_MEDIA)
+         *         .build();
+         * AudioMixingRule noMediaRule = new AudioMixingRule.Builder()
+         *         .addMixRule(AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE, mediaAttr)
+         *         .excludeMixRule(AudioMixingRule.RULE_MATCH_UID, new Integer(uidToExclude)
+         *         .build();
+         * </pre>
+         * <br>will create a rule which maps to usage USAGE_MEDIA, but excludes any stream
+         * coming from the specified UID.
+         * @param rule one of {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_USAGE},
+         *     {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET} or
+         *     {@link AudioMixingRule#RULE_MATCH_UID} or
+         *     {@link AudioMixingRule#RULE_MATCH_USERID}.
+         * @param property see the definition of each rule for the type to use (either an
+         *     {@link AudioAttributes} or an {@link java.lang.Integer}).
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        public Builder excludeMixRule(int rule, Object property) throws IllegalArgumentException {
+            if (!isValidSystemApiRule(rule)) {
+                throw new IllegalArgumentException("Illegal rule value " + rule);
+            }
+            return checkAddRuleObjInternal(rule | RULE_EXCLUSION_MASK, property);
+        }
+
+        /**
+         * Set if the audio of app that opted out of audio playback capture should be captured.
+         *
+         * Caller of this method with <code>true</code>, MUST abide to the restriction listed in
+         * {@link ALLOW_CAPTURE_BY_SYSTEM}, including but not limited to the captured audio
+         * can not leave the capturing app, and the quality is limited to 16k mono.
+         *
+         * The permission {@link CAPTURE_AUDIO_OUTPUT} or {@link CAPTURE_MEDIA_OUTPUT} is needed
+         * to ignore the opt-out.
+         *
+         * Only affects LOOPBACK|RENDER mix.
+         *
+         * @return the same Builder instance.
+         */
+        public @NonNull Builder allowPrivilegedPlaybackCapture(boolean allow) {
+            mAllowPrivilegedMediaPlaybackCapture = allow;
+            return this;
+        }
+
+        /**
+         * Set if the caller of the rule is able to capture voice communication output.
+         * A system app can capture voice communication output only if it is granted with the.
+         * CAPTURE_VOICE_COMMUNICATION_OUTPUT permission.
+         *
+         * Note that this method is for internal use only and should not be called by the app that
+         * creates the rule.
+         *
+         * @return the same Builder instance.
+         *
+         * @hide
+         */
+        public @NonNull Builder voiceCommunicationCaptureAllowed(boolean allowed) {
+            mVoiceCommunicationCaptureAllowed = allowed;
+            return this;
+        }
+
+        /**
+         * Set target mix type of the mixing rule.
+         *
+         * <p>Note: If the mix type was not specified, it will be decided automatically by mixing
+         * rule. For {@link #RULE_MATCH_UID}, the default type is {@link AudioMix#MIX_TYPE_PLAYERS}.
+         *
+         * @param mixType {@link AudioMix#MIX_TYPE_PLAYERS} or {@link AudioMix#MIX_TYPE_RECORDERS}
+         * @return the same Builder instance.
+         *
+         * @hide
+         */
+        public @NonNull Builder setTargetMixType(int mixType) {
+            mTargetMixType = mixType;
+            Log.i("AudioMixingRule", "Builder setTargetMixType " + mixType);
+            return this;
+        }
+
+        /**
+         * Add or exclude a rule for the selection of which streams are mixed together.
+         * Does error checking on the parameters.
+         * @param rule
+         * @param property
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        private Builder checkAddRuleObjInternal(int rule, Object property)
+                throws IllegalArgumentException {
+            if (property == null) {
+                throw new IllegalArgumentException("Illegal null argument for mixing rule");
+            }
+            if (!isValidRule(rule)) {
+                throw new IllegalArgumentException("Illegal rule value " + rule);
+            }
+            final int match_rule = rule & ~RULE_EXCLUSION_MASK;
+            if (isAudioAttributeRule(match_rule)) {
+                if (!(property instanceof AudioAttributes)) {
+                    throw new IllegalArgumentException("Invalid AudioAttributes argument");
+                }
+                return addRuleInternal((AudioAttributes) property, null, rule);
+            } else {
+                // implies integer match rule
+                if (!(property instanceof Integer)) {
+                    throw new IllegalArgumentException("Invalid Integer argument");
+                }
+                return addRuleInternal(null, (Integer) property, rule);
+            }
+        }
+
+        /**
+         * Add or exclude a rule on AudioAttributes or integer property for the selection of which
+         * streams are mixed together.
+         * No rule-to-parameter type check, all done in {@link #checkAddRuleObjInternal(int, Object)}.
+         * Exceptions are thrown only when incompatible rules are added.
+         * @param attrToMatch a non-null AudioAttributes instance for which a contradictory
+         *     rule hasn't been set yet, null if not used.
+         * @param intProp an integer property to match or exclude, null if not used.
+         * @param rule one of {@link AudioMixingRule#RULE_EXCLUDE_ATTRIBUTE_USAGE},
+         *     {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_USAGE},
+         *     {@link AudioMixingRule#RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET} or
+         *     {@link AudioMixingRule#RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET},
+         *     {@link AudioMixingRule#RULE_MATCH_UID}, {@link AudioMixingRule#RULE_EXCLUDE_UID}.
+         *     {@link AudioMixingRule#RULE_MATCH_USERID},
+         *     {@link AudioMixingRule#RULE_EXCLUDE_USERID}.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        private Builder addRuleInternal(AudioAttributes attrToMatch, Integer intProp, int rule)
+                throws IllegalArgumentException {
+            // as rules are added to the Builder, we verify they are consistent with the type
+            // of mix being built. When adding the first rule, the mix type is MIX_TYPE_INVALID.
+            if (mTargetMixType == AudioMix.MIX_TYPE_INVALID) {
+                if (isPlayerRule(rule)) {
+                    mTargetMixType = AudioMix.MIX_TYPE_PLAYERS;
+                } else if (isRecorderRule(rule)) {
+                    mTargetMixType = AudioMix.MIX_TYPE_RECORDERS;
+                } else {
+                    // For rules which are not player or recorder specific (e.g. RULE_MATCH_UID),
+                    // the default mix type is MIX_TYPE_PLAYERS.
+                    mTargetMixType = AudioMix.MIX_TYPE_PLAYERS;
+                }
+            } else if ((isPlayerRule(rule) && (mTargetMixType != AudioMix.MIX_TYPE_PLAYERS))
+                    || (isRecorderRule(rule)) && (mTargetMixType != AudioMix.MIX_TYPE_RECORDERS))
+            {
+                throw new IllegalArgumentException("Incompatible rule for mix");
+            }
+            synchronized (mCriteria) {
+                Iterator<AudioMixMatchCriterion> crIterator = mCriteria.iterator();
+                final int match_rule = rule & ~RULE_EXCLUSION_MASK;
+                while (crIterator.hasNext()) {
+                    final AudioMixMatchCriterion criterion = crIterator.next();
+
+                    if ((criterion.mRule & ~RULE_EXCLUSION_MASK) != match_rule) {
+                        continue; // The two rules are not of the same type
+                    }
+                    switch (match_rule) {
+                        case RULE_MATCH_ATTRIBUTE_USAGE:
+                            // "usage"-based rule
+                            if (criterion.mAttr.getSystemUsage() == attrToMatch.getSystemUsage()) {
+                                if (criterion.mRule == rule) {
+                                    // rule already exists, we're done
+                                    return this;
+                                } else {
+                                    // criterion already exists with a another rule,
+                                    // it is incompatible
+                                    throw new IllegalArgumentException("Contradictory rule exists"
+                                            + " for " + attrToMatch);
+                                }
+                            }
+                            break;
+                        case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+                            // "capture preset"-base rule
+                            if (criterion.mAttr.getCapturePreset() == attrToMatch.getCapturePreset()) {
+                                if (criterion.mRule == rule) {
+                                    // rule already exists, we're done
+                                    return this;
+                                } else {
+                                    // criterion already exists with a another rule,
+                                    // it is incompatible
+                                    throw new IllegalArgumentException("Contradictory rule exists"
+                                            + " for " + attrToMatch);
+                                }
+                            }
+                            break;
+                        case RULE_MATCH_UID:
+                            // "usage"-based rule
+                            if (criterion.mIntProp == intProp.intValue()) {
+                                if (criterion.mRule == rule) {
+                                    // rule already exists, we're done
+                                    return this;
+                                } else {
+                                    // criterion already exists with a another rule,
+                                    // it is incompatible
+                                    throw new IllegalArgumentException("Contradictory rule exists"
+                                            + " for UID " + intProp);
+                                }
+                            }
+                            break;
+                        case RULE_MATCH_USERID:
+                            // "userid"-based rule
+                            if (criterion.mIntProp == intProp.intValue()) {
+                                if (criterion.mRule == rule) {
+                                    // rule already exists, we're done
+                                    return this;
+                                } else {
+                                    // criterion already exists with a another rule,
+                                    // it is incompatible
+                                    throw new IllegalArgumentException("Contradictory rule exists"
+                                            + " for userId " + intProp);
+                                }
+                            }
+                            break;
+                    }
+                }
+                // rule didn't exist, add it
+                switch (match_rule) {
+                    case RULE_MATCH_ATTRIBUTE_USAGE:
+                    case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+                        mCriteria.add(new AudioMixMatchCriterion(attrToMatch, rule));
+                        break;
+                    case RULE_MATCH_UID:
+                    case RULE_MATCH_USERID:
+                        mCriteria.add(new AudioMixMatchCriterion(intProp, rule));
+                        break;
+                    default:
+                        throw new IllegalStateException("Unreachable code in addRuleInternal()");
+                }
+            }
+            return this;
+        }
+
+        Builder addRuleFromParcel(Parcel in) throws IllegalArgumentException {
+            final int rule = in.readInt();
+            final int match_rule = rule & ~RULE_EXCLUSION_MASK;
+            AudioAttributes attr = null;
+            Integer intProp = null;
+            switch (match_rule) {
+                case RULE_MATCH_ATTRIBUTE_USAGE:
+                    int usage = in.readInt();
+                    if (AudioAttributes.isSystemUsage(usage)) {
+                        attr = new AudioAttributes.Builder()
+                                .setSystemUsage(usage).build();
+                    } else {
+                        attr = new AudioAttributes.Builder()
+                                .setUsage(usage).build();
+                    }
+                    break;
+                case RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+                    int preset = in.readInt();
+                    attr = new AudioAttributes.Builder()
+                            .setInternalCapturePreset(preset).build();
+                    break;
+                case RULE_MATCH_UID:
+                case RULE_MATCH_USERID:
+                    intProp = new Integer(in.readInt());
+                    break;
+                default:
+                    // assume there was in int value to read as for now they come in pair
+                    in.readInt();
+                    throw new IllegalArgumentException("Illegal rule value " + rule + " in parcel");
+            }
+            return addRuleInternal(attr, intProp, rule);
+        }
+
+        /**
+         * Combines all of the matching and exclusion rules that have been set and return a new
+         * {@link AudioMixingRule} object.
+         * @return a new {@link AudioMixingRule} object
+         */
+        public AudioMixingRule build() {
+            return new AudioMixingRule(mTargetMixType, mCriteria,
+                mAllowPrivilegedMediaPlaybackCapture, mVoiceCommunicationCaptureAllowed);
+        }
+    }
+}
diff --git a/android/media/audiopolicy/AudioPolicy.java b/android/media/audiopolicy/AudioPolicy.java
new file mode 100644
index 0000000..3e8d76a
--- /dev/null
+++ b/android/media/audiopolicy/AudioPolicy.java
@@ -0,0 +1,1065 @@
+/*
+ * Copyright (C) 2014 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.audiopolicy;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.annotation.UserIdInt;
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.media.AudioAttributes;
+import android.media.AudioDeviceInfo;
+import android.media.AudioFocusInfo;
+import android.media.AudioFormat;
+import android.media.AudioManager;
+import android.media.AudioRecord;
+import android.media.AudioTrack;
+import android.media.IAudioService;
+import android.media.MediaRecorder;
+import android.media.projection.MediaProjection;
+import android.os.Binder;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+import android.util.Slog;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @hide
+ * AudioPolicy provides access to the management of audio routing and audio focus.
+ */
+@SystemApi
+public class AudioPolicy {
+
+    private static final String TAG = "AudioPolicy";
+    private static final boolean DEBUG = false;
+    private final Object mLock = new Object();
+
+    /**
+     * The status of an audio policy that is valid but cannot be used because it is not registered.
+     */
+    public static final int POLICY_STATUS_UNREGISTERED = 1;
+    /**
+     * The status of an audio policy that is valid, successfully registered and thus active.
+     */
+    public static final int POLICY_STATUS_REGISTERED = 2;
+
+    private int mStatus;
+    private String mRegistrationId;
+    private AudioPolicyStatusListener mStatusListener;
+    private boolean mIsFocusPolicy;
+    private boolean mIsTestFocusPolicy;
+
+    /**
+     * The list of AudioTrack instances created to inject audio into the associated mixes
+     * Lazy initialization in {@link #createAudioTrackSource(AudioMix)}
+     */
+    @GuardedBy("mLock")
+    @Nullable private ArrayList<WeakReference<AudioTrack>> mInjectors;
+    /**
+     * The list AudioRecord instances created to capture audio from the associated mixes
+     * Lazy initialization in {@link #createAudioRecordSink(AudioMix)}
+     */
+    @GuardedBy("mLock")
+    @Nullable private ArrayList<WeakReference<AudioRecord>> mCaptors;
+
+    /**
+     * The behavior of a policy with regards to audio focus where it relies on the application
+     * to do the ducking, the is the legacy and default behavior.
+     */
+    public static final int FOCUS_POLICY_DUCKING_IN_APP = 0;
+    public static final int FOCUS_POLICY_DUCKING_DEFAULT = FOCUS_POLICY_DUCKING_IN_APP;
+    /**
+     * The behavior of a policy with regards to audio focus where it handles ducking instead
+     * of the application losing focus and being signaled it can duck (as communicated by
+     * {@link android.media.AudioManager#AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK}).
+     * <br>Can only be used after having set a listener with
+     * {@link AudioPolicy#setAudioPolicyFocusListener(AudioPolicyFocusListener)}.
+     */
+    public static final int FOCUS_POLICY_DUCKING_IN_POLICY = 1;
+
+    private AudioPolicyFocusListener mFocusListener;
+
+    private final AudioPolicyVolumeCallback mVolCb;
+
+    private Context mContext;
+
+    private AudioPolicyConfig mConfig;
+
+    private final MediaProjection mProjection;
+
+    /** @hide */
+    public AudioPolicyConfig getConfig() { return mConfig; }
+    /** @hide */
+    public boolean hasFocusListener() { return mFocusListener != null; }
+    /** @hide */
+    public boolean isFocusPolicy() { return mIsFocusPolicy; }
+    /** @hide */
+    public boolean isTestFocusPolicy() {
+        return mIsTestFocusPolicy;
+    }
+    /** @hide */
+    public boolean isVolumeController() { return mVolCb != null; }
+    /** @hide */
+    public @Nullable MediaProjection getMediaProjection() {
+        return mProjection;
+    }
+
+    /**
+     * The parameters are guaranteed non-null through the Builder
+     */
+    private AudioPolicy(AudioPolicyConfig config, Context context, Looper looper,
+            AudioPolicyFocusListener fl, AudioPolicyStatusListener sl,
+            boolean isFocusPolicy, boolean isTestFocusPolicy,
+            AudioPolicyVolumeCallback vc, @Nullable MediaProjection projection) {
+        mConfig = config;
+        mStatus = POLICY_STATUS_UNREGISTERED;
+        mContext = context;
+        if (looper == null) {
+            looper = Looper.getMainLooper();
+        }
+        if (looper != null) {
+            mEventHandler = new EventHandler(this, looper);
+        } else {
+            mEventHandler = null;
+            Log.e(TAG, "No event handler due to looper without a thread");
+        }
+        mFocusListener = fl;
+        mStatusListener = sl;
+        mIsFocusPolicy = isFocusPolicy;
+        mIsTestFocusPolicy = isTestFocusPolicy;
+        mVolCb = vc;
+        mProjection = projection;
+    }
+
+    /**
+     * Builder class for {@link AudioPolicy} objects.
+     * By default the policy to be created doesn't govern audio focus decisions.
+     */
+    public static class Builder {
+        private ArrayList<AudioMix> mMixes;
+        private Context mContext;
+        private Looper mLooper;
+        private AudioPolicyFocusListener mFocusListener;
+        private AudioPolicyStatusListener mStatusListener;
+        private boolean mIsFocusPolicy = false;
+        private boolean mIsTestFocusPolicy = false;
+        private AudioPolicyVolumeCallback mVolCb;
+        private MediaProjection mProjection;
+
+        /**
+         * Constructs a new Builder with no audio mixes.
+         * @param context the context for the policy
+         */
+        public Builder(Context context) {
+            mMixes = new ArrayList<AudioMix>();
+            mContext = context;
+        }
+
+        /**
+         * Add an {@link AudioMix} to be part of the audio policy being built.
+         * @param mix a non-null {@link AudioMix} to be part of the audio policy.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        @NonNull
+        public Builder addMix(@NonNull AudioMix mix) throws IllegalArgumentException {
+            if (mix == null) {
+                throw new IllegalArgumentException("Illegal null AudioMix argument");
+            }
+            mMixes.add(mix);
+            return this;
+        }
+
+        /**
+         * Sets the {@link Looper} on which to run the event loop.
+         * @param looper a non-null specific Looper.
+         * @return the same Builder instance.
+         * @throws IllegalArgumentException
+         */
+        @NonNull
+        public Builder setLooper(@NonNull Looper looper) throws IllegalArgumentException {
+            if (looper == null) {
+                throw new IllegalArgumentException("Illegal null Looper argument");
+            }
+            mLooper = looper;
+            return this;
+        }
+
+        /**
+         * Sets the audio focus listener for the policy.
+         * @param l a {@link AudioPolicy.AudioPolicyFocusListener}
+         */
+        public void setAudioPolicyFocusListener(AudioPolicyFocusListener l) {
+            mFocusListener = l;
+        }
+
+        /**
+         * Declares whether this policy will grant and deny audio focus through
+         * the {@link AudioPolicy.AudioPolicyFocusListener}.
+         * If set to {@code true}, it is mandatory to set an
+         * {@link AudioPolicy.AudioPolicyFocusListener} in order to successfully build
+         * an {@code AudioPolicy} instance.
+         * @param enforce true if the policy will govern audio focus decisions.
+         * @return the same Builder instance.
+         */
+        @NonNull
+        public Builder setIsAudioFocusPolicy(boolean isFocusPolicy) {
+            mIsFocusPolicy = isFocusPolicy;
+            return this;
+        }
+
+        /**
+         * @hide
+         * Test method to declare whether this audio focus policy is for test purposes only.
+         * Having a test policy registered will disable the current focus policy and replace it
+         * with this test policy. When unregistered, the previous focus policy will be restored.
+         * <p>A value of <code>true</code> will be ignored if the AudioPolicy is not also
+         * focus policy.
+         * @param isTestFocusPolicy true if the focus policy to register is for testing purposes.
+         * @return the same Builder instance
+         */
+        @TestApi
+        @NonNull
+        public Builder setIsTestFocusPolicy(boolean isTestFocusPolicy) {
+            mIsTestFocusPolicy = isTestFocusPolicy;
+            return this;
+        }
+
+        /**
+         * Sets the audio policy status listener.
+         * @param l a {@link AudioPolicy.AudioPolicyStatusListener}
+         */
+        public void setAudioPolicyStatusListener(AudioPolicyStatusListener l) {
+            mStatusListener = l;
+        }
+
+        /**
+         * Sets the callback to receive all volume key-related events.
+         * The callback will only be called if the device is configured to handle volume events
+         * in the PhoneWindowManager (see config_handleVolumeKeysInWindowManager)
+         * @param vc
+         * @return the same Builder instance.
+         */
+        @NonNull
+        public Builder setAudioPolicyVolumeCallback(@NonNull AudioPolicyVolumeCallback vc) {
+            if (vc == null) {
+                throw new IllegalArgumentException("Invalid null volume callback");
+            }
+            mVolCb = vc;
+            return this;
+        }
+
+        /**
+         * Set a media projection obtained through createMediaProjection().
+         *
+         * A MediaProjection that can project audio allows to register an audio
+         * policy LOOPBACK|RENDER without the MODIFY_AUDIO_ROUTING permission.
+         *
+         * @hide
+         */
+        @NonNull
+        public Builder setMediaProjection(@NonNull MediaProjection projection) {
+            if (projection == null) {
+                throw new IllegalArgumentException("Invalid null volume callback");
+            }
+            mProjection = projection;
+            return this;
+
+        }
+
+        /**
+         * Combines all of the attributes that have been set on this {@code Builder} and returns a
+         * new {@link AudioPolicy} object.
+         * @return a new {@code AudioPolicy} object.
+         * @throws IllegalStateException if there is no
+         *     {@link AudioPolicy.AudioPolicyStatusListener} but the policy was configured
+         *     as an audio focus policy with {@link #setIsAudioFocusPolicy(boolean)}.
+         */
+        @NonNull
+        public AudioPolicy build() {
+            if (mStatusListener != null) {
+                // the AudioPolicy status listener includes updates on each mix activity state
+                for (AudioMix mix : mMixes) {
+                    mix.mCallbackFlags |= AudioMix.CALLBACK_FLAG_NOTIFY_ACTIVITY;
+                }
+            }
+            if (mIsFocusPolicy && mFocusListener == null) {
+                throw new IllegalStateException("Cannot be a focus policy without "
+                        + "an AudioPolicyFocusListener");
+            }
+            return new AudioPolicy(new AudioPolicyConfig(mMixes), mContext, mLooper,
+                    mFocusListener, mStatusListener, mIsFocusPolicy, mIsTestFocusPolicy,
+                    mVolCb, mProjection);
+        }
+    }
+
+    /**
+     * Update the current configuration of the set of audio mixes by adding new ones, while
+     * keeping the policy registered.
+     * This method can only be called on a registered policy.
+     * @param mixes the list of {@link AudioMix} to add
+     * @return {@link AudioManager#SUCCESS} if the change was successful, {@link AudioManager#ERROR}
+     *    otherwise.
+     */
+    public int attachMixes(@NonNull List<AudioMix> mixes) {
+        if (mixes == null) {
+            throw new IllegalArgumentException("Illegal null list of AudioMix");
+        }
+        synchronized (mLock) {
+            if (mStatus != POLICY_STATUS_REGISTERED) {
+                throw new IllegalStateException("Cannot alter unregistered AudioPolicy");
+            }
+            final ArrayList<AudioMix> zeMixes = new ArrayList<AudioMix>(mixes.size());
+            for (AudioMix mix : mixes) {
+                if (mix == null) {
+                    throw new IllegalArgumentException("Illegal null AudioMix in attachMixes");
+                } else {
+                    zeMixes.add(mix);
+                }
+            }
+            final AudioPolicyConfig cfg = new AudioPolicyConfig(zeMixes);
+            IAudioService service = getService();
+            try {
+                final int status = service.addMixForPolicy(cfg, this.cb());
+                if (status == AudioManager.SUCCESS) {
+                    mConfig.add(zeMixes);
+                }
+                return status;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in attachMixes", e);
+                return AudioManager.ERROR;
+            }
+        }
+    }
+
+    /**
+     * Update the current configuration of the set of audio mixes by removing some, while
+     * keeping the policy registered.
+     * This method can only be called on a registered policy.
+     * @param mixes the list of {@link AudioMix} to remove
+     * @return {@link AudioManager#SUCCESS} if the change was successful, {@link AudioManager#ERROR}
+     *    otherwise.
+     */
+    public int detachMixes(@NonNull List<AudioMix> mixes) {
+        if (mixes == null) {
+            throw new IllegalArgumentException("Illegal null list of AudioMix");
+        }
+        synchronized (mLock) {
+            if (mStatus != POLICY_STATUS_REGISTERED) {
+                throw new IllegalStateException("Cannot alter unregistered AudioPolicy");
+            }
+            final ArrayList<AudioMix> zeMixes = new ArrayList<AudioMix>(mixes.size());
+            for (AudioMix mix : mixes) {
+                if (mix == null) {
+                    throw new IllegalArgumentException("Illegal null AudioMix in detachMixes");
+                    // TODO also check mix is currently contained in list of mixes
+                } else {
+                    zeMixes.add(mix);
+                }
+            }
+            final AudioPolicyConfig cfg = new AudioPolicyConfig(zeMixes);
+            IAudioService service = getService();
+            try {
+                final int status = service.removeMixForPolicy(cfg, this.cb());
+                if (status == AudioManager.SUCCESS) {
+                    mConfig.remove(zeMixes);
+                }
+                return status;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in detachMixes", e);
+                return AudioManager.ERROR;
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Configures the audio framework so that all audio streams originating from the given UID
+     * can only come from a set of audio devices.
+     * For this routing to be operational, a number of {@link AudioMix} instances must have been
+     * previously registered on this policy, and routed to a super-set of the given audio devices
+     * with {@link AudioMix.Builder#setDevice(android.media.AudioDeviceInfo)}. Note that having
+     * multiple devices in the list doesn't imply the signals will be duplicated on the different
+     * audio devices, final routing will depend on the {@link AudioAttributes} of the sounds being
+     * played.
+     * @param uid UID of the application to affect.
+     * @param devices list of devices to which the audio stream of the application may be routed.
+     * @return true if the change was successful, false otherwise.
+     */
+    @SystemApi
+    public boolean setUidDeviceAffinity(int uid, @NonNull List<AudioDeviceInfo> devices) {
+        if (devices == null) {
+            throw new IllegalArgumentException("Illegal null list of audio devices");
+        }
+        synchronized (mLock) {
+            if (mStatus != POLICY_STATUS_REGISTERED) {
+                throw new IllegalStateException("Cannot use unregistered AudioPolicy");
+            }
+            final int[] deviceTypes = new int[devices.size()];
+            final String[] deviceAdresses = new String[devices.size()];
+            int i = 0;
+            for (AudioDeviceInfo device : devices) {
+                if (device == null) {
+                    throw new IllegalArgumentException(
+                            "Illegal null AudioDeviceInfo in setUidDeviceAffinity");
+                }
+                deviceTypes[i] =
+                        AudioDeviceInfo.convertDeviceTypeToInternalDevice(device.getType());
+                deviceAdresses[i] = device.getAddress();
+                i++;
+            }
+            final IAudioService service = getService();
+            try {
+                final int status = service.setUidDeviceAffinity(this.cb(),
+                        uid, deviceTypes, deviceAdresses);
+                return (status == AudioManager.SUCCESS);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in setUidDeviceAffinity", e);
+                return false;
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Removes audio device affinity previously set by
+     * {@link #setUidDeviceAffinity(int, java.util.List)}.
+     * @param uid UID of the application affected.
+     * @return true if the change was successful, false otherwise.
+     */
+    @SystemApi
+    public boolean removeUidDeviceAffinity(int uid) {
+        synchronized (mLock) {
+            if (mStatus != POLICY_STATUS_REGISTERED) {
+                throw new IllegalStateException("Cannot use unregistered AudioPolicy");
+            }
+            final IAudioService service = getService();
+            try {
+                final int status = service.removeUidDeviceAffinity(this.cb(), uid);
+                return (status == AudioManager.SUCCESS);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in removeUidDeviceAffinity", e);
+                return false;
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Removes audio device affinity previously set by
+     * {@link #setUserIdDeviceAffinity(int, java.util.List)}.
+     * @param userId userId of the application affected, as obtained via
+     * {@link UserHandle#getIdentifier}. Not to be confused with application uid.
+     * @return true if the change was successful, false otherwise.
+     */
+    @SystemApi
+    public boolean removeUserIdDeviceAffinity(@UserIdInt int userId) {
+        synchronized (mLock) {
+            if (mStatus != POLICY_STATUS_REGISTERED) {
+                throw new IllegalStateException("Cannot use unregistered AudioPolicy");
+            }
+            final IAudioService service = getService();
+            try {
+                final int status = service.removeUserIdDeviceAffinity(this.cb(), userId);
+                return (status == AudioManager.SUCCESS);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in removeUserIdDeviceAffinity", e);
+                return false;
+            }
+        }
+    }
+
+    /**
+     * @hide
+     * Configures the audio framework so that all audio streams originating from the given user
+     * can only come from a set of audio devices.
+     * For this routing to be operational, a number of {@link AudioMix} instances must have been
+     * previously registered on this policy, and routed to a super-set of the given audio devices
+     * with {@link AudioMix.Builder#setDevice(android.media.AudioDeviceInfo)}. Note that having
+     * multiple devices in the list doesn't imply the signals will be duplicated on the different
+     * audio devices, final routing will depend on the {@link AudioAttributes} of the sounds being
+     * played.
+     * @param userId userId of the application affected, as obtained via
+     * {@link UserHandle#getIdentifier}. Not to be confused with application uid.
+     * @param devices list of devices to which the audio stream of the application may be routed.
+     * @return true if the change was successful, false otherwise.
+     */
+    @SystemApi
+    public boolean setUserIdDeviceAffinity(@UserIdInt int userId,
+            @NonNull List<AudioDeviceInfo> devices) {
+        Objects.requireNonNull(devices, "Illegal null list of audio devices");
+        synchronized (mLock) {
+            if (mStatus != POLICY_STATUS_REGISTERED) {
+                throw new IllegalStateException("Cannot use unregistered AudioPolicy");
+            }
+            final int[] deviceTypes = new int[devices.size()];
+            final String[] deviceAddresses = new String[devices.size()];
+            int i = 0;
+            for (AudioDeviceInfo device : devices) {
+                if (device == null) {
+                    throw new IllegalArgumentException(
+                            "Illegal null AudioDeviceInfo in setUserIdDeviceAffinity");
+                }
+                deviceTypes[i] =
+                        AudioDeviceInfo.convertDeviceTypeToInternalDevice(device.getType());
+                deviceAddresses[i] = device.getAddress();
+                i++;
+            }
+            final IAudioService service = getService();
+            try {
+                final int status = service.setUserIdDeviceAffinity(this.cb(),
+                        userId, deviceTypes, deviceAddresses);
+                return (status == AudioManager.SUCCESS);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in setUserIdDeviceAffinity", e);
+                return false;
+            }
+        }
+    }
+
+    /** @hide */
+    public void reset() {
+        setRegistration(null);
+        mConfig.reset();
+    }
+
+    public void setRegistration(String regId) {
+        synchronized (mLock) {
+            mRegistrationId = regId;
+            mConfig.setRegistration(regId);
+            if (regId != null) {
+                mStatus = POLICY_STATUS_REGISTERED;
+            } else {
+                mStatus = POLICY_STATUS_UNREGISTERED;
+            }
+        }
+        sendMsg(MSG_POLICY_STATUS_CHANGE);
+    }
+
+    /**@hide*/
+    public String getRegistration() {
+        return mRegistrationId;
+    }
+
+    private boolean policyReadyToUse() {
+        synchronized (mLock) {
+            if (mStatus != POLICY_STATUS_REGISTERED) {
+                Log.e(TAG, "Cannot use unregistered AudioPolicy");
+                return false;
+            }
+            if (mRegistrationId == null) {
+                Log.e(TAG, "Cannot use unregistered AudioPolicy");
+                return false;
+            }
+        }
+
+        // Loopback|capture only need an audio projection, everything else need MODIFY_AUDIO_ROUTING
+        boolean canModifyAudioRouting = PackageManager.PERMISSION_GRANTED
+                == checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_AUDIO_ROUTING);
+
+        boolean canProjectAudio;
+        try {
+            canProjectAudio = mProjection != null && mProjection.getProjection().canProjectAudio();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to check if MediaProjection#canProjectAudio");
+            throw e.rethrowFromSystemServer();
+        }
+
+        if (!((isLoopbackRenderPolicy() && canProjectAudio) || canModifyAudioRouting)) {
+            Slog.w(TAG, "Cannot use AudioPolicy for pid " + Binder.getCallingPid() + " / uid "
+                    + Binder.getCallingUid() + ", needs MODIFY_AUDIO_ROUTING or "
+                    + "MediaProjection that can project audio.");
+            return false;
+        }
+        return true;
+    }
+
+    private boolean isLoopbackRenderPolicy() {
+        synchronized (mLock) {
+            return mConfig.mMixes.stream().allMatch(mix -> mix.getRouteFlags()
+                    == (mix.ROUTE_FLAG_RENDER | mix.ROUTE_FLAG_LOOP_BACK));
+        }
+    }
+
+    /**
+     * Returns {@link PackageManager#PERMISSION_GRANTED} if the caller has the given permission.
+     */
+    private @PackageManager.PermissionResult int checkCallingOrSelfPermission(String permission) {
+        if (mContext != null) {
+            return mContext.checkCallingOrSelfPermission(permission);
+        }
+        Slog.v(TAG, "Null context, checking permission via ActivityManager");
+        int pid = Binder.getCallingPid();
+        int uid = Binder.getCallingUid();
+        try {
+            return ActivityManager.getService().checkPermission(permission, pid, uid);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    private void checkMixReadyToUse(AudioMix mix, boolean forTrack)
+            throws IllegalArgumentException{
+        if (mix == null) {
+            String msg = forTrack ? "Invalid null AudioMix for AudioTrack creation"
+                    : "Invalid null AudioMix for AudioRecord creation";
+            throw new IllegalArgumentException(msg);
+        }
+        if (!mConfig.mMixes.contains(mix)) {
+            throw new IllegalArgumentException("Invalid mix: not part of this policy");
+        }
+        if ((mix.getRouteFlags() & AudioMix.ROUTE_FLAG_LOOP_BACK) != AudioMix.ROUTE_FLAG_LOOP_BACK)
+        {
+            throw new IllegalArgumentException("Invalid AudioMix: not defined for loop back");
+        }
+        if (forTrack && (mix.getMixType() != AudioMix.MIX_TYPE_RECORDERS)) {
+            throw new IllegalArgumentException(
+                    "Invalid AudioMix: not defined for being a recording source");
+        }
+        if (!forTrack && (mix.getMixType() != AudioMix.MIX_TYPE_PLAYERS)) {
+            throw new IllegalArgumentException(
+                    "Invalid AudioMix: not defined for capturing playback");
+        }
+    }
+
+    /**
+     * Returns the current behavior for audio focus-related ducking.
+     * @return {@link #FOCUS_POLICY_DUCKING_IN_APP} or {@link #FOCUS_POLICY_DUCKING_IN_POLICY}
+     */
+    public int getFocusDuckingBehavior() {
+        return mConfig.mDuckingPolicy;
+    }
+
+    // Note on implementation: not part of the Builder as there can be only one registered policy
+    // that handles ducking but there can be multiple policies
+    /**
+     * Sets the behavior for audio focus-related ducking.
+     * There must be a focus listener if this policy is to handle ducking.
+     * @param behavior {@link #FOCUS_POLICY_DUCKING_IN_APP} or
+     *     {@link #FOCUS_POLICY_DUCKING_IN_POLICY}
+     * @return {@link AudioManager#SUCCESS} or {@link AudioManager#ERROR} (for instance if there
+     *     is already an audio policy that handles ducking).
+     * @throws IllegalArgumentException
+     * @throws IllegalStateException
+     */
+    public int setFocusDuckingBehavior(int behavior)
+            throws IllegalArgumentException, IllegalStateException {
+        if ((behavior != FOCUS_POLICY_DUCKING_IN_APP)
+                && (behavior != FOCUS_POLICY_DUCKING_IN_POLICY)) {
+            throw new IllegalArgumentException("Invalid ducking behavior " + behavior);
+        }
+        synchronized (mLock) {
+            if (mStatus != POLICY_STATUS_REGISTERED) {
+                throw new IllegalStateException(
+                        "Cannot change ducking behavior for unregistered policy");
+            }
+            if ((behavior == FOCUS_POLICY_DUCKING_IN_POLICY)
+                    && (mFocusListener == null)) {
+                // there must be a focus listener if the policy handles ducking
+                throw new IllegalStateException(
+                        "Cannot handle ducking without an audio focus listener");
+            }
+            IAudioService service = getService();
+            try {
+                final int status = service.setFocusPropertiesForPolicy(behavior /*duckingBehavior*/,
+                        this.cb());
+                if (status == AudioManager.SUCCESS) {
+                    mConfig.mDuckingPolicy = behavior;
+                }
+                return status;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in setFocusPropertiesForPolicy for behavior", e);
+                return AudioManager.ERROR;
+            }
+        }
+    }
+
+    /**
+     * Create an {@link AudioRecord} instance that is associated with the given {@link AudioMix}.
+     * Audio buffers recorded through the created instance will contain the mix of the audio
+     * streams that fed the given mixer.
+     * @param mix a non-null {@link AudioMix} instance whose routing flags was defined with
+     *     {@link AudioMix#ROUTE_FLAG_LOOP_BACK}, previously added to this policy.
+     * @return a new {@link AudioRecord} instance whose data format is the one defined in the
+     *     {@link AudioMix}, or null if this policy was not successfully registered
+     *     with {@link AudioManager#registerAudioPolicy(AudioPolicy)}.
+     * @throws IllegalArgumentException
+     */
+    public AudioRecord createAudioRecordSink(AudioMix mix) throws IllegalArgumentException {
+        if (!policyReadyToUse()) {
+            Log.e(TAG, "Cannot create AudioRecord sink for AudioMix");
+            return null;
+        }
+        checkMixReadyToUse(mix, false/*not for an AudioTrack*/);
+        // create an AudioFormat from the mix format compatible with recording, as the mix
+        // was defined for playback
+        AudioFormat mixFormat = new AudioFormat.Builder(mix.getFormat())
+                .setChannelMask(AudioFormat.inChannelMaskFromOutChannelMask(
+                        mix.getFormat().getChannelMask()))
+                .build();
+        // create the AudioRecord, configured for loop back, using the same format as the mix
+        AudioRecord ar = new AudioRecord(
+                new AudioAttributes.Builder()
+                        .setInternalCapturePreset(MediaRecorder.AudioSource.REMOTE_SUBMIX)
+                        .addTag(addressForTag(mix))
+                        .addTag(AudioRecord.SUBMIX_FIXED_VOLUME)
+                        .build(),
+                mixFormat,
+                AudioRecord.getMinBufferSize(mix.getFormat().getSampleRate(),
+                        // using stereo for buffer size to avoid the current poor support for masks
+                        AudioFormat.CHANNEL_IN_STEREO, mix.getFormat().getEncoding()),
+                AudioManager.AUDIO_SESSION_ID_GENERATE
+                );
+        synchronized (mLock) {
+            if (mCaptors == null) {
+                mCaptors = new ArrayList<>(1);
+            }
+            mCaptors.add(new WeakReference<AudioRecord>(ar));
+        }
+        return ar;
+    }
+
+    /**
+     * Create an {@link AudioTrack} instance that is associated with the given {@link AudioMix}.
+     * Audio buffers played through the created instance will be sent to the given mix
+     * to be recorded through the recording APIs.
+     * @param mix a non-null {@link AudioMix} instance whose routing flags was defined with
+     *     {@link AudioMix#ROUTE_FLAG_LOOP_BACK}, previously added to this policy.
+     * @return a new {@link AudioTrack} instance whose data format is the one defined in the
+     *     {@link AudioMix}, or null if this policy was not successfully registered
+     *     with {@link AudioManager#registerAudioPolicy(AudioPolicy)}.
+     * @throws IllegalArgumentException
+     */
+    public AudioTrack createAudioTrackSource(AudioMix mix) throws IllegalArgumentException {
+        if (!policyReadyToUse()) {
+            Log.e(TAG, "Cannot create AudioTrack source for AudioMix");
+            return null;
+        }
+        checkMixReadyToUse(mix, true/*for an AudioTrack*/);
+        // create the AudioTrack, configured for loop back, using the same format as the mix
+        AudioTrack at = new AudioTrack(
+                new AudioAttributes.Builder()
+                        .setUsage(AudioAttributes.USAGE_VIRTUAL_SOURCE)
+                        .addTag(addressForTag(mix))
+                        .build(),
+                mix.getFormat(),
+                AudioTrack.getMinBufferSize(mix.getFormat().getSampleRate(),
+                        mix.getFormat().getChannelMask(), mix.getFormat().getEncoding()),
+                AudioTrack.MODE_STREAM,
+                AudioManager.AUDIO_SESSION_ID_GENERATE
+                );
+        synchronized (mLock) {
+            if (mInjectors == null) {
+                mInjectors = new ArrayList<>(1);
+            }
+            mInjectors.add(new WeakReference<AudioTrack>(at));
+        }
+        return at;
+    }
+
+    /**
+     * @hide
+     */
+    public void invalidateCaptorsAndInjectors() {
+        if (!policyReadyToUse()) {
+            return;
+        }
+        synchronized (mLock) {
+            if (mInjectors != null) {
+                for (final WeakReference<AudioTrack> weakTrack : mInjectors) {
+                    final AudioTrack track = weakTrack.get();
+                    if (track == null) {
+                        break;
+                    }
+                    try {
+                        // TODO: add synchronous versions
+                        track.stop();
+                        track.flush();
+                    } catch (IllegalStateException e) {
+                        // ignore exception, AudioTrack could have already been stopped or
+                        // released by the user of the AudioPolicy
+                    }
+                }
+            }
+            if (mCaptors != null) {
+                for (final WeakReference<AudioRecord> weakRecord : mCaptors) {
+                    final AudioRecord record = weakRecord.get();
+                    if (record == null) {
+                        break;
+                    }
+                    try {
+                        // TODO: if needed: implement an invalidate method
+                        record.stop();
+                    } catch (IllegalStateException e) {
+                        // ignore exception, AudioRecord could have already been stopped or
+                        // released by the user of the AudioPolicy
+                    }
+                }
+            }
+        }
+    }
+
+    public int getStatus() {
+        return mStatus;
+    }
+
+    public static abstract class AudioPolicyStatusListener {
+        public void onStatusChange() {}
+        public void onMixStateUpdate(AudioMix mix) {}
+    }
+
+    public static abstract class AudioPolicyFocusListener {
+        public void onAudioFocusGrant(AudioFocusInfo afi, int requestResult) {}
+        public void onAudioFocusLoss(AudioFocusInfo afi, boolean wasNotified) {}
+        /**
+         * Called whenever an application requests audio focus.
+         * Only ever called if the {@link AudioPolicy} was built with
+         * {@link AudioPolicy.Builder#setIsAudioFocusPolicy(boolean)} set to {@code true}.
+         * @param afi information about the focus request and the requester
+         * @param requestResult deprecated after the addition of
+         *     {@link AudioManager#setFocusRequestResult(AudioFocusInfo, int, AudioPolicy)}
+         *     in Android P, always equal to {@link #AUDIOFOCUS_REQUEST_GRANTED}.
+         */
+        public void onAudioFocusRequest(AudioFocusInfo afi, int requestResult) {}
+        /**
+         * Called whenever an application abandons audio focus.
+         * Only ever called if the {@link AudioPolicy} was built with
+         * {@link AudioPolicy.Builder#setIsAudioFocusPolicy(boolean)} set to {@code true}.
+         * @param afi information about the focus request being abandoned and the original
+         *     requester.
+         */
+        public void onAudioFocusAbandon(AudioFocusInfo afi) {}
+    }
+
+    /**
+     * Callback class to receive volume change-related events.
+     * See {@link #Builder.setAudioPolicyVolumeCallback(AudioPolicyCallback)} to configure the
+     * {@link AudioPolicy} to receive those events.
+     *
+     */
+    public static abstract class AudioPolicyVolumeCallback {
+        public AudioPolicyVolumeCallback() {}
+        /**
+         * Called when volume key-related changes are triggered, on the key down event.
+         * @param adjustment the type of volume adjustment for the key.
+         */
+        public void onVolumeAdjustment(@AudioManager.VolumeAdjustment int adjustment) {}
+    }
+
+    private void onPolicyStatusChange() {
+        AudioPolicyStatusListener l;
+        synchronized (mLock) {
+            if (mStatusListener == null) {
+                return;
+            }
+            l = mStatusListener;
+        }
+        l.onStatusChange();
+    }
+
+    //==================================================
+    // Callback interface
+
+    /** @hide */
+    public IAudioPolicyCallback cb() { return mPolicyCb; }
+
+    private final IAudioPolicyCallback mPolicyCb = new IAudioPolicyCallback.Stub() {
+
+        public void notifyAudioFocusGrant(AudioFocusInfo afi, int requestResult) {
+            sendMsg(MSG_FOCUS_GRANT, afi, requestResult);
+            if (DEBUG) {
+                Log.v(TAG, "notifyAudioFocusGrant: pack=" + afi.getPackageName() + " client="
+                        + afi.getClientId() + "reqRes=" + requestResult);
+            }
+        }
+
+        public void notifyAudioFocusLoss(AudioFocusInfo afi, boolean wasNotified) {
+            sendMsg(MSG_FOCUS_LOSS, afi, wasNotified ? 1 : 0);
+            if (DEBUG) {
+                Log.v(TAG, "notifyAudioFocusLoss: pack=" + afi.getPackageName() + " client="
+                        + afi.getClientId() + "wasNotified=" + wasNotified);
+            }
+        }
+
+        public void notifyAudioFocusRequest(AudioFocusInfo afi, int requestResult) {
+            sendMsg(MSG_FOCUS_REQUEST, afi, requestResult);
+            if (DEBUG) {
+                Log.v(TAG, "notifyAudioFocusRequest: pack=" + afi.getPackageName() + " client="
+                        + afi.getClientId() + " gen=" + afi.getGen());
+            }
+        }
+
+        public void notifyAudioFocusAbandon(AudioFocusInfo afi) {
+            sendMsg(MSG_FOCUS_ABANDON, afi, 0 /* ignored */);
+            if (DEBUG) {
+                Log.v(TAG, "notifyAudioFocusAbandon: pack=" + afi.getPackageName() + " client="
+                        + afi.getClientId());
+            }
+        }
+
+        public void notifyMixStateUpdate(String regId, int state) {
+            for (AudioMix mix : mConfig.getMixes()) {
+                if (mix.getRegistration().equals(regId)) {
+                    mix.mMixState = state;
+                    sendMsg(MSG_MIX_STATE_UPDATE, mix, 0/*ignored*/);
+                    if (DEBUG) {
+                        Log.v(TAG, "notifyMixStateUpdate: regId=" + regId + " state=" + state);
+                    }
+                }
+            }
+        }
+
+        public void notifyVolumeAdjust(int adjustment) {
+            sendMsg(MSG_VOL_ADJUST, null /* ignored */, adjustment);
+            if (DEBUG) {
+                Log.v(TAG, "notifyVolumeAdjust: " + adjustment);
+            }
+        }
+
+        public void notifyUnregistration() {
+            setRegistration(null);
+        }
+    };
+
+    //==================================================
+    // Event handling
+    private final EventHandler mEventHandler;
+    private final static int MSG_POLICY_STATUS_CHANGE = 0;
+    private final static int MSG_FOCUS_GRANT = 1;
+    private final static int MSG_FOCUS_LOSS = 2;
+    private final static int MSG_MIX_STATE_UPDATE = 3;
+    private final static int MSG_FOCUS_REQUEST = 4;
+    private final static int MSG_FOCUS_ABANDON = 5;
+    private final static int MSG_VOL_ADJUST = 6;
+
+    private class EventHandler extends Handler {
+        public EventHandler(AudioPolicy ap, Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch(msg.what) {
+                case MSG_POLICY_STATUS_CHANGE:
+                    onPolicyStatusChange();
+                    break;
+                case MSG_FOCUS_GRANT:
+                    if (mFocusListener != null) {
+                        mFocusListener.onAudioFocusGrant(
+                                (AudioFocusInfo) msg.obj, msg.arg1);
+                    }
+                    break;
+                case MSG_FOCUS_LOSS:
+                    if (mFocusListener != null) {
+                        mFocusListener.onAudioFocusLoss(
+                                (AudioFocusInfo) msg.obj, msg.arg1 != 0);
+                    }
+                    break;
+                case MSG_MIX_STATE_UPDATE:
+                    if (mStatusListener != null) {
+                        mStatusListener.onMixStateUpdate((AudioMix) msg.obj);
+                    }
+                    break;
+                case MSG_FOCUS_REQUEST:
+                    if (mFocusListener != null) {
+                        mFocusListener.onAudioFocusRequest((AudioFocusInfo) msg.obj, msg.arg1);
+                    } else { // should never be null, but don't crash
+                        Log.e(TAG, "Invalid null focus listener for focus request event");
+                    }
+                    break;
+                case MSG_FOCUS_ABANDON:
+                    if (mFocusListener != null) { // should never be null
+                        mFocusListener.onAudioFocusAbandon((AudioFocusInfo) msg.obj);
+                    } else { // should never be null, but don't crash
+                        Log.e(TAG, "Invalid null focus listener for focus abandon event");
+                    }
+                    break;
+                case MSG_VOL_ADJUST:
+                    if (mVolCb != null) {
+                        mVolCb.onVolumeAdjustment(msg.arg1);
+                    } else { // should never be null, but don't crash
+                        Log.e(TAG, "Invalid null volume event");
+                    }
+                    break;
+                default:
+                    Log.e(TAG, "Unknown event " + msg.what);
+            }
+        }
+    }
+
+    //==========================================================
+    // Utils
+    private static String addressForTag(AudioMix mix) {
+        return "addr=" + mix.getRegistration();
+    }
+
+    private void sendMsg(int msg) {
+        if (mEventHandler != null) {
+            mEventHandler.sendEmptyMessage(msg);
+        }
+    }
+
+    private void sendMsg(int msg, Object obj, int i) {
+        if (mEventHandler != null) {
+            mEventHandler.sendMessage(
+                    mEventHandler.obtainMessage(msg, i /*arg1*/, 0 /*arg2, ignored*/, obj));
+        }
+    }
+
+    private static IAudioService sService;
+
+    private static IAudioService getService()
+    {
+        if (sService != null) {
+            return sService;
+        }
+        IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
+        sService = IAudioService.Stub.asInterface(b);
+        return sService;
+    }
+
+    public String toLogFriendlyString() {
+        String textDump = new String("android.media.audiopolicy.AudioPolicy:\n");
+        textDump += "config=" + mConfig.toLogFriendlyString();
+        return (textDump);
+    }
+
+    /** @hide */
+    @IntDef({
+        POLICY_STATUS_REGISTERED,
+        POLICY_STATUS_UNREGISTERED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PolicyStatus {}
+}
diff --git a/android/media/audiopolicy/AudioPolicyConfig.java b/android/media/audiopolicy/AudioPolicyConfig.java
new file mode 100644
index 0000000..346edc3
--- /dev/null
+++ b/android/media/audiopolicy/AudioPolicyConfig.java
@@ -0,0 +1,314 @@
+/*
+ * Copyright (C) 2014 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.audiopolicy;
+
+import android.annotation.NonNull;
+import android.media.AudioFormat;
+import android.media.audiopolicy.AudioMixingRule.AudioMixMatchCriterion;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.Objects;
+
+/**
+ * @hide
+ * Internal storage class for AudioPolicy configuration.
+ */
+public class AudioPolicyConfig implements Parcelable {
+
+    private static final String TAG = "AudioPolicyConfig";
+
+    protected final ArrayList<AudioMix> mMixes;
+    protected int mDuckingPolicy = AudioPolicy.FOCUS_POLICY_DUCKING_IN_APP;
+
+    private String mRegistrationId = null;
+
+    /** counter for the mixes that are / have been in the list of AudioMix
+     *  e.g. register 4 mixes (counter is 3), remove 1 (counter is 3), add 1 (counter is 4)
+     */
+    private int mMixCounter = 0;
+
+    protected AudioPolicyConfig(AudioPolicyConfig conf) {
+        mMixes = conf.mMixes;
+    }
+
+    AudioPolicyConfig(ArrayList<AudioMix> mixes) {
+        mMixes = mixes;
+    }
+
+    /**
+     * Add an {@link AudioMix} to be part of the audio policy being built.
+     * @param mix a non-null {@link AudioMix} to be part of the audio policy.
+     * @return the same Builder instance.
+     * @throws IllegalArgumentException
+     */
+    public void addMix(AudioMix mix) throws IllegalArgumentException {
+        if (mix == null) {
+            throw new IllegalArgumentException("Illegal null AudioMix argument");
+        }
+        mMixes.add(mix);
+    }
+
+    public ArrayList<AudioMix> getMixes() {
+        return mMixes;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mMixes);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mMixes.size());
+        for (AudioMix mix : mMixes) {
+            // write mix route flags
+            dest.writeInt(mix.getRouteFlags());
+            // write callback flags
+            dest.writeInt(mix.mCallbackFlags);
+            // write device information
+            dest.writeInt(mix.mDeviceSystemType);
+            dest.writeString(mix.mDeviceAddress);
+            // write mix format
+            dest.writeInt(mix.getFormat().getSampleRate());
+            dest.writeInt(mix.getFormat().getEncoding());
+            dest.writeInt(mix.getFormat().getChannelMask());
+            // write opt-out respect
+            dest.writeBoolean(mix.getRule().allowPrivilegedMediaPlaybackCapture());
+            // write voice communication capture allowed flag
+            dest.writeBoolean(mix.getRule().voiceCommunicationCaptureAllowed());
+            // write specified mix type
+            dest.writeInt(mix.getRule().getTargetMixType());
+            // write mix rules
+            final ArrayList<AudioMixMatchCriterion> criteria = mix.getRule().getCriteria();
+            dest.writeInt(criteria.size());
+            for (AudioMixMatchCriterion criterion : criteria) {
+                criterion.writeToParcel(dest);
+            }
+        }
+    }
+
+    private AudioPolicyConfig(Parcel in) {
+        mMixes = new ArrayList<AudioMix>();
+        int nbMixes = in.readInt();
+        for (int i = 0 ; i < nbMixes ; i++) {
+            final AudioMix.Builder mixBuilder = new AudioMix.Builder();
+            // read mix route flags
+            int routeFlags = in.readInt();
+            mixBuilder.setRouteFlags(routeFlags);
+            // read callback flags
+            mixBuilder.setCallbackFlags(in.readInt());
+            // read device information
+            mixBuilder.setDevice(in.readInt(), in.readString());
+            // read mix format
+            int sampleRate = in.readInt();
+            int encoding = in.readInt();
+            int channelMask = in.readInt();
+            final AudioFormat format = new AudioFormat.Builder().setSampleRate(sampleRate)
+                    .setChannelMask(channelMask).setEncoding(encoding).build();
+            mixBuilder.setFormat(format);
+
+            AudioMixingRule.Builder ruleBuilder = new AudioMixingRule.Builder();
+            // read opt-out respect
+            ruleBuilder.allowPrivilegedPlaybackCapture(in.readBoolean());
+            // read voice capture allowed flag
+            ruleBuilder.voiceCommunicationCaptureAllowed(in.readBoolean());
+            // read specified mix type
+            ruleBuilder.setTargetMixType(in.readInt());
+            // read mix rules
+            int nbRules = in.readInt();
+            for (int j = 0 ; j < nbRules ; j++) {
+                // read the matching rules
+                ruleBuilder.addRuleFromParcel(in);
+            }
+            mixBuilder.setMixingRule(ruleBuilder.build());
+            mMixes.add(mixBuilder.build());
+        }
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<AudioPolicyConfig> CREATOR
+            = new Parcelable.Creator<AudioPolicyConfig>() {
+        /**
+         * Rebuilds an AudioPolicyConfig previously stored with writeToParcel().
+         * @param p Parcel object to read the AudioPolicyConfig from
+         * @return a new AudioPolicyConfig created from the data in the parcel
+         */
+        public AudioPolicyConfig createFromParcel(Parcel p) {
+            return new AudioPolicyConfig(p);
+        }
+        public AudioPolicyConfig[] newArray(int size) {
+            return new AudioPolicyConfig[size];
+        }
+    };
+
+    public String toLogFriendlyString () {
+        String textDump = new String("android.media.audiopolicy.AudioPolicyConfig:\n");
+        textDump += mMixes.size() + " AudioMix, reg:" + mRegistrationId + "\n";
+        for(AudioMix mix : mMixes) {
+            // write mix route flags
+            textDump += "* route flags=0x" + Integer.toHexString(mix.getRouteFlags()) + "\n";
+            // write mix format
+            textDump += "  rate=" + mix.getFormat().getSampleRate() + "Hz\n";
+            textDump += "  encoding=" + mix.getFormat().getEncoding() + "\n";
+            textDump += "  channels=0x";
+            textDump += Integer.toHexString(mix.getFormat().getChannelMask()).toUpperCase() + "\n";
+            textDump += "  ignore playback capture opt out="
+                    + mix.getRule().allowPrivilegedMediaPlaybackCapture() + "\n";
+            textDump += "  allow voice communication capture="
+                    + mix.getRule().voiceCommunicationCaptureAllowed() + "\n";
+            // write mix rules
+            textDump += "  specified mix type="
+                    + mix.getRule().getTargetMixType() + "\n";
+            final ArrayList<AudioMixMatchCriterion> criteria = mix.getRule().getCriteria();
+            for (AudioMixMatchCriterion criterion : criteria) {
+                switch(criterion.mRule) {
+                    case AudioMixingRule.RULE_EXCLUDE_ATTRIBUTE_USAGE:
+                        textDump += "  exclude usage ";
+                        textDump += criterion.mAttr.usageToString();
+                        break;
+                    case AudioMixingRule.RULE_MATCH_ATTRIBUTE_USAGE:
+                        textDump += "  match usage ";
+                        textDump += criterion.mAttr.usageToString();
+                        break;
+                    case AudioMixingRule.RULE_EXCLUDE_ATTRIBUTE_CAPTURE_PRESET:
+                        textDump += "  exclude capture preset ";
+                        textDump += criterion.mAttr.getCapturePreset();
+                        break;
+                    case AudioMixingRule.RULE_MATCH_ATTRIBUTE_CAPTURE_PRESET:
+                        textDump += "  match capture preset ";
+                        textDump += criterion.mAttr.getCapturePreset();
+                        break;
+                    case AudioMixingRule.RULE_MATCH_UID:
+                        textDump += "  match UID ";
+                        textDump += criterion.mIntProp;
+                        break;
+                    case AudioMixingRule.RULE_EXCLUDE_UID:
+                        textDump += "  exclude UID ";
+                        textDump += criterion.mIntProp;
+                        break;
+                    case AudioMixingRule.RULE_MATCH_USERID:
+                        textDump += "  match userId ";
+                        textDump += criterion.mIntProp;
+                        break;
+                    case AudioMixingRule.RULE_EXCLUDE_USERID:
+                        textDump += "  exclude userId ";
+                        textDump += criterion.mIntProp;
+                        break;
+                    default:
+                        textDump += "invalid rule!";
+                }
+                textDump += "\n";
+            }
+        }
+        return textDump;
+    }
+
+    /**
+     * Very short dump of configuration
+     * @return a condensed dump of configuration, uniquely identifies a policy in a log
+     */
+    public String toCompactLogString() {
+        String compactDump = "reg:" + mRegistrationId;
+        int mixNum = 0;
+        for (AudioMix mix : mMixes) {
+            compactDump += " Mix:" + mixNum + "-Typ:" + mixTypePrefix(mix.getMixType())
+                    + "-Rul:" + mix.getRule().getCriteria().size();
+            mixNum++;
+        }
+        return compactDump;
+    }
+
+    private static String mixTypePrefix(int mixType) {
+        switch (mixType) {
+            case AudioMix.MIX_TYPE_PLAYERS:
+                return "p";
+            case AudioMix.MIX_TYPE_RECORDERS:
+                return "r";
+            case AudioMix.MIX_TYPE_INVALID:
+            default:
+                return "#";
+
+        }
+    }
+
+    protected void reset() {
+        mMixCounter = 0;
+    }
+
+    protected void setRegistration(String regId) {
+        final boolean currentRegNull = (mRegistrationId == null) || mRegistrationId.isEmpty();
+        final boolean newRegNull = (regId == null) || regId.isEmpty();
+        if (!currentRegNull && !newRegNull && !mRegistrationId.equals(regId)) {
+            Log.e(TAG, "Invalid registration transition from " + mRegistrationId + " to " + regId);
+            return;
+        }
+        mRegistrationId = regId == null ? "" : regId;
+        for (AudioMix mix : mMixes) {
+            setMixRegistration(mix);
+        }
+    }
+
+    private void setMixRegistration(@NonNull final AudioMix mix) {
+        if (!mRegistrationId.isEmpty()) {
+            if ((mix.getRouteFlags() & AudioMix.ROUTE_FLAG_LOOP_BACK) ==
+                    AudioMix.ROUTE_FLAG_LOOP_BACK) {
+                mix.setRegistration(mRegistrationId + "mix" + mixTypeId(mix.getMixType()) + ":"
+                        + mMixCounter);
+            } else if ((mix.getRouteFlags() & AudioMix.ROUTE_FLAG_RENDER) ==
+                    AudioMix.ROUTE_FLAG_RENDER) {
+                mix.setRegistration(mix.mDeviceAddress);
+            }
+        } else {
+            mix.setRegistration("");
+        }
+        mMixCounter++;
+    }
+
+    @GuardedBy("mMixes")
+    protected void add(@NonNull ArrayList<AudioMix> mixes) {
+        for (AudioMix mix : mixes) {
+            setMixRegistration(mix);
+            mMixes.add(mix);
+        }
+    }
+
+    @GuardedBy("mMixes")
+    protected void remove(@NonNull ArrayList<AudioMix> mixes) {
+        for (AudioMix mix : mixes) {
+            mMixes.remove(mix);
+        }
+    }
+
+    private static String mixTypeId(int type) {
+        if (type == AudioMix.MIX_TYPE_PLAYERS) return "p";
+        else if (type == AudioMix.MIX_TYPE_RECORDERS) return "r";
+        else return "i";
+    }
+
+    protected String getRegistration() {
+        return mRegistrationId;
+    }
+}
diff --git a/android/media/audiopolicy/AudioProductStrategy.java b/android/media/audiopolicy/AudioProductStrategy.java
new file mode 100644
index 0000000..fca3498
--- /dev/null
+++ b/android/media/audiopolicy/AudioProductStrategy.java
@@ -0,0 +1,493 @@
+/*
+ * Copyright (C) 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.audiopolicy;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.media.AudioAttributes;
+import android.media.AudioSystem;
+import android.media.MediaRecorder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @hide
+ * A class to encapsulate a collection of attributes associated to a given product strategy
+ * (and for legacy reason, keep the association with the stream type).
+ */
+@SystemApi
+public final class AudioProductStrategy implements Parcelable {
+    /**
+     * group value to use when introspection API fails.
+     * @hide
+     */
+    public static final int DEFAULT_GROUP = -1;
+
+
+    private static final String TAG = "AudioProductStrategy";
+
+    private final AudioAttributesGroup[] mAudioAttributesGroups;
+    private final String mName;
+    /**
+     * Unique identifier of a product strategy.
+     * This Id can be assimilated to Car Audio Usage and even more generally to usage.
+     * For legacy platforms, the product strategy id is the routing_strategy, which was hidden to
+     * upper layer but was transpiring in the {@link AudioAttributes#getUsage()}.
+     */
+    private int mId;
+
+    private static final Object sLock = new Object();
+
+    @GuardedBy("sLock")
+    private static List<AudioProductStrategy> sAudioProductStrategies;
+
+    /**
+     * @hide
+     * @return the list of AudioProductStrategy discovered from platform configuration file.
+     */
+    @NonNull
+    public static List<AudioProductStrategy> getAudioProductStrategies() {
+        if (sAudioProductStrategies == null) {
+            synchronized (sLock) {
+                if (sAudioProductStrategies == null) {
+                    sAudioProductStrategies = initializeAudioProductStrategies();
+                }
+            }
+        }
+        return sAudioProductStrategies;
+    }
+
+    /**
+     * @hide
+     * Return the AudioProductStrategy object for the given strategy ID.
+     * @param id the ID of the strategy to find
+     * @return an AudioProductStrategy on which getId() would return id, null if no such strategy
+     *     exists.
+     */
+    public static @Nullable AudioProductStrategy getAudioProductStrategyWithId(int id) {
+        synchronized (sLock) {
+            if (sAudioProductStrategies == null) {
+                sAudioProductStrategies = initializeAudioProductStrategies();
+            }
+            for (AudioProductStrategy strategy : sAudioProductStrategies) {
+                if (strategy.getId() == id) {
+                    return strategy;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @hide
+     * Create an invalid AudioProductStrategy instance for testing
+     * @param id the ID for the invalid strategy, always use a different one than in use
+     * @return an invalid instance that cannot successfully be used for volume groups or routing
+     */
+    @SystemApi
+    public static @NonNull AudioProductStrategy createInvalidAudioProductStrategy(int id) {
+        return new AudioProductStrategy("dummy strategy", id, new AudioAttributesGroup[0]);
+    }
+
+    /**
+     * @hide
+     * @param streamType to match against AudioProductStrategy
+     * @return the AudioAttributes for the first strategy found with the associated stream type
+     *          If no match is found, returns AudioAttributes with unknown content_type and usage
+     */
+    @NonNull
+    public static AudioAttributes getAudioAttributesForStrategyWithLegacyStreamType(
+            int streamType) {
+        for (final AudioProductStrategy productStrategy :
+                AudioProductStrategy.getAudioProductStrategies()) {
+            AudioAttributes aa = productStrategy.getAudioAttributesForLegacyStreamType(streamType);
+            if (aa != null) {
+                return aa;
+            }
+        }
+        return new AudioAttributes.Builder()
+            .setContentType(AudioAttributes.CONTENT_TYPE_UNKNOWN)
+            .setUsage(AudioAttributes.USAGE_UNKNOWN).build();
+    }
+
+    /**
+     * @hide
+     * @param audioAttributes to identify AudioProductStrategy with
+     * @return legacy stream type associated with matched AudioProductStrategy
+     *              Defaults to STREAM_MUSIC if no match is found, or if matches is STREAM_DEFAULT
+     */
+    public static int getLegacyStreamTypeForStrategyWithAudioAttributes(
+            @NonNull AudioAttributes audioAttributes) {
+        Preconditions.checkNotNull(audioAttributes, "AudioAttributes must not be null");
+        for (final AudioProductStrategy productStrategy :
+                AudioProductStrategy.getAudioProductStrategies()) {
+            if (productStrategy.supportsAudioAttributes(audioAttributes)) {
+                int streamType = productStrategy.getLegacyStreamTypeForAudioAttributes(
+                        audioAttributes);
+                if (streamType == AudioSystem.STREAM_DEFAULT) {
+                    Log.w(TAG, "Attributes " + audioAttributes.toString() + " ported by strategy "
+                            + productStrategy.getId() + " has no stream type associated, "
+                            + "DO NOT USE STREAM TO CONTROL THE VOLUME");
+                    return AudioSystem.STREAM_MUSIC;
+                }
+                if (streamType < AudioSystem.getNumStreamTypes()) {
+                    return streamType;
+                }
+            }
+        }
+        return AudioSystem.STREAM_MUSIC;
+    }
+
+    private static List<AudioProductStrategy> initializeAudioProductStrategies() {
+        ArrayList<AudioProductStrategy> apsList = new ArrayList<AudioProductStrategy>();
+        int status = native_list_audio_product_strategies(apsList);
+        if (status != AudioSystem.SUCCESS) {
+            Log.w(TAG, ": initializeAudioProductStrategies failed");
+        }
+        return apsList;
+    }
+
+    private static native int native_list_audio_product_strategies(
+            ArrayList<AudioProductStrategy> strategies);
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        AudioProductStrategy thatStrategy = (AudioProductStrategy) o;
+
+        return mName == thatStrategy.mName && mId == thatStrategy.mId
+                && mAudioAttributesGroups.equals(thatStrategy.mAudioAttributesGroups);
+    }
+
+    /**
+     * @param name of the product strategy
+     * @param id of the product strategy
+     * @param aag {@link AudioAttributesGroup} associated to the given product strategy
+     */
+    private AudioProductStrategy(@NonNull String name, int id,
+            @NonNull AudioAttributesGroup[] aag) {
+        Preconditions.checkNotNull(name, "name must not be null");
+        Preconditions.checkNotNull(aag, "AudioAttributesGroups must not be null");
+        mName = name;
+        mId = id;
+        mAudioAttributesGroups = aag;
+    }
+
+    /**
+     * @hide
+     * @return the product strategy ID (which is the generalisation of Car Audio Usage / legacy
+     *         routing_strategy linked to {@link AudioAttributes#getUsage()}).
+     */
+    @SystemApi
+    public int getId() {
+        return mId;
+    }
+
+    /**
+     * @hide
+     * @return first {@link AudioAttributes} associated to this product strategy.
+     */
+    @SystemApi
+    public @NonNull AudioAttributes getAudioAttributes() {
+        // We need a choice, so take the first one
+        return mAudioAttributesGroups.length == 0 ? (new AudioAttributes.Builder().build())
+                : mAudioAttributesGroups[0].getAudioAttributes();
+    }
+
+    /**
+     * @hide
+     * @param streamType legacy stream type used for volume operation only
+     * @return the {@link AudioAttributes} relevant for the given streamType.
+     *         If none is found, it builds the default attributes.
+     */
+    public @Nullable AudioAttributes getAudioAttributesForLegacyStreamType(int streamType) {
+        for (final AudioAttributesGroup aag : mAudioAttributesGroups) {
+            if (aag.supportsStreamType(streamType)) {
+                return aag.getAudioAttributes();
+            }
+        }
+        return null;
+    }
+
+    /**
+     * @hide
+     * @param aa the {@link AudioAttributes} to be considered
+     * @return the legacy stream type relevant for the given {@link AudioAttributes}.
+     *         If none is found, it return DEFAULT stream type.
+     */
+    public int getLegacyStreamTypeForAudioAttributes(@NonNull AudioAttributes aa) {
+        Preconditions.checkNotNull(aa, "AudioAttributes must not be null");
+        for (final AudioAttributesGroup aag : mAudioAttributesGroups) {
+            if (aag.supportsAttributes(aa)) {
+                return aag.getStreamType();
+            }
+        }
+        return AudioSystem.STREAM_DEFAULT;
+    }
+
+    /**
+     * @hide
+     * @param aa the {@link AudioAttributes} to be considered
+     * @return true if the {@link AudioProductStrategy} supports the given {@link AudioAttributes},
+     *         false otherwise.
+     */
+    @SystemApi
+    public boolean supportsAudioAttributes(@NonNull AudioAttributes aa) {
+        Preconditions.checkNotNull(aa, "AudioAttributes must not be null");
+        for (final AudioAttributesGroup aag : mAudioAttributesGroups) {
+            if (aag.supportsAttributes(aa)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * @hide
+     * @param streamType legacy stream type used for volume operation only
+     * @return the volume group id relevant for the given streamType.
+     *         If none is found, {@link AudioVolumeGroup#DEFAULT_VOLUME_GROUP} is returned.
+     */
+    public int getVolumeGroupIdForLegacyStreamType(int streamType) {
+        for (final AudioAttributesGroup aag : mAudioAttributesGroups) {
+            if (aag.supportsStreamType(streamType)) {
+                return aag.getVolumeGroupId();
+            }
+        }
+        return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
+    }
+
+    /**
+     * @hide
+     * @param aa the {@link AudioAttributes} to be considered
+     * @return the volume group id associated with the given audio attributes if found,
+     *         {@link AudioVolumeGroup#DEFAULT_VOLUME_GROUP} otherwise.
+     */
+    public int getVolumeGroupIdForAudioAttributes(@NonNull AudioAttributes aa) {
+        Preconditions.checkNotNull(aa, "AudioAttributes must not be null");
+        for (final AudioAttributesGroup aag : mAudioAttributesGroups) {
+            if (aag.supportsAttributes(aa)) {
+                return aag.getVolumeGroupId();
+            }
+        }
+        return AudioVolumeGroup.DEFAULT_VOLUME_GROUP;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mName);
+        dest.writeInt(mId);
+        dest.writeInt(mAudioAttributesGroups.length);
+        for (AudioAttributesGroup aag : mAudioAttributesGroups) {
+            aag.writeToParcel(dest, flags);
+        }
+    }
+
+    @NonNull
+    public static final Parcelable.Creator<AudioProductStrategy> CREATOR =
+            new Parcelable.Creator<AudioProductStrategy>() {
+                @Override
+                public AudioProductStrategy createFromParcel(@NonNull Parcel in) {
+                    String name = in.readString();
+                    int id = in.readInt();
+                    int nbAttributesGroups = in.readInt();
+                    AudioAttributesGroup[] aag = new AudioAttributesGroup[nbAttributesGroups];
+                    for (int index = 0; index < nbAttributesGroups; index++) {
+                        aag[index] = AudioAttributesGroup.CREATOR.createFromParcel(in);
+                    }
+                    return new AudioProductStrategy(name, id, aag);
+                }
+
+                @Override
+                public @NonNull AudioProductStrategy[] newArray(int size) {
+                    return new AudioProductStrategy[size];
+                }
+            };
+
+    @NonNull
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder();
+        s.append("\n Name: ");
+        s.append(mName);
+        s.append(" Id: ");
+        s.append(Integer.toString(mId));
+        for (AudioAttributesGroup aag : mAudioAttributesGroups) {
+            s.append(aag.toString());
+        }
+        return s.toString();
+    }
+
+    /**
+     * @hide
+     * Default attributes, with default source to be aligned with native.
+     */
+    public static final @NonNull AudioAttributes sDefaultAttributes =
+            new AudioAttributes.Builder().setCapturePreset(MediaRecorder.AudioSource.DEFAULT)
+                                         .build();
+
+    /**
+     * To avoid duplicating the logic in java and native, we shall make use of
+     * native API native_get_product_strategies_from_audio_attributes
+     * Keep in sync with frameworks/av/media/libaudioclient/AudioProductStrategy::attributesMatches
+     * @param refAttr {@link AudioAttributes} to be taken as the reference
+     * @param attr {@link AudioAttributes} of the requester.
+     */
+    private static boolean attributesMatches(@NonNull AudioAttributes refAttr,
+            @NonNull AudioAttributes attr) {
+        Preconditions.checkNotNull(refAttr, "refAttr must not be null");
+        Preconditions.checkNotNull(attr, "attr must not be null");
+        String refFormattedTags = TextUtils.join(";", refAttr.getTags());
+        String cliFormattedTags = TextUtils.join(";", attr.getTags());
+        if (refAttr.equals(sDefaultAttributes)) {
+            return false;
+        }
+        return ((refAttr.getSystemUsage() == AudioAttributes.USAGE_UNKNOWN)
+                || (attr.getSystemUsage() == refAttr.getSystemUsage()))
+            && ((refAttr.getContentType() == AudioAttributes.CONTENT_TYPE_UNKNOWN)
+                || (attr.getContentType() == refAttr.getContentType()))
+            && ((refAttr.getAllFlags() == 0)
+                || (attr.getAllFlags() != 0
+                && (attr.getAllFlags() & refAttr.getAllFlags()) == refAttr.getAllFlags()))
+            && ((refFormattedTags.length() == 0) || refFormattedTags.equals(cliFormattedTags));
+    }
+
+    private static final class AudioAttributesGroup implements Parcelable {
+        private int mVolumeGroupId;
+        private int mLegacyStreamType;
+        private final AudioAttributes[] mAudioAttributes;
+
+        AudioAttributesGroup(int volumeGroupId, int streamType,
+                @NonNull AudioAttributes[] audioAttributes) {
+            mVolumeGroupId = volumeGroupId;
+            mLegacyStreamType = streamType;
+            mAudioAttributes = audioAttributes;
+        }
+
+        @Override
+        public boolean equals(@Nullable Object o) {
+            if (this == o) return true;
+            if (o == null || getClass() != o.getClass()) return false;
+
+            AudioAttributesGroup thatAag = (AudioAttributesGroup) o;
+
+            return mVolumeGroupId == thatAag.mVolumeGroupId
+                    && mLegacyStreamType == thatAag.mLegacyStreamType
+                    && mAudioAttributes.equals(thatAag.mAudioAttributes);
+        }
+
+        public int getStreamType() {
+            return mLegacyStreamType;
+        }
+
+        public int getVolumeGroupId() {
+            return mVolumeGroupId;
+        }
+
+        public @NonNull AudioAttributes getAudioAttributes() {
+            // We need a choice, so take the first one
+            return mAudioAttributes.length == 0 ? (new AudioAttributes.Builder().build())
+                    : mAudioAttributes[0];
+        }
+
+        /**
+         * Checks if a {@link AudioAttributes} is supported by this product strategy.
+         * @param {@link AudioAttributes} to check upon support
+         * @return true if the {@link AudioAttributes} follows this product strategy,
+                   false otherwise.
+         */
+        public boolean supportsAttributes(@NonNull AudioAttributes attributes) {
+            for (final AudioAttributes refAa : mAudioAttributes) {
+                if (refAa.equals(attributes) || attributesMatches(refAa, attributes)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        public boolean supportsStreamType(int streamType) {
+            return mLegacyStreamType == streamType;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(@NonNull Parcel dest, int flags) {
+            dest.writeInt(mVolumeGroupId);
+            dest.writeInt(mLegacyStreamType);
+            dest.writeInt(mAudioAttributes.length);
+            for (AudioAttributes attributes : mAudioAttributes) {
+                attributes.writeToParcel(dest, flags | AudioAttributes.FLATTEN_TAGS/*flags*/);
+            }
+        }
+
+        public static final @android.annotation.NonNull Parcelable.Creator<AudioAttributesGroup> CREATOR =
+                new Parcelable.Creator<AudioAttributesGroup>() {
+                    @Override
+                    public AudioAttributesGroup createFromParcel(@NonNull Parcel in) {
+                        int volumeGroupId = in.readInt();
+                        int streamType = in.readInt();
+                        int nbAttributes = in.readInt();
+                        AudioAttributes[] aa = new AudioAttributes[nbAttributes];
+                        for (int index = 0; index < nbAttributes; index++) {
+                            aa[index] = AudioAttributes.CREATOR.createFromParcel(in);
+                        }
+                        return new AudioAttributesGroup(volumeGroupId, streamType, aa);
+                    }
+
+                    @Override
+                    public @NonNull AudioAttributesGroup[] newArray(int size) {
+                        return new AudioAttributesGroup[size];
+                    }
+                };
+
+
+        @Override
+        public @NonNull String toString() {
+            StringBuilder s = new StringBuilder();
+            s.append("\n    Legacy Stream Type: ");
+            s.append(Integer.toString(mLegacyStreamType));
+            s.append(" Volume Group Id: ");
+            s.append(Integer.toString(mVolumeGroupId));
+
+            for (AudioAttributes attribute : mAudioAttributes) {
+                s.append("\n    -");
+                s.append(attribute.toString());
+            }
+            return s.toString();
+        }
+    }
+}
diff --git a/android/media/audiopolicy/AudioVolumeGroup.java b/android/media/audiopolicy/AudioVolumeGroup.java
new file mode 100644
index 0000000..79be922
--- /dev/null
+++ b/android/media/audiopolicy/AudioVolumeGroup.java
@@ -0,0 +1,214 @@
+/*
+ * Copyright (C) 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.audiopolicy;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.media.AudioAttributes;
+import android.media.AudioSystem;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.Preconditions;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * A class to create the association between different playback attributes
+ * (e.g. media, mapping direction) to a single volume control.
+ * @hide
+ */
+@SystemApi
+public final class AudioVolumeGroup implements Parcelable {
+    private static final String TAG = "AudioVolumeGroup";
+    /**
+     * Volume group value to use when introspection API fails.
+     */
+    public static final int DEFAULT_VOLUME_GROUP = -1;
+
+    /**
+     * Unique identifier of a volume group.
+     */
+    private int mId;
+    /**
+     * human-readable name of this volume group.
+     */
+    private final String mName;
+
+    private final AudioAttributes[] mAudioAttributes;
+    private int[] mLegacyStreamTypes;
+
+    private static final Object sLock = new Object();
+
+    @GuardedBy("sLock")
+    private static List<AudioVolumeGroup> sAudioVolumeGroups;
+
+    /**
+     * @hide
+     * @return the List of AudioVolumeGroup discovered from platform configuration file.
+     */
+    @NonNull
+    public static List<AudioVolumeGroup> getAudioVolumeGroups() {
+        if (sAudioVolumeGroups == null) {
+            synchronized (sLock) {
+                if (sAudioVolumeGroups == null) {
+                    sAudioVolumeGroups = initializeAudioVolumeGroups();
+                }
+            }
+        }
+        return sAudioVolumeGroups;
+    }
+
+    private static List<AudioVolumeGroup> initializeAudioVolumeGroups() {
+        ArrayList<AudioVolumeGroup> avgList = new ArrayList<>();
+        int status = native_list_audio_volume_groups(avgList);
+        if (status != AudioSystem.SUCCESS) {
+            Log.w(TAG, ": listAudioVolumeGroups failed");
+        }
+        return avgList;
+    }
+
+    private static native int native_list_audio_volume_groups(
+            ArrayList<AudioVolumeGroup> groups);
+
+    /**
+     * @param name of the volume group
+     * @param id of the volume group
+     * @param legacyStreamTypes of volume group
+     */
+    AudioVolumeGroup(@NonNull String name, int id,
+                     @NonNull AudioAttributes[] audioAttributes,
+                     @NonNull int[] legacyStreamTypes) {
+        Preconditions.checkNotNull(name, "name must not be null");
+        Preconditions.checkNotNull(audioAttributes, "audioAttributes must not be null");
+        Preconditions.checkNotNull(legacyStreamTypes, "legacyStreamTypes must not be null");
+        mName = name;
+        mId = id;
+        mAudioAttributes = audioAttributes;
+        mLegacyStreamTypes = legacyStreamTypes;
+    }
+
+    @Override
+    public boolean equals(@NonNull Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        AudioVolumeGroup thatAvg = (AudioVolumeGroup) o;
+
+        return mName == thatAvg.mName && mId == thatAvg.mId
+                && mAudioAttributes.equals(thatAvg.mAudioAttributes);
+    }
+
+    /**
+     * @return List of {@link AudioAttributes} involved in this {@link AudioVolumeGroup}.
+     */
+    public @NonNull List<AudioAttributes> getAudioAttributes() {
+        return Arrays.asList(mAudioAttributes);
+    }
+
+    /**
+     * @return the stream types involved in this {@link AudioVolumeGroup}.
+     */
+    public @NonNull int[] getLegacyStreamTypes() {
+        return mLegacyStreamTypes;
+    }
+
+    /**
+     * @return human-readable name of this volume group.
+     */
+    public @NonNull String name() {
+        return mName;
+    }
+
+    /**
+     * @return the volume group unique identifier id.
+     */
+    public int getId() {
+        return mId;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mName);
+        dest.writeInt(mId);
+        dest.writeInt(mAudioAttributes.length);
+        for (AudioAttributes attributes : mAudioAttributes) {
+            attributes.writeToParcel(dest, flags | AudioAttributes.FLATTEN_TAGS/*flags*/);
+        }
+        dest.writeInt(mLegacyStreamTypes.length);
+        for (int streamType : mLegacyStreamTypes) {
+            dest.writeInt(streamType);
+        }
+    }
+
+    public static final Parcelable.Creator<AudioVolumeGroup> CREATOR =
+            new Parcelable.Creator<AudioVolumeGroup>() {
+                @Override
+                public @NonNull AudioVolumeGroup createFromParcel(@NonNull Parcel in) {
+                    Preconditions.checkNotNull(in, "in Parcel must not be null");
+                    String name = in.readString();
+                    int id = in.readInt();
+                    int nbAttributes = in.readInt();
+                    AudioAttributes[] audioAttributes = new AudioAttributes[nbAttributes];
+                    for (int index = 0; index < nbAttributes; index++) {
+                        audioAttributes[index] = AudioAttributes.CREATOR.createFromParcel(in);
+                    }
+                    int nbStreamTypes = in.readInt();
+                    int[] streamTypes = new int[nbStreamTypes];
+                    for (int index = 0; index < nbStreamTypes; index++) {
+                        streamTypes[index] = in.readInt();
+                    }
+                    return new AudioVolumeGroup(name, id, audioAttributes, streamTypes);
+                }
+
+                @Override
+                public @NonNull AudioVolumeGroup[] newArray(int size) {
+                    return new AudioVolumeGroup[size];
+                }
+            };
+
+    @Override
+    public @NonNull String toString() {
+        StringBuilder s = new StringBuilder();
+        s.append("\n Name: ");
+        s.append(mName);
+        s.append(" Id: ");
+        s.append(Integer.toString(mId));
+
+        s.append("\n     Supported Audio Attributes:");
+        for (AudioAttributes attribute : mAudioAttributes) {
+            s.append("\n       -");
+            s.append(attribute.toString());
+        }
+        s.append("\n     Supported Legacy Stream Types: { ");
+        for (int legacyStreamType : mLegacyStreamTypes) {
+            s.append(Integer.toString(legacyStreamType));
+            s.append(" ");
+        }
+        s.append("}");
+        return s.toString();
+    }
+}
diff --git a/android/media/audiopolicy/AudioVolumeGroupChangeHandler.java b/android/media/audiopolicy/AudioVolumeGroupChangeHandler.java
new file mode 100644
index 0000000..022cfee
--- /dev/null
+++ b/android/media/audiopolicy/AudioVolumeGroupChangeHandler.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 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.audiopolicy;
+
+import android.annotation.NonNull;
+import android.media.AudioManager;
+import android.os.Handler;
+import android.os.HandlerThread;
+import android.os.Message;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+
+/**
+ * The AudioVolumeGroupChangeHandler handles AudioManager.OnAudioVolumeGroupChangedListener
+ * callbacks posted from JNI
+ *
+ * TODO: Make use of Executor of callbacks.
+ * @hide
+ */
+public class AudioVolumeGroupChangeHandler {
+    private Handler mHandler;
+    private HandlerThread mHandlerThread;
+    private final ArrayList<AudioManager.VolumeGroupCallback> mListeners =
+            new ArrayList<AudioManager.VolumeGroupCallback>();
+
+    private static final String TAG = "AudioVolumeGroupChangeHandler";
+
+    private static final int AUDIOVOLUMEGROUP_EVENT_VOLUME_CHANGED = 1000;
+    private static final int AUDIOVOLUMEGROUP_EVENT_NEW_LISTENER = 4;
+
+    /**
+     * Accessed by native methods: JNI Callback context.
+     */
+    @SuppressWarnings("unused")
+    private long mJniCallback;
+
+    /**
+     * Initialization
+     */
+    public void init() {
+        synchronized (this) {
+            if (mHandler != null) {
+                return;
+            }
+            // create a new thread for our new event handler
+            mHandlerThread = new HandlerThread(TAG);
+            mHandlerThread.start();
+
+            if (mHandlerThread.getLooper() == null) {
+                mHandler = null;
+                return;
+            }
+            mHandler = new Handler(mHandlerThread.getLooper()) {
+                @Override
+                public void handleMessage(Message msg) {
+                    ArrayList<AudioManager.VolumeGroupCallback> listeners;
+                    synchronized (this) {
+                        if (msg.what == AUDIOVOLUMEGROUP_EVENT_NEW_LISTENER) {
+                            listeners =
+                                    new ArrayList<AudioManager.VolumeGroupCallback>();
+                            if (mListeners.contains(msg.obj)) {
+                                listeners.add(
+                                        (AudioManager.VolumeGroupCallback) msg.obj);
+                            }
+                        } else {
+                            listeners = (ArrayList<AudioManager.VolumeGroupCallback>)
+                                    mListeners.clone();
+                        }
+                    }
+                    if (listeners.isEmpty()) {
+                        return;
+                    }
+
+                    switch (msg.what) {
+                        case AUDIOVOLUMEGROUP_EVENT_VOLUME_CHANGED:
+                            for (int i = 0; i < listeners.size(); i++) {
+                                listeners.get(i).onAudioVolumeGroupChanged((int) msg.arg1,
+                                                                           (int) msg.arg2);
+                            }
+                            break;
+
+                        default:
+                            break;
+                    }
+                }
+            };
+            native_setup(new WeakReference<AudioVolumeGroupChangeHandler>(this));
+        }
+    }
+
+    private native void native_setup(Object moduleThis);
+
+    @Override
+    protected void finalize() {
+        native_finalize();
+        if (mHandlerThread.isAlive()) {
+            mHandlerThread.quit();
+        }
+    }
+    private native void native_finalize();
+
+   /**
+    * @param cb the {@link AudioManager.VolumeGroupCallback} to register
+    */
+    public void registerListener(@NonNull AudioManager.VolumeGroupCallback cb) {
+        Preconditions.checkNotNull(cb, "volume group callback shall not be null");
+        synchronized (this) {
+            mListeners.add(cb);
+        }
+        if (mHandler != null) {
+            Message m = mHandler.obtainMessage(
+                    AUDIOVOLUMEGROUP_EVENT_NEW_LISTENER, 0, 0, cb);
+            mHandler.sendMessage(m);
+        }
+    }
+
+   /**
+    * @param cb the {@link AudioManager.VolumeGroupCallback} to unregister
+    */
+    public void unregisterListener(@NonNull AudioManager.VolumeGroupCallback cb) {
+        Preconditions.checkNotNull(cb, "volume group callback shall not be null");
+        synchronized (this) {
+            mListeners.remove(cb);
+        }
+    }
+
+    Handler handler() {
+        return mHandler;
+    }
+
+    @SuppressWarnings("unused")
+    private static void postEventFromNative(Object moduleRef,
+                                            int what, int arg1, int arg2, Object obj) {
+        AudioVolumeGroupChangeHandler eventHandler =
+                (AudioVolumeGroupChangeHandler) ((WeakReference) moduleRef).get();
+        if (eventHandler == null) {
+            return;
+        }
+
+        if (eventHandler != null) {
+            Handler handler = eventHandler.handler();
+            if (handler != null) {
+                Message m = handler.obtainMessage(what, arg1, arg2, obj);
+                // Do not remove previous messages, as we would lose notification of group changes
+                handler.sendMessage(m);
+            }
+        }
+    }
+}
diff --git a/android/media/browse/MediaBrowser.java b/android/media/browse/MediaBrowser.java
new file mode 100644
index 0000000..b662901
--- /dev/null
+++ b/android/media/browse/MediaBrowser.java
@@ -0,0 +1,1164 @@
+/*
+ * Copyright (C) 2014 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.browse;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.ServiceConnection;
+import android.content.pm.ParceledListSlice;
+import android.media.MediaDescription;
+import android.media.session.MediaSession;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.service.media.IMediaBrowserService;
+import android.service.media.IMediaBrowserServiceCallbacks;
+import android.service.media.MediaBrowserService;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+
+/**
+ * Browses media content offered by a link MediaBrowserService.
+ * <p>
+ * This object is not thread-safe. All calls should happen on the thread on which the browser
+ * was constructed.
+ * </p>
+ * <h3>Standard Extra Data</h3>
+ *
+ * <p>These are the current standard fields that can be used as extra data via
+ * {@link #subscribe(String, Bundle, SubscriptionCallback)},
+ * {@link #unsubscribe(String, SubscriptionCallback)}, and
+ * {@link SubscriptionCallback#onChildrenLoaded(String, List, Bundle)}.
+ *
+ * <ul>
+ *     <li> {@link #EXTRA_PAGE}
+ *     <li> {@link #EXTRA_PAGE_SIZE}
+ * </ul>
+ */
+public final class MediaBrowser {
+    private static final String TAG = "MediaBrowser";
+    private static final boolean DBG = false;
+
+    /**
+     * Used as an int extra field to denote the page number to subscribe.
+     * The value of {@code EXTRA_PAGE} should be greater than or equal to 0.
+     *
+     * @see #EXTRA_PAGE_SIZE
+     */
+    public static final String EXTRA_PAGE = "android.media.browse.extra.PAGE";
+
+    /**
+     * Used as an int extra field to denote the number of media items in a page.
+     * The value of {@code EXTRA_PAGE_SIZE} should be greater than or equal to 1.
+     *
+     * @see #EXTRA_PAGE
+     */
+    public static final String EXTRA_PAGE_SIZE = "android.media.browse.extra.PAGE_SIZE";
+
+    private static final int CONNECT_STATE_DISCONNECTING = 0;
+    private static final int CONNECT_STATE_DISCONNECTED = 1;
+    private static final int CONNECT_STATE_CONNECTING = 2;
+    private static final int CONNECT_STATE_CONNECTED = 3;
+    private static final int CONNECT_STATE_SUSPENDED = 4;
+
+    private final Context mContext;
+    private final ComponentName mServiceComponent;
+    private final ConnectionCallback mCallback;
+    private final Bundle mRootHints;
+    private final Handler mHandler = new Handler();
+    private final ArrayMap<String, Subscription> mSubscriptions = new ArrayMap<>();
+
+    private volatile int mState = CONNECT_STATE_DISCONNECTED;
+    private volatile String mRootId;
+    private volatile MediaSession.Token mMediaSessionToken;
+    private volatile Bundle mExtras;
+
+    private MediaServiceConnection mServiceConnection;
+    private IMediaBrowserService mServiceBinder;
+    private IMediaBrowserServiceCallbacks mServiceCallbacks;
+
+    /**
+     * Creates a media browser for the specified media browser service.
+     *
+     * @param context The context.
+     * @param serviceComponent The component name of the media browser service.
+     * @param callback The connection callback.
+     * @param rootHints An optional bundle of service-specific arguments to send
+     * to the media browser service when connecting and retrieving the root id
+     * for browsing, or null if none. The contents of this bundle may affect
+     * the information returned when browsing.
+     * @see android.service.media.MediaBrowserService.BrowserRoot#EXTRA_RECENT
+     * @see android.service.media.MediaBrowserService.BrowserRoot#EXTRA_OFFLINE
+     * @see android.service.media.MediaBrowserService.BrowserRoot#EXTRA_SUGGESTED
+     */
+    public MediaBrowser(Context context, ComponentName serviceComponent,
+            ConnectionCallback callback, Bundle rootHints) {
+        if (context == null) {
+            throw new IllegalArgumentException("context must not be null");
+        }
+        if (serviceComponent == null) {
+            throw new IllegalArgumentException("service component must not be null");
+        }
+        if (callback == null) {
+            throw new IllegalArgumentException("connection callback must not be null");
+        }
+        mContext = context;
+        mServiceComponent = serviceComponent;
+        mCallback = callback;
+        mRootHints = rootHints == null ? null : new Bundle(rootHints);
+    }
+
+    /**
+     * Connects to the media browser service.
+     * <p>
+     * The connection callback specified in the constructor will be invoked
+     * when the connection completes or fails.
+     * </p>
+     */
+    public void connect() {
+        if (mState != CONNECT_STATE_DISCONNECTING && mState != CONNECT_STATE_DISCONNECTED) {
+            throw new IllegalStateException("connect() called while neither disconnecting nor "
+                    + "disconnected (state=" + getStateLabel(mState) + ")");
+        }
+
+        mState = CONNECT_STATE_CONNECTING;
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                if (mState == CONNECT_STATE_DISCONNECTING) {
+                    return;
+                }
+                mState = CONNECT_STATE_CONNECTING;
+                // TODO: remove this extra check.
+                if (DBG) {
+                    if (mServiceConnection != null) {
+                        throw new RuntimeException("mServiceConnection should be null. Instead it"
+                                + " is " + mServiceConnection);
+                    }
+                }
+                if (mServiceBinder != null) {
+                    throw new RuntimeException("mServiceBinder should be null. Instead it is "
+                            + mServiceBinder);
+                }
+                if (mServiceCallbacks != null) {
+                    throw new RuntimeException("mServiceCallbacks should be null. Instead it is "
+                            + mServiceCallbacks);
+                }
+
+                final Intent intent = new Intent(MediaBrowserService.SERVICE_INTERFACE);
+                intent.setComponent(mServiceComponent);
+
+                mServiceConnection = new MediaServiceConnection();
+
+                boolean bound = false;
+                try {
+                    bound = mContext.bindService(intent, mServiceConnection,
+                            Context.BIND_AUTO_CREATE | Context.BIND_INCLUDE_CAPABILITIES);
+                } catch (Exception ex) {
+                    Log.e(TAG, "Failed binding to service " + mServiceComponent);
+                }
+
+                if (!bound) {
+                    // Tell them that it didn't work.
+                    forceCloseConnection();
+                    mCallback.onConnectionFailed();
+                }
+
+                if (DBG) {
+                    Log.d(TAG, "connect...");
+                    dump();
+                }
+            }
+        });
+    }
+
+    /**
+     * Disconnects from the media browser service.
+     * After this, no more callbacks will be received.
+     */
+    public void disconnect() {
+        // It's ok to call this any state, because allowing this lets apps not have
+        // to check isConnected() unnecessarily. They won't appreciate the extra
+        // assertions for this. We do everything we can here to go back to a valid state.
+        mState = CONNECT_STATE_DISCONNECTING;
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                // connect() could be called before this. Then we will disconnect and reconnect.
+                if (mServiceCallbacks != null) {
+                    try {
+                        mServiceBinder.disconnect(mServiceCallbacks);
+                    } catch (RemoteException ex) {
+                        // We are disconnecting anyway. Log, just for posterity but it's not
+                        // a big problem.
+                        Log.w(TAG, "RemoteException during connect for " + mServiceComponent);
+                    }
+                }
+                int state = mState;
+                forceCloseConnection();
+                // If the state was not CONNECT_STATE_DISCONNECTING, keep the state so that
+                // the operation came after disconnect() can be handled properly.
+                if (state != CONNECT_STATE_DISCONNECTING) {
+                    mState = state;
+                }
+                if (DBG) {
+                    Log.d(TAG, "disconnect...");
+                    dump();
+                }
+            }
+        });
+    }
+
+    /**
+     * Null out the variables and unbind from the service. This doesn't include
+     * calling disconnect on the service, because we only try to do that in the
+     * clean shutdown cases.
+     * <p>
+     * Everywhere that calls this EXCEPT for disconnect() should follow it with
+     * a call to mCallback.onConnectionFailed(). Disconnect doesn't do that callback
+     * for a clean shutdown, but everywhere else is a dirty shutdown and should
+     * notify the app.
+     * <p>
+     * Also, mState should be updated properly. Mostly it should be CONNECT_STATE_DIACONNECTED
+     * except for disconnect().
+     */
+    private void forceCloseConnection() {
+        if (mServiceConnection != null) {
+            try {
+                mContext.unbindService(mServiceConnection);
+            } catch (IllegalArgumentException e) {
+                if (DBG) {
+                    Log.d(TAG, "unbindService failed", e);
+                }
+            }
+        }
+        mState = CONNECT_STATE_DISCONNECTED;
+        mServiceConnection = null;
+        mServiceBinder = null;
+        mServiceCallbacks = null;
+        mRootId = null;
+        mMediaSessionToken = null;
+    }
+
+    /**
+     * Returns whether the browser is connected to the service.
+     */
+    public boolean isConnected() {
+        return mState == CONNECT_STATE_CONNECTED;
+    }
+
+    /**
+     * Gets the service component that the media browser is connected to.
+     */
+    public @NonNull ComponentName getServiceComponent() {
+        if (!isConnected()) {
+            throw new IllegalStateException("getServiceComponent() called while not connected"
+                    + " (state=" + mState + ")");
+        }
+        return mServiceComponent;
+    }
+
+    /**
+     * Gets the root id.
+     * <p>
+     * Note that the root id may become invalid or change when the
+     * browser is disconnected.
+     * </p>
+     *
+     * @throws IllegalStateException if not connected.
+     */
+    public @NonNull String getRoot() {
+        if (!isConnected()) {
+            throw new IllegalStateException("getRoot() called while not connected (state="
+                    + getStateLabel(mState) + ")");
+        }
+        return mRootId;
+    }
+
+    /**
+     * Gets any extras for the media service.
+     *
+     * @throws IllegalStateException if not connected.
+     */
+    public @Nullable Bundle getExtras() {
+        if (!isConnected()) {
+            throw new IllegalStateException("getExtras() called while not connected (state="
+                    + getStateLabel(mState) + ")");
+        }
+        return mExtras;
+    }
+
+    /**
+     * Gets the media session token associated with the media browser.
+     * <p>
+     * Note that the session token may become invalid or change when the
+     * browser is disconnected.
+     * </p>
+     *
+     * @return The session token for the browser, never null.
+     *
+     * @throws IllegalStateException if not connected.
+     */
+    public @NonNull MediaSession.Token getSessionToken() {
+        if (!isConnected()) {
+            throw new IllegalStateException("getSessionToken() called while not connected (state="
+                    + mState + ")");
+        }
+        return mMediaSessionToken;
+    }
+
+    /**
+     * Queries for information about the media items that are contained within
+     * the specified id and subscribes to receive updates when they change.
+     * <p>
+     * The list of subscriptions is maintained even when not connected and is
+     * restored after the reconnection. It is ok to subscribe while not connected
+     * but the results will not be returned until the connection completes.
+     * </p>
+     * <p>
+     * If the id is already subscribed with a different callback then the new
+     * callback will replace the previous one and the child data will be
+     * reloaded.
+     * </p>
+     *
+     * @param parentId The id of the parent media item whose list of children
+     *            will be subscribed.
+     * @param callback The callback to receive the list of children.
+     */
+    public void subscribe(@NonNull String parentId, @NonNull SubscriptionCallback callback) {
+        subscribeInternal(parentId, null, callback);
+    }
+
+    /**
+     * Queries with service-specific arguments for information about the media items
+     * that are contained within the specified id and subscribes to receive updates
+     * when they change.
+     * <p>
+     * The list of subscriptions is maintained even when not connected and is
+     * restored after the reconnection. It is ok to subscribe while not connected
+     * but the results will not be returned until the connection completes.
+     * </p>
+     * <p>
+     * If the id is already subscribed with a different callback then the new
+     * callback will replace the previous one and the child data will be
+     * reloaded.
+     * </p>
+     *
+     * @param parentId The id of the parent media item whose list of children
+     *            will be subscribed.
+     * @param options The bundle of service-specific arguments to send to the media
+     *            browser service. The contents of this bundle may affect the
+     *            information returned when browsing.
+     * @param callback The callback to receive the list of children.
+     */
+    public void subscribe(@NonNull String parentId, @NonNull Bundle options,
+            @NonNull SubscriptionCallback callback) {
+        if (options == null) {
+            throw new IllegalArgumentException("options cannot be null");
+        }
+        subscribeInternal(parentId, new Bundle(options), callback);
+    }
+
+    /**
+     * Unsubscribes for changes to the children of the specified media id.
+     * <p>
+     * The query callback will no longer be invoked for results associated with
+     * this id once this method returns.
+     * </p>
+     *
+     * @param parentId The id of the parent media item whose list of children
+     *            will be unsubscribed.
+     */
+    public void unsubscribe(@NonNull String parentId) {
+        unsubscribeInternal(parentId, null);
+    }
+
+    /**
+     * Unsubscribes for changes to the children of the specified media id through a callback.
+     * <p>
+     * The query callback will no longer be invoked for results associated with
+     * this id once this method returns.
+     * </p>
+     *
+     * @param parentId The id of the parent media item whose list of children
+     *            will be unsubscribed.
+     * @param callback A callback sent to the media browser service to subscribe.
+     */
+    public void unsubscribe(@NonNull String parentId, @NonNull SubscriptionCallback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback cannot be null");
+        }
+        unsubscribeInternal(parentId, callback);
+    }
+
+    /**
+     * Retrieves a specific {@link MediaItem} from the connected service. Not
+     * all services may support this, so falling back to subscribing to the
+     * parent's id should be used when unavailable.
+     *
+     * @param mediaId The id of the item to retrieve.
+     * @param cb The callback to receive the result on.
+     */
+    public void getItem(final @NonNull String mediaId, @NonNull final ItemCallback cb) {
+        if (TextUtils.isEmpty(mediaId)) {
+            throw new IllegalArgumentException("mediaId cannot be empty.");
+        }
+        if (cb == null) {
+            throw new IllegalArgumentException("cb cannot be null.");
+        }
+        if (mState != CONNECT_STATE_CONNECTED) {
+            Log.i(TAG, "Not connected, unable to retrieve the MediaItem.");
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    cb.onError(mediaId);
+                }
+            });
+            return;
+        }
+        ResultReceiver receiver = new ResultReceiver(mHandler) {
+            @Override
+            protected void onReceiveResult(int resultCode, Bundle resultData) {
+                if (!isConnected()) {
+                    return;
+                }
+                if (resultCode != 0 || resultData == null
+                        || !resultData.containsKey(MediaBrowserService.KEY_MEDIA_ITEM)) {
+                    cb.onError(mediaId);
+                    return;
+                }
+                Parcelable item = resultData.getParcelable(MediaBrowserService.KEY_MEDIA_ITEM);
+                if (item != null && !(item instanceof MediaItem)) {
+                    cb.onError(mediaId);
+                    return;
+                }
+                cb.onItemLoaded((MediaItem) item);
+            }
+        };
+        try {
+            mServiceBinder.getMediaItem(mediaId, receiver, mServiceCallbacks);
+        } catch (RemoteException e) {
+            Log.i(TAG, "Remote error getting media item.");
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    cb.onError(mediaId);
+                }
+            });
+        }
+    }
+
+    private void subscribeInternal(String parentId, Bundle options, SubscriptionCallback callback) {
+        // Check arguments.
+        if (TextUtils.isEmpty(parentId)) {
+            throw new IllegalArgumentException("parentId cannot be empty.");
+        }
+        if (callback == null) {
+            throw new IllegalArgumentException("callback cannot be null");
+        }
+        // Update or create the subscription.
+        Subscription sub = mSubscriptions.get(parentId);
+        if (sub == null) {
+            sub = new Subscription();
+            mSubscriptions.put(parentId, sub);
+        }
+        sub.putCallback(mContext, options, callback);
+
+        // If we are connected, tell the service that we are watching. If we aren't connected,
+        // the service will be told when we connect.
+        if (isConnected()) {
+            try {
+                if (options == null) {
+                    mServiceBinder.addSubscriptionDeprecated(parentId, mServiceCallbacks);
+                }
+                mServiceBinder.addSubscription(parentId, callback.mToken, options,
+                        mServiceCallbacks);
+            } catch (RemoteException ex) {
+                // Process is crashing. We will disconnect, and upon reconnect we will
+                // automatically reregister. So nothing to do here.
+                Log.d(TAG, "addSubscription failed with RemoteException parentId=" + parentId);
+            }
+        }
+    }
+
+    private void unsubscribeInternal(String parentId, SubscriptionCallback callback) {
+        // Check arguments.
+        if (TextUtils.isEmpty(parentId)) {
+            throw new IllegalArgumentException("parentId cannot be empty.");
+        }
+
+        Subscription sub = mSubscriptions.get(parentId);
+        if (sub == null) {
+            return;
+        }
+        // Tell the service if necessary.
+        try {
+            if (callback == null) {
+                if (isConnected()) {
+                    mServiceBinder.removeSubscriptionDeprecated(parentId, mServiceCallbacks);
+                    mServiceBinder.removeSubscription(parentId, null, mServiceCallbacks);
+                }
+            } else {
+                final List<SubscriptionCallback> callbacks = sub.getCallbacks();
+                final List<Bundle> optionsList = sub.getOptionsList();
+                for (int i = callbacks.size() - 1; i >= 0; --i) {
+                    if (callbacks.get(i) == callback) {
+                        if (isConnected()) {
+                            mServiceBinder.removeSubscription(
+                                    parentId, callback.mToken, mServiceCallbacks);
+                        }
+                        callbacks.remove(i);
+                        optionsList.remove(i);
+                    }
+                }
+            }
+        } catch (RemoteException ex) {
+            // Process is crashing. We will disconnect, and upon reconnect we will
+            // automatically reregister. So nothing to do here.
+            Log.d(TAG, "removeSubscription failed with RemoteException parentId=" + parentId);
+        }
+
+        if (sub.isEmpty() || callback == null) {
+            mSubscriptions.remove(parentId);
+        }
+    }
+
+    /**
+     * For debugging.
+     */
+    private static String getStateLabel(int state) {
+        switch (state) {
+            case CONNECT_STATE_DISCONNECTING:
+                return "CONNECT_STATE_DISCONNECTING";
+            case CONNECT_STATE_DISCONNECTED:
+                return "CONNECT_STATE_DISCONNECTED";
+            case CONNECT_STATE_CONNECTING:
+                return "CONNECT_STATE_CONNECTING";
+            case CONNECT_STATE_CONNECTED:
+                return "CONNECT_STATE_CONNECTED";
+            case CONNECT_STATE_SUSPENDED:
+                return "CONNECT_STATE_SUSPENDED";
+            default:
+                return "UNKNOWN/" + state;
+        }
+    }
+
+    private void onServiceConnected(final IMediaBrowserServiceCallbacks callback,
+            final String root, final MediaSession.Token session, final Bundle extra) {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                // Check to make sure there hasn't been a disconnect or a different
+                // ServiceConnection.
+                if (!isCurrent(callback, "onConnect")) {
+                    return;
+                }
+                // Don't allow them to call us twice.
+                if (mState != CONNECT_STATE_CONNECTING) {
+                    Log.w(TAG, "onConnect from service while mState="
+                            + getStateLabel(mState) + "... ignoring");
+                    return;
+                }
+                mRootId = root;
+                mMediaSessionToken = session;
+                mExtras = extra;
+                mState = CONNECT_STATE_CONNECTED;
+
+                if (DBG) {
+                    Log.d(TAG, "ServiceCallbacks.onConnect...");
+                    dump();
+                }
+                mCallback.onConnected();
+
+                // we may receive some subscriptions before we are connected, so re-subscribe
+                // everything now
+                for (Entry<String, Subscription> subscriptionEntry : mSubscriptions.entrySet()) {
+                    String id = subscriptionEntry.getKey();
+                    Subscription sub = subscriptionEntry.getValue();
+                    List<SubscriptionCallback> callbackList = sub.getCallbacks();
+                    List<Bundle> optionsList = sub.getOptionsList();
+                    for (int i = 0; i < callbackList.size(); ++i) {
+                        try {
+                            mServiceBinder.addSubscription(id, callbackList.get(i).mToken,
+                                    optionsList.get(i), mServiceCallbacks);
+                        } catch (RemoteException ex) {
+                            // Process is crashing. We will disconnect, and upon reconnect we will
+                            // automatically reregister. So nothing to do here.
+                            Log.d(TAG, "addSubscription failed with RemoteException parentId="
+                                    + id);
+                        }
+                    }
+                }
+            }
+        });
+    }
+
+    private void onConnectionFailed(final IMediaBrowserServiceCallbacks callback) {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                Log.e(TAG, "onConnectFailed for " + mServiceComponent);
+
+                // Check to make sure there hasn't been a disconnect or a different
+                // ServiceConnection.
+                if (!isCurrent(callback, "onConnectFailed")) {
+                    return;
+                }
+                // Don't allow them to call us twice.
+                if (mState != CONNECT_STATE_CONNECTING) {
+                    Log.w(TAG, "onConnect from service while mState="
+                            + getStateLabel(mState) + "... ignoring");
+                    return;
+                }
+
+                // Clean up
+                forceCloseConnection();
+
+                // Tell the app.
+                mCallback.onConnectionFailed();
+            }
+        });
+    }
+
+    private void onLoadChildren(final IMediaBrowserServiceCallbacks callback,
+            final String parentId, final ParceledListSlice list, final Bundle options) {
+        mHandler.post(new Runnable() {
+            @Override
+            public void run() {
+                // Check that there hasn't been a disconnect or a different
+                // ServiceConnection.
+                if (!isCurrent(callback, "onLoadChildren")) {
+                    return;
+                }
+
+                if (DBG) {
+                    Log.d(TAG, "onLoadChildren for " + mServiceComponent + " id=" + parentId);
+                }
+
+                // Check that the subscription is still subscribed.
+                final Subscription subscription = mSubscriptions.get(parentId);
+                if (subscription != null) {
+                    // Tell the app.
+                    SubscriptionCallback subscriptionCallback =
+                            subscription.getCallback(mContext, options);
+                    if (subscriptionCallback != null) {
+                        List<MediaItem> data = list == null ? null : list.getList();
+                        if (options == null) {
+                            if (data == null) {
+                                subscriptionCallback.onError(parentId);
+                            } else {
+                                subscriptionCallback.onChildrenLoaded(parentId, data);
+                            }
+                        } else {
+                            if (data == null) {
+                                subscriptionCallback.onError(parentId, options);
+                            } else {
+                                subscriptionCallback.onChildrenLoaded(parentId, data, options);
+                            }
+                        }
+                        return;
+                    }
+                }
+                if (DBG) {
+                    Log.d(TAG, "onLoadChildren for id that isn't subscribed id=" + parentId);
+                }
+            }
+        });
+    }
+
+    /**
+     * Return true if {@code callback} is the current ServiceCallbacks. Also logs if it's not.
+     */
+    private boolean isCurrent(IMediaBrowserServiceCallbacks callback, String funcName) {
+        if (mServiceCallbacks != callback || mState == CONNECT_STATE_DISCONNECTING
+                || mState == CONNECT_STATE_DISCONNECTED) {
+            if (mState != CONNECT_STATE_DISCONNECTING && mState != CONNECT_STATE_DISCONNECTED) {
+                Log.i(TAG, funcName + " for " + mServiceComponent + " with mServiceConnection="
+                        + mServiceCallbacks + " this=" + this);
+            }
+            return false;
+        }
+        return true;
+    }
+
+    private ServiceCallbacks getNewServiceCallbacks() {
+        return new ServiceCallbacks(this);
+    }
+
+    /**
+     * Log internal state.
+     * @hide
+     */
+    void dump() {
+        Log.d(TAG, "MediaBrowser...");
+        Log.d(TAG, "  mServiceComponent=" + mServiceComponent);
+        Log.d(TAG, "  mCallback=" + mCallback);
+        Log.d(TAG, "  mRootHints=" + mRootHints);
+        Log.d(TAG, "  mState=" + getStateLabel(mState));
+        Log.d(TAG, "  mServiceConnection=" + mServiceConnection);
+        Log.d(TAG, "  mServiceBinder=" + mServiceBinder);
+        Log.d(TAG, "  mServiceCallbacks=" + mServiceCallbacks);
+        Log.d(TAG, "  mRootId=" + mRootId);
+        Log.d(TAG, "  mMediaSessionToken=" + mMediaSessionToken);
+    }
+
+    /**
+     * A class with information on a single media item for use in browsing/searching media.
+     * MediaItems are application dependent so we cannot guarantee that they contain the
+     * right values.
+     */
+    public static class MediaItem implements Parcelable {
+        private final int mFlags;
+        private final MediaDescription mDescription;
+
+        /** @hide */
+        @Retention(RetentionPolicy.SOURCE)
+        @IntDef(flag = true, value = { FLAG_BROWSABLE, FLAG_PLAYABLE })
+        public @interface Flags { }
+
+        /**
+         * Flag: Indicates that the item has children of its own.
+         */
+        public static final int FLAG_BROWSABLE = 1 << 0;
+
+        /**
+         * Flag: Indicates that the item is playable.
+         * <p>
+         * The id of this item may be passed to
+         * {@link android.media.session.MediaController.TransportControls
+         * #playFromMediaId(String, Bundle)} to start playing it.
+         * </p>
+         */
+        public static final int FLAG_PLAYABLE = 1 << 1;
+
+        /**
+         * Create a new MediaItem for use in browsing media.
+         * @param description The description of the media, which must include a
+         *            media id.
+         * @param flags The flags for this item.
+         */
+        public MediaItem(@NonNull MediaDescription description, @Flags int flags) {
+            if (description == null) {
+                throw new IllegalArgumentException("description cannot be null");
+            }
+            if (TextUtils.isEmpty(description.getMediaId())) {
+                throw new IllegalArgumentException("description must have a non-empty media id");
+            }
+            mFlags = flags;
+            mDescription = description;
+        }
+
+        /**
+         * Private constructor.
+         */
+        private MediaItem(Parcel in) {
+            mFlags = in.readInt();
+            mDescription = MediaDescription.CREATOR.createFromParcel(in);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel out, int flags) {
+            out.writeInt(mFlags);
+            mDescription.writeToParcel(out, flags);
+        }
+
+        @Override
+        public String toString() {
+            final StringBuilder sb = new StringBuilder("MediaItem{");
+            sb.append("mFlags=").append(mFlags);
+            sb.append(", mDescription=").append(mDescription);
+            sb.append('}');
+            return sb.toString();
+        }
+
+        public static final @android.annotation.NonNull Parcelable.Creator<MediaItem> CREATOR =
+                new Parcelable.Creator<MediaItem>() {
+                    @Override
+                    public MediaItem createFromParcel(Parcel in) {
+                        return new MediaItem(in);
+                    }
+
+                    @Override
+                    public MediaItem[] newArray(int size) {
+                        return new MediaItem[size];
+                    }
+                };
+
+        /**
+         * Gets the flags of the item.
+         */
+        public @Flags int getFlags() {
+            return mFlags;
+        }
+
+        /**
+         * Returns whether this item is browsable.
+         * @see #FLAG_BROWSABLE
+         */
+        public boolean isBrowsable() {
+            return (mFlags & FLAG_BROWSABLE) != 0;
+        }
+
+        /**
+         * Returns whether this item is playable.
+         * @see #FLAG_PLAYABLE
+         */
+        public boolean isPlayable() {
+            return (mFlags & FLAG_PLAYABLE) != 0;
+        }
+
+        /**
+         * Returns the description of the media.
+         */
+        public @NonNull MediaDescription getDescription() {
+            return mDescription;
+        }
+
+        /**
+         * Returns the media id in the {@link MediaDescription} for this item.
+         * @see android.media.MediaMetadata#METADATA_KEY_MEDIA_ID
+         */
+        public @Nullable String getMediaId() {
+            return mDescription.getMediaId();
+        }
+    }
+
+    /**
+     * Callbacks for connection related events.
+     */
+    public static class ConnectionCallback {
+        /**
+         * Invoked after {@link MediaBrowser#connect()} when the request has successfully completed.
+         */
+        public void onConnected() {
+        }
+
+        /**
+         * Invoked when the client is disconnected from the media browser.
+         */
+        public void onConnectionSuspended() {
+        }
+
+        /**
+         * Invoked when the connection to the media browser failed.
+         */
+        public void onConnectionFailed() {
+        }
+    }
+
+    /**
+     * Callbacks for subscription related events.
+     */
+    public abstract static class SubscriptionCallback {
+        Binder mToken;
+
+        public SubscriptionCallback() {
+            mToken = new Binder();
+        }
+
+        /**
+         * Called when the list of children is loaded or updated.
+         *
+         * @param parentId The media id of the parent media item.
+         * @param children The children which were loaded.
+         */
+        public void onChildrenLoaded(@NonNull String parentId, @NonNull List<MediaItem> children) {
+        }
+
+        /**
+         * Called when the list of children is loaded or updated.
+         *
+         * @param parentId The media id of the parent media item.
+         * @param children The children which were loaded.
+         * @param options The bundle of service-specific arguments sent to the media
+         *            browser service. The contents of this bundle may affect the
+         *            information returned when browsing.
+         */
+        public void onChildrenLoaded(@NonNull String parentId, @NonNull List<MediaItem> children,
+                @NonNull Bundle options) {
+        }
+
+        /**
+         * Called when the id doesn't exist or other errors in subscribing.
+         * <p>
+         * If this is called, the subscription remains until {@link MediaBrowser#unsubscribe}
+         * called, because some errors may heal themselves.
+         * </p>
+         *
+         * @param parentId The media id of the parent media item whose children could
+         *            not be loaded.
+         */
+        public void onError(@NonNull String parentId) {
+        }
+
+        /**
+         * Called when the id doesn't exist or other errors in subscribing.
+         * <p>
+         * If this is called, the subscription remains until {@link MediaBrowser#unsubscribe}
+         * called, because some errors may heal themselves.
+         * </p>
+         *
+         * @param parentId The media id of the parent media item whose children could
+         *            not be loaded.
+         * @param options The bundle of service-specific arguments sent to the media
+         *            browser service.
+         */
+        public void onError(@NonNull String parentId, @NonNull Bundle options) {
+        }
+    }
+
+    /**
+     * Callback for receiving the result of {@link #getItem}.
+     */
+    public abstract static class ItemCallback {
+        /**
+         * Called when the item has been returned by the connected service.
+         *
+         * @param item The item that was returned or null if it doesn't exist.
+         */
+        public void onItemLoaded(MediaItem item) {
+        }
+
+        /**
+         * Called there was an error retrieving it or the connected service doesn't support
+         * {@link #getItem}.
+         *
+         * @param mediaId The media id of the media item which could not be loaded.
+         */
+        public void onError(@NonNull String mediaId) {
+        }
+    }
+
+    /**
+     * ServiceConnection to the other app.
+     */
+    private class MediaServiceConnection implements ServiceConnection {
+        @Override
+        public void onServiceConnected(final ComponentName name, final IBinder binder) {
+            postOrRun(new Runnable() {
+                @Override
+                public void run() {
+                    if (DBG) {
+                        Log.d(TAG, "MediaServiceConnection.onServiceConnected name=" + name
+                                + " binder=" + binder);
+                        dump();
+                    }
+
+                    // Make sure we are still the current connection, and that they haven't called
+                    // disconnect().
+                    if (!isCurrent("onServiceConnected")) {
+                        return;
+                    }
+
+                    // Save their binder
+                    mServiceBinder = IMediaBrowserService.Stub.asInterface(binder);
+
+                    // We make a new mServiceCallbacks each time we connect so that we can drop
+                    // responses from previous connections.
+                    mServiceCallbacks = getNewServiceCallbacks();
+                    mState = CONNECT_STATE_CONNECTING;
+
+                    // Call connect, which is async. When we get a response from that we will
+                    // say that we're connected.
+                    try {
+                        if (DBG) {
+                            Log.d(TAG, "ServiceCallbacks.onConnect...");
+                            dump();
+                        }
+                        mServiceBinder.connect(mContext.getPackageName(), mRootHints,
+                                mServiceCallbacks);
+                    } catch (RemoteException ex) {
+                        // Connect failed, which isn't good. But the auto-reconnect on the service
+                        // will take over and we will come back. We will also get the
+                        // onServiceDisconnected, which has all the cleanup code. So let that do
+                        // it.
+                        Log.w(TAG, "RemoteException during connect for " + mServiceComponent);
+                        if (DBG) {
+                            Log.d(TAG, "ServiceCallbacks.onConnect...");
+                            dump();
+                        }
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void onServiceDisconnected(final ComponentName name) {
+            postOrRun(new Runnable() {
+                @Override
+                public void run() {
+                    if (DBG) {
+                        Log.d(TAG, "MediaServiceConnection.onServiceDisconnected name=" + name
+                                + " this=" + this + " mServiceConnection=" + mServiceConnection);
+                        dump();
+                    }
+
+                    // Make sure we are still the current connection, and that they haven't called
+                    // disconnect().
+                    if (!isCurrent("onServiceDisconnected")) {
+                        return;
+                    }
+
+                    // Clear out what we set in onServiceConnected
+                    mServiceBinder = null;
+                    mServiceCallbacks = null;
+
+                    // And tell the app that it's suspended.
+                    mState = CONNECT_STATE_SUSPENDED;
+                    mCallback.onConnectionSuspended();
+                }
+            });
+        }
+
+        private void postOrRun(Runnable r) {
+            if (Thread.currentThread() == mHandler.getLooper().getThread()) {
+                r.run();
+            } else {
+                mHandler.post(r);
+            }
+        }
+
+        /**
+         * Return true if this is the current ServiceConnection. Also logs if it's not.
+         */
+        private boolean isCurrent(String funcName) {
+            if (mServiceConnection != this || mState == CONNECT_STATE_DISCONNECTING
+                    || mState == CONNECT_STATE_DISCONNECTED) {
+                if (mState != CONNECT_STATE_DISCONNECTING && mState != CONNECT_STATE_DISCONNECTED) {
+                    // Check mState, because otherwise this log is noisy.
+                    Log.i(TAG, funcName + " for " + mServiceComponent + " with mServiceConnection="
+                            + mServiceConnection + " this=" + this);
+                }
+                return false;
+            }
+            return true;
+        }
+    }
+
+    /**
+     * Callbacks from the service.
+     */
+    private static class ServiceCallbacks extends IMediaBrowserServiceCallbacks.Stub {
+        private WeakReference<MediaBrowser> mMediaBrowser;
+
+        ServiceCallbacks(MediaBrowser mediaBrowser) {
+            mMediaBrowser = new WeakReference<MediaBrowser>(mediaBrowser);
+        }
+
+        /**
+         * The other side has acknowledged our connection. The parameters to this function
+         * are the initial data as requested.
+         */
+        @Override
+        public void onConnect(String root, MediaSession.Token session,
+                final Bundle extras) {
+            MediaBrowser mediaBrowser = mMediaBrowser.get();
+            if (mediaBrowser != null) {
+                mediaBrowser.onServiceConnected(this, root, session, extras);
+            }
+        }
+
+        /**
+         * The other side does not like us. Tell the app via onConnectionFailed.
+         */
+        @Override
+        public void onConnectFailed() {
+            MediaBrowser mediaBrowser = mMediaBrowser.get();
+            if (mediaBrowser != null) {
+                mediaBrowser.onConnectionFailed(this);
+            }
+        }
+
+        @Override
+        public void onLoadChildren(String parentId, ParceledListSlice list, Bundle options) {
+            MediaBrowser mediaBrowser = mMediaBrowser.get();
+            if (mediaBrowser != null) {
+                mediaBrowser.onLoadChildren(this, parentId, list, options);
+            }
+        }
+    }
+
+    private static class Subscription {
+        private final List<SubscriptionCallback> mCallbacks;
+        private final List<Bundle> mOptionsList;
+
+        Subscription() {
+            mCallbacks = new ArrayList<>();
+            mOptionsList = new ArrayList<>();
+        }
+
+        public boolean isEmpty() {
+            return mCallbacks.isEmpty();
+        }
+
+        public List<Bundle> getOptionsList() {
+            return mOptionsList;
+        }
+
+        public List<SubscriptionCallback> getCallbacks() {
+            return mCallbacks;
+        }
+
+        public SubscriptionCallback getCallback(Context context, Bundle options) {
+            if (options != null) {
+                options.setClassLoader(context.getClassLoader());
+            }
+            for (int i = 0; i < mOptionsList.size(); ++i) {
+                if (MediaBrowserUtils.areSameOptions(mOptionsList.get(i), options)) {
+                    return mCallbacks.get(i);
+                }
+            }
+            return null;
+        }
+
+        public void putCallback(Context context, Bundle options, SubscriptionCallback callback) {
+            if (options != null) {
+                options.setClassLoader(context.getClassLoader());
+            }
+            for (int i = 0; i < mOptionsList.size(); ++i) {
+                if (MediaBrowserUtils.areSameOptions(mOptionsList.get(i), options)) {
+                    mCallbacks.set(i, callback);
+                    return;
+                }
+            }
+            mCallbacks.add(callback);
+            mOptionsList.add(options);
+        }
+    }
+}
diff --git a/android/media/browse/MediaBrowserUtils.java b/android/media/browse/MediaBrowserUtils.java
new file mode 100644
index 0000000..19d9f00
--- /dev/null
+++ b/android/media/browse/MediaBrowserUtils.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2016 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.browse;
+
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+public class MediaBrowserUtils {
+    /**
+     * Compares whether two bundles are the same.
+     */
+    public static boolean areSameOptions(Bundle options1, Bundle options2) {
+        if (options1 == options2) {
+            return true;
+        } else if (options1 == null) {
+            return options2.getInt(MediaBrowser.EXTRA_PAGE, -1) == -1
+                    && options2.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1) == -1;
+        } else if (options2 == null) {
+            return options1.getInt(MediaBrowser.EXTRA_PAGE, -1) == -1
+                    && options1.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1) == -1;
+        } else {
+            return options1.getInt(MediaBrowser.EXTRA_PAGE, -1)
+                    == options2.getInt(MediaBrowser.EXTRA_PAGE, -1)
+                    && options1.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1)
+                    == options2.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1);
+        }
+    }
+
+    /**
+     * Returnes true if the page options has duplicated items.
+     */
+    public static boolean hasDuplicatedItems(Bundle options1, Bundle options2) {
+        int page1 = options1 == null ? -1 : options1.getInt(MediaBrowser.EXTRA_PAGE, -1);
+        int page2 = options2 == null ? -1 : options2.getInt(MediaBrowser.EXTRA_PAGE, -1);
+        int pageSize1 = options1 == null ? -1 : options1.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1);
+        int pageSize2 = options2 == null ? -1 : options2.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1);
+
+        int startIndex1, startIndex2, endIndex1, endIndex2;
+        if (page1 == -1 || pageSize1 == -1) {
+            startIndex1 = 0;
+            endIndex1 = Integer.MAX_VALUE;
+        } else {
+            startIndex1 = pageSize1 * page1;
+            endIndex1 = startIndex1 + pageSize1 - 1;
+        }
+
+        if (page2 == -1 || pageSize2 == -1) {
+            startIndex2 = 0;
+            endIndex2 = Integer.MAX_VALUE;
+        } else {
+            startIndex2 = pageSize2 * page2;
+            endIndex2 = startIndex2 + pageSize2 - 1;
+        }
+
+        if (startIndex1 <= startIndex2 && startIndex2 <= endIndex1) {
+            return true;
+        } else if (startIndex1 <= endIndex2 && endIndex2 <= endIndex1) {
+            return true;
+        }
+        return false;
+    }
+}
diff --git a/android/media/effect/Effect.java b/android/media/effect/Effect.java
new file mode 100644
index 0000000..b2b4427
--- /dev/null
+++ b/android/media/effect/Effect.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2011 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.effect;
+
+
+/**
+ * <p>Effects are high-performance transformations that can be applied to image frames. These are
+ * passed in the form of OpenGL ES 2.0 texture names. Typical frames could be images loaded from
+ * disk, or frames from the camera or other video streams.</p>
+ *
+ * <p>To create an Effect you must first create an EffectContext. You can obtain an instance of the
+ * context's EffectFactory by calling
+ * {@link android.media.effect.EffectContext#getFactory() getFactory()}. The EffectFactory allows
+ * you to instantiate specific Effects.</p>
+ *
+ * <p>The application is responsible for creating an EGL context, and making it current before
+ * applying an effect. An effect is bound to a single EffectContext, which in turn is bound to a
+ * single EGL context. If your EGL context is destroyed, the EffectContext becomes invalid and any
+ * effects bound to this context can no longer be used.</p>
+ *
+ */
+public abstract class Effect {
+
+    /**
+     * Get the effect name.
+     *
+     * Returns the unique name of the effect, which matches the name used for instantiating this
+     * effect by the EffectFactory.
+     *
+     * @return The name of the effect.
+     */
+    public abstract String getName();
+
+    /**
+     * Apply an effect to GL textures.
+     *
+     * <p>Apply the Effect on the specified input GL texture, and write the result into the
+     * output GL texture. The texture names passed must be valid in the current GL context.</p>
+     *
+     * <p>The input texture must be a valid texture name with the given width and height and must be
+     * bound to a GL_TEXTURE_2D texture image (usually done by calling the glTexImage2D() function).
+     * Multiple mipmap levels may be provided.</p>
+     *
+     * <p>If the output texture has not been bound to a texture image, it will be automatically
+     * bound by the effect as a GL_TEXTURE_2D. It will contain one mipmap level (0), which will have
+     * the same size as the input. No other mipmap levels are defined. If the output texture was
+     * bound already, and its size does not match the input texture size, the result may be clipped
+     * or only partially fill the texture.</p>
+     *
+     * <p>Note, that regardless of whether a texture image was originally provided or not, both the
+     * input and output textures are owned by the caller. That is, the caller is responsible for
+     * calling glDeleteTextures() to deallocate the input and output textures.</p>
+     *
+     * @param inputTexId The GL texture name of a valid and bound input texture.
+     * @param width The width of the input texture in pixels.
+     * @param height The height of the input texture in pixels.
+     * @param outputTexId The GL texture name of the output texture.
+     */
+    public abstract void apply(int inputTexId, int width, int height, int outputTexId);
+
+    /**
+     * Set a filter parameter.
+     *
+     * Consult the effect documentation for a list of supported parameter keys for each effect.
+     *
+     * @param parameterKey The name of the parameter to adjust.
+     * @param value The new value to set the parameter to.
+     * @throws InvalidArgumentException if parameterName is not a recognized name, or the value is
+     *         not a valid value for this parameter.
+     */
+    public abstract void setParameter(String parameterKey, Object value);
+
+    /**
+     * Set an effect listener.
+     *
+     * Some effects may report state changes back to the host, if a listener is set. Consult the
+     * individual effect documentation for more details.
+     *
+     * @param listener The listener to receive update callbacks on.
+     */
+    public void setUpdateListener(EffectUpdateListener listener) {
+    }
+
+    /**
+     * Release an effect.
+     *
+     * <p>Releases the effect and any resources associated with it. You may call this if you need to
+     * make sure acquired resources are no longer held by the effect. Releasing an effect makes it
+     * invalid for reuse.</p>
+     *
+     * <p>Note that this method must be called with the EffectContext and EGL context current, as
+     * the effect may release internal GL resources.</p>
+     */
+    public abstract void release();
+}
+
diff --git a/android/media/effect/EffectContext.java b/android/media/effect/EffectContext.java
new file mode 100644
index 0000000..a11b9c4
--- /dev/null
+++ b/android/media/effect/EffectContext.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright (C) 2011 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.effect;
+
+import android.filterfw.core.CachedFrameManager;
+import android.filterfw.core.FilterContext;
+import android.filterfw.core.GLEnvironment;
+import android.opengl.GLES20;
+
+/**
+ * <p>An EffectContext keeps all necessary state information to run Effects within a Open GL ES 2.0
+ * context.</p>
+ *
+ * <p>Every EffectContext is bound to one GL context. The application is responsible for creating
+ * this EGL context, and making it current before applying any effect. If your EGL context is
+ * destroyed, the EffectContext becomes invalid and any effects bound to this context can no longer
+ * be used. If you switch to another EGL context, you must create a new EffectContext. Each Effect
+ * is bound to a single EffectContext, and can only be executed in that context.</p>
+ */
+public class EffectContext {
+
+    private final int GL_STATE_FBO          = 0;
+    private final int GL_STATE_PROGRAM      = 1;
+    private final int GL_STATE_ARRAYBUFFER  = 2;
+    private final int GL_STATE_COUNT        = 3;
+
+    FilterContext mFilterContext;
+
+    private EffectFactory mFactory;
+
+    private int[] mOldState = new int[GL_STATE_COUNT];
+
+    /**
+     * Creates a context within the current GL context.
+     *
+     * <p>Binds the EffectContext to the current OpenGL context. All subsequent calls to the
+     * EffectContext must be made in the GL context that was active during creation.
+     * When you have finished using a context, you must call {@link #release()}. to dispose of all
+     * resources associated with this context.</p>
+     */
+    public static EffectContext createWithCurrentGlContext() {
+        EffectContext result = new EffectContext();
+        result.initInCurrentGlContext();
+        return result;
+    }
+
+    /**
+     * Returns the EffectFactory for this context.
+     *
+     * <p>The EffectFactory returned from this method allows instantiating new effects within this
+     * context.</p>
+     *
+     * @return The EffectFactory instance for this context.
+     */
+    public EffectFactory getFactory() {
+        return mFactory;
+    }
+
+    /**
+     * Releases the context.
+     *
+     * <p>Releases all the resources and effects associated with the EffectContext. This renders the
+     * context and all the effects bound to this context invalid. You must no longer use the context
+     * or any of its bound effects after calling release().</p>
+     *
+     * <p>Note that this method must be called with the proper EGL context made current, as the
+     * EffectContext and its effects may release internal GL resources.</p>
+     */
+    public void release() {
+        mFilterContext.tearDown();
+        mFilterContext = null;
+    }
+
+    private EffectContext() {
+        mFilterContext = new FilterContext();
+        mFilterContext.setFrameManager(new CachedFrameManager());
+        mFactory = new EffectFactory(this);
+    }
+
+    private void initInCurrentGlContext() {
+        if (!GLEnvironment.isAnyContextActive()) {
+            throw new RuntimeException("Attempting to initialize EffectContext with no active "
+                + "GL context!");
+        }
+        GLEnvironment glEnvironment = new GLEnvironment();
+        glEnvironment.initWithCurrentContext();
+        mFilterContext.initGLEnvironment(glEnvironment);
+    }
+
+    final void assertValidGLState() {
+        GLEnvironment glEnv = mFilterContext.getGLEnvironment();
+        if (glEnv == null || !glEnv.isContextActive()) {
+            if (GLEnvironment.isAnyContextActive()) {
+                throw new RuntimeException("Applying effect in wrong GL context!");
+            } else {
+                throw new RuntimeException("Attempting to apply effect without valid GL context!");
+            }
+        }
+    }
+
+    final void saveGLState() {
+        GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, mOldState, GL_STATE_FBO);
+        GLES20.glGetIntegerv(GLES20.GL_CURRENT_PROGRAM, mOldState, GL_STATE_PROGRAM);
+        GLES20.glGetIntegerv(GLES20.GL_ARRAY_BUFFER_BINDING, mOldState, GL_STATE_ARRAYBUFFER);
+    }
+
+    final void restoreGLState() {
+        GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mOldState[GL_STATE_FBO]);
+        GLES20.glUseProgram(mOldState[GL_STATE_PROGRAM]);
+        GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, mOldState[GL_STATE_ARRAYBUFFER]);
+    }
+}
+
diff --git a/android/media/effect/EffectFactory.java b/android/media/effect/EffectFactory.java
new file mode 100644
index 0000000..f6fcba7
--- /dev/null
+++ b/android/media/effect/EffectFactory.java
@@ -0,0 +1,516 @@
+/*
+ * Copyright (C) 2011 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.effect;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * <p>The EffectFactory class defines the list of available Effects, and provides functionality to
+ * inspect and instantiate them. Some effects may not be available on all platforms, so before
+ * creating a certain effect, the application should confirm that the effect is supported on this
+ * platform by calling {@link #isEffectSupported(String)}.</p>
+ */
+public class EffectFactory {
+
+    private EffectContext mEffectContext;
+
+    private final static String[] EFFECT_PACKAGES = {
+        "android.media.effect.effects.",  // Default effect package
+        ""                                // Allows specifying full class path
+    };
+
+    /** List of Effects */
+    /**
+     * <p>Copies the input texture to the output.</p>
+     * <p>Available parameters: None</p>
+     * @hide
+     */
+    public final static String EFFECT_IDENTITY = "IdentityEffect";
+
+    /**
+     * <p>Adjusts the brightness of the image.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>brightness</code></td>
+     *     <td>The brightness multiplier.</td>
+     *     <td>Positive float. 1.0 means no change;
+               larger values will increase brightness.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_BRIGHTNESS =
+            "android.media.effect.effects.BrightnessEffect";
+
+    /**
+     * <p>Adjusts the contrast of the image.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>contrast</code></td>
+     *     <td>The contrast multiplier.</td>
+     *     <td>Float. 1.0 means no change;
+               larger values will increase contrast.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_CONTRAST =
+            "android.media.effect.effects.ContrastEffect";
+
+    /**
+     * <p>Applies a fisheye lens distortion to the image.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>scale</code></td>
+     *     <td>The scale of the distortion.</td>
+     *     <td>Float, between 0 and 1. Zero means no distortion.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_FISHEYE =
+            "android.media.effect.effects.FisheyeEffect";
+
+    /**
+     * <p>Replaces the background of the input frames with frames from a
+     * selected video.  Requires an initial learning period with only the
+     * background visible before the effect becomes active. The effect will wait
+     * until it does not see any motion in the scene before learning the
+     * background and starting the effect.</p>
+     *
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>source</code></td>
+     *     <td>A URI for the background video to use. This parameter must be
+     *         supplied before calling apply() for the first time.</td>
+     *     <td>String, such as from
+     *         {@link android.net.Uri#toString Uri.toString()}</td>
+     * </tr>
+     * </table>
+     *
+     * <p>If the update listener is set for this effect using
+     * {@link Effect#setUpdateListener}, it will be called when the effect has
+     * finished learning the background, with a null value for the info
+     * parameter.</p>
+     */
+    public final static String EFFECT_BACKDROPPER =
+            "android.media.effect.effects.BackDropperEffect";
+
+    /**
+     * <p>Attempts to auto-fix the image based on histogram equalization.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>scale</code></td>
+     *     <td>The scale of the adjustment.</td>
+     *     <td>Float, between 0 and 1. Zero means no adjustment, while 1 indicates the maximum
+     *     amount of adjustment.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_AUTOFIX =
+            "android.media.effect.effects.AutoFixEffect";
+
+    /**
+     * <p>Adjusts the range of minimal and maximal color pixel intensities.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>black</code></td>
+     *     <td>The value of the minimal pixel.</td>
+     *     <td>Float, between 0 and 1.</td>
+     * </tr>
+     * <tr><td><code>white</code></td>
+     *     <td>The value of the maximal pixel.</td>
+     *     <td>Float, between 0 and 1.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_BLACKWHITE =
+            "android.media.effect.effects.BlackWhiteEffect";
+
+    /**
+     * <p>Crops an upright rectangular area from the image. If the crop region falls outside of
+     * the image bounds, the results are undefined.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>xorigin</code></td>
+     *     <td>The origin's x-value.</td>
+     *     <td>Integer, between 0 and width of the image.</td>
+     * </tr>
+     * <tr><td><code>yorigin</code></td>
+     *     <td>The origin's y-value.</td>
+     *     <td>Integer, between 0 and height of the image.</td>
+     * </tr>
+     * <tr><td><code>width</code></td>
+     *     <td>The width of the cropped image.</td>
+     *     <td>Integer, between 1 and the width of the image minus xorigin.</td>
+     * </tr>
+     * <tr><td><code>height</code></td>
+     *     <td>The height of the cropped image.</td>
+     *     <td>Integer, between 1 and the height of the image minus yorigin.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_CROP =
+            "android.media.effect.effects.CropEffect";
+
+    /**
+     * <p>Applies a cross process effect on image, in which the red and green channels are
+     * enhanced while the blue channel is restricted.</p>
+     * <p>Available parameters: None</p>
+     */
+    public final static String EFFECT_CROSSPROCESS =
+            "android.media.effect.effects.CrossProcessEffect";
+
+    /**
+     * <p>Applies black and white documentary style effect on image..</p>
+     * <p>Available parameters: None</p>
+     */
+    public final static String EFFECT_DOCUMENTARY =
+            "android.media.effect.effects.DocumentaryEffect";
+
+
+    /**
+     * <p>Overlays a bitmap (with premultiplied alpha channel) onto the input image. The bitmap
+     * is stretched to fit the input image.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>bitmap</code></td>
+     *     <td>The overlay bitmap.</td>
+     *     <td>A non-null Bitmap instance.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_BITMAPOVERLAY =
+            "android.media.effect.effects.BitmapOverlayEffect";
+
+    /**
+     * <p>Representation of photo using only two color tones.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>first_color</code></td>
+     *     <td>The first color tone.</td>
+     *     <td>Integer, representing an ARGB color with 8 bits per channel. May be created using
+     *     {@link android.graphics.Color Color} class.</td>
+     * </tr>
+     * <tr><td><code>second_color</code></td>
+     *     <td>The second color tone.</td>
+     *     <td>Integer, representing an ARGB color with 8 bits per channel. May be created using
+     *     {@link android.graphics.Color Color} class.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_DUOTONE =
+            "android.media.effect.effects.DuotoneEffect";
+
+    /**
+     * <p>Applies back-light filling to the image.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>strength</code></td>
+     *     <td>The strength of the backlight.</td>
+     *     <td>Float, between 0 and 1. Zero means no change.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_FILLLIGHT =
+            "android.media.effect.effects.FillLightEffect";
+
+    /**
+     * <p>Flips image vertically and/or horizontally.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>vertical</code></td>
+     *     <td>Whether to flip image vertically.</td>
+     *     <td>Boolean</td>
+     * </tr>
+     * <tr><td><code>horizontal</code></td>
+     *     <td>Whether to flip image horizontally.</td>
+     *     <td>Boolean</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_FLIP =
+            "android.media.effect.effects.FlipEffect";
+
+    /**
+     * <p>Applies film grain effect to image.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>strength</code></td>
+     *     <td>The strength of the grain effect.</td>
+     *     <td>Float, between 0 and 1. Zero means no change.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_GRAIN =
+            "android.media.effect.effects.GrainEffect";
+
+    /**
+     * <p>Converts image to grayscale.</p>
+     * <p>Available parameters: None</p>
+     */
+    public final static String EFFECT_GRAYSCALE =
+            "android.media.effect.effects.GrayscaleEffect";
+
+    /**
+     * <p>Applies lomo-camera style effect to image.</p>
+     * <p>Available parameters: None</p>
+     */
+    public final static String EFFECT_LOMOISH =
+            "android.media.effect.effects.LomoishEffect";
+
+    /**
+     * <p>Inverts the image colors.</p>
+     * <p>Available parameters: None</p>
+     */
+    public final static String EFFECT_NEGATIVE =
+            "android.media.effect.effects.NegativeEffect";
+
+    /**
+     * <p>Applies posterization effect to image.</p>
+     * <p>Available parameters: None</p>
+     */
+    public final static String EFFECT_POSTERIZE =
+            "android.media.effect.effects.PosterizeEffect";
+
+    /**
+     * <p>Removes red eyes on specified region.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>centers</code></td>
+     *     <td>Multiple center points (x, y) of the red eye regions.</td>
+     *     <td>An array of floats, where (f[2*i], f[2*i+1]) specifies the center of the i'th eye.
+     *     Coordinate values are expected to be normalized between 0 and 1.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_REDEYE =
+            "android.media.effect.effects.RedEyeEffect";
+
+    /**
+     * <p>Rotates the image. The output frame size must be able to fit the rotated version of
+     * the input image. Note that the rotation snaps to a the closest multiple of 90 degrees.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>angle</code></td>
+     *     <td>The angle of rotation in degrees.</td>
+     *     <td>Integer value. This will be rounded to the nearest multiple of 90.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_ROTATE =
+            "android.media.effect.effects.RotateEffect";
+
+    /**
+     * <p>Adjusts color saturation of image.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>scale</code></td>
+     *     <td>The scale of color saturation.</td>
+     *     <td>Float, between -1 and 1. 0 means no change, while -1 indicates full desaturation,
+     *     i.e. grayscale.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_SATURATE =
+            "android.media.effect.effects.SaturateEffect";
+
+    /**
+     * <p>Converts image to sepia tone.</p>
+     * <p>Available parameters: None</p>
+     */
+    public final static String EFFECT_SEPIA =
+            "android.media.effect.effects.SepiaEffect";
+
+    /**
+     * <p>Sharpens the image.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>scale</code></td>
+     *     <td>The degree of sharpening.</td>
+     *     <td>Float, between 0 and 1. 0 means no change.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_SHARPEN =
+            "android.media.effect.effects.SharpenEffect";
+
+    /**
+     * <p>Rotates the image according to the specified angle, and crops the image so that no
+     * non-image portions are visible.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>angle</code></td>
+     *     <td>The angle of rotation.</td>
+     *     <td>Float, between -45 and +45.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_STRAIGHTEN =
+            "android.media.effect.effects.StraightenEffect";
+
+    /**
+     * <p>Adjusts color temperature of the image.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>scale</code></td>
+     *     <td>The value of color temperature.</td>
+     *     <td>Float, between 0 and 1, with 0 indicating cool, and 1 indicating warm. A value of
+     *     of 0.5 indicates no change.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_TEMPERATURE =
+            "android.media.effect.effects.ColorTemperatureEffect";
+
+    /**
+     * <p>Tints the photo with specified color.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>tint</code></td>
+     *     <td>The color of the tint.</td>
+     *     <td>Integer, representing an ARGB color with 8 bits per channel. May be created using
+     *     {@link android.graphics.Color Color} class.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_TINT =
+            "android.media.effect.effects.TintEffect";
+
+    /**
+     * <p>Adds a vignette effect to image, i.e. fades away the outer image edges.</p>
+     * <p>Available parameters:</p>
+     * <table>
+     * <tr><td>Parameter name</td><td>Meaning</td><td>Valid values</td></tr>
+     * <tr><td><code>scale</code></td>
+     *     <td>The scale of vignetting.</td>
+     *     <td>Float, between 0 and 1. 0 means no change.</td>
+     * </tr>
+     * </table>
+     */
+    public final static String EFFECT_VIGNETTE =
+            "android.media.effect.effects.VignetteEffect";
+
+    EffectFactory(EffectContext effectContext) {
+        mEffectContext = effectContext;
+    }
+
+    /**
+     * Instantiate a new effect with the given effect name.
+     *
+     * <p>The effect's parameters will be set to their default values.</p>
+     *
+     * <p>Note that the EGL context associated with the current EffectContext need not be made
+     * current when creating an effect. This allows the host application to instantiate effects
+     * before any EGL context has become current.</p>
+     *
+     * @param effectName The name of the effect to create.
+     * @return A new Effect instance.
+     * @throws IllegalArgumentException if the effect with the specified name is not supported or
+     *         not known.
+     */
+    public Effect createEffect(String effectName) {
+        Class effectClass = getEffectClassByName(effectName);
+        if (effectClass == null) {
+            throw new IllegalArgumentException("Cannot instantiate unknown effect '" +
+                effectName + "'!");
+        }
+        return instantiateEffect(effectClass, effectName);
+    }
+
+    /**
+     * Check if an effect is supported on this platform.
+     *
+     * <p>Some effects may only be available on certain platforms. Use this method before
+     * instantiating an effect to make sure it is supported.</p>
+     *
+     * @param effectName The name of the effect.
+     * @return true, if the effect is supported on this platform.
+     * @throws IllegalArgumentException if the effect name is not known.
+     */
+    public static boolean isEffectSupported(String effectName) {
+        return getEffectClassByName(effectName) != null;
+    }
+
+    private static Class getEffectClassByName(String className) {
+        Class effectClass = null;
+
+        // Get context's classloader; otherwise cannot load non-framework effects
+        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
+
+        // Look for the class in the imported packages
+        for (String packageName : EFFECT_PACKAGES) {
+            try {
+                effectClass = contextClassLoader.loadClass(packageName + className);
+            } catch (ClassNotFoundException e) {
+                continue;
+            }
+            // Exit loop if class was found.
+            if (effectClass != null) {
+                break;
+            }
+        }
+        return effectClass;
+    }
+
+    private Effect instantiateEffect(Class effectClass, String name) {
+        // Make sure this is an Effect subclass
+        try {
+            effectClass.asSubclass(Effect.class);
+        } catch (ClassCastException e) {
+            throw new IllegalArgumentException("Attempting to allocate effect '" + effectClass
+                + "' which is not a subclass of Effect!", e);
+        }
+
+        // Look for the correct constructor
+        Constructor effectConstructor = null;
+        try {
+            effectConstructor = effectClass.getConstructor(EffectContext.class, String.class);
+        } catch (NoSuchMethodException e) {
+            throw new RuntimeException("The effect class '" + effectClass + "' does not have "
+                + "the required constructor.", e);
+        }
+
+        // Construct the effect
+        Effect effect = null;
+        try {
+            effect = (Effect)effectConstructor.newInstance(mEffectContext, name);
+        } catch (Throwable t) {
+            throw new RuntimeException("There was an error constructing the effect '" + effectClass
+                + "'!", t);
+        }
+
+        return effect;
+    }
+}
diff --git a/android/media/effect/EffectUpdateListener.java b/android/media/effect/EffectUpdateListener.java
new file mode 100644
index 0000000..155fe49
--- /dev/null
+++ b/android/media/effect/EffectUpdateListener.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 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.effect;
+
+/**
+ * Some effects may issue callbacks to inform the host of changes to the effect state. This is the
+ * listener interface for receiving those callbacks.
+ */
+public interface EffectUpdateListener {
+
+    /**
+     * Called when the effect state is updated.
+     *
+     * @param effect The effect that has been updated.
+     * @param info A value that gives more information about the update. See the effect's
+     *             documentation for more details on what this object is.
+     */
+    public void onEffectUpdated(Effect effect, Object info);
+
+}
+
diff --git a/android/media/effect/FilterEffect.java b/android/media/effect/FilterEffect.java
new file mode 100644
index 0000000..34b3549
--- /dev/null
+++ b/android/media/effect/FilterEffect.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2011 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.effect;
+
+import android.filterfw.core.FilterContext;
+import android.filterfw.core.GLFrame;
+import android.filterfw.core.Frame;
+import android.filterfw.core.FrameFormat;
+import android.filterfw.core.FrameManager;
+import android.filterfw.format.ImageFormat;
+
+/**
+ * The FilterEffect class is the base class for all Effects based on Filters from the Mobile
+ * Filter Framework (MFF).
+ * @hide
+ */
+public abstract class FilterEffect extends Effect {
+
+    protected EffectContext mEffectContext;
+    private String mName;
+
+    /**
+     * Protected constructor as FilterEffects should be created by Factory.
+     */
+    protected FilterEffect(EffectContext context, String name) {
+        mEffectContext = context;
+        mName = name;
+    }
+
+    /**
+     * Get the effect name.
+     *
+     * Returns the unique name of the effect, which matches the name used for instantiating this
+     * effect by the EffectFactory.
+     *
+     * @return The name of the effect.
+     */
+    @Override
+    public String getName() {
+        return mName;
+    }
+
+    // Helper Methods for subclasses ///////////////////////////////////////////////////////////////
+    /**
+     * Call this before manipulating the GL context. Will assert that the GL environment is in a
+     * valid state, and save it.
+     */
+    protected void beginGLEffect() {
+        mEffectContext.assertValidGLState();
+        mEffectContext.saveGLState();
+    }
+
+    /**
+     * Call this after manipulating the GL context. Restores the previous GL state.
+     */
+    protected void endGLEffect() {
+        mEffectContext.restoreGLState();
+    }
+
+    /**
+     * Returns the active filter context for this effect.
+     */
+    protected FilterContext getFilterContext() {
+        return mEffectContext.mFilterContext;
+    }
+
+    /**
+     * Converts a texture into a Frame.
+     */
+    protected Frame frameFromTexture(int texId, int width, int height) {
+        FrameManager manager = getFilterContext().getFrameManager();
+        FrameFormat format = ImageFormat.create(width, height,
+                                                ImageFormat.COLORSPACE_RGBA,
+                                                FrameFormat.TARGET_GPU);
+        Frame frame = manager.newBoundFrame(format,
+                                            GLFrame.EXISTING_TEXTURE_BINDING,
+                                            texId);
+        frame.setTimestamp(Frame.TIMESTAMP_UNKNOWN);
+        return frame;
+    }
+
+}
+
diff --git a/android/media/effect/FilterGraphEffect.java b/android/media/effect/FilterGraphEffect.java
new file mode 100644
index 0000000..80c695b
--- /dev/null
+++ b/android/media/effect/FilterGraphEffect.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright (C) 2011 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.effect;
+
+import android.filterfw.core.Filter;
+import android.filterfw.core.FilterGraph;
+import android.filterfw.core.GraphRunner;
+import android.filterfw.core.SyncRunner;
+import android.media.effect.FilterEffect;
+import android.media.effect.EffectContext;
+import android.filterfw.io.GraphIOException;
+import android.filterfw.io.GraphReader;
+import android.filterfw.io.TextGraphReader;
+
+/**
+ * Effect subclass for effects based on a single Filter. Subclasses need only invoke the
+ * constructor with the correct arguments to obtain an Effect implementation.
+ *
+ * @hide
+ */
+public class FilterGraphEffect extends FilterEffect {
+
+    private static final String TAG = "FilterGraphEffect";
+
+    protected String mInputName;
+    protected String mOutputName;
+    protected GraphRunner mRunner;
+    protected FilterGraph mGraph;
+    protected Class mSchedulerClass;
+
+    /**
+     * Constructs a new FilterGraphEffect.
+     *
+     * @param name The name of this effect (used to create it in the EffectFactory).
+     * @param graphString The graph string to create the graph.
+     * @param inputName The name of the input GLTextureSource filter.
+     * @param outputName The name of the output GLTextureSource filter.
+     */
+    public FilterGraphEffect(EffectContext context,
+                              String name,
+                              String graphString,
+                              String inputName,
+                              String outputName,
+                              Class scheduler) {
+        super(context, name);
+
+        mInputName = inputName;
+        mOutputName = outputName;
+        mSchedulerClass = scheduler;
+        createGraph(graphString);
+
+    }
+
+    private void createGraph(String graphString) {
+        GraphReader reader = new TextGraphReader();
+        try {
+            mGraph = reader.readGraphString(graphString);
+        } catch (GraphIOException e) {
+            throw new RuntimeException("Could not setup effect", e);
+        }
+
+        if (mGraph == null) {
+            throw new RuntimeException("Could not setup effect");
+        }
+        mRunner = new SyncRunner(getFilterContext(), mGraph, mSchedulerClass);
+    }
+
+    @Override
+    public void apply(int inputTexId, int width, int height, int outputTexId) {
+        beginGLEffect();
+        Filter src = mGraph.getFilter(mInputName);
+        if (src != null) {
+            src.setInputValue("texId", inputTexId);
+            src.setInputValue("width", width);
+            src.setInputValue("height", height);
+        } else {
+            throw new RuntimeException("Internal error applying effect");
+        }
+        Filter dest  = mGraph.getFilter(mOutputName);
+        if (dest != null) {
+            dest.setInputValue("texId", outputTexId);
+        } else {
+            throw new RuntimeException("Internal error applying effect");
+        }
+        try {
+            mRunner.run();
+        } catch (RuntimeException e) {
+            throw new RuntimeException("Internal error applying effect: ", e);
+        }
+        endGLEffect();
+    }
+
+    @Override
+    public void setParameter(String parameterKey, Object value) {
+    }
+
+    @Override
+    public void release() {
+         mGraph.tearDown(getFilterContext());
+         mGraph = null;
+    }
+}
diff --git a/android/media/effect/SingleFilterEffect.java b/android/media/effect/SingleFilterEffect.java
new file mode 100644
index 0000000..121443f
--- /dev/null
+++ b/android/media/effect/SingleFilterEffect.java
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011 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.effect;
+
+import android.compat.annotation.UnsupportedAppUsage;
+import android.filterfw.core.Filter;
+import android.filterfw.core.FilterFactory;
+import android.filterfw.core.FilterFunction;
+import android.filterfw.core.Frame;
+
+/**
+ * Effect subclass for effects based on a single Filter. Subclasses need only invoke the
+ * constructor with the correct arguments to obtain an Effect implementation.
+ *
+ * @hide
+ */
+public class SingleFilterEffect extends FilterEffect {
+
+    protected FilterFunction mFunction;
+    protected String mInputName;
+    protected String mOutputName;
+
+    /**
+     * Constructs a new FilterFunctionEffect.
+     *
+     * @param name The name of this effect (used to create it in the EffectFactory).
+     * @param filterClass The class of the filter to wrap.
+     * @param inputName The name of the input image port.
+     * @param outputName The name of the output image port.
+     * @param finalParameters Key-value pairs of final input port assignments.
+     */
+    @UnsupportedAppUsage
+    public SingleFilterEffect(EffectContext context,
+                              String name,
+                              Class filterClass,
+                              String inputName,
+                              String outputName,
+                              Object... finalParameters) {
+        super(context, name);
+
+        mInputName = inputName;
+        mOutputName = outputName;
+
+        String filterName = filterClass.getSimpleName();
+        FilterFactory factory = FilterFactory.sharedFactory();
+        Filter filter = factory.createFilterByClass(filterClass, filterName);
+        filter.initWithAssignmentList(finalParameters);
+
+        mFunction = new FilterFunction(getFilterContext(), filter);
+    }
+
+    @Override
+    public void apply(int inputTexId, int width, int height, int outputTexId) {
+        beginGLEffect();
+
+        Frame inputFrame = frameFromTexture(inputTexId, width, height);
+        Frame outputFrame = frameFromTexture(outputTexId, width, height);
+
+        Frame resultFrame = mFunction.executeWithArgList(mInputName, inputFrame);
+
+        outputFrame.setDataFromFrame(resultFrame);
+
+        inputFrame.release();
+        outputFrame.release();
+        resultFrame.release();
+
+        endGLEffect();
+    }
+
+    @Override
+    public void setParameter(String parameterKey, Object value) {
+        mFunction.setInputValue(parameterKey, value);
+    }
+
+    @Override
+    public void release() {
+        mFunction.tearDown();
+        mFunction = null;
+    }
+}
+
diff --git a/android/media/effect/SizeChangeEffect.java b/android/media/effect/SizeChangeEffect.java
new file mode 100644
index 0000000..1bf7d40
--- /dev/null
+++ b/android/media/effect/SizeChangeEffect.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2011 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.effect;
+
+import android.filterfw.core.Frame;
+import android.media.effect.EffectContext;
+
+/**
+ * Effect subclass for effects based on a single Filter with output size differnet
+ * from input.  Subclasses need only invoke the constructor with the correct arguments
+ * to obtain an Effect implementation.
+ *
+ * @hide
+ */
+public class SizeChangeEffect extends SingleFilterEffect {
+
+    public SizeChangeEffect(EffectContext context,
+                            String name,
+                            Class filterClass,
+                            String inputName,
+                            String outputName,
+                            Object... finalParameters) {
+        super(context, name, filterClass, inputName, outputName, finalParameters);
+    }
+
+    @Override
+    public void apply(int inputTexId, int width, int height, int outputTexId) {
+        beginGLEffect();
+
+        Frame inputFrame = frameFromTexture(inputTexId, width, height);
+        Frame resultFrame = mFunction.executeWithArgList(mInputName, inputFrame);
+
+        int outputWidth = resultFrame.getFormat().getWidth();
+        int outputHeight = resultFrame.getFormat().getHeight();
+
+        Frame outputFrame = frameFromTexture(outputTexId, outputWidth, outputHeight);
+        outputFrame.setDataFromFrame(resultFrame);
+
+        inputFrame.release();
+        outputFrame.release();
+        resultFrame.release();
+
+        endGLEffect();
+    }
+}
diff --git a/android/media/effect/effects/AutoFixEffect.java b/android/media/effect/effects/AutoFixEffect.java
new file mode 100644
index 0000000..44a141b
--- /dev/null
+++ b/android/media/effect/effects/AutoFixEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.AutoFixFilter;
+
+/**
+ * @hide
+ */
+public class AutoFixEffect extends SingleFilterEffect {
+    public AutoFixEffect(EffectContext context, String name) {
+        super(context, name, AutoFixFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/BackDropperEffect.java b/android/media/effect/effects/BackDropperEffect.java
new file mode 100644
index 0000000..f977e60
--- /dev/null
+++ b/android/media/effect/effects/BackDropperEffect.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.filterfw.core.Filter;
+import android.filterfw.core.OneShotScheduler;
+import android.media.effect.EffectContext;
+import android.media.effect.FilterGraphEffect;
+import android.media.effect.EffectUpdateListener;
+
+import android.filterpacks.videoproc.BackDropperFilter;
+import android.filterpacks.videoproc.BackDropperFilter.LearningDoneListener;
+
+/**
+ * Background replacement Effect.
+ *
+ * Replaces the background of the input video stream with a selected video
+ * Learns the background when it first starts up;
+ * needs unobstructed view of background when this happens.
+ *
+ * Effect parameters:
+ *   source: A URI for the background video
+ * Listener: Called when learning period is complete
+ *
+ * @hide
+ */
+public class BackDropperEffect extends FilterGraphEffect {
+    private static final String mGraphDefinition =
+            "@import android.filterpacks.base;\n" +
+            "@import android.filterpacks.videoproc;\n" +
+            "@import android.filterpacks.videosrc;\n" +
+            "\n" +
+            "@filter GLTextureSource foreground {\n" +
+            "  texId = 0;\n" + // Will be set by base class
+            "  width = 0;\n" +
+            "  height = 0;\n" +
+            "  repeatFrame = true;\n" +
+            "}\n" +
+            "\n" +
+            "@filter MediaSource background {\n" +
+            "  sourceUrl = \"no_file_specified\";\n" +
+            "  waitForNewFrame = false;\n" +
+            "  sourceIsUrl = true;\n" +
+            "}\n" +
+            "\n" +
+            "@filter BackDropperFilter replacer {\n" +
+            "  autowbToggle = 1;\n" +
+            "}\n" +
+            "\n" +
+            "@filter GLTextureTarget output {\n" +
+            "  texId = 0;\n" +
+            "}\n" +
+            "\n" +
+            "@connect foreground[frame]  => replacer[video];\n" +
+            "@connect background[video]  => replacer[background];\n" +
+            "@connect replacer[video]    => output[frame];\n";
+
+    private EffectUpdateListener mEffectListener = null;
+
+    private LearningDoneListener mLearningListener = new LearningDoneListener() {
+        public void onLearningDone(BackDropperFilter filter) {
+            if (mEffectListener != null) {
+                mEffectListener.onEffectUpdated(BackDropperEffect.this, null);
+            }
+        }
+    };
+
+    public BackDropperEffect(EffectContext context, String name) {
+        super(context, name, mGraphDefinition, "foreground", "output", OneShotScheduler.class);
+
+        Filter replacer = mGraph.getFilter("replacer");
+        replacer.setInputValue("learningDoneListener", mLearningListener);
+    }
+
+    @Override
+    public void setParameter(String parameterKey, Object value) {
+        if (parameterKey.equals("source")) {
+            Filter background = mGraph.getFilter("background");
+            background.setInputValue("sourceUrl", value);
+        } else if (parameterKey.equals("context")) {
+            Filter background = mGraph.getFilter("background");
+            background.setInputValue("context", value);
+        }
+    }
+
+    @Override
+    public void setUpdateListener(EffectUpdateListener listener) {
+        mEffectListener = listener;
+    }
+
+}
\ No newline at end of file
diff --git a/android/media/effect/effects/BitmapOverlayEffect.java b/android/media/effect/effects/BitmapOverlayEffect.java
new file mode 100644
index 0000000..43f461c
--- /dev/null
+++ b/android/media/effect/effects/BitmapOverlayEffect.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.BitmapOverlayFilter;
+
+/**
+ * @hide
+ */
+public class BitmapOverlayEffect extends SingleFilterEffect {
+    public BitmapOverlayEffect(EffectContext context, String name) {
+        super(context, name, BitmapOverlayFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/BlackWhiteEffect.java b/android/media/effect/effects/BlackWhiteEffect.java
new file mode 100644
index 0000000..771afff
--- /dev/null
+++ b/android/media/effect/effects/BlackWhiteEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.BlackWhiteFilter;
+
+/**
+ * @hide
+ */
+public class BlackWhiteEffect extends SingleFilterEffect {
+    public BlackWhiteEffect(EffectContext context, String name) {
+        super(context, name, BlackWhiteFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/BrightnessEffect.java b/android/media/effect/effects/BrightnessEffect.java
new file mode 100644
index 0000000..774e72f
--- /dev/null
+++ b/android/media/effect/effects/BrightnessEffect.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.BrightnessFilter;
+
+/**
+ * @hide
+ */
+public class BrightnessEffect extends SingleFilterEffect {
+    public BrightnessEffect(EffectContext context, String name) {
+        super(context, name, BrightnessFilter.class, "image", "image");
+    }
+}
+
diff --git a/android/media/effect/effects/ColorTemperatureEffect.java b/android/media/effect/effects/ColorTemperatureEffect.java
new file mode 100644
index 0000000..62d98ce
--- /dev/null
+++ b/android/media/effect/effects/ColorTemperatureEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.ColorTemperatureFilter;
+
+/**
+ * @hide
+ */
+public class ColorTemperatureEffect extends SingleFilterEffect {
+    public ColorTemperatureEffect(EffectContext context, String name) {
+        super(context, name, ColorTemperatureFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/ContrastEffect.java b/android/media/effect/effects/ContrastEffect.java
new file mode 100644
index 0000000..d5bfc21
--- /dev/null
+++ b/android/media/effect/effects/ContrastEffect.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.ContrastFilter;
+
+/**
+ * @hide
+ */
+public class ContrastEffect extends SingleFilterEffect {
+    public ContrastEffect(EffectContext context, String name) {
+        super(context, name, ContrastFilter.class, "image", "image");
+    }
+}
+
diff --git a/android/media/effect/effects/CropEffect.java b/android/media/effect/effects/CropEffect.java
new file mode 100644
index 0000000..7e1c495
--- /dev/null
+++ b/android/media/effect/effects/CropEffect.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SizeChangeEffect;
+import android.filterpacks.imageproc.CropRectFilter;
+
+/**
+ * @hide
+ */
+//public class CropEffect extends SingleFilterEffect {
+public class CropEffect extends SizeChangeEffect {
+    public CropEffect(EffectContext context, String name) {
+        super(context, name, CropRectFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/CrossProcessEffect.java b/android/media/effect/effects/CrossProcessEffect.java
new file mode 100644
index 0000000..d7a7df5
--- /dev/null
+++ b/android/media/effect/effects/CrossProcessEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.CrossProcessFilter;
+
+/**
+ * @hide
+ */
+public class CrossProcessEffect extends SingleFilterEffect {
+    public CrossProcessEffect(EffectContext context, String name) {
+        super(context, name, CrossProcessFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/DocumentaryEffect.java b/android/media/effect/effects/DocumentaryEffect.java
new file mode 100644
index 0000000..1a5ea35
--- /dev/null
+++ b/android/media/effect/effects/DocumentaryEffect.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.DocumentaryFilter;
+
+/**
+ * @hide
+ */
+public class DocumentaryEffect extends SingleFilterEffect {
+    public DocumentaryEffect(EffectContext context, String name) {
+        super(context, name, DocumentaryFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/DuotoneEffect.java b/android/media/effect/effects/DuotoneEffect.java
new file mode 100644
index 0000000..1391b1f
--- /dev/null
+++ b/android/media/effect/effects/DuotoneEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.DuotoneFilter;
+
+/**
+ * @hide
+ */
+public class DuotoneEffect extends SingleFilterEffect {
+    public DuotoneEffect(EffectContext context, String name) {
+        super(context, name, DuotoneFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/FillLightEffect.java b/android/media/effect/effects/FillLightEffect.java
new file mode 100644
index 0000000..5260de3
--- /dev/null
+++ b/android/media/effect/effects/FillLightEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.FillLightFilter;
+
+/**
+ * @hide
+ */
+public class FillLightEffect extends SingleFilterEffect {
+    public FillLightEffect(EffectContext context, String name) {
+        super(context, name, FillLightFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/FisheyeEffect.java b/android/media/effect/effects/FisheyeEffect.java
new file mode 100644
index 0000000..6abfe42
--- /dev/null
+++ b/android/media/effect/effects/FisheyeEffect.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.FisheyeFilter;
+
+/**
+ * @hide
+ */
+public class FisheyeEffect extends SingleFilterEffect {
+    public FisheyeEffect(EffectContext context, String name) {
+        super(context, name, FisheyeFilter.class, "image", "image");
+    }
+}
+
diff --git a/android/media/effect/effects/FlipEffect.java b/android/media/effect/effects/FlipEffect.java
new file mode 100644
index 0000000..0f5c421
--- /dev/null
+++ b/android/media/effect/effects/FlipEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.FlipFilter;
+
+/**
+ * @hide
+ */
+public class FlipEffect extends SingleFilterEffect {
+    public FlipEffect(EffectContext context, String name) {
+        super(context, name, FlipFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/GrainEffect.java b/android/media/effect/effects/GrainEffect.java
new file mode 100644
index 0000000..2fda7e9
--- /dev/null
+++ b/android/media/effect/effects/GrainEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.GrainFilter;
+
+/**
+ * @hide
+ */
+public class GrainEffect extends SingleFilterEffect {
+    public GrainEffect(EffectContext context, String name) {
+        super(context, name, GrainFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/GrayscaleEffect.java b/android/media/effect/effects/GrayscaleEffect.java
new file mode 100644
index 0000000..26ca081
--- /dev/null
+++ b/android/media/effect/effects/GrayscaleEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.ToGrayFilter;
+
+/**
+ * @hide
+ */
+public class GrayscaleEffect extends SingleFilterEffect {
+    public GrayscaleEffect(EffectContext context, String name) {
+        super(context, name, ToGrayFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/IdentityEffect.java b/android/media/effect/effects/IdentityEffect.java
new file mode 100644
index 0000000..d07779e
--- /dev/null
+++ b/android/media/effect/effects/IdentityEffect.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.filterfw.core.Frame;
+import android.media.effect.EffectContext;
+import android.media.effect.FilterEffect;
+
+/**
+ * @hide
+ */
+public class IdentityEffect extends FilterEffect {
+
+    public IdentityEffect(EffectContext context, String name) {
+        super(context, name);
+    }
+
+    @Override
+    public void apply(int inputTexId, int width, int height, int outputTexId) {
+        beginGLEffect();
+
+        Frame inputFrame = frameFromTexture(inputTexId, width, height);
+        Frame outputFrame = frameFromTexture(outputTexId, width, height);
+
+        outputFrame.setDataFromFrame(inputFrame);
+
+        inputFrame.release();
+        outputFrame.release();
+
+        endGLEffect();
+    }
+
+    @Override
+    public void setParameter(String parameterKey, Object value) {
+        throw new IllegalArgumentException("Unknown parameter " + parameterKey
+            + " for IdentityEffect!");
+    }
+
+    @Override
+    public void release() {
+    }
+}
+
diff --git a/android/media/effect/effects/LomoishEffect.java b/android/media/effect/effects/LomoishEffect.java
new file mode 100644
index 0000000..776e53c
--- /dev/null
+++ b/android/media/effect/effects/LomoishEffect.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.LomoishFilter;
+
+/**
+ * @hide
+ */
+public class LomoishEffect extends SingleFilterEffect {
+    public LomoishEffect(EffectContext context, String name) {
+        super(context, name, LomoishFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/NegativeEffect.java b/android/media/effect/effects/NegativeEffect.java
new file mode 100644
index 0000000..29fc94a
--- /dev/null
+++ b/android/media/effect/effects/NegativeEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.NegativeFilter;
+
+/**
+ * @hide
+ */
+public class NegativeEffect extends SingleFilterEffect {
+    public NegativeEffect(EffectContext context, String name) {
+        super(context, name, NegativeFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/PosterizeEffect.java b/android/media/effect/effects/PosterizeEffect.java
new file mode 100644
index 0000000..20a8a37
--- /dev/null
+++ b/android/media/effect/effects/PosterizeEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.PosterizeFilter;
+
+/**
+ * @hide
+ */
+public class PosterizeEffect extends SingleFilterEffect {
+    public PosterizeEffect(EffectContext context, String name) {
+        super(context, name, PosterizeFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/RedEyeEffect.java b/android/media/effect/effects/RedEyeEffect.java
new file mode 100644
index 0000000..8ed9909
--- /dev/null
+++ b/android/media/effect/effects/RedEyeEffect.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.RedEyeFilter;
+
+/**
+ * @hide
+ */
+public class RedEyeEffect extends SingleFilterEffect {
+    public RedEyeEffect(EffectContext context, String name) {
+        super(context, name, RedEyeFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/RotateEffect.java b/android/media/effect/effects/RotateEffect.java
new file mode 100644
index 0000000..2340015
--- /dev/null
+++ b/android/media/effect/effects/RotateEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SizeChangeEffect;
+import android.filterpacks.imageproc.RotateFilter;
+
+/**
+ * @hide
+ */
+public class RotateEffect extends SizeChangeEffect {
+    public RotateEffect(EffectContext context, String name) {
+        super(context, name, RotateFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/SaturateEffect.java b/android/media/effect/effects/SaturateEffect.java
new file mode 100644
index 0000000..fe9250a
--- /dev/null
+++ b/android/media/effect/effects/SaturateEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.SaturateFilter;
+
+/**
+ * @hide
+ */
+public class SaturateEffect extends SingleFilterEffect {
+    public SaturateEffect(EffectContext context, String name) {
+        super(context, name, SaturateFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/SepiaEffect.java b/android/media/effect/effects/SepiaEffect.java
new file mode 100644
index 0000000..de85b2d
--- /dev/null
+++ b/android/media/effect/effects/SepiaEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.SepiaFilter;
+
+/**
+ * @hide
+ */
+public class SepiaEffect extends SingleFilterEffect {
+    public SepiaEffect(EffectContext context, String name) {
+        super(context, name, SepiaFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/SharpenEffect.java b/android/media/effect/effects/SharpenEffect.java
new file mode 100644
index 0000000..46776eb
--- /dev/null
+++ b/android/media/effect/effects/SharpenEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.SharpenFilter;
+
+/**
+ * @hide
+ */
+public class SharpenEffect extends SingleFilterEffect {
+    public SharpenEffect(EffectContext context, String name) {
+        super(context, name, SharpenFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/StraightenEffect.java b/android/media/effect/effects/StraightenEffect.java
new file mode 100644
index 0000000..49253a0
--- /dev/null
+++ b/android/media/effect/effects/StraightenEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.StraightenFilter;
+
+/**
+ * @hide
+ */
+public class StraightenEffect extends SingleFilterEffect {
+    public StraightenEffect(EffectContext context, String name) {
+        super(context, name, StraightenFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/TintEffect.java b/android/media/effect/effects/TintEffect.java
new file mode 100644
index 0000000..6de9ea8
--- /dev/null
+++ b/android/media/effect/effects/TintEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.TintFilter;
+
+/**
+ * @hide
+ */
+public class TintEffect extends SingleFilterEffect {
+    public TintEffect(EffectContext context, String name) {
+        super(context, name, TintFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/effect/effects/VignetteEffect.java b/android/media/effect/effects/VignetteEffect.java
new file mode 100644
index 0000000..b143d77
--- /dev/null
+++ b/android/media/effect/effects/VignetteEffect.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2011 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.effect.effects;
+
+import android.media.effect.EffectContext;
+import android.media.effect.SingleFilterEffect;
+import android.filterpacks.imageproc.VignetteFilter;
+
+/**
+ * @hide
+ */
+public class VignetteEffect extends SingleFilterEffect {
+    public VignetteEffect(EffectContext context, String name) {
+        super(context, name, VignetteFilter.class, "image", "image");
+    }
+}
diff --git a/android/media/metrics/Event.java b/android/media/metrics/Event.java
new file mode 100644
index 0000000..4a69ac5
--- /dev/null
+++ b/android/media/metrics/Event.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 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.metrics;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.os.Bundle;
+
+/**
+ * Abstract class for metrics events.
+ */
+public abstract class Event {
+    final long mTimeSinceCreatedMillis;
+    Bundle mMetricsBundle = new Bundle();
+
+    // hide default constructor
+    /* package */ Event() {
+        mTimeSinceCreatedMillis = MediaMetricsManager.INVALID_TIMESTAMP;
+    }
+
+    /* package */ Event(long timeSinceCreatedMillis, Bundle extras) {
+        mTimeSinceCreatedMillis = timeSinceCreatedMillis;
+        mMetricsBundle = extras;
+    }
+
+    /**
+     * Gets time since the corresponding log session is created in millisecond.
+     * @return the timestamp since the instance is created, or -1 if unknown.
+     * @see LogSessionId
+     * @see PlaybackSession
+     * @see RecordingSession
+     */
+    @IntRange(from = -1)
+    public long getTimeSinceCreatedMillis() {
+        return mTimeSinceCreatedMillis;
+    }
+
+    /**
+     * Gets metrics-related information that is not supported by dedicated methods.
+     * <p>It is intended to be used for backwards compatibility by the metrics infrastructure.
+     */
+    @NonNull
+    public Bundle getMetricsBundle() {
+        return mMetricsBundle;
+    }
+}
diff --git a/android/media/metrics/LogSessionId.java b/android/media/metrics/LogSessionId.java
new file mode 100644
index 0000000..41f3093
--- /dev/null
+++ b/android/media/metrics/LogSessionId.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 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.metrics;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.TestApi;
+
+import java.util.Objects;
+
+/**
+ * An instances of this class represents the ID of a log session.
+ */
+public final class LogSessionId {
+    @NonNull private final String mSessionId;
+
+    /**
+     * A {@link LogSessionId} object which is used to clear any existing session ID.
+     */
+    @NonNull public static final LogSessionId LOG_SESSION_ID_NONE = new LogSessionId("");
+
+    /** @hide */
+    @TestApi
+    public LogSessionId(@NonNull String id) {
+        mSessionId = Objects.requireNonNull(id);
+    }
+
+    /** Returns the ID represented by a string. */
+    @NonNull
+    public String getStringId() {
+        return mSessionId;
+    }
+
+    @Override
+    public String toString() {
+        return mSessionId;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        LogSessionId that = (LogSessionId) o;
+        return Objects.equals(mSessionId, that.mSessionId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mSessionId);
+    }
+}
diff --git a/android/media/metrics/MediaMetricsManager.java b/android/media/metrics/MediaMetricsManager.java
new file mode 100644
index 0000000..23b697f
--- /dev/null
+++ b/android/media/metrics/MediaMetricsManager.java
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2020 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.metrics;
+
+import android.annotation.NonNull;
+import android.annotation.SystemService;
+import android.content.Context;
+import android.os.RemoteException;
+
+/**
+ * This class gives information about, and interacts with media metrics.
+ */
+@SystemService(Context.MEDIA_METRICS_SERVICE)
+public final class MediaMetricsManager {
+    public static final long INVALID_TIMESTAMP = -1;
+
+    private static final String TAG = "MediaMetricsManager";
+
+    private IMediaMetricsManager mService;
+    private int mUserId;
+
+    /**
+     * @hide
+     */
+    public MediaMetricsManager(IMediaMetricsManager service, int userId) {
+        mService = service;
+        mUserId = userId;
+    }
+
+    /**
+     * Reports playback metrics.
+     * @hide
+     */
+    public void reportPlaybackMetrics(@NonNull String sessionId, PlaybackMetrics metrics) {
+        try {
+            mService.reportPlaybackMetrics(sessionId, metrics, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+    /**
+     * Reports network event.
+     * @hide
+     */
+    public void reportNetworkEvent(@NonNull String sessionId, NetworkEvent event) {
+        try {
+            mService.reportNetworkEvent(sessionId, event, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Reports playback state event.
+     * @hide
+     */
+    public void reportPlaybackStateEvent(@NonNull String sessionId, PlaybackStateEvent event) {
+        try {
+            mService.reportPlaybackStateEvent(sessionId, event, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Reports track change event.
+     * @hide
+     */
+    public void reportTrackChangeEvent(@NonNull String sessionId, TrackChangeEvent event) {
+        try {
+            mService.reportTrackChangeEvent(sessionId, event, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Creates a playback session.
+     */
+    @NonNull
+    public PlaybackSession createPlaybackSession() {
+        try {
+            String id = mService.getPlaybackSessionId(mUserId);
+            PlaybackSession session = new PlaybackSession(id, this);
+            return session;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Creates a recording session.
+     */
+    @NonNull
+    public RecordingSession createRecordingSession() {
+        try {
+            String id = mService.getRecordingSessionId(mUserId);
+            RecordingSession session = new RecordingSession(id, this);
+            return session;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Reports error event.
+     * @hide
+     */
+    public void reportPlaybackErrorEvent(@NonNull String sessionId, PlaybackErrorEvent event) {
+        try {
+            mService.reportPlaybackErrorEvent(sessionId, event, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+}
diff --git a/android/media/metrics/NetworkEvent.java b/android/media/metrics/NetworkEvent.java
new file mode 100644
index 0000000..7471d1d
--- /dev/null
+++ b/android/media/metrics/NetworkEvent.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2020 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.metrics;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Media network event.
+ */
+public final class NetworkEvent extends Event implements Parcelable {
+    /** Network type is not known. Default type. */
+    public static final int NETWORK_TYPE_UNKNOWN = 0;
+    /** Other network type */
+    public static final int NETWORK_TYPE_OTHER = 1;
+    /** Wi-Fi network */
+    public static final int NETWORK_TYPE_WIFI = 2;
+    /** Ethernet network */
+    public static final int NETWORK_TYPE_ETHERNET = 3;
+    /** 2G network */
+    public static final int NETWORK_TYPE_2G = 4;
+    /** 3G network */
+    public static final int NETWORK_TYPE_3G = 5;
+    /** 4G network */
+    public static final int NETWORK_TYPE_4G = 6;
+    /** 5G NSA network */
+    public static final int NETWORK_TYPE_5G_NSA = 7;
+    /** 5G SA network */
+    public static final int NETWORK_TYPE_5G_SA = 8;
+    /** Not network connected */
+    public static final int NETWORK_TYPE_OFFLINE = 9;
+
+    private final int mNetworkType;
+    private final long mTimeSinceCreatedMillis;
+
+    /** @hide */
+    @IntDef(prefix = "NETWORK_TYPE_", value = {
+        NETWORK_TYPE_UNKNOWN,
+        NETWORK_TYPE_OTHER,
+        NETWORK_TYPE_WIFI,
+        NETWORK_TYPE_ETHERNET,
+        NETWORK_TYPE_2G,
+        NETWORK_TYPE_3G,
+        NETWORK_TYPE_4G,
+        NETWORK_TYPE_5G_NSA,
+        NETWORK_TYPE_5G_SA,
+        NETWORK_TYPE_OFFLINE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface NetworkType {}
+
+    /**
+     * Network type to string.
+     * @hide
+     */
+    public static String networkTypeToString(@NetworkType int value) {
+        switch (value) {
+            case NETWORK_TYPE_UNKNOWN:
+                return "NETWORK_TYPE_UNKNOWN";
+            case NETWORK_TYPE_OTHER:
+                return "NETWORK_TYPE_OTHER";
+            case NETWORK_TYPE_WIFI:
+                return "NETWORK_TYPE_WIFI";
+            case NETWORK_TYPE_ETHERNET:
+                return "NETWORK_TYPE_ETHERNET";
+            case NETWORK_TYPE_2G:
+                return "NETWORK_TYPE_2G";
+            case NETWORK_TYPE_3G:
+                return "NETWORK_TYPE_3G";
+            case NETWORK_TYPE_4G:
+                return "NETWORK_TYPE_4G";
+            case NETWORK_TYPE_5G_NSA:
+                return "NETWORK_TYPE_5G_NSA";
+            case NETWORK_TYPE_5G_SA:
+                return "NETWORK_TYPE_5G_SA";
+            case NETWORK_TYPE_OFFLINE:
+                return "NETWORK_TYPE_OFFLINE";
+            default:
+                return Integer.toHexString(value);
+        }
+    }
+
+    /**
+     * Creates a new NetworkEvent.
+     */
+    private NetworkEvent(@NetworkType int type, long timeSinceCreatedMillis,
+            @NonNull Bundle extras) {
+        this.mNetworkType = type;
+        this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
+        this.mMetricsBundle = extras == null ? null : extras.deepCopy();
+    }
+
+    /**
+     * Gets network type.
+     */
+    @NetworkType
+    public int getNetworkType() {
+        return mNetworkType;
+    }
+
+    /**
+     * Gets timestamp since the creation of the log session in milliseconds.
+     * @return the timestamp since the creation in milliseconds, or -1 if unknown.
+     * @see LogSessionId
+     * @see PlaybackSession
+     * @see RecordingSession
+     */
+    @Override
+    @IntRange(from = -1)
+    public long getTimeSinceCreatedMillis() {
+        return mTimeSinceCreatedMillis;
+    }
+
+    /**
+     * Gets metrics-related information that is not supported by dedicated methods.
+     * <p>It is intended to be used for backwards compatibility by the metrics infrastructure.
+     */
+    @Override
+    @NonNull
+    public Bundle getMetricsBundle() {
+        return mMetricsBundle;
+    }
+
+    @Override
+    public String toString() {
+        return "NetworkEvent { "
+                + "networkType = " + mNetworkType + ", "
+                + "timeSinceCreatedMillis = " + mTimeSinceCreatedMillis
+                + " }";
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        NetworkEvent that = (NetworkEvent) o;
+        return mNetworkType == that.mNetworkType
+                && mTimeSinceCreatedMillis == that.mTimeSinceCreatedMillis;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mNetworkType, mTimeSinceCreatedMillis);
+    }
+
+    @Override
+    public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
+        dest.writeInt(mNetworkType);
+        dest.writeLong(mTimeSinceCreatedMillis);
+        dest.writeBundle(mMetricsBundle);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    private NetworkEvent(@NonNull android.os.Parcel in) {
+        int type = in.readInt();
+        long timeSinceCreatedMillis = in.readLong();
+        Bundle extras = in.readBundle();
+
+        this.mNetworkType = type;
+        this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
+        this.mMetricsBundle = extras;
+    }
+
+    /**
+     * Used to read a NetworkEvent from a Parcel.
+     */
+    public static final @NonNull Parcelable.Creator<NetworkEvent> CREATOR =
+            new Parcelable.Creator<NetworkEvent>() {
+        @Override
+        public NetworkEvent[] newArray(int size) {
+            return new NetworkEvent[size];
+        }
+
+        @Override
+        public NetworkEvent createFromParcel(@NonNull Parcel in) {
+            return new NetworkEvent(in);
+        }
+    };
+
+    /**
+     * A builder for {@link NetworkEvent}
+     */
+    public static final class Builder {
+        private int mNetworkType = NETWORK_TYPE_UNKNOWN;
+        private long mTimeSinceCreatedMillis = -1;
+        private Bundle mMetricsBundle = new Bundle();
+
+        /**
+         * Creates a new Builder.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Sets network type.
+         */
+        public @NonNull Builder setNetworkType(@NetworkType int value) {
+            mNetworkType = value;
+            return this;
+        }
+
+        /**
+         * Sets timestamp since the creation in milliseconds.
+         * @param value the timestamp since the creation in milliseconds.
+         *              -1 indicates the value is unknown.
+         * @see #getTimeSinceCreatedMillis()
+         */
+        public @NonNull Builder setTimeSinceCreatedMillis(@IntRange(from = -1) long value) {
+            mTimeSinceCreatedMillis = value;
+            return this;
+        }
+
+        /**
+         * Sets metrics-related information that is not supported by dedicated
+         * methods.
+         * <p>It is intended to be used for backwards compatibility by the
+         * metrics infrastructure.
+         */
+        public @NonNull Builder setMetricsBundle(@NonNull Bundle metricsBundle) {
+            mMetricsBundle = metricsBundle;
+            return this;
+        }
+
+        /** Builds the instance. */
+        public @NonNull NetworkEvent build() {
+            NetworkEvent o =
+                    new NetworkEvent(mNetworkType, mTimeSinceCreatedMillis, mMetricsBundle);
+            return o;
+        }
+    }
+}
diff --git a/android/media/metrics/PlaybackErrorEvent.java b/android/media/metrics/PlaybackErrorEvent.java
new file mode 100644
index 0000000..4e3b426
--- /dev/null
+++ b/android/media/metrics/PlaybackErrorEvent.java
@@ -0,0 +1,399 @@
+/*
+ * Copyright (C) 2020 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.metrics;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.util.Objects;
+
+/**
+ * Playback error event.
+ */
+public final class PlaybackErrorEvent extends Event implements Parcelable {
+    /** Unknown error code. */
+    public static final int ERROR_UNKNOWN = 0;
+    /** Error code for other errors */
+    public static final int ERROR_OTHER = 1;
+    /** Error code for runtime errors */
+    public static final int ERROR_RUNTIME = 2;
+
+    /** Error code for lack of network connectivity while trying to access a network resource */
+    public static final int ERROR_IO_NETWORK_UNAVAILABLE = 3;
+    /** Error code for a failure while establishing a network connection */
+    public static final int ERROR_IO_NETWORK_CONNECTION_FAILED = 4;
+    /** Error code for an HTTP server returning an unexpected HTTP response status code */
+    public static final int ERROR_IO_BAD_HTTP_STATUS = 5;
+    /** Error code for failing to resolve a hostname */
+    public static final int ERROR_IO_DNS_FAILED = 6;
+    /**
+     * Error code for a network timeout, meaning the server is taking too long to fulfill
+     * a request
+     */
+    public static final int ERROR_IO_CONNECTION_TIMEOUT = 7;
+    /** Error code for an existing network connection being unexpectedly closed */
+    public static final int ERROR_IO_CONNECTION_CLOSED = 8;
+    /** Error code for other Input/Output errors */
+    public static final int ERROR_IO_OTHER = 9;
+
+    /** Error code for a parsing error associated to a media manifest */
+    public static final int ERROR_PARSING_MANIFEST_MALFORMED = 10;
+    /** Error code for a parsing error associated to a media container format bitstream */
+    public static final int ERROR_PARSING_CONTAINER_MALFORMED = 11;
+    /** Error code for other media parsing errors */
+    public static final int ERROR_PARSING_OTHER = 12;
+
+    /** Error code for a decoder initialization failure */
+    public static final int ERROR_DECODER_INIT_FAILED = 13;
+    /** Error code for a failure while trying to decode media samples */
+    public static final int ERROR_DECODING_FAILED = 14;
+    /**
+     * Error code for trying to decode content whose format exceeds the capabilities of the device.
+     */
+    public static final int ERROR_DECODING_FORMAT_EXCEEDS_CAPABILITIES = 15;
+    /** Error code for other decoding errors */
+    public static final int ERROR_DECODING_OTHER = 16;
+
+    /** Error code for an AudioTrack initialization failure */
+    public static final int ERROR_AUDIO_TRACK_INIT_FAILED = 17;
+    /** Error code for an AudioTrack write operation failure */
+    public static final int ERROR_AUDIO_TRACK_WRITE_FAILED = 18;
+    /** Error code for other AudioTrack errors */
+    public static final int ERROR_AUDIO_TRACK_OTHER = 19;
+
+    /** Error code for an unidentified error in a remote controller or player */
+    public static final int ERROR_PLAYER_REMOTE = 20;
+    /**
+     * Error code for the loading position falling behind the sliding window of available live
+     * content.
+     */
+    public static final int ERROR_PLAYER_BEHIND_LIVE_WINDOW = 21;
+    /** Error code for other player errors */
+    public static final int ERROR_PLAYER_OTHER = 22;
+
+    /** Error code for a chosen DRM protection scheme not being supported by the device */
+    public static final int ERROR_DRM_SCHEME_UNSUPPORTED = 23;
+    /** Error code for a failure while provisioning the device */
+    public static final int ERROR_DRM_PROVISIONING_FAILED = 24;
+    /** Error code for a failure while trying to obtain a license */
+    public static final int ERROR_DRM_LICENSE_ACQUISITION_FAILED = 25;
+    /** Error code an operation being disallowed by a license policy */
+    public static final int ERROR_DRM_DISALLOWED_OPERATION = 26;
+    /** Error code for an error in the DRM system */
+    public static final int ERROR_DRM_SYSTEM_ERROR = 27;
+    /** Error code for attempting to play incompatible DRM-protected content */
+    public static final int ERROR_DRM_CONTENT_ERROR = 28;
+    /** Error code for the device having revoked DRM privileges */
+    public static final int ERROR_DRM_DEVICE_REVOKED = 29;
+    /** Error code for other DRM errors */
+    public static final int ERROR_DRM_OTHER = 30;
+
+    /** Error code for a non-existent file */
+    public static final int ERROR_IO_FILE_NOT_FOUND = 31;
+    /**
+     * Error code for lack of permission to perform an IO operation, for example, lack of permission
+     * to access internet or external storage.
+     */
+    public static final int ERROR_IO_NO_PERMISSION = 32;
+
+    /** Error code for an unsupported feature in a media manifest */
+    public static final int ERROR_PARSING_MANIFEST_UNSUPPORTED = 33;
+    /**
+     * Error code for attempting to extract a file with an unsupported media container format, or an
+     * unsupported media container feature
+     */
+    public static final int ERROR_PARSING_CONTAINER_UNSUPPORTED = 34;
+
+    /** Error code for trying to decode content whose format is not supported */
+    public static final int ERROR_DECODING_FORMAT_UNSUPPORTED = 35;
+
+
+    private final @Nullable String mExceptionStack;
+    private final int mErrorCode;
+    private final int mSubErrorCode;
+    private final long mTimeSinceCreatedMillis;
+
+
+    /** @hide */
+    @IntDef(prefix = "ERROR_", value = {
+        ERROR_UNKNOWN,
+        ERROR_OTHER,
+        ERROR_RUNTIME,
+        ERROR_IO_NETWORK_UNAVAILABLE,
+        ERROR_IO_NETWORK_CONNECTION_FAILED,
+        ERROR_IO_BAD_HTTP_STATUS,
+        ERROR_IO_DNS_FAILED,
+        ERROR_IO_CONNECTION_TIMEOUT,
+        ERROR_IO_CONNECTION_CLOSED,
+        ERROR_IO_OTHER,
+        ERROR_PARSING_MANIFEST_MALFORMED,
+        ERROR_PARSING_CONTAINER_MALFORMED,
+        ERROR_PARSING_OTHER,
+        ERROR_DECODER_INIT_FAILED,
+        ERROR_DECODING_FAILED,
+        ERROR_DECODING_FORMAT_EXCEEDS_CAPABILITIES,
+        ERROR_DECODING_OTHER,
+        ERROR_AUDIO_TRACK_INIT_FAILED,
+        ERROR_AUDIO_TRACK_WRITE_FAILED,
+        ERROR_AUDIO_TRACK_OTHER,
+        ERROR_PLAYER_REMOTE,
+        ERROR_PLAYER_BEHIND_LIVE_WINDOW,
+        ERROR_PLAYER_OTHER,
+        ERROR_DRM_SCHEME_UNSUPPORTED,
+        ERROR_DRM_PROVISIONING_FAILED,
+        ERROR_DRM_LICENSE_ACQUISITION_FAILED,
+        ERROR_DRM_DISALLOWED_OPERATION,
+        ERROR_DRM_SYSTEM_ERROR,
+        ERROR_DRM_CONTENT_ERROR,
+        ERROR_DRM_DEVICE_REVOKED,
+        ERROR_DRM_OTHER,
+        ERROR_IO_FILE_NOT_FOUND,
+        ERROR_IO_NO_PERMISSION,
+        ERROR_PARSING_MANIFEST_UNSUPPORTED,
+        ERROR_PARSING_CONTAINER_UNSUPPORTED,
+        ERROR_DECODING_FORMAT_UNSUPPORTED,
+    })
+    @Retention(java.lang.annotation.RetentionPolicy.SOURCE)
+    public @interface ErrorCode {}
+
+    /**
+     * Creates a new PlaybackErrorEvent.
+     */
+    private PlaybackErrorEvent(
+            @Nullable String exceptionStack,
+            int errorCode,
+            int subErrorCode,
+            long timeSinceCreatedMillis,
+            @NonNull Bundle extras) {
+        this.mExceptionStack = exceptionStack;
+        this.mErrorCode = errorCode;
+        this.mSubErrorCode = subErrorCode;
+        this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
+        this.mMetricsBundle = extras.deepCopy();
+    }
+
+    /** @hide */
+    @Nullable
+    public String getExceptionStack() {
+        return mExceptionStack;
+    }
+
+
+    /**
+     * Gets error code.
+     */
+    @ErrorCode
+    public int getErrorCode() {
+        return mErrorCode;
+    }
+
+
+    /**
+     * Gets sub error code.
+     */
+    @IntRange(from = Integer.MIN_VALUE, to = Integer.MAX_VALUE)
+    public int getSubErrorCode() {
+        return mSubErrorCode;
+    }
+
+    /**
+     * Gets the timestamp since creation of the playback session in milliseconds.
+     * @return the timestamp since the playback is created, or -1 if unknown.
+     * @see LogSessionId
+     * @see PlaybackSession
+     */
+    @Override
+    @IntRange(from = -1)
+    public long getTimeSinceCreatedMillis() {
+        return mTimeSinceCreatedMillis;
+    }
+
+    /**
+     * Gets metrics-related information that is not supported by dedicated methods.
+     * <p>It is intended to be used for backwards compatibility by the metrics infrastructure.
+     */
+    @Override
+    @NonNull
+    public Bundle getMetricsBundle() {
+        return mMetricsBundle;
+    }
+
+    @Override
+    public String toString() {
+        return "PlaybackErrorEvent { "
+                + "exceptionStack = " + mExceptionStack + ", "
+                + "errorCode = " + mErrorCode + ", "
+                + "subErrorCode = " + mSubErrorCode + ", "
+                + "timeSinceCreatedMillis = " + mTimeSinceCreatedMillis
+                + " }";
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PlaybackErrorEvent that = (PlaybackErrorEvent) o;
+        return Objects.equals(mExceptionStack, that.mExceptionStack)
+                && mErrorCode == that.mErrorCode
+                && mSubErrorCode == that.mSubErrorCode
+                && mTimeSinceCreatedMillis == that.mTimeSinceCreatedMillis;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mExceptionStack, mErrorCode, mSubErrorCode,
+            mTimeSinceCreatedMillis);
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        byte flg = 0;
+        if (mExceptionStack != null) flg |= 0x1;
+        dest.writeByte(flg);
+        if (mExceptionStack != null) dest.writeString(mExceptionStack);
+        dest.writeInt(mErrorCode);
+        dest.writeInt(mSubErrorCode);
+        dest.writeLong(mTimeSinceCreatedMillis);
+        dest.writeBundle(mMetricsBundle);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    private PlaybackErrorEvent(@NonNull Parcel in) {
+        byte flg = in.readByte();
+        String exceptionStack = (flg & 0x1) == 0 ? null : in.readString();
+        int errorCode = in.readInt();
+        int subErrorCode = in.readInt();
+        long timeSinceCreatedMillis = in.readLong();
+        Bundle extras = in.readBundle();
+
+        this.mExceptionStack = exceptionStack;
+        this.mErrorCode = errorCode;
+        this.mSubErrorCode = subErrorCode;
+        this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
+        this.mMetricsBundle = extras;
+    }
+
+
+    public static final @NonNull Parcelable.Creator<PlaybackErrorEvent> CREATOR =
+            new Parcelable.Creator<PlaybackErrorEvent>() {
+        @Override
+        public PlaybackErrorEvent[] newArray(int size) {
+            return new PlaybackErrorEvent[size];
+        }
+
+        @Override
+        public PlaybackErrorEvent createFromParcel(@NonNull Parcel in) {
+            return new PlaybackErrorEvent(in);
+        }
+    };
+
+    /**
+     * A builder for {@link PlaybackErrorEvent}
+     */
+    public static final class Builder {
+        private @Nullable Exception mException;
+        private int mErrorCode = ERROR_UNKNOWN;
+        private int mSubErrorCode;
+        private long mTimeSinceCreatedMillis = -1;
+        private Bundle mMetricsBundle = new Bundle();
+
+        /**
+         * Creates a new Builder.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Sets the {@link Exception} object.
+         */
+        @SuppressLint("MissingGetterMatchingBuilder") // Exception is not parcelable.
+        public @NonNull Builder setException(@NonNull Exception value) {
+            mException = value;
+            return this;
+        }
+
+        /**
+         * Sets error code.
+         */
+        public @NonNull Builder setErrorCode(@ErrorCode int value) {
+            mErrorCode = value;
+            return this;
+        }
+
+        /**
+         * Sets sub error code.
+         */
+        public @NonNull Builder setSubErrorCode(
+                @IntRange(from = Integer.MIN_VALUE, to = Integer.MAX_VALUE) int value) {
+            mSubErrorCode = value;
+            return this;
+        }
+
+        /**
+         * Set the timestamp since creation in milliseconds.
+         * @param value the timestamp since the creation in milliseconds.
+         *              -1 indicates the value is unknown.
+         * @see #getTimeSinceCreatedMillis()
+         */
+        public @NonNull Builder setTimeSinceCreatedMillis(@IntRange(from = -1) long value) {
+            mTimeSinceCreatedMillis = value;
+            return this;
+        }
+
+        /**
+         * Sets metrics-related information that is not supported by dedicated
+         * methods.
+         * <p>It is intended to be used for backwards compatibility by the
+         * metrics infrastructure.
+         */
+        public @NonNull Builder setMetricsBundle(@NonNull Bundle metricsBundle) {
+            mMetricsBundle = metricsBundle;
+            return this;
+        }
+
+        /** Builds the instance. */
+        public @NonNull PlaybackErrorEvent build() {
+
+            String stack;
+            if (mException.getStackTrace() != null && mException.getStackTrace().length > 0) {
+                // TODO: a better definition of the stack trace
+                stack = mException.getStackTrace()[0].toString();
+            } else {
+                stack = null;
+            }
+
+            PlaybackErrorEvent o = new PlaybackErrorEvent(
+                    stack,
+                    mErrorCode,
+                    mSubErrorCode,
+                    mTimeSinceCreatedMillis,
+                    mMetricsBundle);
+            return o;
+        }
+    }
+}
diff --git a/android/media/metrics/PlaybackMetrics.java b/android/media/metrics/PlaybackMetrics.java
new file mode 100644
index 0000000..e71ee20
--- /dev/null
+++ b/android/media/metrics/PlaybackMetrics.java
@@ -0,0 +1,710 @@
+/*
+ * Copyright (C) 2020 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.metrics;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import com.android.internal.util.AnnotationValidations;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * This class is used to store playback data.
+ */
+public final class PlaybackMetrics implements Parcelable {
+    /** Unknown stream source. */
+    public static final int STREAM_SOURCE_UNKNOWN = 0;
+    /** Stream from network. */
+    public static final int STREAM_SOURCE_NETWORK = 1;
+    /** Stream from device. */
+    public static final int STREAM_SOURCE_DEVICE = 2;
+    /** Stream from more than one sources. */
+    public static final int STREAM_SOURCE_MIXED = 3;
+
+    /** Unknown stream type. */
+    public static final int STREAM_TYPE_UNKNOWN = 0;
+    /** Other stream type. */
+    public static final int STREAM_TYPE_OTHER = 1;
+    /** Progressive stream type. */
+    public static final int STREAM_TYPE_PROGRESSIVE = 2;
+    /** DASH (Dynamic Adaptive Streaming over HTTP) stream type. */
+    public static final int STREAM_TYPE_DASH = 3;
+    /** HLS (HTTP Live Streaming) stream type. */
+    public static final int STREAM_TYPE_HLS = 4;
+    /** SS (HTTP Smooth Streaming) stream type. */
+    public static final int STREAM_TYPE_SS = 5;
+
+    /** Unknown playback type. */
+    public static final int PLAYBACK_TYPE_UNKNOWN = 0;
+    /** VOD (Video on Demand) playback type. */
+    public static final int PLAYBACK_TYPE_VOD = 1;
+    /** Live playback type. */
+    public static final int PLAYBACK_TYPE_LIVE = 2;
+    /** Other playback type. */
+    public static final int PLAYBACK_TYPE_OTHER = 3;
+
+    /** DRM is not used. */
+    public static final int DRM_TYPE_NONE = 0;
+    /** Other DRM type. */
+    public static final int DRM_TYPE_OTHER = 1;
+    /** Play ready DRM type. */
+    public static final int DRM_TYPE_PLAY_READY = 2;
+    /** Widevine L1 DRM type. */
+    public static final int DRM_TYPE_WIDEVINE_L1 = 3;
+    /** Widevine L3 DRM type. */
+    public static final int DRM_TYPE_WIDEVINE_L3 = 4;
+    /** Widevine L3 fallback DRM type. */
+    public static final int DRM_TYPE_WV_L3_FALLBACK = 5;
+    /** Clear key DRM type. */
+    public static final int DRM_TYPE_CLEARKEY = 6;
+
+    /** Unknown content type. */
+    public static final int CONTENT_TYPE_UNKNOWN = 0;
+    /** Main contents. */
+    public static final int CONTENT_TYPE_MAIN = 1;
+    /** Advertisement contents. */
+    public static final int CONTENT_TYPE_AD = 2;
+    /** Other contents. */
+    public static final int CONTENT_TYPE_OTHER = 3;
+
+
+    /** @hide */
+    @IntDef(prefix = "STREAM_SOURCE_", value = {
+        STREAM_SOURCE_UNKNOWN,
+        STREAM_SOURCE_NETWORK,
+        STREAM_SOURCE_DEVICE,
+        STREAM_SOURCE_MIXED
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface StreamSource {}
+
+    /** @hide */
+    @IntDef(prefix = "STREAM_TYPE_", value = {
+        STREAM_TYPE_UNKNOWN,
+        STREAM_TYPE_OTHER,
+        STREAM_TYPE_PROGRESSIVE,
+        STREAM_TYPE_DASH,
+        STREAM_TYPE_HLS,
+        STREAM_TYPE_SS
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface StreamType {}
+
+    /** @hide */
+    @IntDef(prefix = "PLAYBACK_TYPE_", value = {
+        PLAYBACK_TYPE_UNKNOWN,
+        PLAYBACK_TYPE_VOD,
+        PLAYBACK_TYPE_LIVE,
+        PLAYBACK_TYPE_OTHER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PlaybackType {}
+
+    /** @hide */
+    @IntDef(prefix = "DRM_TYPE_", value = {
+        DRM_TYPE_NONE,
+        DRM_TYPE_OTHER,
+        DRM_TYPE_PLAY_READY,
+        DRM_TYPE_WIDEVINE_L1,
+        DRM_TYPE_WIDEVINE_L3,
+        DRM_TYPE_WV_L3_FALLBACK,
+        DRM_TYPE_CLEARKEY
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DrmType {}
+
+    /** @hide */
+    @IntDef(prefix = "CONTENT_TYPE_", value = {
+        CONTENT_TYPE_UNKNOWN,
+        CONTENT_TYPE_MAIN,
+        CONTENT_TYPE_AD,
+        CONTENT_TYPE_OTHER
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ContentType {}
+
+
+
+    private final long mMediaDurationMillis;
+    private final int mStreamSource;
+    private final int mStreamType;
+    private final int mPlaybackType;
+    private final int mDrmType;
+    private final int mContentType;
+    private final @Nullable String mPlayerName;
+    private final @Nullable String mPlayerVersion;
+    private final @NonNull long[] mExperimentIds;
+    private final int mVideoFramesPlayed;
+    private final int mVideoFramesDropped;
+    private final int mAudioUnderrunCount;
+    private final long mNetworkBytesRead;
+    private final long mLocalBytesRead;
+    private final long mNetworkTransferDurationMillis;
+    private final byte[] mDrmSessionId;
+    private final @NonNull Bundle mMetricsBundle;
+
+    /**
+     * Creates a new PlaybackMetrics.
+     *
+     * @hide
+     */
+    public PlaybackMetrics(
+            long mediaDurationMillis,
+            int streamSource,
+            int streamType,
+            int playbackType,
+            int drmType,
+            int contentType,
+            @Nullable String playerName,
+            @Nullable String playerVersion,
+            @NonNull long[] experimentIds,
+            int videoFramesPlayed,
+            int videoFramesDropped,
+            int audioUnderrunCount,
+            long networkBytesRead,
+            long localBytesRead,
+            long networkTransferDurationMillis,
+            byte[] drmSessionId,
+            @NonNull Bundle extras) {
+        this.mMediaDurationMillis = mediaDurationMillis;
+        this.mStreamSource = streamSource;
+        this.mStreamType = streamType;
+        this.mPlaybackType = playbackType;
+        this.mDrmType = drmType;
+        this.mContentType = contentType;
+        this.mPlayerName = playerName;
+        this.mPlayerVersion = playerVersion;
+        this.mExperimentIds = experimentIds;
+        AnnotationValidations.validate(NonNull.class, null, mExperimentIds);
+        this.mVideoFramesPlayed = videoFramesPlayed;
+        this.mVideoFramesDropped = videoFramesDropped;
+        this.mAudioUnderrunCount = audioUnderrunCount;
+        this.mNetworkBytesRead = networkBytesRead;
+        this.mLocalBytesRead = localBytesRead;
+        this.mNetworkTransferDurationMillis = networkTransferDurationMillis;
+        this.mDrmSessionId = drmSessionId;
+        this.mMetricsBundle = extras.deepCopy();
+    }
+
+    /**
+     * Gets the media duration in milliseconds.
+     * <p>Media duration is the length of the media.
+     * @return the media duration in milliseconds, or -1 if unknown.
+     */
+    @IntRange(from = -1)
+    public long getMediaDurationMillis() {
+        return mMediaDurationMillis;
+    }
+
+    /**
+     * Gets stream source type.
+     */
+    @StreamSource
+    public int getStreamSource() {
+        return mStreamSource;
+    }
+
+    /**
+     * Gets stream type.
+     */
+    @StreamType
+    public int getStreamType() {
+        return mStreamType;
+    }
+
+
+    /**
+     * Gets playback type.
+     */
+    @PlaybackType
+    public int getPlaybackType() {
+        return mPlaybackType;
+    }
+
+    /**
+     * Gets DRM type.
+     */
+    @DrmType
+    public int getDrmType() {
+        return mDrmType;
+    }
+
+    /**
+     * Gets content type.
+     */
+    @ContentType
+    public int getContentType() {
+        return mContentType;
+    }
+
+    /**
+     * Gets player name.
+     */
+    public @Nullable String getPlayerName() {
+        return mPlayerName;
+    }
+
+    /**
+     * Gets player version.
+     */
+    public @Nullable String getPlayerVersion() {
+        return mPlayerVersion;
+    }
+
+    /**
+     * Gets experiment IDs.
+     */
+    public @NonNull long[] getExperimentIds() {
+        return Arrays.copyOf(mExperimentIds, mExperimentIds.length);
+    }
+
+    /**
+     * Gets video frames played.
+     * @return the video frames played, or -1 if unknown.
+     */
+    @IntRange(from = -1, to = Integer.MAX_VALUE)
+    public int getVideoFramesPlayed() {
+        return mVideoFramesPlayed;
+    }
+
+    /**
+     * Gets video frames dropped.
+     * @return the video frames dropped, or -1 if unknown.
+     */
+    @IntRange(from = -1, to = Integer.MAX_VALUE)
+    public int getVideoFramesDropped() {
+        return mVideoFramesDropped;
+    }
+
+    /**
+     * Gets audio underrun count.
+     * @return the audio underrun count, or -1 if unknown.
+     */
+    @IntRange(from = -1, to = Integer.MAX_VALUE)
+    public int getAudioUnderrunCount() {
+        return mAudioUnderrunCount;
+    }
+
+    /**
+     * Gets number of network bytes read.
+     * @return the number of network bytes read, or -1 if unknown.
+     */
+    @IntRange(from = -1)
+    public long getNetworkBytesRead() {
+        return mNetworkBytesRead;
+    }
+
+    /**
+     * Gets number of local bytes read.
+     */
+    @IntRange(from = -1)
+    public long getLocalBytesRead() {
+        return mLocalBytesRead;
+    }
+
+    /**
+     * Gets network transfer duration in milliseconds.
+     * <p>Total transfer time spent reading from the network in ms. For parallel requests, the
+     * overlapping time intervals are counted only once.
+     */
+    @IntRange(from = -1)
+    public long getNetworkTransferDurationMillis() {
+        return mNetworkTransferDurationMillis;
+    }
+
+    /**
+     * Gets DRM session ID.
+     */
+    @NonNull
+    public byte[] getDrmSessionId() {
+        return mDrmSessionId;
+    }
+
+    /**
+     * Gets metrics-related information that is not supported by dedicated methods.
+     * <p>It is intended to be used for backwards compatibility by the metrics infrastructure.
+     */
+    @NonNull
+    public Bundle getMetricsBundle() {
+        return mMetricsBundle;
+    }
+
+    @Override
+    public String toString() {
+        return "PlaybackMetrics { "
+                + "mediaDurationMillis = " + mMediaDurationMillis + ", "
+                + "streamSource = " + mStreamSource + ", "
+                + "streamType = " + mStreamType + ", "
+                + "playbackType = " + mPlaybackType + ", "
+                + "drmType = " + mDrmType + ", "
+                + "contentType = " + mContentType + ", "
+                + "playerName = " + mPlayerName + ", "
+                + "playerVersion = " + mPlayerVersion + ", "
+                + "experimentIds = " + Arrays.toString(mExperimentIds) + ", "
+                + "videoFramesPlayed = " + mVideoFramesPlayed + ", "
+                + "videoFramesDropped = " + mVideoFramesDropped + ", "
+                + "audioUnderrunCount = " + mAudioUnderrunCount + ", "
+                + "networkBytesRead = " + mNetworkBytesRead + ", "
+                + "localBytesRead = " + mLocalBytesRead + ", "
+                + "networkTransferDurationMillis = " + mNetworkTransferDurationMillis
+                + "drmSessionId = " + Arrays.toString(mDrmSessionId)
+                + " }";
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PlaybackMetrics that = (PlaybackMetrics) o;
+        return mMediaDurationMillis == that.mMediaDurationMillis
+                && mStreamSource == that.mStreamSource
+                && mStreamType == that.mStreamType
+                && mPlaybackType == that.mPlaybackType
+                && mDrmType == that.mDrmType
+                && mContentType == that.mContentType
+                && Objects.equals(mPlayerName, that.mPlayerName)
+                && Objects.equals(mPlayerVersion, that.mPlayerVersion)
+                && Arrays.equals(mExperimentIds, that.mExperimentIds)
+                && mVideoFramesPlayed == that.mVideoFramesPlayed
+                && mVideoFramesDropped == that.mVideoFramesDropped
+                && mAudioUnderrunCount == that.mAudioUnderrunCount
+                && mNetworkBytesRead == that.mNetworkBytesRead
+                && mLocalBytesRead == that.mLocalBytesRead
+                && mNetworkTransferDurationMillis == that.mNetworkTransferDurationMillis
+                && Arrays.equals(mDrmSessionId, that.mDrmSessionId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mMediaDurationMillis, mStreamSource, mStreamType, mPlaybackType,
+                mDrmType, mContentType, mPlayerName, mPlayerVersion, mExperimentIds,
+                mVideoFramesPlayed, mVideoFramesDropped, mAudioUnderrunCount, mNetworkBytesRead,
+                mLocalBytesRead, mNetworkTransferDurationMillis, mDrmSessionId);
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        long flg = 0;
+        if (mPlayerName != null) flg |= 0x80;
+        if (mPlayerVersion != null) flg |= 0x100;
+        dest.writeLong(flg);
+        dest.writeLong(mMediaDurationMillis);
+        dest.writeInt(mStreamSource);
+        dest.writeInt(mStreamType);
+        dest.writeInt(mPlaybackType);
+        dest.writeInt(mDrmType);
+        dest.writeInt(mContentType);
+        if (mPlayerName != null) dest.writeString(mPlayerName);
+        if (mPlayerVersion != null) dest.writeString(mPlayerVersion);
+        dest.writeLongArray(mExperimentIds);
+        dest.writeInt(mVideoFramesPlayed);
+        dest.writeInt(mVideoFramesDropped);
+        dest.writeInt(mAudioUnderrunCount);
+        dest.writeLong(mNetworkBytesRead);
+        dest.writeLong(mLocalBytesRead);
+        dest.writeLong(mNetworkTransferDurationMillis);
+        dest.writeInt(mDrmSessionId.length);
+        dest.writeByteArray(mDrmSessionId);
+        dest.writeBundle(mMetricsBundle);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /** @hide */
+    /* package-private */ PlaybackMetrics(@NonNull Parcel in) {
+        long flg = in.readLong();
+        long mediaDurationMillis = in.readLong();
+        int streamSource = in.readInt();
+        int streamType = in.readInt();
+        int playbackType = in.readInt();
+        int drmType = in.readInt();
+        int contentType = in.readInt();
+        String playerName = (flg & 0x80) == 0 ? null : in.readString();
+        String playerVersion = (flg & 0x100) == 0 ? null : in.readString();
+        long[] experimentIds = in.createLongArray();
+        int videoFramesPlayed = in.readInt();
+        int videoFramesDropped = in.readInt();
+        int audioUnderrunCount = in.readInt();
+        long networkBytesRead = in.readLong();
+        long localBytesRead = in.readLong();
+        long networkTransferDurationMillis = in.readLong();
+        int drmSessionIdLen = in.readInt();
+        byte[] drmSessionId = new byte[drmSessionIdLen];
+        in.readByteArray(drmSessionId);
+        Bundle extras = in.readBundle();
+
+        this.mMediaDurationMillis = mediaDurationMillis;
+        this.mStreamSource = streamSource;
+        this.mStreamType = streamType;
+        this.mPlaybackType = playbackType;
+        this.mDrmType = drmType;
+        this.mContentType = contentType;
+        this.mPlayerName = playerName;
+        this.mPlayerVersion = playerVersion;
+        this.mExperimentIds = experimentIds;
+        AnnotationValidations.validate(NonNull.class, null, mExperimentIds);
+        this.mVideoFramesPlayed = videoFramesPlayed;
+        this.mVideoFramesDropped = videoFramesDropped;
+        this.mAudioUnderrunCount = audioUnderrunCount;
+        this.mNetworkBytesRead = networkBytesRead;
+        this.mLocalBytesRead = localBytesRead;
+        this.mNetworkTransferDurationMillis = networkTransferDurationMillis;
+        this.mDrmSessionId = drmSessionId;
+        this.mMetricsBundle = extras;
+    }
+
+    public static final @NonNull Parcelable.Creator<PlaybackMetrics> CREATOR =
+            new Parcelable.Creator<PlaybackMetrics>() {
+        @Override
+        public PlaybackMetrics[] newArray(int size) {
+            return new PlaybackMetrics[size];
+        }
+
+        @Override
+        public PlaybackMetrics createFromParcel(@NonNull Parcel in) {
+            return new PlaybackMetrics(in);
+        }
+    };
+
+    /**
+     * A builder for {@link PlaybackMetrics}
+     */
+    public static final class Builder {
+
+        private long mMediaDurationMillis = -1;
+        private int mStreamSource = STREAM_SOURCE_UNKNOWN;
+        private int mStreamType = STREAM_TYPE_UNKNOWN;
+        private int mPlaybackType = PLAYBACK_TYPE_UNKNOWN;
+        private int mDrmType = DRM_TYPE_NONE;
+        private int mContentType = CONTENT_TYPE_UNKNOWN;
+        private @Nullable String mPlayerName;
+        private @Nullable String mPlayerVersion;
+        private @NonNull List<Long> mExperimentIds = new ArrayList<>();
+        private int mVideoFramesPlayed = -1;
+        private int mVideoFramesDropped = -1;
+        private int mAudioUnderrunCount = -1;
+        private long mNetworkBytesRead = -1;
+        private long mLocalBytesRead = -1;
+        private long mNetworkTransferDurationMillis = -1;
+        private byte[] mDrmSessionId = new byte[0];
+        private Bundle mMetricsBundle = new Bundle();
+
+        /**
+         * Creates a new Builder.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Sets the media duration in milliseconds.
+         * @param value the media duration in milliseconds. -1 indicates the value is unknown.
+         * @see #getMediaDurationMillis()
+         */
+        public @NonNull Builder setMediaDurationMillis(@IntRange(from = -1) long value) {
+            mMediaDurationMillis = value;
+            return this;
+        }
+
+        /**
+         * Sets the stream source type.
+         */
+        public @NonNull Builder setStreamSource(@StreamSource int value) {
+            mStreamSource = value;
+            return this;
+        }
+
+        /**
+         * Sets the stream type.
+         */
+        public @NonNull Builder setStreamType(@StreamType int value) {
+            mStreamType = value;
+            return this;
+        }
+
+        /**
+         * Sets the playback type.
+         */
+        public @NonNull Builder setPlaybackType(@PlaybackType int value) {
+            mPlaybackType = value;
+            return this;
+        }
+
+        /**
+         * Sets the DRM type.
+         */
+        public @NonNull Builder setDrmType(@DrmType int value) {
+            mDrmType = value;
+            return this;
+        }
+
+        /**
+         * Sets the content type.
+         */
+        public @NonNull Builder setContentType(@ContentType int value) {
+            mContentType = value;
+            return this;
+        }
+
+        /**
+         * Sets the player name.
+         */
+        public @NonNull Builder setPlayerName(@NonNull String value) {
+            mPlayerName = value;
+            return this;
+        }
+
+        /**
+         * Sets the player version.
+         */
+        public @NonNull Builder setPlayerVersion(@NonNull String value) {
+            mPlayerVersion = value;
+            return this;
+        }
+
+        /**
+         * Adds the experiment ID.
+         */
+        public @NonNull Builder addExperimentId(long value) {
+            mExperimentIds.add(value);
+            return this;
+        }
+
+        /**
+         * Sets the video frames played.
+         * @param value the video frames played. -1 indicates the value is unknown.
+         */
+        public @NonNull Builder setVideoFramesPlayed(
+                @IntRange(from = -1, to = Integer.MAX_VALUE) int value) {
+            mVideoFramesPlayed = value;
+            return this;
+        }
+
+        /**
+         * Sets the video frames dropped.
+         * @param value the video frames dropped. -1 indicates the value is unknown.
+         */
+        public @NonNull Builder setVideoFramesDropped(
+                @IntRange(from = -1, to = Integer.MAX_VALUE) int value) {
+            mVideoFramesDropped = value;
+            return this;
+        }
+
+        /**
+         * Sets the audio underrun count.
+         * @param value the audio underrun count. -1 indicates the value is unknown.
+         */
+        public @NonNull Builder setAudioUnderrunCount(
+                @IntRange(from = -1, to = Integer.MAX_VALUE) int value) {
+            mAudioUnderrunCount = value;
+            return this;
+        }
+
+        /**
+         * Sets the number of network bytes read.
+         * @param value the number of network bytes read. -1 indicates the value is unknown.
+         */
+        public @NonNull Builder setNetworkBytesRead(@IntRange(from = -1) long value) {
+            mNetworkBytesRead = value;
+            return this;
+        }
+
+        /**
+         * Sets the number of local bytes read.
+         * @param value the number of local bytes read. -1 indicates the value is unknown.
+         */
+        public @NonNull Builder setLocalBytesRead(@IntRange(from = -1) long value) {
+            mLocalBytesRead = value;
+            return this;
+        }
+
+        /**
+         * Sets the network transfer duration in milliseconds.
+         * @param value the network transfer duration in milliseconds.
+         *              -1 indicates the value is unknown.
+         * @see #getNetworkTransferDurationMillis()
+         */
+        public @NonNull Builder setNetworkTransferDurationMillis(@IntRange(from = -1) long value) {
+            mNetworkTransferDurationMillis = value;
+            return this;
+        }
+
+        /**
+         * Sets DRM session ID.
+         */
+        public @NonNull Builder setDrmSessionId(@NonNull byte[] drmSessionId) {
+            mDrmSessionId = drmSessionId;
+            return this;
+        }
+
+        /**
+         * Sets metrics-related information that is not supported by dedicated
+         * methods.
+         * <p>It is intended to be used for backwards compatibility by the
+         * metrics infrastructure.
+         */
+        public @NonNull Builder setMetricsBundle(@NonNull Bundle metricsBundle) {
+            mMetricsBundle = metricsBundle;
+            return this;
+        }
+
+        /** Builds the instance. This builder should not be touched after calling this! */
+        public @NonNull PlaybackMetrics build() {
+
+            PlaybackMetrics o = new PlaybackMetrics(
+                    mMediaDurationMillis,
+                    mStreamSource,
+                    mStreamType,
+                    mPlaybackType,
+                    mDrmType,
+                    mContentType,
+                    mPlayerName,
+                    mPlayerVersion,
+                    idsToLongArray(),
+                    mVideoFramesPlayed,
+                    mVideoFramesDropped,
+                    mAudioUnderrunCount,
+                    mNetworkBytesRead,
+                    mLocalBytesRead,
+                    mNetworkTransferDurationMillis,
+                    mDrmSessionId,
+                    mMetricsBundle);
+            return o;
+        }
+
+        private long[] idsToLongArray() {
+            long[] ids = new long[mExperimentIds.size()];
+            for (int i = 0; i < mExperimentIds.size(); i++) {
+                ids[i] = mExperimentIds.get(i);
+            }
+            return ids;
+        }
+    }
+}
diff --git a/android/media/metrics/PlaybackSession.java b/android/media/metrics/PlaybackSession.java
new file mode 100644
index 0000000..aad510e
--- /dev/null
+++ b/android/media/metrics/PlaybackSession.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2020 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.metrics;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.util.AnnotationValidations;
+
+import java.util.Objects;
+
+/**
+ * An instances of this class represents a session of media playback.
+ */
+public final class PlaybackSession implements AutoCloseable {
+    private final @NonNull String mId;
+    private final @NonNull MediaMetricsManager mManager;
+    private final @NonNull LogSessionId mLogSessionId;
+    private boolean mClosed = false;
+
+    /**
+     * Creates a new PlaybackSession.
+     *
+     * @hide
+     */
+    public PlaybackSession(@NonNull String id, @NonNull MediaMetricsManager manager) {
+        mId = id;
+        mManager = manager;
+        AnnotationValidations.validate(NonNull.class, null, mId);
+        AnnotationValidations.validate(NonNull.class, null, mManager);
+        mLogSessionId = new LogSessionId(mId);
+    }
+
+    /**
+     * Reports playback metrics.
+     */
+    public void reportPlaybackMetrics(@NonNull PlaybackMetrics metrics) {
+        mManager.reportPlaybackMetrics(mId, metrics);
+    }
+
+    /**
+     * Reports error event.
+     */
+    public void reportPlaybackErrorEvent(@NonNull PlaybackErrorEvent event) {
+        mManager.reportPlaybackErrorEvent(mId, event);
+    }
+
+    /**
+     * Reports network event.
+     */
+    public void reportNetworkEvent(@NonNull NetworkEvent event) {
+        mManager.reportNetworkEvent(mId, event);
+    }
+
+    /**
+     * Reports playback state event.
+     */
+    public void reportPlaybackStateEvent(@NonNull PlaybackStateEvent event) {
+        mManager.reportPlaybackStateEvent(mId, event);
+    }
+
+    /**
+     * Reports track change event.
+     */
+    public void reportTrackChangeEvent(@NonNull TrackChangeEvent event) {
+        mManager.reportTrackChangeEvent(mId, event);
+    }
+
+    public @NonNull LogSessionId getSessionId() {
+        return mLogSessionId;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PlaybackSession that = (PlaybackSession) o;
+        return Objects.equals(mId, that.mId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mId);
+    }
+
+    @Override
+    public void close() {
+        mClosed = true;
+    }
+}
diff --git a/android/media/metrics/PlaybackStateEvent.java b/android/media/metrics/PlaybackStateEvent.java
new file mode 100644
index 0000000..8e74825
--- /dev/null
+++ b/android/media/metrics/PlaybackStateEvent.java
@@ -0,0 +1,277 @@
+/*
+ * Copyright (C) 2020 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.metrics;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.util.Objects;
+
+/**
+ * Playback state event.
+ */
+public final class PlaybackStateEvent extends Event implements Parcelable {
+    /** Playback has not started (initial state) */
+    public static final int STATE_NOT_STARTED = 0;
+    /** Playback is buffering in the background for initial playback start */
+    public static final int STATE_JOINING_BACKGROUND = 1;
+    /** Playback is buffering in the foreground for initial playback start */
+    public static final int STATE_JOINING_FOREGROUND = 2;
+    /** Playback is actively playing */
+    public static final int STATE_PLAYING = 3;
+    /** Playback is paused but ready to play */
+    public static final int STATE_PAUSED = 4;
+    /** Playback is handling a seek. */
+    public static final int STATE_SEEKING = 5;
+    /** Playback is buffering to resume active playback. */
+    public static final int STATE_BUFFERING = 6;
+    /** Playback is buffering while paused. */
+    public static final int STATE_PAUSED_BUFFERING = 7;
+    /** Playback is suppressed (e.g. due to audio focus loss). */
+    public static final int STATE_SUPPRESSED = 9;
+    /**
+     * Playback is suppressed (e.g. due to audio focus loss) while buffering to resume a playback.
+     */
+    public static final int STATE_SUPPRESSED_BUFFERING = 10;
+    /** Playback has reached the end of the media. */
+    public static final int STATE_ENDED = 11;
+    /** Playback is stopped and can be restarted. */
+    public static final int STATE_STOPPED = 12;
+    /** Playback is stopped due a fatal error and can be retried. */
+    public static final int STATE_FAILED = 13;
+    /** Playback is interrupted by an ad. */
+    public static final int STATE_INTERRUPTED_BY_AD = 14;
+    /** Playback is abandoned before reaching the end of the media. */
+    public static final int STATE_ABANDONED = 15;
+
+    private final int mState;
+    private final long mTimeSinceCreatedMillis;
+
+    // These track ExoPlayer states. See the ExoPlayer documentation for the state transitions.
+    /** @hide */
+    @IntDef(prefix = "STATE_", value = {
+        STATE_NOT_STARTED,
+        STATE_JOINING_BACKGROUND,
+        STATE_JOINING_FOREGROUND,
+        STATE_PLAYING,
+        STATE_PAUSED,
+        STATE_SEEKING,
+        STATE_BUFFERING,
+        STATE_PAUSED_BUFFERING,
+        STATE_SUPPRESSED,
+        STATE_SUPPRESSED_BUFFERING,
+        STATE_ENDED,
+        STATE_STOPPED,
+        STATE_FAILED,
+        STATE_INTERRUPTED_BY_AD,
+        STATE_ABANDONED,
+    })
+    @Retention(java.lang.annotation.RetentionPolicy.SOURCE)
+    public @interface State {}
+
+    /**
+     * Converts playback state to string.
+     * @hide
+     */
+    public static String stateToString(@State int value) {
+        switch (value) {
+            case STATE_NOT_STARTED:
+                return "STATE_NOT_STARTED";
+            case STATE_JOINING_BACKGROUND:
+                return "STATE_JOINING_BACKGROUND";
+            case STATE_JOINING_FOREGROUND:
+                return "STATE_JOINING_FOREGROUND";
+            case STATE_PLAYING:
+                return "STATE_PLAYING";
+            case STATE_PAUSED:
+                return "STATE_PAUSED";
+            case STATE_SEEKING:
+                return "STATE_SEEKING";
+            case STATE_BUFFERING:
+                return "STATE_BUFFERING";
+            case STATE_PAUSED_BUFFERING:
+                return "STATE_PAUSED_BUFFERING";
+            case STATE_SUPPRESSED:
+                return "STATE_SUPPRESSED";
+            case STATE_SUPPRESSED_BUFFERING:
+                return "STATE_SUPPRESSED_BUFFERING";
+            case STATE_ENDED:
+                return "STATE_ENDED";
+            case STATE_STOPPED:
+                return "STATE_STOPPED";
+            case STATE_FAILED:
+                return "STATE_FAILED";
+            case STATE_INTERRUPTED_BY_AD:
+                return "STATE_INTERRUPTED_BY_AD";
+            case STATE_ABANDONED:
+                return "STATE_ABANDONED";
+            default:
+                return Integer.toHexString(value);
+        }
+    }
+
+    /**
+     * Creates a new PlaybackStateEvent.
+     */
+    private PlaybackStateEvent(
+            int state,
+            long timeSinceCreatedMillis,
+            @NonNull Bundle extras) {
+        this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
+        this.mState = state;
+        this.mMetricsBundle = extras.deepCopy();
+    }
+
+    /**
+     * Gets playback state.
+     */
+    @State
+    public int getState() {
+        return mState;
+    }
+
+    /**
+     * Gets time since the corresponding playback session is created in millisecond.
+     * @return the timestamp since the playback is created, or -1 if unknown.
+     * @see LogSessionId
+     * @see PlaybackSession
+     */
+    @Override
+    @IntRange(from = -1)
+    public long getTimeSinceCreatedMillis() {
+        return mTimeSinceCreatedMillis;
+    }
+
+    /**
+     * Gets metrics-related information that is not supported by dedicated methods.
+     * <p>It is intended to be used for backwards compatibility by the metrics infrastructure.
+     */
+    @Override
+    @NonNull
+    public Bundle getMetricsBundle() {
+        return mMetricsBundle;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        PlaybackStateEvent that = (PlaybackStateEvent) o;
+        return mState == that.mState
+                && mTimeSinceCreatedMillis == that.mTimeSinceCreatedMillis;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mState, mTimeSinceCreatedMillis);
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mState);
+        dest.writeLong(mTimeSinceCreatedMillis);
+        dest.writeBundle(mMetricsBundle);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    private PlaybackStateEvent(@NonNull Parcel in) {
+        int state = in.readInt();
+        long timeSinceCreatedMillis = in.readLong();
+        Bundle extras = in.readBundle();
+
+        this.mState = state;
+        this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
+        this.mMetricsBundle = extras;
+    }
+
+    public static final @NonNull Parcelable.Creator<PlaybackStateEvent> CREATOR =
+            new Parcelable.Creator<PlaybackStateEvent>() {
+        @Override
+        public PlaybackStateEvent[] newArray(int size) {
+            return new PlaybackStateEvent[size];
+        }
+
+        @Override
+        public PlaybackStateEvent createFromParcel(@NonNull Parcel in) {
+            return new PlaybackStateEvent(in);
+        }
+    };
+
+    /**
+     * A builder for {@link PlaybackStateEvent}
+     */
+    public static final class Builder {
+        private int mState = STATE_NOT_STARTED;
+        private long mTimeSinceCreatedMillis = -1;
+        private Bundle mMetricsBundle = new Bundle();
+
+        /**
+         * Creates a new Builder.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Sets playback state.
+         */
+        public @NonNull Builder setState(@State int value) {
+            mState = value;
+            return this;
+        }
+
+        /**
+         * Sets timestamp since the creation in milliseconds.
+         * @param value the timestamp since the creation in milliseconds.
+         *              -1 indicates the value is unknown.
+         * @see #getTimeSinceCreatedMillis()
+         */
+        public @NonNull Builder setTimeSinceCreatedMillis(@IntRange(from = -1) long value) {
+            mTimeSinceCreatedMillis = value;
+            return this;
+        }
+
+        /**
+         * Sets metrics-related information that is not supported by dedicated
+         * methods.
+         * <p>It is intended to be used for backwards compatibility by the
+         * metrics infrastructure.
+         */
+        public @NonNull Builder setMetricsBundle(@NonNull Bundle metricsBundle) {
+            mMetricsBundle = metricsBundle;
+            return this;
+        }
+
+        /** Builds the instance. */
+        public @NonNull PlaybackStateEvent build() {
+            PlaybackStateEvent o = new PlaybackStateEvent(
+                    mState,
+                    mTimeSinceCreatedMillis,
+                    mMetricsBundle);
+            return o;
+        }
+    }
+}
diff --git a/android/media/metrics/RecordingSession.java b/android/media/metrics/RecordingSession.java
new file mode 100644
index 0000000..d388351
--- /dev/null
+++ b/android/media/metrics/RecordingSession.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2021 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.metrics;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+import com.android.internal.util.AnnotationValidations;
+
+import java.util.Objects;
+
+/**
+ * An instances of this class represents a session of media recording.
+ */
+public final class RecordingSession implements AutoCloseable {
+    private final @NonNull String mId;
+    private final @NonNull MediaMetricsManager mManager;
+    private final @NonNull LogSessionId mLogSessionId;
+    private boolean mClosed = false;
+
+    /** @hide */
+    public RecordingSession(@NonNull String id, @NonNull MediaMetricsManager manager) {
+        mId = id;
+        mManager = manager;
+        AnnotationValidations.validate(NonNull.class, null, mId);
+        AnnotationValidations.validate(NonNull.class, null, mManager);
+        mLogSessionId = new LogSessionId(mId);
+    }
+
+    public @NonNull LogSessionId getSessionId() {
+        return mLogSessionId;
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        RecordingSession that = (RecordingSession) o;
+        return Objects.equals(mId, that.mId);
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mId);
+    }
+
+    @Override
+    public void close() {
+        mClosed = true;
+    }
+}
diff --git a/android/media/metrics/TrackChangeEvent.java b/android/media/metrics/TrackChangeEvent.java
new file mode 100644
index 0000000..65d011c
--- /dev/null
+++ b/android/media/metrics/TrackChangeEvent.java
@@ -0,0 +1,647 @@
+/*
+ * Copyright (C) 2020 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.metrics;
+
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Playback track change event.
+ */
+public final class TrackChangeEvent extends Event implements Parcelable {
+    /** The track is off. */
+    public static final int TRACK_STATE_OFF = 0;
+    /** The track is on. */
+    public static final int TRACK_STATE_ON = 1;
+
+    /** Unknown track change reason. */
+    public static final int TRACK_CHANGE_REASON_UNKNOWN = 0;
+    /** Other track change reason. */
+    public static final int TRACK_CHANGE_REASON_OTHER = 1;
+    /** Track change reason for initial state. */
+    public static final int TRACK_CHANGE_REASON_INITIAL = 2;
+    /** Track change reason for manual changes. */
+    public static final int TRACK_CHANGE_REASON_MANUAL = 3;
+    /** Track change reason for adaptive changes. */
+    public static final int TRACK_CHANGE_REASON_ADAPTIVE = 4;
+
+    /** Audio track. */
+    public static final int TRACK_TYPE_AUDIO = 0;
+    /** Video track. */
+    public static final int TRACK_TYPE_VIDEO = 1;
+    /** Text track. */
+    public static final int TRACK_TYPE_TEXT = 2;
+
+    private final int mState;
+    private final int mReason;
+    private final @Nullable String mContainerMimeType;
+    private final @Nullable String mSampleMimeType;
+    private final @Nullable String mCodecName;
+    private final int mBitrate;
+    private final long mTimeSinceCreatedMillis;
+    private final int mType;
+    private final @Nullable String mLanguage;
+    private final @Nullable String mLanguageRegion;
+    private final int mChannelCount;
+    private final int mAudioSampleRate;
+    private final int mWidth;
+    private final int mHeight;
+    private final float mVideoFrameRate;
+
+
+
+    /** @hide */
+    @IntDef(prefix = "TRACK_STATE_", value = {
+        TRACK_STATE_OFF,
+        TRACK_STATE_ON
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TrackState {}
+
+    /** @hide */
+    @IntDef(prefix = "TRACK_CHANGE_REASON_", value = {
+        TRACK_CHANGE_REASON_UNKNOWN,
+        TRACK_CHANGE_REASON_OTHER,
+        TRACK_CHANGE_REASON_INITIAL,
+        TRACK_CHANGE_REASON_MANUAL,
+        TRACK_CHANGE_REASON_ADAPTIVE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TrackChangeReason {}
+
+    /** @hide */
+    @IntDef(prefix = "TRACK_TYPE_", value = {
+        TRACK_TYPE_AUDIO,
+        TRACK_TYPE_VIDEO,
+        TRACK_TYPE_TEXT
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TrackType {}
+
+    private TrackChangeEvent(
+            int state,
+            int reason,
+            @Nullable String containerMimeType,
+            @Nullable String sampleMimeType,
+            @Nullable String codecName,
+            int bitrate,
+            long timeSinceCreatedMillis,
+            int type,
+            @Nullable String language,
+            @Nullable String languageRegion,
+            int channelCount,
+            int sampleRate,
+            int width,
+            int height,
+            float videoFrameRate,
+            @NonNull Bundle extras) {
+        this.mState = state;
+        this.mReason = reason;
+        this.mContainerMimeType = containerMimeType;
+        this.mSampleMimeType = sampleMimeType;
+        this.mCodecName = codecName;
+        this.mBitrate = bitrate;
+        this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
+        this.mType = type;
+        this.mLanguage = language;
+        this.mLanguageRegion = languageRegion;
+        this.mChannelCount = channelCount;
+        this.mAudioSampleRate = sampleRate;
+        this.mWidth = width;
+        this.mHeight = height;
+        this.mVideoFrameRate = videoFrameRate;
+        this.mMetricsBundle = extras.deepCopy();
+    }
+
+    /**
+     * Gets track state.
+     */
+    @TrackState
+    public int getTrackState() {
+        return mState;
+    }
+
+    /**
+     * Gets track change reason.
+     */
+    @TrackChangeReason
+    public int getTrackChangeReason() {
+        return mReason;
+    }
+
+    /**
+     * Gets container MIME type.
+     */
+    public @Nullable String getContainerMimeType() {
+        return mContainerMimeType;
+    }
+
+    /**
+     * Gets the MIME type of the video/audio/text samples.
+     */
+    public @Nullable String getSampleMimeType() {
+        return mSampleMimeType;
+    }
+
+    /**
+     * Gets codec name.
+     */
+    public @Nullable String getCodecName() {
+        return mCodecName;
+    }
+
+    /**
+     * Gets bitrate.
+     * @return the bitrate, or -1 if unknown.
+     */
+    @IntRange(from = -1, to = Integer.MAX_VALUE)
+    public int getBitrate() {
+        return mBitrate;
+    }
+
+    /**
+     * Gets timestamp since the creation of the log session in milliseconds.
+     * @return the timestamp since the creation in milliseconds, or -1 if unknown.
+     * @see LogSessionId
+     * @see PlaybackSession
+     * @see RecordingSession
+     */
+    @Override
+    @IntRange(from = -1)
+    public long getTimeSinceCreatedMillis() {
+        return mTimeSinceCreatedMillis;
+    }
+
+    /**
+     * Gets the track type.
+     * <p>The track type must be one of {@link #TRACK_TYPE_AUDIO}, {@link #TRACK_TYPE_VIDEO},
+     * {@link #TRACK_TYPE_TEXT}.
+     */
+    @TrackType
+    public int getTrackType() {
+        return mType;
+    }
+
+    /**
+     * Gets language code.
+     * @return a two-letter ISO 639-1 language code.
+     */
+    public @Nullable String getLanguage() {
+        return mLanguage;
+    }
+
+
+    /**
+     * Gets language region code.
+     * @return an IETF BCP 47 optional language region subtag based on a two-letter country code.
+     */
+    public @Nullable String getLanguageRegion() {
+        return mLanguageRegion;
+    }
+
+    /**
+     * Gets channel count.
+     * @return the channel count, or -1 if unknown.
+     */
+    @IntRange(from = -1, to = Integer.MAX_VALUE)
+    public int getChannelCount() {
+        return mChannelCount;
+    }
+
+    /**
+     * Gets audio sample rate.
+     * @return the sample rate, or -1 if unknown.
+     */
+    @IntRange(from = -1, to = Integer.MAX_VALUE)
+    public int getAudioSampleRate() {
+        return mAudioSampleRate;
+    }
+
+    /**
+     * Gets video width.
+     * @return the video width, or -1 if unknown.
+     */
+    @IntRange(from = -1, to = Integer.MAX_VALUE)
+    public int getWidth() {
+        return mWidth;
+    }
+
+    /**
+     * Gets video height.
+     * @return the video height, or -1 if unknown.
+     */
+    @IntRange(from = -1, to = Integer.MAX_VALUE)
+    public int getHeight() {
+        return mHeight;
+    }
+
+    /**
+     * Gets video frame rate.
+     * @return the video frame rate, or -1 if unknown.
+     */
+    @FloatRange(from = -1, to = Float.MAX_VALUE)
+    public float getVideoFrameRate() {
+        return mVideoFrameRate;
+    }
+
+    /**
+     * Gets metrics-related information that is not supported by dedicated methods.
+     * <p>It is intended to be used for backwards compatibility by the metrics infrastructure.
+     */
+    @Override
+    @NonNull
+    public Bundle getMetricsBundle() {
+        return mMetricsBundle;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        int flg = 0;
+        if (mContainerMimeType != null) flg |= 0x4;
+        if (mSampleMimeType != null) flg |= 0x8;
+        if (mCodecName != null) flg |= 0x10;
+        if (mLanguage != null) flg |= 0x100;
+        if (mLanguageRegion != null) flg |= 0x200;
+        dest.writeInt(flg);
+        dest.writeInt(mState);
+        dest.writeInt(mReason);
+        if (mContainerMimeType != null) dest.writeString(mContainerMimeType);
+        if (mSampleMimeType != null) dest.writeString(mSampleMimeType);
+        if (mCodecName != null) dest.writeString(mCodecName);
+        dest.writeInt(mBitrate);
+        dest.writeLong(mTimeSinceCreatedMillis);
+        dest.writeInt(mType);
+        if (mLanguage != null) dest.writeString(mLanguage);
+        if (mLanguageRegion != null) dest.writeString(mLanguageRegion);
+        dest.writeInt(mChannelCount);
+        dest.writeInt(mAudioSampleRate);
+        dest.writeInt(mWidth);
+        dest.writeInt(mHeight);
+        dest.writeFloat(mVideoFrameRate);
+        dest.writeBundle(mMetricsBundle);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    private TrackChangeEvent(@NonNull Parcel in) {
+        int flg = in.readInt();
+        int state = in.readInt();
+        int reason = in.readInt();
+        String containerMimeType = (flg & 0x4) == 0 ? null : in.readString();
+        String sampleMimeType = (flg & 0x8) == 0 ? null : in.readString();
+        String codecName = (flg & 0x10) == 0 ? null : in.readString();
+        int bitrate = in.readInt();
+        long timeSinceCreatedMillis = in.readLong();
+        int type = in.readInt();
+        String language = (flg & 0x100) == 0 ? null : in.readString();
+        String languageRegion = (flg & 0x200) == 0 ? null : in.readString();
+        int channelCount = in.readInt();
+        int sampleRate = in.readInt();
+        int width = in.readInt();
+        int height = in.readInt();
+        float videoFrameRate = in.readFloat();
+        Bundle extras = in.readBundle();
+
+        this.mState = state;
+        this.mReason = reason;
+        this.mContainerMimeType = containerMimeType;
+        this.mSampleMimeType = sampleMimeType;
+        this.mCodecName = codecName;
+        this.mBitrate = bitrate;
+        this.mTimeSinceCreatedMillis = timeSinceCreatedMillis;
+        this.mType = type;
+        this.mLanguage = language;
+        this.mLanguageRegion = languageRegion;
+        this.mChannelCount = channelCount;
+        this.mAudioSampleRate = sampleRate;
+        this.mWidth = width;
+        this.mHeight = height;
+        this.mVideoFrameRate = videoFrameRate;
+        this.mMetricsBundle = extras;
+    }
+
+    public static final @NonNull Parcelable.Creator<TrackChangeEvent> CREATOR =
+            new Parcelable.Creator<TrackChangeEvent>() {
+        @Override
+        public TrackChangeEvent[] newArray(int size) {
+            return new TrackChangeEvent[size];
+        }
+
+        @Override
+        public TrackChangeEvent createFromParcel(@NonNull Parcel in) {
+            return new TrackChangeEvent(in);
+        }
+    };
+
+    @Override
+    public String toString() {
+        return "TrackChangeEvent { "
+                + "state = " + mState + ", "
+                + "reason = " + mReason + ", "
+                + "containerMimeType = " + mContainerMimeType + ", "
+                + "sampleMimeType = " + mSampleMimeType + ", "
+                + "codecName = " + mCodecName + ", "
+                + "bitrate = " + mBitrate + ", "
+                + "timeSinceCreatedMillis = " + mTimeSinceCreatedMillis + ", "
+                + "type = " + mType + ", "
+                + "language = " + mLanguage + ", "
+                + "languageRegion = " + mLanguageRegion + ", "
+                + "channelCount = " + mChannelCount + ", "
+                + "sampleRate = " + mAudioSampleRate + ", "
+                + "width = " + mWidth + ", "
+                + "height = " + mHeight + ", "
+                + "videoFrameRate = " + mVideoFrameRate
+                + " }";
+    }
+
+    @Override
+    public boolean equals(@Nullable Object o) {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+        TrackChangeEvent that = (TrackChangeEvent) o;
+        return mState == that.mState
+                && mReason == that.mReason
+                && Objects.equals(mContainerMimeType, that.mContainerMimeType)
+                && Objects.equals(mSampleMimeType, that.mSampleMimeType)
+                && Objects.equals(mCodecName, that.mCodecName)
+                && mBitrate == that.mBitrate
+                && mTimeSinceCreatedMillis == that.mTimeSinceCreatedMillis
+                && mType == that.mType
+                && Objects.equals(mLanguage, that.mLanguage)
+                && Objects.equals(mLanguageRegion, that.mLanguageRegion)
+                && mChannelCount == that.mChannelCount
+                && mAudioSampleRate == that.mAudioSampleRate
+                && mWidth == that.mWidth
+                && mHeight == that.mHeight
+                && mVideoFrameRate == that.mVideoFrameRate;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mState, mReason, mContainerMimeType, mSampleMimeType, mCodecName,
+                mBitrate, mTimeSinceCreatedMillis, mType, mLanguage, mLanguageRegion,
+                mChannelCount, mAudioSampleRate, mWidth, mHeight, mVideoFrameRate);
+    }
+
+    /**
+     * A builder for {@link TrackChangeEvent}
+     */
+    public static final class Builder {
+        // TODO: check track type for the setters.
+        private int mState = TRACK_STATE_OFF;
+        private int mReason = TRACK_CHANGE_REASON_UNKNOWN;
+        private @Nullable String mContainerMimeType;
+        private @Nullable String mSampleMimeType;
+        private @Nullable String mCodecName;
+        private int mBitrate = -1;
+        private long mTimeSinceCreatedMillis = -1;
+        private final int mType;
+        private @Nullable String mLanguage;
+        private @Nullable String mLanguageRegion;
+        private int mChannelCount = -1;
+        private int mAudioSampleRate = -1;
+        private int mWidth = -1;
+        private int mHeight = -1;
+        private float mVideoFrameRate = -1;
+        private Bundle mMetricsBundle = new Bundle();
+
+        private long mBuilderFieldsSet = 0L;
+
+        /**
+         * Creates a new Builder.
+         * @param type the track type. It must be one of {@link #TRACK_TYPE_AUDIO},
+         *             {@link #TRACK_TYPE_VIDEO}, {@link #TRACK_TYPE_TEXT}.
+         */
+        public Builder(@TrackType int type) {
+            if (type != TRACK_TYPE_AUDIO && type != TRACK_TYPE_VIDEO && type != TRACK_TYPE_TEXT) {
+                throw new IllegalArgumentException("track type must be one of TRACK_TYPE_AUDIO, "
+                    + "TRACK_TYPE_VIDEO, TRACK_TYPE_TEXT.");
+            }
+            mType = type;
+        }
+
+        /**
+         * Sets track state.
+         */
+        public @NonNull Builder setTrackState(@TrackState int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x1;
+            mState = value;
+            return this;
+        }
+
+        /**
+         * Sets track change reason.
+         */
+        public @NonNull Builder setTrackChangeReason(@TrackChangeReason int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x2;
+            mReason = value;
+            return this;
+        }
+
+        /**
+         * Sets container MIME type.
+         */
+        public @NonNull Builder setContainerMimeType(@NonNull String value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x4;
+            mContainerMimeType = value;
+            return this;
+        }
+
+        /**
+         * Sets the MIME type of the video/audio/text samples.
+         */
+        public @NonNull Builder setSampleMimeType(@NonNull String value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x8;
+            mSampleMimeType = value;
+            return this;
+        }
+
+        /**
+         * Sets codec name.
+         */
+        public @NonNull Builder setCodecName(@NonNull String value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x10;
+            mCodecName = value;
+            return this;
+        }
+
+        /**
+         * Sets bitrate in bits per second.
+         * @param value the bitrate in bits per second. -1 indicates the value is unknown.
+         */
+        public @NonNull Builder setBitrate(@IntRange(from = -1, to = Integer.MAX_VALUE) int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x20;
+            mBitrate = value;
+            return this;
+        }
+
+        /**
+         * Sets timestamp since the creation in milliseconds.
+         * @param value the timestamp since the creation in milliseconds.
+         *              -1 indicates the value is unknown.
+         * @see #getTimeSinceCreatedMillis()
+         */
+        public @NonNull Builder setTimeSinceCreatedMillis(@IntRange(from = -1) long value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x40;
+            mTimeSinceCreatedMillis = value;
+            return this;
+        }
+
+        /**
+         * Sets language code.
+         * @param value a two-letter ISO 639-1 language code.
+         */
+        public @NonNull Builder setLanguage(@NonNull String value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x100;
+            mLanguage = value;
+            return this;
+        }
+
+        /**
+         * Sets language region code.
+         * @param value an IETF BCP 47 optional language region subtag based on a two-letter country
+         *              code.
+         */
+        public @NonNull Builder setLanguageRegion(@NonNull String value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x200;
+            mLanguageRegion = value;
+            return this;
+        }
+
+        /**
+         * Sets channel count.
+         * @param value the channel count. -1 indicates the value is unknown.
+         */
+        public @NonNull Builder setChannelCount(
+                @IntRange(from = -1, to = Integer.MAX_VALUE) int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x400;
+            mChannelCount = value;
+            return this;
+        }
+
+        /**
+         * Sets sample rate.
+         * @param value the sample rate. -1 indicates the value is unknown.
+         */
+        public @NonNull Builder setAudioSampleRate(
+                @IntRange(from = -1, to = Integer.MAX_VALUE) int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x800;
+            mAudioSampleRate = value;
+            return this;
+        }
+
+        /**
+         * Sets video width.
+         * @param value the video width. -1 indicates the value is unknown.
+         */
+        public @NonNull Builder setWidth(@IntRange(from = -1, to = Integer.MAX_VALUE) int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x1000;
+            mWidth = value;
+            return this;
+        }
+
+        /**
+         * Sets video height.
+         * @param value the video height. -1 indicates the value is unknown.
+         */
+        public @NonNull Builder setHeight(@IntRange(from = -1, to = Integer.MAX_VALUE) int value) {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x2000;
+            mHeight = value;
+            return this;
+        }
+
+        /**
+         * Sets video frame rate.
+         * @param value the video frame rate. -1 indicates the value is unknown.
+         */
+        public @NonNull Builder setVideoFrameRate(
+                @FloatRange(from = -1, to = Float.MAX_VALUE) float value) {
+            checkNotUsed();
+            mVideoFrameRate = value;
+            return this;
+        }
+
+        /**
+         * Sets metrics-related information that is not supported by dedicated
+         * methods.
+         * <p>It is intended to be used for backwards compatibility by the
+         * metrics infrastructure.
+         */
+        public @NonNull Builder setMetricsBundle(@NonNull Bundle metricsBundle) {
+            mMetricsBundle = metricsBundle;
+            return this;
+        }
+
+        /** Builds the instance. This builder should not be touched after calling this! */
+        public @NonNull TrackChangeEvent build() {
+            checkNotUsed();
+            mBuilderFieldsSet |= 0x4000; // Mark builder used
+
+            TrackChangeEvent o = new TrackChangeEvent(
+                    mState,
+                    mReason,
+                    mContainerMimeType,
+                    mSampleMimeType,
+                    mCodecName,
+                    mBitrate,
+                    mTimeSinceCreatedMillis,
+                    mType,
+                    mLanguage,
+                    mLanguageRegion,
+                    mChannelCount,
+                    mAudioSampleRate,
+                    mWidth,
+                    mHeight,
+                    mVideoFrameRate,
+                    mMetricsBundle);
+            return o;
+        }
+
+        private void checkNotUsed() {
+            if ((mBuilderFieldsSet & 0x4000) != 0) {
+                throw new IllegalStateException(
+                        "This Builder should not be reused. Use a new Builder instance instead");
+            }
+        }
+    }
+}
diff --git a/android/media/midi/MidiDevice.java b/android/media/midi/MidiDevice.java
new file mode 100644
index 0000000..6096355
--- /dev/null
+++ b/android/media/midi/MidiDevice.java
@@ -0,0 +1,258 @@
+/*
+ * Copyright (C) 2014 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.midi;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.util.Log;
+
+import dalvik.system.CloseGuard;
+
+import libcore.io.IoUtils;
+
+import java.io.Closeable;
+import java.io.FileDescriptor;
+import java.io.IOException;
+
+import java.util.HashSet;
+
+/**
+ * This class is used for sending and receiving data to and from a MIDI device
+ * Instances of this class are created by {@link MidiManager#openDevice}.
+ */
+public final class MidiDevice implements Closeable {
+    private static final String TAG = "MidiDevice";
+
+    private final MidiDeviceInfo mDeviceInfo;    // accessed from native code
+    private final IMidiDeviceServer mDeviceServer;
+    private final IBinder mDeviceServerBinder;    // accessed from native code
+    private final IMidiManager mMidiManager;
+    private final IBinder mClientToken;
+    private final IBinder mDeviceToken;
+    private boolean mIsDeviceClosed;    // accessed from native code
+
+    private long mNativeHandle;    // accessed from native code
+
+    private final CloseGuard mGuard = CloseGuard.get();
+
+    /**
+     * This class represents a connection between the output port of one device
+     * and the input port of another. Created by {@link #connectPorts}.
+     * Close this object to terminate the connection.
+     */
+    public class MidiConnection implements Closeable {
+        private final IMidiDeviceServer mInputPortDeviceServer;
+        private final IBinder mInputPortToken;
+        private final IBinder mOutputPortToken;
+        private final CloseGuard mGuard = CloseGuard.get();
+        private boolean mIsClosed;
+
+        MidiConnection(IBinder outputPortToken, MidiInputPort inputPort) {
+            mInputPortDeviceServer = inputPort.getDeviceServer();
+            mInputPortToken = inputPort.getToken();
+            mOutputPortToken = outputPortToken;
+            mGuard.open("close");
+        }
+
+        @Override
+        public void close() throws IOException {
+            synchronized (mGuard) {
+                if (mIsClosed) return;
+                mGuard.close();
+                try {
+                    // close input port
+                    mInputPortDeviceServer.closePort(mInputPortToken);
+                    // close output port
+                    mDeviceServer.closePort(mOutputPortToken);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoteException in MidiConnection.close");
+                }
+                mIsClosed = true;
+            }
+        }
+
+        @Override
+        protected void finalize() throws Throwable {
+            try {
+                if (mGuard != null) {
+                    mGuard.warnIfOpen();
+                }
+
+                close();
+            } finally {
+                super.finalize();
+            }
+        }
+    }
+
+    /* package */ MidiDevice(MidiDeviceInfo deviceInfo, IMidiDeviceServer server,
+            IMidiManager midiManager, IBinder clientToken, IBinder deviceToken) {
+        mDeviceInfo = deviceInfo;
+        mDeviceServer = server;
+        mDeviceServerBinder = mDeviceServer.asBinder();
+        mMidiManager = midiManager;
+        mClientToken = clientToken;
+        mDeviceToken = deviceToken;
+        mGuard.open("close");
+    }
+
+    /**
+     * Returns a {@link MidiDeviceInfo} object, which describes this device.
+     *
+     * @return the {@link MidiDeviceInfo} object
+     */
+    public MidiDeviceInfo getInfo() {
+        return mDeviceInfo;
+    }
+
+    /**
+     * Called to open a {@link MidiInputPort} for the specified port number.
+     *
+     * An input port can only be used by one sender at a time.
+     * Opening an input port will fail if another application has already opened it for use.
+     * A {@link MidiDeviceStatus} can be used to determine if an input port is already open.
+     *
+     * @param portNumber the number of the input port to open
+     * @return the {@link MidiInputPort} if the open is successful,
+     *         or null in case of failure.
+     */
+    public MidiInputPort openInputPort(int portNumber) {
+        if (mIsDeviceClosed) {
+            return null;
+        }
+        try {
+            IBinder token = new Binder();
+            FileDescriptor fd = mDeviceServer.openInputPort(token, portNumber);
+            if (fd == null) {
+                return null;
+            }
+            return new MidiInputPort(mDeviceServer, token, fd, portNumber);
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in openInputPort");
+            return null;
+        }
+    }
+
+    /**
+     * Called to open a {@link MidiOutputPort} for the specified port number.
+     *
+     * An output port may be opened by multiple applications.
+     *
+     * @param portNumber the number of the output port to open
+     * @return the {@link MidiOutputPort} if the open is successful,
+     *         or null in case of failure.
+     */
+    public MidiOutputPort openOutputPort(int portNumber) {
+        if (mIsDeviceClosed) {
+            return null;
+        }
+        try {
+            IBinder token = new Binder();
+            FileDescriptor fd = mDeviceServer.openOutputPort(token, portNumber);
+            if (fd == null) {
+                return null;
+            }
+            return new MidiOutputPort(mDeviceServer, token, fd, portNumber);
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in openOutputPort");
+            return null;
+        }
+    }
+
+    /**
+     * Connects the supplied {@link MidiInputPort} to the output port of this device
+     * with the specified port number. Once the connection is made, the MidiInput port instance
+     * can no longer receive data via its {@link MidiReceiver#onSend} method.
+     * This method returns a {@link MidiDevice.MidiConnection} object, which can be used
+     * to close the connection.
+     *
+     * @param inputPort the inputPort to connect
+     * @param outputPortNumber the port number of the output port to connect inputPort to.
+     * @return {@link MidiDevice.MidiConnection} object if the connection is successful,
+     *         or null in case of failure.
+     */
+    public MidiConnection connectPorts(MidiInputPort inputPort, int outputPortNumber) {
+        if (outputPortNumber < 0 || outputPortNumber >= mDeviceInfo.getOutputPortCount()) {
+            throw new IllegalArgumentException("outputPortNumber out of range");
+        }
+        if (mIsDeviceClosed) {
+            return null;
+        }
+
+        FileDescriptor fd = inputPort.claimFileDescriptor();
+        if (fd == null) {
+            return null;
+        }
+        try {
+            IBinder token = new Binder();
+            int calleePid = mDeviceServer.connectPorts(token, fd, outputPortNumber);
+            // If the service is a different Process then it will duplicate the fd
+            // and we can safely close this one.
+            // But if the service is in the same Process then closing the fd will
+            // kill the connection. So don't do that.
+            if (calleePid != Process.myPid()) {
+                // close our copy of the file descriptor
+                IoUtils.closeQuietly(fd);
+            }
+
+            return new MidiConnection(token, inputPort);
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in connectPorts");
+            return null;
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        synchronized (mGuard) {
+            // What if there is a native reference to this?
+            if (mNativeHandle != 0) {
+                Log.w(TAG, "MidiDevice#close() called while there is an outstanding native client 0x"
+                           + Long.toHexString(mNativeHandle));
+            }
+            if (!mIsDeviceClosed && mNativeHandle == 0) {
+                mGuard.close();
+                mIsDeviceClosed = true;
+                try {
+                    mMidiManager.closeDevice(mClientToken, mDeviceToken);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoteException in closeDevice");
+                }
+            }
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+            }
+
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    @Override
+    public String toString() {
+        return ("MidiDevice: " + mDeviceInfo.toString());
+    }
+}
diff --git a/android/media/midi/MidiDeviceInfo.java b/android/media/midi/MidiDeviceInfo.java
new file mode 100644
index 0000000..dd3b6db
--- /dev/null
+++ b/android/media/midi/MidiDeviceInfo.java
@@ -0,0 +1,403 @@
+/*
+ * Copyright (C) 2014 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.midi;
+
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * This class contains information to describe a MIDI device.
+ * For now we only have information that can be retrieved easily for USB devices,
+ * but we will probably expand this in the future.
+ *
+ * This class is just an immutable object to encapsulate the MIDI device description.
+ * Use the MidiDevice class to actually communicate with devices.
+ */
+public final class MidiDeviceInfo implements Parcelable {
+
+    private static final String TAG = "MidiDeviceInfo";
+
+    /*
+     * Please note that constants and (un)marshalling code need to be kept in sync
+     * with the native implementation (MidiDeviceInfo.h|cpp)
+     */
+
+    /**
+     * Constant representing USB MIDI devices for {@link #getType}
+     */
+    public static final int TYPE_USB = 1;
+
+    /**
+     * Constant representing virtual (software based) MIDI devices for {@link #getType}
+     */
+    public static final int TYPE_VIRTUAL = 2;
+
+    /**
+     * Constant representing Bluetooth MIDI devices for {@link #getType}
+     */
+    public static final int TYPE_BLUETOOTH = 3;
+
+    /**
+     * Bundle key for the device's user visible name property.
+     * The value for this property is of type {@link java.lang.String}.
+     * Used with the {@link android.os.Bundle} returned by {@link #getProperties}.
+     * For USB devices, this is a concatenation of the manufacturer and product names.
+     */
+    public static final String PROPERTY_NAME = "name";
+
+    /**
+     * Bundle key for the device's manufacturer name property.
+     * The value for this property is of type {@link java.lang.String}.
+     * Used with the {@link android.os.Bundle} returned by {@link #getProperties}.
+     * Matches the USB device manufacturer name string for USB MIDI devices.
+     */
+    public static final String PROPERTY_MANUFACTURER = "manufacturer";
+
+    /**
+     * Bundle key for the device's product name property.
+     * The value for this property is of type {@link java.lang.String}.
+     * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
+     * Matches the USB device product name string for USB MIDI devices.
+     */
+    public static final String PROPERTY_PRODUCT = "product";
+
+    /**
+     * Bundle key for the device's version property.
+     * The value for this property is of type {@link java.lang.String}.
+     * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
+     * Matches the USB device version number for USB MIDI devices.
+     */
+    public static final String PROPERTY_VERSION = "version";
+
+    /**
+     * Bundle key for the device's serial number property.
+     * The value for this property is of type {@link java.lang.String}.
+     * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
+     * Matches the USB device serial number for USB MIDI devices.
+     */
+    public static final String PROPERTY_SERIAL_NUMBER = "serial_number";
+
+    /**
+     * Bundle key for the device's corresponding USB device.
+     * The value for this property is of type {@link android.hardware.usb.UsbDevice}.
+     * Only set for USB MIDI devices.
+     * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
+     */
+    public static final String PROPERTY_USB_DEVICE = "usb_device";
+
+    /**
+     * Bundle key for the device's corresponding Bluetooth device.
+     * The value for this property is of type {@link android.bluetooth.BluetoothDevice}.
+     * Only set for Bluetooth MIDI devices.
+     * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
+     */
+    public static final String PROPERTY_BLUETOOTH_DEVICE = "bluetooth_device";
+
+    /**
+     * Bundle key for the device's ALSA card number.
+     * The value for this property is an integer.
+     * Only set for USB MIDI devices.
+     * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
+     *
+     * @hide
+     */
+    public static final String PROPERTY_ALSA_CARD = "alsa_card";
+
+    /**
+     * Bundle key for the device's ALSA device number.
+     * The value for this property is an integer.
+     * Only set for USB MIDI devices.
+     * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
+     *
+     * @hide
+     */
+    public static final String PROPERTY_ALSA_DEVICE = "alsa_device";
+
+    /**
+     * ServiceInfo for the service hosting the device implementation.
+     * The value for this property is of type {@link android.content.pm.ServiceInfo}.
+     * Only set for Virtual MIDI devices.
+     * Used with the {@link android.os.Bundle} returned by {@link #getProperties}
+     *
+     * @hide
+     */
+    public static final String PROPERTY_SERVICE_INFO = "service_info";
+
+    /**
+     * Contains information about an input or output port.
+     */
+    public static final class PortInfo {
+        /**
+         * Port type for input ports
+         */
+        public static final int TYPE_INPUT = 1;
+
+        /**
+         * Port type for output ports
+         */
+        public static final int TYPE_OUTPUT = 2;
+
+        private final int mPortType;
+        private final int mPortNumber;
+        private final String mName;
+
+        PortInfo(int type, int portNumber, String name) {
+            mPortType = type;
+            mPortNumber = portNumber;
+            mName = (name == null ? "" : name);
+        }
+
+        /**
+         * Returns the port type of the port (either {@link #TYPE_INPUT} or {@link #TYPE_OUTPUT})
+         * @return the port type
+         */
+        public int getType() {
+            return mPortType;
+        }
+
+        /**
+         * Returns the port number of the port
+         * @return the port number
+         */
+        public int getPortNumber() {
+            return mPortNumber;
+        }
+
+        /**
+         * Returns the name of the port, or empty string if the port has no name
+         * @return the port name
+         */
+        public String getName() {
+            return mName;
+        }
+    }
+
+    private final int mType;    // USB or virtual
+    private final int mId;      // unique ID generated by MidiService. Accessed from native code.
+    private final int mInputPortCount;
+    private final int mOutputPortCount;
+    private final String[] mInputPortNames;
+    private final String[] mOutputPortNames;
+    private final Bundle mProperties;
+    private final boolean mIsPrivate;
+
+    /**
+     * MidiDeviceInfo should only be instantiated by MidiService implementation
+     * @hide
+     */
+    public MidiDeviceInfo(int type, int id, int numInputPorts, int numOutputPorts,
+            String[] inputPortNames, String[] outputPortNames, Bundle properties,
+            boolean isPrivate) {
+        // Check num ports for out-of-range values. Typical values will be
+        // between zero and three. More than 16 would be very unlikely
+        // because the port index field in the USB packet is only 4 bits.
+        // This check is mainly just to prevent OutOfMemoryErrors when
+        // fuzz testing.
+        final int maxPorts = 256; // arbitrary and very high
+        if (numInputPorts < 0 || numInputPorts > maxPorts) {
+            throw new IllegalArgumentException("numInputPorts out of range = "
+                    + numInputPorts);
+        }
+        if (numOutputPorts < 0 || numOutputPorts > maxPorts) {
+            throw new IllegalArgumentException("numOutputPorts out of range = "
+                    + numOutputPorts);
+        }
+        mType = type;
+        mId = id;
+        mInputPortCount = numInputPorts;
+        mOutputPortCount = numOutputPorts;
+        if (inputPortNames == null) {
+            mInputPortNames = new String[numInputPorts];
+        } else {
+            mInputPortNames = inputPortNames;
+        }
+        if (outputPortNames == null) {
+            mOutputPortNames = new String[numOutputPorts];
+        } else {
+            mOutputPortNames = outputPortNames;
+        }
+        mProperties = properties;
+        mIsPrivate = isPrivate;
+    }
+
+    /**
+     * Returns the type of the device.
+     *
+     * @return the device's type
+     */
+    public int getType() {
+        return mType;
+    }
+
+    /**
+     * Returns the ID of the device.
+     * This ID is generated by the MIDI service and is not persistent across device unplugs.
+     *
+     * @return the device's ID
+     */
+    public int getId() {
+        return mId;
+    }
+
+    /**
+     * Returns the device's number of input ports.
+     *
+     * @return the number of input ports
+     */
+    public int getInputPortCount() {
+        return mInputPortCount;
+    }
+
+    /**
+     * Returns the device's number of output ports.
+     *
+     * @return the number of output ports
+     */
+    public int getOutputPortCount() {
+        return mOutputPortCount;
+    }
+
+    /**
+     * Returns information about the device's ports.
+     * The ports are in unspecified order.
+     *
+     * @return array of {@link PortInfo}
+     */
+    public PortInfo[] getPorts() {
+        PortInfo[] ports = new PortInfo[mInputPortCount + mOutputPortCount];
+
+        int index = 0;
+        for (int i = 0; i < mInputPortCount; i++) {
+            ports[index++] = new PortInfo(PortInfo.TYPE_INPUT, i, mInputPortNames[i]);
+        }
+        for (int i = 0; i < mOutputPortCount; i++) {
+            ports[index++] = new PortInfo(PortInfo.TYPE_OUTPUT, i, mOutputPortNames[i]);
+        }
+
+        return ports;
+    }
+
+    /**
+     * Returns the {@link android.os.Bundle} containing the device's properties.
+     *
+     * @return the device's properties
+     */
+    public Bundle getProperties() {
+        return mProperties;
+    }
+
+    /**
+     * Returns true if the device is private.  Private devices are only visible and accessible
+     * to clients with the same UID as the application that is hosting the device.
+     *
+     * @return true if the device is private
+     */
+    public boolean isPrivate() {
+        return mIsPrivate;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof MidiDeviceInfo) {
+            return (((MidiDeviceInfo)o).mId == mId);
+        } else {
+            return false;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return mId;
+    }
+
+    @Override
+    public String toString() {
+        // This is a hack to force the mProperties Bundle to unparcel so we can
+        // print all the names and values.
+        mProperties.getString(PROPERTY_NAME);
+        return ("MidiDeviceInfo[mType=" + mType +
+                ",mInputPortCount=" + mInputPortCount +
+                ",mOutputPortCount=" + mOutputPortCount +
+                ",mProperties=" + mProperties +
+                ",mIsPrivate=" + mIsPrivate);
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<MidiDeviceInfo> CREATOR =
+        new Parcelable.Creator<MidiDeviceInfo>() {
+        public MidiDeviceInfo createFromParcel(Parcel in) {
+            // Needs to be kept in sync with code in MidiDeviceInfo.cpp
+            int type = in.readInt();
+            int id = in.readInt();
+            int inputPortCount = in.readInt();
+            int outputPortCount = in.readInt();
+            String[] inputPortNames = in.createStringArray();
+            String[] outputPortNames = in.createStringArray();
+            boolean isPrivate = (in.readInt() == 1);
+            Bundle basicPropertiesIgnored = in.readBundle();
+            Bundle properties = in.readBundle();
+            return new MidiDeviceInfo(type, id, inputPortCount, outputPortCount,
+                    inputPortNames, outputPortNames, properties, isPrivate);
+        }
+
+        public MidiDeviceInfo[] newArray(int size) {
+            return new MidiDeviceInfo[size];
+        }
+    };
+
+    public int describeContents() {
+        return 0;
+    }
+
+    private Bundle getBasicProperties(String[] keys) {
+        Bundle basicProperties = new Bundle();
+        for (String key : keys) {
+            Object val = mProperties.get(key);
+            if (val != null) {
+                if (val instanceof String) {
+                    basicProperties.putString(key, (String) val);
+                } else if (val instanceof Integer) {
+                    basicProperties.putInt(key, (Integer) val);
+                } else {
+                    Log.w(TAG, "Unsupported property type: " + val.getClass().getName());
+                }
+            }
+        }
+        return basicProperties;
+    }
+
+    public void writeToParcel(Parcel parcel, int flags) {
+        // Needs to be kept in sync with code in MidiDeviceInfo.cpp
+        parcel.writeInt(mType);
+        parcel.writeInt(mId);
+        parcel.writeInt(mInputPortCount);
+        parcel.writeInt(mOutputPortCount);
+        parcel.writeStringArray(mInputPortNames);
+        parcel.writeStringArray(mOutputPortNames);
+        parcel.writeInt(mIsPrivate ? 1 : 0);
+        // "Basic" properties only contain properties of primitive types
+        // and thus can be read back by native code. "Extra" properties is
+        // a superset that contains all properties.
+        parcel.writeBundle(getBasicProperties(new String[] {
+            PROPERTY_NAME, PROPERTY_MANUFACTURER, PROPERTY_PRODUCT, PROPERTY_VERSION,
+            PROPERTY_SERIAL_NUMBER, PROPERTY_ALSA_CARD, PROPERTY_ALSA_DEVICE
+        }));
+        // Must be serialized last so native code can safely ignore it.
+        parcel.writeBundle(mProperties);
+   }
+}
diff --git a/android/media/midi/MidiDeviceServer.java b/android/media/midi/MidiDeviceServer.java
new file mode 100644
index 0000000..d5916b9
--- /dev/null
+++ b/android/media/midi/MidiDeviceServer.java
@@ -0,0 +1,452 @@
+/*
+ * Copyright (C) 2014 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.midi;
+
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Process;
+import android.os.RemoteException;
+import android.system.ErrnoException;
+import android.system.Os;
+import android.system.OsConstants;
+import android.util.Log;
+
+import com.android.internal.midi.MidiDispatcher;
+
+import dalvik.system.CloseGuard;
+
+import libcore.io.IoUtils;
+
+import java.io.Closeable;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+
+/**
+ * Internal class used for providing an implementation for a MIDI device.
+ *
+ * @hide
+ */
+public final class MidiDeviceServer implements Closeable {
+    private static final String TAG = "MidiDeviceServer";
+
+    private final IMidiManager mMidiManager;
+
+    // MidiDeviceInfo for the device implemented by this server
+    private MidiDeviceInfo mDeviceInfo;
+    private final int mInputPortCount;
+    private final int mOutputPortCount;
+
+    // MidiReceivers for receiving data on our input ports
+    private final MidiReceiver[] mInputPortReceivers;
+
+    // MidiDispatchers for sending data on our output ports
+    private MidiDispatcher[] mOutputPortDispatchers;
+
+    // MidiOutputPorts for clients connected to our input ports
+    private final MidiOutputPort[] mInputPortOutputPorts;
+
+    // List of all MidiInputPorts we created
+    private final CopyOnWriteArrayList<MidiInputPort> mInputPorts
+            = new CopyOnWriteArrayList<MidiInputPort>();
+
+
+    // for reporting device status
+    private final boolean[] mInputPortOpen;
+    private final int[] mOutputPortOpenCount;
+
+    private final CloseGuard mGuard = CloseGuard.get();
+    private boolean mIsClosed;
+
+    private final Callback mCallback;
+
+    private final HashMap<IBinder, PortClient> mPortClients = new HashMap<IBinder, PortClient>();
+    private final HashMap<MidiInputPort, PortClient> mInputPortClients =
+            new HashMap<MidiInputPort, PortClient>();
+
+    public interface Callback {
+        /**
+         * Called to notify when an our device status has changed
+         * @param server the {@link MidiDeviceServer} that changed
+         * @param status the {@link MidiDeviceStatus} for the device
+         */
+        public void onDeviceStatusChanged(MidiDeviceServer server, MidiDeviceStatus status);
+
+        /**
+         * Called to notify when the device is closed
+         */
+        public void onClose();
+    }
+
+    abstract private class PortClient implements IBinder.DeathRecipient {
+        final IBinder mToken;
+
+        PortClient(IBinder token) {
+            mToken = token;
+
+            try {
+                token.linkToDeath(this, 0);
+            } catch (RemoteException e) {
+                close();
+            }
+        }
+
+        abstract void close();
+
+        MidiInputPort getInputPort() {
+            return null;
+        }
+
+        @Override
+        public void binderDied() {
+            close();
+        }
+    }
+
+    private class InputPortClient extends PortClient {
+        private final MidiOutputPort mOutputPort;
+
+        InputPortClient(IBinder token, MidiOutputPort outputPort) {
+            super(token);
+            mOutputPort = outputPort;
+        }
+
+        @Override
+        void close() {
+            mToken.unlinkToDeath(this, 0);
+            synchronized (mInputPortOutputPorts) {
+                int portNumber = mOutputPort.getPortNumber();
+                mInputPortOutputPorts[portNumber] = null;
+                mInputPortOpen[portNumber] = false;
+                updateDeviceStatus();
+            }
+            IoUtils.closeQuietly(mOutputPort);
+        }
+    }
+
+    private class OutputPortClient extends PortClient {
+        private final MidiInputPort mInputPort;
+
+        OutputPortClient(IBinder token, MidiInputPort inputPort) {
+            super(token);
+            mInputPort = inputPort;
+        }
+
+        @Override
+        void close() {
+            mToken.unlinkToDeath(this, 0);
+            int portNumber = mInputPort.getPortNumber();
+            MidiDispatcher dispatcher = mOutputPortDispatchers[portNumber];
+            synchronized (dispatcher) {
+                dispatcher.getSender().disconnect(mInputPort);
+                int openCount = dispatcher.getReceiverCount();
+                mOutputPortOpenCount[portNumber] = openCount;
+                updateDeviceStatus();
+           }
+
+            mInputPorts.remove(mInputPort);
+            IoUtils.closeQuietly(mInputPort);
+        }
+
+        @Override
+        MidiInputPort getInputPort() {
+            return mInputPort;
+        }
+    }
+
+    private static FileDescriptor[] createSeqPacketSocketPair() throws IOException {
+        try {
+            final FileDescriptor fd0 = new FileDescriptor();
+            final FileDescriptor fd1 = new FileDescriptor();
+            Os.socketpair(OsConstants.AF_UNIX, OsConstants.SOCK_SEQPACKET, 0, fd0, fd1);
+            return new FileDescriptor[] { fd0, fd1 };
+        } catch (ErrnoException e) {
+            throw e.rethrowAsIOException();
+        }
+    }
+
+    // Binder interface stub for receiving connection requests from clients
+    private final IMidiDeviceServer mServer = new IMidiDeviceServer.Stub() {
+
+        @Override
+        public FileDescriptor openInputPort(IBinder token, int portNumber) {
+            if (mDeviceInfo.isPrivate()) {
+                if (Binder.getCallingUid() != Process.myUid()) {
+                    throw new SecurityException("Can't access private device from different UID");
+                }
+            }
+
+            if (portNumber < 0 || portNumber >= mInputPortCount) {
+                Log.e(TAG, "portNumber out of range in openInputPort: " + portNumber);
+                return null;
+            }
+
+            synchronized (mInputPortOutputPorts) {
+                if (mInputPortOutputPorts[portNumber] != null) {
+                    Log.d(TAG, "port " + portNumber + " already open");
+                    return null;
+                }
+
+                try {
+                    FileDescriptor[] pair = createSeqPacketSocketPair();
+                    MidiOutputPort outputPort = new MidiOutputPort(pair[0], portNumber);
+                    mInputPortOutputPorts[portNumber] = outputPort;
+                    outputPort.connect(mInputPortReceivers[portNumber]);
+                    InputPortClient client = new InputPortClient(token, outputPort);
+                    synchronized (mPortClients) {
+                        mPortClients.put(token, client);
+                    }
+                    mInputPortOpen[portNumber] = true;
+                    updateDeviceStatus();
+                    return pair[1];
+                } catch (IOException e) {
+                    Log.e(TAG, "unable to create FileDescriptors in openInputPort");
+                    return null;
+                }
+            }
+        }
+
+        @Override
+        public FileDescriptor openOutputPort(IBinder token, int portNumber) {
+            if (mDeviceInfo.isPrivate()) {
+                if (Binder.getCallingUid() != Process.myUid()) {
+                    throw new SecurityException("Can't access private device from different UID");
+                }
+            }
+
+            if (portNumber < 0 || portNumber >= mOutputPortCount) {
+                Log.e(TAG, "portNumber out of range in openOutputPort: " + portNumber);
+                return null;
+            }
+
+            try {
+                FileDescriptor[] pair = createSeqPacketSocketPair();
+                MidiInputPort inputPort = new MidiInputPort(pair[0], portNumber);
+                // Undo the default blocking-mode of the server-side socket for
+                // physical devices to avoid stalling the Java device handler if
+                // client app code gets stuck inside 'onSend' handler.
+                if (mDeviceInfo.getType() != MidiDeviceInfo.TYPE_VIRTUAL) {
+                    IoUtils.setBlocking(pair[0], false);
+                }
+                MidiDispatcher dispatcher = mOutputPortDispatchers[portNumber];
+                synchronized (dispatcher) {
+                    dispatcher.getSender().connect(inputPort);
+                    int openCount = dispatcher.getReceiverCount();
+                    mOutputPortOpenCount[portNumber] = openCount;
+                    updateDeviceStatus();
+                }
+
+                mInputPorts.add(inputPort);
+                OutputPortClient client = new OutputPortClient(token, inputPort);
+                synchronized (mPortClients) {
+                    mPortClients.put(token, client);
+                }
+                synchronized (mInputPortClients) {
+                    mInputPortClients.put(inputPort, client);
+                }
+                return pair[1];
+            } catch (IOException e) {
+                Log.e(TAG, "unable to create FileDescriptors in openOutputPort");
+                return null;
+            }
+        }
+
+        @Override
+        public void closePort(IBinder token) {
+            MidiInputPort inputPort = null;
+            synchronized (mPortClients) {
+                PortClient client = mPortClients.remove(token);
+                if (client != null) {
+                    inputPort = client.getInputPort();
+                    client.close();
+                }
+            }
+            if (inputPort != null) {
+                synchronized (mInputPortClients) {
+                    mInputPortClients.remove(inputPort);
+                }
+            }
+        }
+
+        @Override
+        public void closeDevice() {
+            if (mCallback != null) {
+                mCallback.onClose();
+            }
+            IoUtils.closeQuietly(MidiDeviceServer.this);
+        }
+
+        @Override
+        public int connectPorts(IBinder token, FileDescriptor fd,
+                int outputPortNumber) {
+            MidiInputPort inputPort = new MidiInputPort(fd, outputPortNumber);
+            MidiDispatcher dispatcher = mOutputPortDispatchers[outputPortNumber];
+            synchronized (dispatcher) {
+                dispatcher.getSender().connect(inputPort);
+                int openCount = dispatcher.getReceiverCount();
+                mOutputPortOpenCount[outputPortNumber] = openCount;
+                updateDeviceStatus();
+            }
+
+            mInputPorts.add(inputPort);
+            OutputPortClient client = new OutputPortClient(token, inputPort);
+            synchronized (mPortClients) {
+                mPortClients.put(token, client);
+            }
+            synchronized (mInputPortClients) {
+                mInputPortClients.put(inputPort, client);
+            }
+            return Process.myPid(); // for caller to detect same process ID
+        }
+
+        @Override
+        public MidiDeviceInfo getDeviceInfo() {
+            return mDeviceInfo;
+        }
+
+        @Override
+        public void setDeviceInfo(MidiDeviceInfo deviceInfo) {
+            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
+                throw new SecurityException("setDeviceInfo should only be called by MidiService");
+            }
+            if (mDeviceInfo != null) {
+                throw new IllegalStateException("setDeviceInfo should only be called once");
+            }
+            mDeviceInfo = deviceInfo;
+        }
+    };
+
+    // Constructor for MidiManager.createDeviceServer()
+    /* package */ MidiDeviceServer(IMidiManager midiManager, MidiReceiver[] inputPortReceivers,
+            int numOutputPorts, Callback callback) {
+        mMidiManager = midiManager;
+        mInputPortReceivers = inputPortReceivers;
+        mInputPortCount = inputPortReceivers.length;
+        mOutputPortCount = numOutputPorts;
+        mCallback = callback;
+
+        mInputPortOutputPorts = new MidiOutputPort[mInputPortCount];
+
+        mOutputPortDispatchers = new MidiDispatcher[numOutputPorts];
+        for (int i = 0; i < numOutputPorts; i++) {
+            mOutputPortDispatchers[i] = new MidiDispatcher(mInputPortFailureHandler);
+        }
+
+        mInputPortOpen = new boolean[mInputPortCount];
+        mOutputPortOpenCount = new int[numOutputPorts];
+
+        mGuard.open("close");
+    }
+
+    private final MidiDispatcher.MidiReceiverFailureHandler mInputPortFailureHandler =
+            new MidiDispatcher.MidiReceiverFailureHandler() {
+                public void onReceiverFailure(MidiReceiver receiver, IOException failure) {
+                    Log.e(TAG, "MidiInputPort failed to send data", failure);
+                    PortClient client = null;
+                    synchronized (mInputPortClients) {
+                        client = mInputPortClients.remove(receiver);
+                    }
+                    if (client != null) {
+                        client.close();
+                    }
+                }
+            };
+
+    // Constructor for MidiDeviceService.onCreate()
+    /* package */ MidiDeviceServer(IMidiManager midiManager, MidiReceiver[] inputPortReceivers,
+           MidiDeviceInfo deviceInfo, Callback callback) {
+        this(midiManager, inputPortReceivers, deviceInfo.getOutputPortCount(), callback);
+        mDeviceInfo = deviceInfo;
+    }
+
+    /* package */ IMidiDeviceServer getBinderInterface() {
+        return mServer;
+    }
+
+    public IBinder asBinder() {
+        return mServer.asBinder();
+    }
+
+    private void updateDeviceStatus() {
+        // clear calling identity, since we may be in a Binder call from one of our clients
+        final long identityToken = Binder.clearCallingIdentity();
+        try {
+            MidiDeviceStatus status = new MidiDeviceStatus(mDeviceInfo, mInputPortOpen,
+                    mOutputPortOpenCount);
+            if (mCallback != null) {
+                mCallback.onDeviceStatusChanged(this, status);
+            }
+
+            mMidiManager.setDeviceStatus(mServer, status);
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in updateDeviceStatus");
+        } finally {
+            Binder.restoreCallingIdentity(identityToken);
+        }
+    }
+
+    @Override
+    public void close() throws IOException {
+        synchronized (mGuard) {
+            if (mIsClosed) return;
+            mGuard.close();
+
+            for (int i = 0; i < mInputPortCount; i++) {
+                MidiOutputPort outputPort = mInputPortOutputPorts[i];
+                if (outputPort != null) {
+                    IoUtils.closeQuietly(outputPort);
+                    mInputPortOutputPorts[i] = null;
+                }
+            }
+            for (MidiInputPort inputPort : mInputPorts) {
+                IoUtils.closeQuietly(inputPort);
+            }
+            mInputPorts.clear();
+            try {
+                mMidiManager.unregisterDeviceServer(mServer);
+            } catch (RemoteException e) {
+                Log.e(TAG, "RemoteException in unregisterDeviceServer");
+            }
+            mIsClosed = true;
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+            }
+
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Returns an array of {@link MidiReceiver} for the device's output ports.
+     * Clients can use these receivers to send data out the device's output ports.
+     * @return array of MidiReceivers
+     */
+    public MidiReceiver[] getOutputPortReceivers() {
+        MidiReceiver[] receivers = new MidiReceiver[mOutputPortCount];
+        System.arraycopy(mOutputPortDispatchers, 0, receivers, 0, mOutputPortCount);
+        return receivers;
+    }
+}
diff --git a/android/media/midi/MidiDeviceService.java b/android/media/midi/MidiDeviceService.java
new file mode 100644
index 0000000..388d95b
--- /dev/null
+++ b/android/media/midi/MidiDeviceService.java
@@ -0,0 +1,145 @@
+/*
+ * Copyright (C) 2015 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.midi;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+
+/**
+ * A service that implements a virtual MIDI device.
+ * Subclasses must implement the {@link #onGetInputPortReceivers} method to provide a
+ * list of {@link MidiReceiver}s to receive data sent to the device's input ports.
+ * Similarly, subclasses can call {@link #getOutputPortReceivers} to fetch a list
+ * of {@link MidiReceiver}s for sending data out the output ports.
+ *
+ * <p>To extend this class, you must declare the service in your manifest file with
+ * an intent filter with the {@link #SERVICE_INTERFACE} action
+ * and meta-data to describe the virtual device.
+ For example:</p>
+ * <pre>
+ * &lt;service android:name=".VirtualDeviceService"
+ *          android:label="&#64;string/service_name">
+ *     &lt;intent-filter>
+ *         &lt;action android:name="android.media.midi.MidiDeviceService" />
+ *     &lt;/intent-filter>
+ *           &lt;meta-data android:name="android.media.midi.MidiDeviceService"
+                android:resource="@xml/device_info" />
+ * &lt;/service></pre>
+ */
+abstract public class MidiDeviceService extends Service {
+    private static final String TAG = "MidiDeviceService";
+
+    public static final String SERVICE_INTERFACE = "android.media.midi.MidiDeviceService";
+
+    private IMidiManager mMidiManager;
+    private MidiDeviceServer mServer;
+    private MidiDeviceInfo mDeviceInfo;
+
+    private final MidiDeviceServer.Callback mCallback = new MidiDeviceServer.Callback() {
+        @Override
+        public void onDeviceStatusChanged(MidiDeviceServer server, MidiDeviceStatus status) {
+            MidiDeviceService.this.onDeviceStatusChanged(status);
+        }
+
+        @Override
+        public void onClose() {
+            MidiDeviceService.this.onClose();
+        }
+    };
+
+    @Override
+    public void onCreate() {
+        mMidiManager = IMidiManager.Stub.asInterface(
+                    ServiceManager.getService(Context.MIDI_SERVICE));
+        MidiDeviceServer server;
+        try {
+            MidiDeviceInfo deviceInfo = mMidiManager.getServiceDeviceInfo(getPackageName(),
+                    this.getClass().getName());
+            if (deviceInfo == null) {
+                Log.e(TAG, "Could not find MidiDeviceInfo for MidiDeviceService " + this);
+                return;
+            }
+            mDeviceInfo = deviceInfo;
+            MidiReceiver[] inputPortReceivers = onGetInputPortReceivers();
+            if (inputPortReceivers == null) {
+                inputPortReceivers = new MidiReceiver[0];
+            }
+            server = new MidiDeviceServer(mMidiManager, inputPortReceivers, deviceInfo, mCallback);
+        } catch (RemoteException e) {
+            Log.e(TAG, "RemoteException in IMidiManager.getServiceDeviceInfo");
+            server = null;
+        }
+        mServer = server;
+   }
+
+    /**
+     * Returns an array of {@link MidiReceiver} for the device's input ports.
+     * Subclasses must override this to provide the receivers which will receive
+     * data sent to the device's input ports. An empty array should be returned if
+     * the device has no input ports.
+     * @return array of MidiReceivers
+     */
+    abstract public MidiReceiver[] onGetInputPortReceivers();
+
+    /**
+     * Returns an array of {@link MidiReceiver} for the device's output ports.
+     * These can be used to send data out the device's output ports.
+     * @return array of MidiReceivers
+     */
+    public final MidiReceiver[] getOutputPortReceivers() {
+        if (mServer == null) {
+            return null;
+        } else {
+            return mServer.getOutputPortReceivers();
+        }
+    }
+
+    /**
+     * returns the {@link MidiDeviceInfo} instance for this service
+     * @return our MidiDeviceInfo
+     */
+    public final MidiDeviceInfo getDeviceInfo() {
+        return mDeviceInfo;
+    }
+
+    /**
+     * Called to notify when an our {@link MidiDeviceStatus} has changed
+     * @param status the number of the port that was opened
+     */
+    public void onDeviceStatusChanged(MidiDeviceStatus status) {
+    }
+
+    /**
+     * Called to notify when our device has been closed by all its clients
+     */
+    public void onClose() {
+    }
+
+    @Override
+    public IBinder onBind(Intent intent) {
+        if (SERVICE_INTERFACE.equals(intent.getAction()) && mServer != null) {
+             return mServer.getBinderInterface().asBinder();
+        } else {
+             return null;
+       }
+    }
+}
diff --git a/android/media/midi/MidiDeviceStatus.java b/android/media/midi/MidiDeviceStatus.java
new file mode 100644
index 0000000..b118279
--- /dev/null
+++ b/android/media/midi/MidiDeviceStatus.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright (C) 2015 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.midi;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * This is an immutable class that describes the current status of a MIDI device's ports.
+ */
+public final class MidiDeviceStatus implements Parcelable {
+
+    private static final String TAG = "MidiDeviceStatus";
+
+    private final MidiDeviceInfo mDeviceInfo;
+    // true if input ports are open
+    private final boolean mInputPortOpen[];
+    // open counts for output ports
+    private final int mOutputPortOpenCount[];
+
+    /**
+     * @hide
+     */
+    public MidiDeviceStatus(MidiDeviceInfo deviceInfo, boolean inputPortOpen[],
+            int outputPortOpenCount[]) {
+        // MidiDeviceInfo is immutable so we can share references
+        mDeviceInfo = deviceInfo;
+
+        // make copies of the arrays
+        mInputPortOpen = new boolean[inputPortOpen.length];
+        System.arraycopy(inputPortOpen, 0, mInputPortOpen, 0, inputPortOpen.length);
+        mOutputPortOpenCount = new int[outputPortOpenCount.length];
+        System.arraycopy(outputPortOpenCount, 0, mOutputPortOpenCount, 0,
+                outputPortOpenCount.length);
+    }
+
+    /**
+     * Creates a MidiDeviceStatus with zero for all port open counts
+     * @hide
+     */
+    public MidiDeviceStatus(MidiDeviceInfo deviceInfo) {
+        mDeviceInfo = deviceInfo;
+        mInputPortOpen = new boolean[deviceInfo.getInputPortCount()];
+        mOutputPortOpenCount = new int[deviceInfo.getOutputPortCount()];
+    }
+
+    /**
+     * Returns the {@link MidiDeviceInfo} of the device.
+     *
+     * @return the device info
+     */
+    public MidiDeviceInfo getDeviceInfo() {
+        return mDeviceInfo;
+    }
+
+    /**
+     * Returns true if an input port is open.
+     * An input port can only be opened by one client at a time.
+     *
+     * @param portNumber the input port's port number
+     * @return input port open status
+     */
+    public boolean isInputPortOpen(int portNumber) {
+        return mInputPortOpen[portNumber];
+    }
+
+    /**
+     * Returns the number of clients currently connected to the specified output port.
+     * Unlike input ports, an output port can be opened by multiple clients at the same time.
+     *
+     * @param portNumber the output port's port number
+     * @return output port open count
+     */
+    public int getOutputPortOpenCount(int portNumber) {
+        return mOutputPortOpenCount[portNumber];
+    }
+
+    @Override
+    public String toString() {
+        int inputPortCount = mDeviceInfo.getInputPortCount();
+        int outputPortCount = mDeviceInfo.getOutputPortCount();
+        StringBuilder builder = new StringBuilder("mInputPortOpen=[");
+        for (int i = 0; i < inputPortCount; i++) {
+            builder.append(mInputPortOpen[i]);
+            if (i < inputPortCount -1) {
+                builder.append(",");
+            }
+        }
+        builder.append("] mOutputPortOpenCount=[");
+        for (int i = 0; i < outputPortCount; i++) {
+            builder.append(mOutputPortOpenCount[i]);
+            if (i < outputPortCount -1) {
+                builder.append(",");
+            }
+        }
+        builder.append("]");
+        return builder.toString();
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<MidiDeviceStatus> CREATOR =
+        new Parcelable.Creator<MidiDeviceStatus>() {
+        public MidiDeviceStatus createFromParcel(Parcel in) {
+            ClassLoader classLoader = MidiDeviceInfo.class.getClassLoader();
+            MidiDeviceInfo deviceInfo = in.readParcelable(classLoader);
+            boolean[] inputPortOpen = in.createBooleanArray();
+            int[] outputPortOpenCount = in.createIntArray();
+            return new MidiDeviceStatus(deviceInfo, inputPortOpen, outputPortOpenCount);
+        }
+
+        public MidiDeviceStatus[] newArray(int size) {
+            return new MidiDeviceStatus[size];
+        }
+    };
+
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeParcelable(mDeviceInfo, flags);
+        parcel.writeBooleanArray(mInputPortOpen);
+        parcel.writeIntArray(mOutputPortOpenCount);
+   }
+}
diff --git a/android/media/midi/MidiInputPort.java b/android/media/midi/MidiInputPort.java
new file mode 100644
index 0000000..a300886
--- /dev/null
+++ b/android/media/midi/MidiInputPort.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright (C) 2014 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.midi;
+
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import dalvik.system.CloseGuard;
+
+import libcore.io.IoUtils;
+
+import java.io.Closeable;
+import java.io.FileDescriptor;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * This class is used for sending data to a port on a MIDI device
+ */
+public final class MidiInputPort extends MidiReceiver implements Closeable {
+    private static final String TAG = "MidiInputPort";
+
+    private IMidiDeviceServer mDeviceServer;
+    private final IBinder mToken;
+    private final int mPortNumber;
+    private FileDescriptor mFileDescriptor;
+    private FileOutputStream mOutputStream;
+
+    private final CloseGuard mGuard = CloseGuard.get();
+    private boolean mIsClosed;
+
+    // buffer to use for sending data out our output stream
+    private final byte[] mBuffer = new byte[MidiPortImpl.MAX_PACKET_SIZE];
+
+    /* package */ MidiInputPort(IMidiDeviceServer server, IBinder token,
+            FileDescriptor fd, int portNumber) {
+        super(MidiPortImpl.MAX_PACKET_DATA_SIZE);
+
+        mDeviceServer = server;
+        mToken = token;
+        mFileDescriptor = fd;
+        mPortNumber = portNumber;
+        mOutputStream = new FileOutputStream(fd);
+        mGuard.open("close");
+    }
+
+    /* package */ MidiInputPort(FileDescriptor fd, int portNumber) {
+        this(null, null, fd, portNumber);
+    }
+
+    /**
+     * Returns the port number of this port
+     *
+     * @return the port's port number
+     */
+    public final int getPortNumber() {
+        return mPortNumber;
+    }
+
+    @Override
+    public void onSend(byte[] msg, int offset, int count, long timestamp) throws IOException {
+        if (offset < 0 || count < 0 || offset + count > msg.length) {
+            throw new IllegalArgumentException("offset or count out of range");
+        }
+        if (count > MidiPortImpl.MAX_PACKET_DATA_SIZE) {
+            throw new IllegalArgumentException("count exceeds max message size");
+        }
+
+        synchronized (mBuffer) {
+            if (mOutputStream == null) {
+                throw new IOException("MidiInputPort is closed");
+            }
+            int length = MidiPortImpl.packData(msg, offset, count, timestamp, mBuffer);
+            mOutputStream.write(mBuffer, 0, length);
+        }
+    }
+
+    @Override
+    public void onFlush() throws IOException {
+        synchronized (mBuffer) {
+            if (mOutputStream == null) {
+                throw new IOException("MidiInputPort is closed");
+            }
+            int length = MidiPortImpl.packFlush(mBuffer);
+            mOutputStream.write(mBuffer, 0, length);
+        }
+    }
+
+    // used by MidiDevice.connectInputPort() to connect our socket directly to another device
+    /* package */ FileDescriptor claimFileDescriptor() {
+        synchronized (mGuard) {
+            FileDescriptor fd;
+            synchronized (mBuffer) {
+                fd = mFileDescriptor;
+                if (fd == null) return null;
+                IoUtils.closeQuietly(mOutputStream);
+                mFileDescriptor = null;
+                mOutputStream = null;
+            }
+
+            // Set mIsClosed = true so we will not call mDeviceServer.closePort() in close().
+            // MidiDevice.MidiConnection.close() will do the cleanup instead.
+            mIsClosed = true;
+            return fd;
+        }
+    }
+
+    // used by MidiDevice.MidiConnection to close this port after the connection is closed
+    /* package */ IBinder getToken() {
+        return mToken;
+    }
+
+    // used by MidiDevice.MidiConnection to close this port after the connection is closed
+    /* package */ IMidiDeviceServer getDeviceServer() {
+        return mDeviceServer;
+    }
+
+    @Override
+    public void close() throws IOException {
+        synchronized (mGuard) {
+            if (mIsClosed) return;
+            mGuard.close();
+            synchronized (mBuffer) {
+                if (mFileDescriptor != null) {
+                    IoUtils.closeQuietly(mFileDescriptor);
+                    mFileDescriptor = null;
+                }
+                if (mOutputStream != null) {
+                    mOutputStream.close();
+                    mOutputStream = null;
+                }
+            }
+            if (mDeviceServer != null) {
+                try {
+                    mDeviceServer.closePort(mToken);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoteException in MidiInputPort.close()");
+                }
+            }
+            mIsClosed = true;
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+            }
+
+            // not safe to make binder calls from finalize()
+            mDeviceServer = null;
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+}
diff --git a/android/media/midi/MidiManager.java b/android/media/midi/MidiManager.java
new file mode 100644
index 0000000..dee94c6
--- /dev/null
+++ b/android/media/midi/MidiManager.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2014 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.midi;
+
+import android.annotation.RequiresFeature;
+import android.annotation.SystemService;
+import android.bluetooth.BluetoothDevice;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * This class is the public application interface to the MIDI service.
+ */
+@SystemService(Context.MIDI_SERVICE)
+@RequiresFeature(PackageManager.FEATURE_MIDI)
+public final class MidiManager {
+    private static final String TAG = "MidiManager";
+
+    /**
+     * Intent for starting BluetoothMidiService
+     * @hide
+     */
+    public static final String BLUETOOTH_MIDI_SERVICE_INTENT =
+                "android.media.midi.BluetoothMidiService";
+
+    /**
+     * BluetoothMidiService package name
+     * @hide
+     */
+    public static final String BLUETOOTH_MIDI_SERVICE_PACKAGE = "com.android.bluetoothmidiservice";
+
+    /**
+     * BluetoothMidiService class name
+     * @hide
+     */
+    public static final String BLUETOOTH_MIDI_SERVICE_CLASS =
+                "com.android.bluetoothmidiservice.BluetoothMidiService";
+
+    private final IMidiManager mService;
+    private final IBinder mToken = new Binder();
+
+    private ConcurrentHashMap<DeviceCallback,DeviceListener> mDeviceListeners =
+        new ConcurrentHashMap<DeviceCallback,DeviceListener>();
+
+    // Binder stub for receiving device notifications from MidiService
+    private class DeviceListener extends IMidiDeviceListener.Stub {
+        private final DeviceCallback mCallback;
+        private final Handler mHandler;
+
+        public DeviceListener(DeviceCallback callback, Handler handler) {
+            mCallback = callback;
+            mHandler = handler;
+        }
+
+        @Override
+        public void onDeviceAdded(MidiDeviceInfo device) {
+            if (mHandler != null) {
+                final MidiDeviceInfo deviceF = device;
+                mHandler.post(new Runnable() {
+                        @Override public void run() {
+                            mCallback.onDeviceAdded(deviceF);
+                        }
+                    });
+            } else {
+                mCallback.onDeviceAdded(device);
+            }
+        }
+
+        @Override
+        public void onDeviceRemoved(MidiDeviceInfo device) {
+            if (mHandler != null) {
+                final MidiDeviceInfo deviceF = device;
+                mHandler.post(new Runnable() {
+                        @Override public void run() {
+                            mCallback.onDeviceRemoved(deviceF);
+                        }
+                    });
+            } else {
+                mCallback.onDeviceRemoved(device);
+            }
+        }
+
+        @Override
+        public void onDeviceStatusChanged(MidiDeviceStatus status) {
+            if (mHandler != null) {
+                final MidiDeviceStatus statusF = status;
+                mHandler.post(new Runnable() {
+                        @Override public void run() {
+                            mCallback.onDeviceStatusChanged(statusF);
+                        }
+                    });
+            } else {
+                mCallback.onDeviceStatusChanged(status);
+            }
+        }
+    }
+
+    /**
+     * Callback class used for clients to receive MIDI device added and removed notifications
+     */
+    public static class DeviceCallback {
+        /**
+         * Called to notify when a new MIDI device has been added
+         *
+         * @param device a {@link MidiDeviceInfo} for the newly added device
+         */
+        public void onDeviceAdded(MidiDeviceInfo device) {
+        }
+
+        /**
+         * Called to notify when a MIDI device has been removed
+         *
+         * @param device a {@link MidiDeviceInfo} for the removed device
+         */
+        public void onDeviceRemoved(MidiDeviceInfo device) {
+        }
+
+        /**
+         * Called to notify when the status of a MIDI device has changed
+         *
+         * @param status a {@link MidiDeviceStatus} for the changed device
+         */
+        public void onDeviceStatusChanged(MidiDeviceStatus status) {
+        }
+    }
+
+    /**
+     * Listener class used for receiving the results of {@link #openDevice} and
+     * {@link #openBluetoothDevice}
+     */
+    public interface OnDeviceOpenedListener {
+        /**
+         * Called to respond to a {@link #openDevice} request
+         *
+         * @param device a {@link MidiDevice} for opened device, or null if opening failed
+         */
+        abstract public void onDeviceOpened(MidiDevice device);
+    }
+
+    /**
+     * @hide
+     */
+    public MidiManager(IMidiManager service) {
+        mService = service;
+    }
+
+    /**
+     * Registers a callback to receive notifications when MIDI devices are added and removed.
+     *
+     * The {@link  DeviceCallback#onDeviceStatusChanged} method will be called immediately
+     * for any devices that have open ports. This allows applications to know which input
+     * ports are already in use and, therefore, unavailable.
+     *
+     * Applications should call {@link #getDevices} before registering the callback
+     * to get a list of devices already added.
+     *
+     * @param callback a {@link DeviceCallback} for MIDI device notifications
+     * @param handler The {@link android.os.Handler Handler} that will be used for delivering the
+     *                device notifications. If handler is null, then the thread used for the
+     *                callback is unspecified.
+     */
+    public void registerDeviceCallback(DeviceCallback callback, Handler handler) {
+        DeviceListener deviceListener = new DeviceListener(callback, handler);
+        try {
+            mService.registerListener(mToken, deviceListener);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        mDeviceListeners.put(callback, deviceListener);
+    }
+
+    /**
+     * Unregisters a {@link DeviceCallback}.
+      *
+     * @param callback a {@link DeviceCallback} to unregister
+     */
+    public void unregisterDeviceCallback(DeviceCallback callback) {
+        DeviceListener deviceListener = mDeviceListeners.remove(callback);
+        if (deviceListener != null) {
+            try {
+                mService.unregisterListener(mToken, deviceListener);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * Gets the list of all connected MIDI devices.
+     *
+     * @return an array of all MIDI devices
+     */
+    public MidiDeviceInfo[] getDevices() {
+        try {
+           return mService.getDevices();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    private void sendOpenDeviceResponse(final MidiDevice device,
+            final OnDeviceOpenedListener listener, Handler handler) {
+        if (handler != null) {
+            handler.post(new Runnable() {
+                    @Override public void run() {
+                        listener.onDeviceOpened(device);
+                    }
+                });
+        } else {
+            listener.onDeviceOpened(device);
+        }
+    }
+
+    /**
+     * Opens a MIDI device for reading and writing.
+     *
+     * @param deviceInfo a {@link android.media.midi.MidiDeviceInfo} to open
+     * @param listener a {@link MidiManager.OnDeviceOpenedListener} to be called
+     *                 to receive the result
+     * @param handler the {@link android.os.Handler Handler} that will be used for delivering
+     *                the result. If handler is null, then the thread used for the
+     *                listener is unspecified.
+     */
+    public void openDevice(MidiDeviceInfo deviceInfo, OnDeviceOpenedListener listener,
+            Handler handler) {
+        final MidiDeviceInfo deviceInfoF = deviceInfo;
+        final OnDeviceOpenedListener listenerF = listener;
+        final Handler handlerF = handler;
+
+        IMidiDeviceOpenCallback callback = new IMidiDeviceOpenCallback.Stub() {
+            @Override
+            public void onDeviceOpened(IMidiDeviceServer server, IBinder deviceToken) {
+                MidiDevice device;
+                if (server != null) {
+                    device = new MidiDevice(deviceInfoF, server, mService, mToken, deviceToken);
+                } else {
+                    device = null;
+                }
+                sendOpenDeviceResponse(device, listenerF, handlerF);
+            }
+        };
+
+        try {
+            mService.openDevice(mToken, deviceInfo, callback);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Opens a Bluetooth MIDI device for reading and writing.
+     *
+     * @param bluetoothDevice a {@link android.bluetooth.BluetoothDevice} to open as a MIDI device
+     * @param listener a {@link MidiManager.OnDeviceOpenedListener} to be called to receive the
+     * result
+     * @param handler the {@link android.os.Handler Handler} that will be used for delivering
+     *                the result. If handler is null, then the thread used for the
+     *                listener is unspecified.
+     */
+    public void openBluetoothDevice(BluetoothDevice bluetoothDevice,
+            OnDeviceOpenedListener listener, Handler handler) {
+        final OnDeviceOpenedListener listenerF = listener;
+        final Handler handlerF = handler;
+
+        IMidiDeviceOpenCallback callback = new IMidiDeviceOpenCallback.Stub() {
+            @Override
+            public void onDeviceOpened(IMidiDeviceServer server, IBinder deviceToken) {
+                MidiDevice device = null;
+                if (server != null) {
+                    try {
+                        // fetch MidiDeviceInfo from the server
+                        MidiDeviceInfo deviceInfo = server.getDeviceInfo();
+                        device = new MidiDevice(deviceInfo, server, mService, mToken, deviceToken);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "remote exception in getDeviceInfo()");
+                    }
+                }
+                sendOpenDeviceResponse(device, listenerF, handlerF);
+            }
+        };
+
+        try {
+            mService.openBluetoothDevice(mToken, bluetoothDevice, callback);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /** @hide */
+    public MidiDeviceServer createDeviceServer(MidiReceiver[] inputPortReceivers,
+            int numOutputPorts, String[] inputPortNames, String[] outputPortNames,
+            Bundle properties, int type, MidiDeviceServer.Callback callback) {
+        try {
+            MidiDeviceServer server = new MidiDeviceServer(mService, inputPortReceivers,
+                    numOutputPorts, callback);
+            MidiDeviceInfo deviceInfo = mService.registerDeviceServer(server.getBinderInterface(),
+                    inputPortReceivers.length, numOutputPorts, inputPortNames, outputPortNames,
+                    properties, type);
+            if (deviceInfo == null) {
+                Log.e(TAG, "registerVirtualDevice failed");
+                return null;
+            }
+            return server;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+}
diff --git a/android/media/midi/MidiOutputPort.java b/android/media/midi/MidiOutputPort.java
new file mode 100644
index 0000000..5411e66
--- /dev/null
+++ b/android/media/midi/MidiOutputPort.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2014 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.midi;
+
+import android.os.IBinder;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.midi.MidiDispatcher;
+
+import dalvik.system.CloseGuard;
+
+import libcore.io.IoUtils;
+
+import java.io.Closeable;
+import java.io.FileDescriptor;
+import java.io.FileInputStream;
+import java.io.IOException;
+
+/**
+ * This class is used for receiving data from a port on a MIDI device
+ */
+public final class MidiOutputPort extends MidiSender implements Closeable {
+    private static final String TAG = "MidiOutputPort";
+
+    private IMidiDeviceServer mDeviceServer;
+    private final IBinder mToken;
+    private final int mPortNumber;
+    private final FileInputStream mInputStream;
+    private final MidiDispatcher mDispatcher = new MidiDispatcher();
+
+    private final CloseGuard mGuard = CloseGuard.get();
+    private boolean mIsClosed;
+
+    // This thread reads MIDI events from a socket and distributes them to the list of
+    // MidiReceivers attached to this device.
+    private final Thread mThread = new Thread() {
+        @Override
+        public void run() {
+            byte[] buffer = new byte[MidiPortImpl.MAX_PACKET_SIZE];
+
+            try {
+                while (true) {
+                    // read next event
+                    int count = mInputStream.read(buffer);
+                    if (count < 0) {
+                        // This is the exit condition as read() returning <0 indicates
+                        // that the pipe has been closed.
+                        break;
+                        // FIXME - inform receivers here?
+                    }
+
+                    int packetType = MidiPortImpl.getPacketType(buffer, count);
+                    switch (packetType) {
+                        case MidiPortImpl.PACKET_TYPE_DATA: {
+                            int offset = MidiPortImpl.getDataOffset(buffer, count);
+                            int size = MidiPortImpl.getDataSize(buffer, count);
+                            long timestamp = MidiPortImpl.getPacketTimestamp(buffer, count);
+
+                            // dispatch to all our receivers
+                            mDispatcher.send(buffer, offset, size, timestamp);
+                            break;
+                        }
+                        case MidiPortImpl.PACKET_TYPE_FLUSH:
+                            mDispatcher.flush();
+                            break;
+                        default:
+                            Log.e(TAG, "Unknown packet type " + packetType);
+                            break;
+                    }
+                } // while (true)
+            } catch (IOException e) {
+                // FIXME report I/O failure?
+                // TODO: The comment above about the exit condition is not currently working
+                // as intended. The read from the closed pipe is throwing an error rather than
+                // returning <0, so this becomes (probably) not an error, but the exit case.
+                // This warrants further investigation;
+                // Silence the (probably) spurious error message.
+                // Log.e(TAG, "read failed", e);
+            } finally {
+                IoUtils.closeQuietly(mInputStream);
+            }
+        }
+    };
+
+    /* package */ MidiOutputPort(IMidiDeviceServer server, IBinder token,
+            FileDescriptor fd, int portNumber) {
+        mDeviceServer = server;
+        mToken = token;
+        mPortNumber = portNumber;
+        mInputStream = new ParcelFileDescriptor.AutoCloseInputStream(new ParcelFileDescriptor(fd));
+        mThread.start();
+        mGuard.open("close");
+    }
+
+    /* package */ MidiOutputPort(FileDescriptor fd, int portNumber) {
+        this(null, null, fd, portNumber);
+    }
+
+    /**
+     * Returns the port number of this port
+     *
+     * @return the port's port number
+     */
+    public final int getPortNumber() {
+        return mPortNumber;
+    }
+
+    @Override
+    public void onConnect(MidiReceiver receiver) {
+        mDispatcher.getSender().connect(receiver);
+    }
+
+    @Override
+    public void onDisconnect(MidiReceiver receiver) {
+        mDispatcher.getSender().disconnect(receiver);
+    }
+
+    @Override
+    public void close() throws IOException {
+        synchronized (mGuard) {
+            if (mIsClosed) return;
+
+            mGuard.close();
+            mInputStream.close();
+            if (mDeviceServer != null) {
+                try {
+                    mDeviceServer.closePort(mToken);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "RemoteException in MidiOutputPort.close()");
+                }
+            }
+            mIsClosed = true;
+        }
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mGuard != null) {
+                mGuard.warnIfOpen();
+            }
+
+            // not safe to make binder calls from finalize()
+            mDeviceServer = null;
+            close();
+        } finally {
+            super.finalize();
+        }
+    }
+}
diff --git a/android/media/midi/MidiPortImpl.java b/android/media/midi/MidiPortImpl.java
new file mode 100644
index 0000000..1cd9ed2
--- /dev/null
+++ b/android/media/midi/MidiPortImpl.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2014 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.midi;
+
+/**
+ * This class contains utilities for socket communication between a
+ * MidiInputPort and MidiOutputPort
+ */
+/* package */ class MidiPortImpl {
+    private static final String TAG = "MidiPort";
+
+    /**
+     * Packet type for data packet
+     */
+    public static final int PACKET_TYPE_DATA = 1;
+
+    /**
+     * Packet type for flush packet
+     */
+    public static final int PACKET_TYPE_FLUSH = 2;
+
+    /**
+     * Maximum size of a packet that can be passed between processes.
+     */
+    public static final int MAX_PACKET_SIZE = 1024;
+
+    /**
+     * size of message timestamp in bytes
+     */
+    private static final int TIMESTAMP_SIZE = 8;
+
+    /**
+     * Data packet overhead is timestamp size plus packet type byte
+     */
+    private static final int DATA_PACKET_OVERHEAD = TIMESTAMP_SIZE + 1;
+
+    /**
+     * Maximum amount of MIDI data that can be included in a packet
+     */
+    public static final int MAX_PACKET_DATA_SIZE = MAX_PACKET_SIZE - DATA_PACKET_OVERHEAD;
+
+    /**
+     * Utility function for packing MIDI data to be passed between processes
+     *
+     * message byte array contains variable length MIDI message.
+     * messageSize is size of variable length MIDI message
+     * timestamp is message timestamp to pack
+     * dest is buffer to pack into
+     * returns size of packed message
+     */
+    public static int packData(byte[] message, int offset, int size, long timestamp,
+            byte[] dest) {
+        if (size  > MAX_PACKET_DATA_SIZE) {
+            size = MAX_PACKET_DATA_SIZE;
+        }
+        int length = 0;
+        // packet type goes first
+        dest[length++] = PACKET_TYPE_DATA;
+        // data goes next
+        System.arraycopy(message, offset, dest, length, size);
+        length += size;
+
+        // followed by timestamp
+        for (int i = 0; i < TIMESTAMP_SIZE; i++) {
+            dest[length++] = (byte)timestamp;
+            timestamp >>= 8;
+        }
+
+        return length;
+    }
+
+    /**
+     * Utility function for packing a flush command to be passed between processes
+     */
+    public static int packFlush(byte[] dest) {
+        dest[0] = PACKET_TYPE_FLUSH;
+        return 1;
+    }
+
+    /**
+     * Returns the packet type (PACKET_TYPE_DATA or PACKET_TYPE_FLUSH)
+     */
+    public static int getPacketType(byte[] buffer, int bufferLength) {
+        return buffer[0];
+    }
+
+    /**
+     * Utility function for unpacking MIDI data received from other process
+     * returns the offset of the MIDI message in packed buffer
+     */
+    public static int getDataOffset(byte[] buffer, int bufferLength) {
+        // data follows packet type byte
+        return 1;
+    }
+
+    /**
+     * Utility function for unpacking MIDI data received from other process
+     * returns size of MIDI data in packed buffer
+     */
+    public static int getDataSize(byte[] buffer, int bufferLength) {
+        // message length is total buffer length minus size of the timestamp
+        return bufferLength - DATA_PACKET_OVERHEAD;
+    }
+
+    /**
+     * Utility function for unpacking MIDI data received from other process
+     * unpacks timestamp from packed buffer
+     */
+    public static long getPacketTimestamp(byte[] buffer, int bufferLength) {
+        // timestamp is at end of the packet
+        int offset = bufferLength;
+        long timestamp = 0;
+
+        for (int i = 0; i < TIMESTAMP_SIZE; i++) {
+            int b = (int)buffer[--offset] & 0xFF;
+            timestamp = (timestamp << 8) | b;
+        }
+        return timestamp;
+    }
+}
diff --git a/android/media/midi/MidiReceiver.java b/android/media/midi/MidiReceiver.java
new file mode 100644
index 0000000..12a5f04
--- /dev/null
+++ b/android/media/midi/MidiReceiver.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2014 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.midi;
+
+import java.io.IOException;
+
+/**
+ * Interface for sending and receiving data to and from a MIDI device.
+ */
+abstract public class MidiReceiver {
+
+    private final int mMaxMessageSize;
+
+    /**
+     * Default MidiReceiver constructor. Maximum message size is set to
+     * {@link java.lang.Integer#MAX_VALUE}
+     */
+    public MidiReceiver() {
+        mMaxMessageSize = Integer.MAX_VALUE;
+    }
+
+    /**
+     * MidiReceiver constructor.
+     * @param maxMessageSize the maximum size of a message this receiver can receive
+     */
+    public MidiReceiver(int maxMessageSize) {
+        mMaxMessageSize = maxMessageSize;
+    }
+
+    /**
+     * Called whenever the receiver is passed new MIDI data.
+     * Subclasses override this method to receive MIDI data.
+     * May fail if count exceeds {@link #getMaxMessageSize}.
+     *
+     * NOTE: the msg array parameter is only valid within the context of this call.
+     * The msg bytes should be copied by the receiver rather than retaining a reference
+     * to this parameter.
+     * Also, modifying the contents of the msg array parameter may result in other receivers
+     * in the same application receiving incorrect values in their {link #onSend} method.
+     *
+     * @param msg a byte array containing the MIDI data
+     * @param offset the offset of the first byte of the data in the array to be processed
+     * @param count the number of bytes of MIDI data in the array to be processed
+     * @param timestamp the timestamp of the message (based on {@link java.lang.System#nanoTime}
+     * @throws IOException
+     */
+    abstract public void onSend(byte[] msg, int offset, int count, long timestamp)
+            throws IOException;
+
+    /**
+     * Instructs the receiver to discard all pending MIDI data.
+     * @throws IOException
+     */
+    public void flush() throws IOException {
+        onFlush();
+    }
+
+    /**
+     * Called when the receiver is instructed to discard all pending MIDI data.
+     * Subclasses should override this method if they maintain a list or queue of MIDI data
+     * to be processed in the future.
+     * @throws IOException
+     */
+    public void onFlush() throws IOException {
+    }
+
+    /**
+     * Returns the maximum size of a message this receiver can receive.
+     * @return maximum message size
+     */
+    public final int getMaxMessageSize() {
+        return mMaxMessageSize;
+    }
+
+    /**
+     * Called to send MIDI data to the receiver without a timestamp.
+     * Data will be processed by receiver in the order sent.
+     * Data will get split into multiple calls to {@link #onSend} if count exceeds
+     * {@link #getMaxMessageSize}.  Blocks until all the data is sent or an exception occurs.
+     * In the latter case, the amount of data sent prior to the exception is not provided to caller.
+     * The communication should be considered corrupt.  The sender should reestablish
+     * communication, reset all controllers and send all notes off.
+     *
+     * @param msg a byte array containing the MIDI data
+     * @param offset the offset of the first byte of the data in the array to be sent
+     * @param count the number of bytes of MIDI data in the array to be sent
+     * @throws IOException if the data could not be sent in entirety
+     */
+    public void send(byte[] msg, int offset, int count) throws IOException {
+        // TODO add public static final TIMESTAMP_NONE = 0L
+        send(msg, offset, count, 0L);
+    }
+
+    /**
+     * Called to send MIDI data to the receiver with a specified timestamp.
+     * Data will be processed by receiver in order first by timestamp, then in the order sent.
+     * Data will get split into multiple calls to {@link #onSend} if count exceeds
+     * {@link #getMaxMessageSize}.  Blocks until all the data is sent or an exception occurs.
+     * In the latter case, the amount of data sent prior to the exception is not provided to caller.
+     * The communication should be considered corrupt.  The sender should reestablish
+     * communication, reset all controllers and send all notes off.
+     *
+     * @param msg a byte array containing the MIDI data
+     * @param offset the offset of the first byte of the data in the array to be sent
+     * @param count the number of bytes of MIDI data in the array to be sent
+     * @param timestamp the timestamp of the message, based on {@link java.lang.System#nanoTime}
+     * @throws IOException if the data could not be sent in entirety
+     */
+    public void send(byte[] msg, int offset, int count, long timestamp)
+            throws IOException {
+        int messageSize = getMaxMessageSize();
+        while (count > 0) {
+            int length = (count > messageSize ? messageSize : count);
+            onSend(msg, offset, length, timestamp);
+            offset += length;
+            count -= length;
+        }
+    }
+}
diff --git a/android/media/midi/MidiSender.java b/android/media/midi/MidiSender.java
new file mode 100644
index 0000000..c5f1edc
--- /dev/null
+++ b/android/media/midi/MidiSender.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2014 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.midi;
+
+/**
+ * Interface provided by a device to allow attaching
+ * MidiReceivers to a MIDI device.
+ */
+abstract public class MidiSender {
+
+    /**
+     * Connects a {@link MidiReceiver} to the sender
+     *
+     * @param receiver the receiver to connect
+     */
+    public void connect(MidiReceiver receiver) {
+        if (receiver == null) {
+            throw new NullPointerException("receiver null in MidiSender.connect");
+        }
+        onConnect(receiver);
+    }
+
+    /**
+     * Disconnects a {@link MidiReceiver} from the sender
+     *
+     * @param receiver the receiver to disconnect
+     */
+    public void disconnect(MidiReceiver receiver) {
+        if (receiver == null) {
+            throw new NullPointerException("receiver null in MidiSender.disconnect");
+        }
+        onDisconnect(receiver);
+    }
+
+    /**
+     * Called to connect a {@link MidiReceiver} to the sender
+     *
+     * @param receiver the receiver to connect
+     */
+    abstract public void onConnect(MidiReceiver receiver);
+
+    /**
+     * Called to disconnect a {@link MidiReceiver} from the sender
+     *
+     * @param receiver the receiver to disconnect
+     */
+    abstract public void onDisconnect(MidiReceiver receiver);
+}
diff --git a/android/media/musicrecognition/MusicRecognitionManager.java b/android/media/musicrecognition/MusicRecognitionManager.java
new file mode 100644
index 0000000..b183eaf
--- /dev/null
+++ b/android/media/musicrecognition/MusicRecognitionManager.java
@@ -0,0 +1,187 @@
+/*
+ * Copyright (C) 2020 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.musicrecognition;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.content.Context;
+import android.media.MediaMetadata;
+import android.os.Bundle;
+import android.os.RemoteException;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
+
+/**
+ * System service that manages music recognition.
+ *
+ * @hide
+ */
+@SystemApi
+@SystemService(Context.MUSIC_RECOGNITION_SERVICE)
+public class MusicRecognitionManager {
+
+    /**
+     * Error code provided by RecognitionCallback#onRecognitionFailed()
+     *
+     * @hide
+     */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = {"RECOGNITION_FAILED_"},
+            value = {RECOGNITION_FAILED_UNKNOWN,
+                    RECOGNITION_FAILED_NOT_FOUND,
+                    RECOGNITION_FAILED_NO_CONNECTIVITY,
+                    RECOGNITION_FAILED_SERVICE_UNAVAILABLE,
+                    RECOGNITION_FAILED_SERVICE_KILLED,
+                    RECOGNITION_FAILED_TIMEOUT,
+                    RECOGNITION_FAILED_AUDIO_UNAVAILABLE})
+    public @interface RecognitionFailureCode {
+    }
+
+    /** Catchall error code. */
+    public static final int RECOGNITION_FAILED_UNKNOWN = -1;
+    /** Recognition was performed but no result could be identified. */
+    public static final int RECOGNITION_FAILED_NOT_FOUND = 1;
+    /** Recognition failed because the server couldn't be reached. */
+    public static final int RECOGNITION_FAILED_NO_CONNECTIVITY = 2;
+    /**
+     * Recognition was not possible because the application which provides it is not available (for
+     * example, disabled).
+     */
+    public static final int RECOGNITION_FAILED_SERVICE_UNAVAILABLE = 3;
+    /** Recognition failed because the recognizer was killed. */
+    public static final int RECOGNITION_FAILED_SERVICE_KILLED = 5;
+    /** Recognition attempt timed out. */
+    public static final int RECOGNITION_FAILED_TIMEOUT = 6;
+    /** Recognition failed due to an issue with obtaining an audio stream. */
+    public static final int RECOGNITION_FAILED_AUDIO_UNAVAILABLE = 7;
+
+    /** Callback interface for the caller of this api. */
+    public interface RecognitionCallback {
+        /**
+         * Should be invoked by receiving app with the result of the search.
+         *
+         * @param recognitionRequest original request that started the recognition
+         * @param result result of the search
+         * @param extras extra data to be supplied back to the caller. Note that all
+         *               executable parameters and file descriptors would be removed from the
+         *               supplied bundle
+         */
+        void onRecognitionSucceeded(@NonNull RecognitionRequest recognitionRequest,
+                @NonNull MediaMetadata result,
+                @SuppressLint("NullableCollection")
+                @Nullable Bundle extras);
+
+        /**
+         * Invoked when the search is not successful (possibly but not necessarily due to error).
+         *
+         * @param recognitionRequest original request that started the recognition
+         * @param failureCode failure code describing reason for failure
+         */
+        void onRecognitionFailed(@NonNull RecognitionRequest recognitionRequest,
+                @RecognitionFailureCode int failureCode);
+
+        /**
+         * Invoked by the system once the audio stream is closed either due to error, reaching the
+         * limit, or the remote service closing the stream.  Always called per
+         * #beingStreamingSearch() invocation.
+         */
+        void onAudioStreamClosed();
+    }
+
+    private final IMusicRecognitionManager mService;
+
+    /** @hide */
+    public MusicRecognitionManager(IMusicRecognitionManager service) {
+        mService = service;
+    }
+
+    /**
+     * Constructs an {@link android.media.AudioRecord} from the given parameters and streams the
+     * audio bytes to the designated cloud lookup service.  After the lookup is done, the given
+     * callback will be invoked by the system with the result or lack thereof.
+     *
+     * @param recognitionRequest audio parameters for the stream to search
+     * @param callbackExecutor where the callback is invoked
+     * @param callback invoked when the result is available
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MANAGE_MUSIC_RECOGNITION)
+    public void beginStreamingSearch(
+            @NonNull RecognitionRequest recognitionRequest,
+            @NonNull @CallbackExecutor Executor callbackExecutor,
+            @NonNull RecognitionCallback callback) {
+        try {
+            mService.beginRecognition(
+                    requireNonNull(recognitionRequest),
+                    new MusicRecognitionCallbackWrapper(
+                            requireNonNull(recognitionRequest),
+                            requireNonNull(callback),
+                            requireNonNull(callbackExecutor)));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    private final class MusicRecognitionCallbackWrapper extends
+            IMusicRecognitionManagerCallback.Stub {
+
+        @NonNull
+        private final RecognitionRequest mRecognitionRequest;
+        @NonNull
+        private final RecognitionCallback mCallback;
+        @NonNull
+        private final Executor mCallbackExecutor;
+
+        MusicRecognitionCallbackWrapper(
+                RecognitionRequest recognitionRequest,
+                RecognitionCallback callback,
+                Executor callbackExecutor) {
+            mRecognitionRequest = recognitionRequest;
+            mCallback = callback;
+            mCallbackExecutor = callbackExecutor;
+        }
+
+        @Override
+        public void onRecognitionSucceeded(MediaMetadata result, Bundle extras) {
+            mCallbackExecutor.execute(
+                    () -> mCallback.onRecognitionSucceeded(mRecognitionRequest, result, extras));
+        }
+
+        @Override
+        public void onRecognitionFailed(@RecognitionFailureCode int failureCode) {
+            mCallbackExecutor.execute(
+                    () -> mCallback.onRecognitionFailed(mRecognitionRequest, failureCode));
+        }
+
+        @Override
+        public void onAudioStreamClosed() {
+            mCallbackExecutor.execute(mCallback::onAudioStreamClosed);
+        }
+    }
+}
diff --git a/android/media/musicrecognition/MusicRecognitionService.java b/android/media/musicrecognition/MusicRecognitionService.java
new file mode 100644
index 0000000..385aff0
--- /dev/null
+++ b/android/media/musicrecognition/MusicRecognitionService.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2020 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.musicrecognition;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Intent;
+import android.media.AudioFormat;
+import android.media.MediaMetadata;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.util.Log;
+
+/**
+ * Implemented by an app that wants to offer music search lookups. The system will start the
+ * service and stream up to 16 seconds of audio over the given file descriptor.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class MusicRecognitionService extends Service {
+
+    private static final String TAG = MusicRecognitionService.class.getSimpleName();
+
+    /** Callback for the result of the remote search. */
+    public interface Callback {
+        /**
+         * Call this method to pass back a successful search result.
+         *
+         * @param result successful result of the search
+         * @param extras extra data to be supplied back to the caller. Note that all executable
+         *               parameters and file descriptors would be removed from the supplied bundle
+         */
+        void onRecognitionSucceeded(@NonNull MediaMetadata result,
+                @SuppressLint("NullableCollection")
+                @Nullable Bundle extras);
+
+        /**
+         * Call this method if the search does not find a result on an error occurred.
+         */
+        void onRecognitionFailed(@MusicRecognitionManager.RecognitionFailureCode int failureCode);
+    }
+
+    /**
+     * Action used to start this service.
+     *
+     * @hide
+     */
+    public static final String ACTION_MUSIC_SEARCH_LOOKUP =
+            "android.service.musicrecognition.MUSIC_RECOGNITION";
+
+    private Handler mHandler;
+    private final IMusicRecognitionService mServiceInterface =
+            new IMusicRecognitionService.Stub() {
+                @Override
+                public void onAudioStreamStarted(ParcelFileDescriptor fd,
+                        AudioFormat audioFormat,
+                        IMusicRecognitionServiceCallback callback) {
+                    mHandler.sendMessage(
+                            obtainMessage(MusicRecognitionService.this::onRecognize, fd,
+                                    audioFormat,
+                                    new Callback() {
+                                        @Override
+                                        public void onRecognitionSucceeded(
+                                                @NonNull MediaMetadata result,
+                                                @Nullable Bundle extras) {
+                                            try {
+                                                callback.onRecognitionSucceeded(result, extras);
+                                            } catch (RemoteException e) {
+                                                throw e.rethrowFromSystemServer();
+                                            }
+                                        }
+
+                                        @Override
+                                        public void onRecognitionFailed(int failureCode) {
+                                            try {
+                                                callback.onRecognitionFailed(failureCode);
+                                            } catch (RemoteException e) {
+                                                throw e.rethrowFromSystemServer();
+                                            }
+                                        }
+                                    }));
+                }
+
+                @Override
+                public void getAttributionTag(
+                        IMusicRecognitionAttributionTagCallback callback) throws RemoteException {
+                    String tag = MusicRecognitionService.this.getAttributionTag();
+                    callback.onAttributionTag(tag);
+                }
+            };
+
+    @Override
+    public void onCreate() {
+        super.onCreate();
+        mHandler = new Handler(Looper.getMainLooper(), null, true);
+    }
+
+    /**
+     * Read audio from this stream. You must invoke the callback whether the music is recognized or
+     * not.
+     *
+     * @param stream containing music to be recognized. Close when you are finished.
+     * @param audioFormat describes sample rate, channels and endianness of the stream
+     * @param callback to invoke after lookup is finished. Must always be called.
+     */
+    public abstract void onRecognize(@NonNull ParcelFileDescriptor stream,
+            @NonNull AudioFormat audioFormat,
+            @NonNull Callback callback);
+
+    /**
+     * @hide
+     */
+    @Nullable
+    @Override
+    public IBinder onBind(@NonNull Intent intent) {
+        if (ACTION_MUSIC_SEARCH_LOOKUP.equals(intent.getAction())) {
+            return mServiceInterface.asBinder();
+        }
+        Log.w(TAG,
+                "Tried to bind to wrong intent (should be " + ACTION_MUSIC_SEARCH_LOOKUP + ": "
+                        + intent);
+        return null;
+    }
+}
diff --git a/android/media/musicrecognition/RecognitionRequest.java b/android/media/musicrecognition/RecognitionRequest.java
new file mode 100644
index 0000000..3298d63
--- /dev/null
+++ b/android/media/musicrecognition/RecognitionRequest.java
@@ -0,0 +1,175 @@
+/*
+ * Copyright (C) 2020 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.musicrecognition;
+
+import static android.media.AudioAttributes.CONTENT_TYPE_MUSIC;
+import static android.media.AudioFormat.ENCODING_PCM_16BIT;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.media.AudioAttributes;
+import android.media.AudioFormat;
+import android.media.AudioRecord;
+import android.media.MediaRecorder;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * Encapsulates parameters for making music recognition queries via {@link MusicRecognitionManager}.
+ *
+ * @hide
+ */
+@SystemApi
+public final class RecognitionRequest implements Parcelable {
+    @NonNull private final AudioAttributes mAudioAttributes;
+    @NonNull private final AudioFormat mAudioFormat;
+    private final int mCaptureSession;
+    private final int mMaxAudioLengthSeconds;
+    private final int mIgnoreBeginningFrames;
+
+    private RecognitionRequest(Builder b) {
+        mAudioAttributes = requireNonNull(b.mAudioAttributes);
+        mAudioFormat = requireNonNull(b.mAudioFormat);
+        mCaptureSession = b.mCaptureSession;
+        mMaxAudioLengthSeconds = b.mMaxAudioLengthSeconds;
+        mIgnoreBeginningFrames = b.mIgnoreBeginningFrames;
+    }
+
+    @NonNull
+    public AudioAttributes getAudioAttributes() {
+        return mAudioAttributes;
+    }
+
+    @NonNull
+    public AudioFormat getAudioFormat() {
+        return mAudioFormat;
+    }
+
+    public int getCaptureSession() {
+        return mCaptureSession;
+    }
+
+    @SuppressWarnings("MethodNameUnits")
+    public int getMaxAudioLengthSeconds() {
+        return mMaxAudioLengthSeconds;
+    }
+
+    public int getIgnoreBeginningFrames() {
+        return mIgnoreBeginningFrames;
+    }
+
+    /**
+     * Builder for constructing StreamSearchRequest objects.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class Builder {
+        private AudioFormat mAudioFormat = new AudioFormat.Builder()
+                .setSampleRate(16000)
+                .setEncoding(ENCODING_PCM_16BIT)
+                .build();
+        private AudioAttributes mAudioAttributes = new AudioAttributes.Builder()
+                .setContentType(CONTENT_TYPE_MUSIC)
+                .build();
+        private int mCaptureSession = MediaRecorder.AudioSource.MIC;
+        private int mMaxAudioLengthSeconds = 24; // Max enforced in system server.
+        private int mIgnoreBeginningFrames = 0;
+
+        /** Attributes passed to the constructed {@link AudioRecord}. */
+        @NonNull
+        public Builder setAudioAttributes(@NonNull AudioAttributes audioAttributes) {
+            mAudioAttributes = audioAttributes;
+            return this;
+        }
+
+        /** AudioFormat passed to the constructed {@link AudioRecord}. */
+        @NonNull
+        public Builder setAudioFormat(@NonNull AudioFormat audioFormat) {
+            mAudioFormat = audioFormat;
+            return this;
+        }
+
+        /** Constant from {@link android.media.MediaRecorder.AudioSource}. */
+        @NonNull
+        public Builder setCaptureSession(int captureSession) {
+            mCaptureSession = captureSession;
+            return this;
+        }
+
+        /** Maximum number of seconds to stream from the audio source. */
+        @NonNull
+        public Builder setMaxAudioLengthSeconds(int maxAudioLengthSeconds) {
+            mMaxAudioLengthSeconds = maxAudioLengthSeconds;
+            return this;
+        }
+
+        /**
+         * Number of frames to drop from the start of the stream
+         * (if recording is PCM stereo, one frame is two samples).
+         **/
+        @NonNull
+        public Builder setIgnoreBeginningFrames(int ignoreBeginningFrames) {
+            mIgnoreBeginningFrames = ignoreBeginningFrames;
+            return this;
+        }
+
+        /** Returns the constructed request. */
+        @NonNull
+        public RecognitionRequest build() {
+            return new RecognitionRequest(this);
+        }
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeParcelable(mAudioFormat, flags);
+        dest.writeParcelable(mAudioAttributes, flags);
+        dest.writeInt(mCaptureSession);
+        dest.writeInt(mMaxAudioLengthSeconds);
+        dest.writeInt(mIgnoreBeginningFrames);
+    }
+
+    private RecognitionRequest(Parcel in) {
+        mAudioFormat = in.readParcelable(AudioFormat.class.getClassLoader());
+        mAudioAttributes = in.readParcelable(AudioAttributes.class.getClassLoader());
+        mCaptureSession = in.readInt();
+        mMaxAudioLengthSeconds = in.readInt();
+        mIgnoreBeginningFrames = in.readInt();
+    }
+
+    @NonNull public static final Creator<RecognitionRequest> CREATOR =
+            new Creator<RecognitionRequest>() {
+
+        @Override
+        public RecognitionRequest createFromParcel(Parcel p) {
+            return new RecognitionRequest(p);
+        }
+
+        @Override
+        public RecognitionRequest[] newArray(int size) {
+            return new RecognitionRequest[size];
+        }
+    };
+}
diff --git a/android/media/permission/ClearCallingIdentityContext.java b/android/media/permission/ClearCallingIdentityContext.java
new file mode 100644
index 0000000..2d58b24
--- /dev/null
+++ b/android/media/permission/ClearCallingIdentityContext.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2020 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.permission;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+
+/**
+ * An RAII-style object, used to establish a scope in which the binder calling identity is cleared.
+ *
+ * <p>
+ * Intended usage:
+ * <pre>
+ * void caller() {
+ *   try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+ *       // Within this scope the binder calling identity is cleared.
+ *       ...
+ *   }
+ *   // Outside the scope the calling identity is restored to its prior state.
+ * </pre>
+ *
+ * @hide
+ */
+public class ClearCallingIdentityContext implements SafeCloseable {
+    private final long mRestoreKey;
+
+    /**
+     * Creates a new instance.
+     * @return A {@link SafeCloseable}, intended to be used in a try-with-resource block.
+     */
+    public static @NonNull
+    SafeCloseable create() {
+        return new ClearCallingIdentityContext();
+    }
+
+    @SuppressWarnings("AndroidFrameworkBinderIdentity")
+    private ClearCallingIdentityContext() {
+        mRestoreKey = Binder.clearCallingIdentity();
+    }
+
+    @Override
+    @SuppressWarnings("AndroidFrameworkBinderIdentity")
+    public void close() {
+        Binder.restoreCallingIdentity(mRestoreKey);
+    }
+}
diff --git a/android/media/permission/CompositeSafeCloseable.java b/android/media/permission/CompositeSafeCloseable.java
new file mode 100644
index 0000000..08990eb
--- /dev/null
+++ b/android/media/permission/CompositeSafeCloseable.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2020 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.permission;
+
+import android.annotation.NonNull;
+
+/**
+ * A composite {@link SafeCloseable}. Will close its children in reverse order.
+ *
+ * @hide
+ */
+class CompositeSafeCloseable implements SafeCloseable {
+    private final @NonNull SafeCloseable[] mChildren;
+
+    CompositeSafeCloseable(@NonNull SafeCloseable... children) {
+        mChildren = children;
+    }
+
+    @Override
+    public void close() {
+        // Close in reverse order.
+        for (int i = mChildren.length - 1; i >= 0; --i) {
+            mChildren[i].close();
+        }
+    }
+}
diff --git a/android/media/permission/IdentityContext.java b/android/media/permission/IdentityContext.java
new file mode 100644
index 0000000..d10654f
--- /dev/null
+++ b/android/media/permission/IdentityContext.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2020 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.permission;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+
+/**
+ * An RAII-style object, used to establish a scope in which a single identity is part of the
+ * context. This is used in order to avoid having to explicitly pass identity information through
+ * deep call-stacks.
+ * <p>
+ * Intended usage:
+ * <pre>
+ * void caller() {
+ *   Identity originator = ...;
+ *   try (SafeCloseable ignored = IdentityContext.create(originator)) {
+ *       // Within this scope the context is established.
+ *       callee();
+ *   }
+ *   // Outside the scope the context is restored to its prior state.
+ *
+ * void callee() {
+ *     // Here we can access the identity without having to explicitly take it as an argument.
+ *     // This is true even if this were a deeply nested call.
+ *     Identity originator = IdentityContext.getNonNull();
+ *     ...
+ * }
+ * </pre>
+ *
+ * @hide
+ */
+public class IdentityContext implements SafeCloseable {
+    private static ThreadLocal<Identity> sThreadLocalIdentity = new ThreadLocal<>();
+    private @Nullable Identity mPrior = get();
+
+    /**
+     * Create a scoped identity context.
+     *
+     * @param identity The identity to establish with the scope.
+     * @return A {@link SafeCloseable}, to be used in a try-with-resources block to establish a
+     * scope.
+     */
+    public static @NonNull
+    SafeCloseable create(@Nullable Identity identity) {
+        return new IdentityContext(identity);
+    }
+
+    /**
+     * Get the current identity context.
+     *
+     * @return The identity, or null if it has not been established.
+     */
+    public static @Nullable
+    Identity get() {
+        return sThreadLocalIdentity.get();
+    }
+
+    /**
+     * Get the current identity context. Throws a {@link NullPointerException} if it has not been
+     * established.
+     *
+     * @return The identity.
+     */
+    public static @NonNull
+    Identity getNonNull() {
+        Identity result = get();
+        if (result == null) {
+            throw new NullPointerException("Identity context is not set");
+        }
+        return result;
+    }
+
+    private IdentityContext(@Nullable Identity identity) {
+        set(identity);
+    }
+
+    @Override
+    public void close() {
+        set(mPrior);
+    }
+
+    private static void set(@Nullable Identity identity) {
+        sThreadLocalIdentity.set(identity);
+    }
+}
diff --git a/android/media/permission/PermissionUtil.java b/android/media/permission/PermissionUtil.java
new file mode 100644
index 0000000..b08d111
--- /dev/null
+++ b/android/media/permission/PermissionUtil.java
@@ -0,0 +1,201 @@
+/*
+ * Copyright (C) 2020 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.permission;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityThread;
+import android.content.Context;
+import android.content.PermissionChecker;
+import android.os.Binder;
+import android.os.Process;
+
+import java.util.Objects;
+
+/**
+ * This module provides some utility methods for facilitating our permission enforcement patterns.
+ * <p>
+ * <h1>Intended usage:</h1>
+ * Close to the client-facing edge of the server, first authenticate the client, using {@link
+ * #establishIdentityDirect(Identity)}, or {@link #establishIdentityIndirect(Context, String,
+ * Identity, Identity)}, depending on whether the client is trying to authenticate as the
+ * originator or a middleman. Those methods will establish a scope with the originator in the
+ * {@link android.media.permission.IdentityContext} and a cleared binder calling identity.
+ * Typically there would be two distinct API methods for the two different options, and typically
+ * those API methods would be used to establish a client session which is associated with the
+ * originator for the lifetime of the session.
+ * <p>
+ * When performing an operation that requires permissions, use {@link
+ * #checkPermissionForPreflight(Context, Identity, String)} or {@link
+ * #checkPermissionForDataDelivery(Context, Identity, String, String)} on the originator
+ * identity. Note that this won't typically be the identity pulled from the {@link
+ * android.media.permission.IdentityContext}, since we are working with a session-based approach,
+ * the originator identity will be established once upon creation of a session, and then all
+ * interactions with this session will using the identity attached to the session. This also covers
+ * performing checks prior to invoking client callbacks for data delivery.
+ *
+ * @hide
+ */
+public class PermissionUtil {
+
+    /**
+     * Authenticate an originator, where the binder call is coming from a middleman.
+     *
+     * The middleman is expected to hold a special permission to act as such, or else a
+     * {@link SecurityException} will be thrown. If the call succeeds:
+     * <ul>
+     *     <li>The passed middlemanIdentity argument will have its uid/pid fields overridden with
+     *     those provided by binder.
+     *     <li>An {@link SafeCloseable} is returned, used to established a scope in which the
+     *     originator identity is available via {@link android.media.permission.IdentityContext}
+     *     and in which the binder
+     *     calling ID is cleared.
+     * </ul>
+     * Example usage:
+     * <pre>
+     *     try (SafeCloseable ignored = PermissionUtil.establishIdentityIndirect(...)) {
+     *         // Within this scope we have the identity context established, and the binder calling
+     *         // identity cleared.
+     *         ...
+     *         Identity originator = IdentityContext.getNonNull();
+     *         ...
+     *     }
+     *     // outside the scope, everything is back to the prior state.
+     * </pre>
+     * <p>
+     * <b>Important note:</b> The binder calling ID will be used to securely establish the identity
+     * of the middleman. However, if the middleman is on the same process as the server,
+     * the middleman must remember to clear the binder calling identity, or else the binder calling
+     * ID will reflect the process calling into the middleman, not the middleman process itself. If
+     * the middleman itself is using this API, this is typically not an issue, since this method
+     * will take care of that.
+     *
+     * @param context             A {@link Context}, used for permission checks.
+     * @param middlemanPermission The permission that will be checked in order to authorize the
+     *                            middleman to act as such (i.e. be trusted to convey the
+     *                            originator
+     *                            identity reliably).
+     * @param middlemanIdentity   The identity of the middleman.
+     * @param originatorIdentity  The identity of the originator.
+     * @return A {@link SafeCloseable}, used to establish a scope, as mentioned above.
+     */
+    public static @NonNull
+    SafeCloseable establishIdentityIndirect(
+            @NonNull Context context,
+            @NonNull String middlemanPermission,
+            @NonNull Identity middlemanIdentity,
+            @NonNull Identity originatorIdentity) {
+        Objects.requireNonNull(context);
+        Objects.requireNonNull(middlemanPermission);
+        Objects.requireNonNull(middlemanIdentity);
+        Objects.requireNonNull(originatorIdentity);
+
+        // Override uid/pid with the secure values provided by binder.
+        middlemanIdentity.pid = Binder.getCallingPid();
+        middlemanIdentity.uid = Binder.getCallingUid();
+
+        // Authorize middleman to delegate identity.
+        context.enforcePermission(middlemanPermission, middlemanIdentity.pid,
+                middlemanIdentity.uid,
+                String.format("Middleman must have the %s permision.", middlemanPermission));
+        return new CompositeSafeCloseable(IdentityContext.create(originatorIdentity),
+                ClearCallingIdentityContext.create());
+    }
+
+    /**
+     * Authenticate an originator, where the binder call is coming directly from the originator.
+     *
+     * If the call succeeds:
+     * <ul>
+     *     <li>The passed originatorIdentity argument will have its uid/pid fields overridden with
+     *     those provided by binder.
+     *     <li>A {@link SafeCloseable} is returned, used to established a scope in which the
+     *     originator identity is available via {@link IdentityContext} and in which the binder
+     *     calling ID is cleared.
+     * </ul>
+     * Example usage:
+     * <pre>
+     *     try (AutoClosable ignored = PermissionUtil.establishIdentityDirect(...)) {
+     *         // Within this scope we have the identity context established, and the binder calling
+     *         // identity cleared.
+     *         ...
+     *         Identity originator = IdentityContext.getNonNull();
+     *         ...
+     *     }
+     *     // outside the scope, everything is back to the prior state.
+     * </pre>
+     * <p>
+     * <b>Important note:</b> The binder calling ID will be used to securely establish the identity
+     * of the client. However, if the client is on the same process as the server, and is itself a
+     * binder server, it must remember to clear the binder calling identity, or else the binder
+     * calling ID will reflect the process calling into the client, not the client process itself.
+     * If the client itself is using this API, this is typically not an issue, since this method
+     * will take care of that.
+     *
+     * @param originatorIdentity The identity of the originator.
+     * @return A {@link SafeCloseable}, used to establish a scope, as mentioned above.
+     */
+    public static @NonNull
+    SafeCloseable establishIdentityDirect(@NonNull Identity originatorIdentity) {
+        Objects.requireNonNull(originatorIdentity);
+
+        originatorIdentity.uid = Binder.getCallingUid();
+        originatorIdentity.pid = Binder.getCallingPid();
+        return new CompositeSafeCloseable(
+                IdentityContext.create(originatorIdentity),
+                ClearCallingIdentityContext.create());
+    }
+
+    /**
+     * Checks whether the given identity has the given permission to receive data.
+     *
+     * @param context    A {@link Context}, used for permission checks.
+     * @param identity   The identity to check.
+     * @param permission The identifier of the permission we want to check.
+     * @param reason     The reason why we're requesting the permission, for auditing purposes.
+     * @return The permission check result which is either
+     * {@link PermissionChecker#PERMISSION_GRANTED}
+     * or {@link PermissionChecker#PERMISSION_SOFT_DENIED} or
+     * {@link PermissionChecker#PERMISSION_HARD_DENIED}.
+     */
+    public static int checkPermissionForDataDelivery(@NonNull Context context,
+            @NonNull Identity identity,
+            @NonNull String permission,
+            @NonNull String reason) {
+        return PermissionChecker.checkPermissionForDataDelivery(context, permission,
+                identity.pid, identity.uid, identity.packageName, identity.attributionTag,
+                reason);
+    }
+
+    /**
+     * Checks whether the given identity has the given permission.
+     *
+     * @param context    A {@link Context}, used for permission checks.
+     * @param identity   The identity to check.
+     * @param permission The identifier of the permission we want to check.
+     * @return The permission check result which is either
+     * {@link PermissionChecker#PERMISSION_GRANTED}
+     * or {@link PermissionChecker#PERMISSION_SOFT_DENIED} or
+     * {@link PermissionChecker#PERMISSION_HARD_DENIED}.
+     */
+    public static int checkPermissionForPreflight(@NonNull Context context,
+            @NonNull Identity identity,
+            @NonNull String permission) {
+        return PermissionChecker.checkPermissionForPreflight(context, permission,
+                identity.pid, identity.uid, identity.packageName);
+    }
+}
diff --git a/android/media/permission/SafeCloseable.java b/android/media/permission/SafeCloseable.java
new file mode 100644
index 0000000..8ec15b1
--- /dev/null
+++ b/android/media/permission/SafeCloseable.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2020 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.permission;
+
+/**
+ * An {@link AutoCloseable} that doesn't throw on {@link #close()}.
+ *
+ * @hide
+ */
+public interface SafeCloseable extends AutoCloseable {
+    @Override
+    void close();
+}
diff --git a/android/media/projection/MediaProjection.java b/android/media/projection/MediaProjection.java
new file mode 100644
index 0000000..37e1415
--- /dev/null
+++ b/android/media/projection/MediaProjection.java
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2014 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.projection;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Context;
+import android.hardware.display.DisplayManager;
+import android.hardware.display.VirtualDisplay;
+import android.hardware.display.VirtualDisplayConfig;
+import android.media.projection.IMediaProjection;
+import android.media.projection.IMediaProjectionCallback;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.view.Surface;
+
+import java.util.Map;
+
+/**
+ * A token granting applications the ability to capture screen contents and/or
+ * record system audio. The exact capabilities granted depend on the type of
+ * MediaProjection.
+ *
+ * <p>
+ * A screen capture session can be started through {@link
+ * MediaProjectionManager#createScreenCaptureIntent}. This grants the ability to
+ * capture screen contents, but not system audio.
+ * </p>
+ */
+public final class MediaProjection {
+    private static final String TAG = "MediaProjection";
+
+    private final IMediaProjection mImpl;
+    private final Context mContext;
+    private final Map<Callback, CallbackRecord> mCallbacks;
+
+    /** @hide */
+    public MediaProjection(Context context, IMediaProjection impl) {
+        mCallbacks = new ArrayMap<Callback, CallbackRecord>();
+        mContext = context;
+        mImpl = impl;
+        try {
+            mImpl.start(new MediaProjectionCallback());
+        } catch (RemoteException e) {
+            throw new RuntimeException("Failed to start media projection", e);
+        }
+    }
+
+    /** Register a listener to receive notifications about when the {@link
+     * MediaProjection} changes state.
+     *
+     * @param callback The callback to call.
+     * @param handler The handler on which the callback should be invoked, or
+     * null if the callback should be invoked on the calling thread's looper.
+     *
+     * @see #unregisterCallback
+     */
+    public void registerCallback(Callback callback, Handler handler) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback should not be null");
+        }
+        if (handler == null) {
+            handler = new Handler();
+        }
+        mCallbacks.put(callback, new CallbackRecord(callback, handler));
+    }
+
+    /** Unregister a MediaProjection listener.
+     *
+     * @param callback The callback to unregister.
+     *
+     * @see #registerCallback
+     */
+    public void unregisterCallback(Callback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback should not be null");
+        }
+        mCallbacks.remove(callback);
+    }
+
+    /**
+     * @hide
+     */
+    public VirtualDisplay createVirtualDisplay(@NonNull String name,
+            int width, int height, int dpi, boolean isSecure, @Nullable Surface surface,
+            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
+        DisplayManager dm = (DisplayManager) mContext.getSystemService(Context.DISPLAY_SERVICE);
+        int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR
+                | DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION;
+        if (isSecure) {
+            flags |= DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
+        }
+        final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
+                height, dpi);
+        builder.setFlags(flags);
+        if (surface != null) {
+            builder.setSurface(surface);
+        }
+        return dm.createVirtualDisplay(this, builder.build(), callback, handler);
+    }
+
+    /**
+     * Creates a {@link android.hardware.display.VirtualDisplay} to capture the
+     * contents of the screen.
+     *
+     * @param name The name of the virtual display, must be non-empty.
+     * @param width The width of the virtual display in pixels. Must be
+     * greater than 0.
+     * @param height The height of the virtual display in pixels. Must be
+     * greater than 0.
+     * @param dpi The density of the virtual display in dpi. Must be greater
+     * than 0.
+     * @param surface The surface to which the content of the virtual display
+     * should be rendered, or null if there is none initially.
+     * @param flags A combination of virtual display flags. See {@link DisplayManager} for the full
+     * list of flags.
+     * @param callback Callback to call when the virtual display's state
+     * changes, or null if none.
+     * @param handler The {@link android.os.Handler} on which the callback should be
+     * invoked, or null if the callback should be invoked on the calling
+     * thread's main {@link android.os.Looper}.
+     *
+     * @see android.hardware.display.VirtualDisplay
+     */
+    public VirtualDisplay createVirtualDisplay(@NonNull String name,
+            int width, int height, int dpi, int flags, @Nullable Surface surface,
+            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
+        final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(name, width,
+                height, dpi);
+        builder.setFlags(flags);
+        if (surface != null) {
+            builder.setSurface(surface);
+        }
+        return createVirtualDisplay(builder.build(), callback, handler);
+    }
+
+    /**
+     * Creates a {@link android.hardware.display.VirtualDisplay} to capture the
+     * contents of the screen.
+     *
+     * @param virtualDisplayConfig The arguments for the virtual display configuration. See
+     * {@link VirtualDisplayConfig} for using it.
+     * @param callback Callback to call when the virtual display's state
+     * changes, or null if none.
+     * @param handler The {@link android.os.Handler} on which the callback should be
+     * invoked, or null if the callback should be invoked on the calling
+     * thread's main {@link android.os.Looper}.
+     *
+     * @see android.hardware.display.VirtualDisplay
+     * @hide
+     */
+    @Nullable
+    public VirtualDisplay createVirtualDisplay(@NonNull VirtualDisplayConfig virtualDisplayConfig,
+            @Nullable VirtualDisplay.Callback callback, @Nullable Handler handler) {
+        DisplayManager dm = mContext.getSystemService(DisplayManager.class);
+        return dm.createVirtualDisplay(this, virtualDisplayConfig, callback, handler);
+    }
+
+    /**
+     * Stops projection.
+     */
+    public void stop() {
+        try {
+            mImpl.stop();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to stop projection", e);
+        }
+    }
+
+    /**
+     * Get the underlying IMediaProjection.
+     * @hide
+     */
+    public IMediaProjection getProjection() {
+        return mImpl;
+    }
+
+    /**
+     * Callbacks for the projection session.
+     */
+    public static abstract class Callback {
+        /**
+         * Called when the MediaProjection session is no longer valid.
+         * <p>
+         * Once a MediaProjection has been stopped, it's up to the application to release any
+         * resources it may be holding (e.g. {@link android.hardware.display.VirtualDisplay}s).
+         * </p>
+         */
+        public void onStop() { }
+    }
+
+    private final class MediaProjectionCallback extends IMediaProjectionCallback.Stub {
+        @Override
+        public void onStop() {
+            for (CallbackRecord cbr : mCallbacks.values()) {
+                cbr.onStop();
+            }
+        }
+    }
+
+    private final static class CallbackRecord {
+        private final Callback mCallback;
+        private final Handler mHandler;
+
+        public CallbackRecord(Callback callback, Handler handler) {
+            mCallback = callback;
+            mHandler = handler;
+        }
+
+        public void onStop() {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onStop();
+                }
+            });
+        }
+    }
+}
diff --git a/android/media/projection/MediaProjectionInfo.java b/android/media/projection/MediaProjectionInfo.java
new file mode 100644
index 0000000..ff60856
--- /dev/null
+++ b/android/media/projection/MediaProjectionInfo.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (C) 2014 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.projection;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.UserHandle;
+
+import java.util.Objects;
+
+/** @hide */
+public final class MediaProjectionInfo implements Parcelable {
+    private final String mPackageName;
+    private final UserHandle mUserHandle;
+
+    public MediaProjectionInfo(String packageName, UserHandle handle) {
+        mPackageName = packageName;
+        mUserHandle = handle;
+    }
+
+    public MediaProjectionInfo(Parcel in) {
+        mPackageName = in.readString();
+        mUserHandle = UserHandle.readFromParcel(in);
+    }
+
+    public String getPackageName() {
+        return mPackageName;
+    }
+
+    public UserHandle getUserHandle() {
+        return mUserHandle;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o instanceof MediaProjectionInfo) {
+            final MediaProjectionInfo other = (MediaProjectionInfo) o;
+            return Objects.equals(other.mPackageName, mPackageName)
+                    && Objects.equals(other.mUserHandle, mUserHandle);
+        }
+        return false;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mPackageName, mUserHandle);
+    }
+
+    @Override
+    public String toString() {
+        return "MediaProjectionInfo{mPackageName="
+            + mPackageName + ", mUserHandle="
+            + mUserHandle + "}";
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel out, int flags) {
+        out.writeString(mPackageName);
+        UserHandle.writeToParcel(mUserHandle, out);
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<MediaProjectionInfo> CREATOR =
+            new Parcelable.Creator<MediaProjectionInfo>() {
+        @Override
+        public MediaProjectionInfo createFromParcel(Parcel in) {
+            return new MediaProjectionInfo (in);
+        }
+
+        @Override
+        public MediaProjectionInfo[] newArray(int size) {
+            return new MediaProjectionInfo[size];
+        }
+    };
+}
diff --git a/android/media/projection/MediaProjectionManager.java b/android/media/projection/MediaProjectionManager.java
new file mode 100644
index 0000000..e719b2a
--- /dev/null
+++ b/android/media/projection/MediaProjectionManager.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2014 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.projection;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemService;
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import java.util.Map;
+
+/**
+ * Manages the retrieval of certain types of {@link MediaProjection} tokens.
+ */
+@SystemService(Context.MEDIA_PROJECTION_SERVICE)
+public final class MediaProjectionManager {
+    private static final String TAG = "MediaProjectionManager";
+    /** @hide */
+    public static final String EXTRA_APP_TOKEN = "android.media.projection.extra.EXTRA_APP_TOKEN";
+    /** @hide */
+    public static final String EXTRA_MEDIA_PROJECTION =
+            "android.media.projection.extra.EXTRA_MEDIA_PROJECTION";
+
+    /** @hide */
+    public static final int TYPE_SCREEN_CAPTURE = 0;
+    /** @hide */
+    public static final int TYPE_MIRRORING = 1;
+    /** @hide */
+    public static final int TYPE_PRESENTATION = 2;
+
+    private Context mContext;
+    private Map<Callback, CallbackDelegate> mCallbacks;
+    private IMediaProjectionManager mService;
+
+    /** @hide */
+    public MediaProjectionManager(Context context) {
+        mContext = context;
+        IBinder b = ServiceManager.getService(Context.MEDIA_PROJECTION_SERVICE);
+        mService = IMediaProjectionManager.Stub.asInterface(b);
+        mCallbacks = new ArrayMap<>();
+    }
+
+    /**
+     * Returns an Intent that <b>must</b> be passed to startActivityForResult()
+     * in order to start screen capture. The activity will prompt
+     * the user whether to allow screen capture.  The result of this
+     * activity should be passed to getMediaProjection.
+     */
+    public Intent createScreenCaptureIntent() {
+        Intent i = new Intent();
+        final ComponentName mediaProjectionPermissionDialogComponent =
+                ComponentName.unflattenFromString(mContext.getResources().getString(
+                        com.android.internal.R.string
+                        .config_mediaProjectionPermissionDialogComponent));
+        i.setComponent(mediaProjectionPermissionDialogComponent);
+        return i;
+    }
+
+    /**
+     * Retrieve the MediaProjection obtained from a succesful screen
+     * capture request. Will be null if the result from the
+     * startActivityForResult() is anything other than RESULT_OK.
+     *
+     * Starting from Android {@link android.os.Build.VERSION_CODES#R}, if your application requests
+     * the {@link android.Manifest.permission#SYSTEM_ALERT_WINDOW} permission, and the
+     * user has not explicitly denied it, the permission will be automatically granted until the
+     * projection is stopped. This allows for user controls to be displayed on top of the screen
+     * being captured.
+     *
+     * <p>
+     * Apps targeting SDK version {@link android.os.Build.VERSION_CODES#Q} or later should specify
+     * the foreground service type using the attribute {@link android.R.attr#foregroundServiceType}
+     * in the service element of the app's manifest file.
+     * The {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION} attribute
+     * should be specified.
+     * </p>
+     *
+     * @see <a href="https://developer.android.com/preview/privacy/foreground-service-types">
+     * Foregroud Service Types</a>
+     *
+     * @param resultCode The result code from {@link android.app.Activity#onActivityResult(int,
+     * int, android.content.Intent)}
+     * @param resultData The resulting data from {@link android.app.Activity#onActivityResult(int,
+     * int, android.content.Intent)}
+     * @throws IllegalStateException on pre-Q devices if a previously gotten MediaProjection
+     * from the same {@code resultData} has not yet been stopped
+     */
+    public MediaProjection getMediaProjection(int resultCode, @NonNull Intent resultData) {
+        if (resultCode != Activity.RESULT_OK || resultData == null) {
+            return null;
+        }
+        IBinder projection = resultData.getIBinderExtra(EXTRA_MEDIA_PROJECTION);
+        if (projection == null) {
+            return null;
+        }
+        return new MediaProjection(mContext, IMediaProjection.Stub.asInterface(projection));
+    }
+
+    /**
+     * Get the {@link MediaProjectionInfo} for the active {@link MediaProjection}.
+     * @hide
+     */
+    public MediaProjectionInfo getActiveProjectionInfo() {
+        try {
+            return mService.getActiveProjectionInfo();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to get the active projection info", e);
+        }
+        return null;
+    }
+
+    /**
+     * Stop the current projection if there is one.
+     * @hide
+     */
+    public void stopActiveProjection() {
+        try {
+            mService.stopActiveProjection();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to stop the currently active media projection", e);
+        }
+    }
+
+    /**
+     * Add a callback to monitor all of the {@link MediaProjection}s activity.
+     * Not for use by regular applications, must have the MANAGE_MEDIA_PROJECTION permission.
+     * @hide
+     */
+    public void addCallback(@NonNull Callback callback, @Nullable Handler handler) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback must not be null");
+        }
+        CallbackDelegate delegate = new CallbackDelegate(callback, handler);
+        mCallbacks.put(callback, delegate);
+        try {
+            mService.addCallback(delegate);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to add callbacks to MediaProjection service", e);
+        }
+    }
+
+    /**
+     * Remove a MediaProjection monitoring callback.
+     * @hide
+     */
+    public void removeCallback(@NonNull Callback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback must not be null");
+        }
+        CallbackDelegate delegate = mCallbacks.remove(callback);
+        try {
+            if (delegate != null) {
+                mService.removeCallback(delegate);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Unable to add callbacks to MediaProjection service", e);
+        }
+    }
+
+    /** @hide */
+    public static abstract class Callback {
+        public abstract void onStart(MediaProjectionInfo info);
+        public abstract void onStop(MediaProjectionInfo info);
+    }
+
+    /** @hide */
+    private final static class CallbackDelegate extends IMediaProjectionWatcherCallback.Stub {
+        private Callback mCallback;
+        private Handler mHandler;
+
+        public CallbackDelegate(Callback callback, Handler handler) {
+            mCallback = callback;
+            if (handler == null) {
+                handler = new Handler();
+            }
+            mHandler = handler;
+        }
+
+        @Override
+        public void onStart(final MediaProjectionInfo info) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onStart(info);
+                }
+            });
+        }
+
+        @Override
+        public void onStop(final MediaProjectionInfo info) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onStop(info);
+                }
+            });
+        }
+    }
+}
diff --git a/android/media/session/MediaController.java b/android/media/session/MediaController.java
new file mode 100644
index 0000000..1da41fb
--- /dev/null
+++ b/android/media/session/MediaController.java
@@ -0,0 +1,1265 @@
+/*
+ * Copyright (C) 2014 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.session;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.PendingIntent;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.content.pm.ParceledListSlice;
+import android.media.AudioAttributes;
+import android.media.AudioManager;
+import android.media.MediaMetadata;
+import android.media.Rating;
+import android.media.VolumeProvider;
+import android.media.VolumeProvider.ControlType;
+import android.media.session.MediaSession.QueueItem;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Allows an app to interact with an ongoing media session. Media buttons and
+ * other commands can be sent to the session. A callback may be registered to
+ * receive updates from the session, such as metadata and play state changes.
+ * <p>
+ * A MediaController can be created through {@link MediaSessionManager} if you
+ * hold the "android.permission.MEDIA_CONTENT_CONTROL" permission or are an
+ * enabled notification listener or by getting a {@link MediaSession.Token}
+ * directly from the session owner.
+ * <p>
+ * MediaController objects are thread-safe.
+ */
+public final class MediaController {
+    private static final String TAG = "MediaController";
+
+    private static final int MSG_EVENT = 1;
+    private static final int MSG_UPDATE_PLAYBACK_STATE = 2;
+    private static final int MSG_UPDATE_METADATA = 3;
+    private static final int MSG_UPDATE_VOLUME = 4;
+    private static final int MSG_UPDATE_QUEUE = 5;
+    private static final int MSG_UPDATE_QUEUE_TITLE = 6;
+    private static final int MSG_UPDATE_EXTRAS = 7;
+    private static final int MSG_DESTROYED = 8;
+
+    private final ISessionController mSessionBinder;
+
+    private final MediaSession.Token mToken;
+    private final Context mContext;
+    private final CallbackStub mCbStub = new CallbackStub(this);
+    private final ArrayList<MessageHandler> mCallbacks = new ArrayList<MessageHandler>();
+    private final Object mLock = new Object();
+
+    private boolean mCbRegistered = false;
+    private String mPackageName;
+    private String mTag;
+    private Bundle mSessionInfo;
+
+    private final TransportControls mTransportControls;
+
+    /**
+     * Create a new MediaController from a session's token.
+     *
+     * @param context The caller's context.
+     * @param token The token for the session.
+     */
+    public MediaController(@NonNull Context context, @NonNull MediaSession.Token token) {
+        if (context == null) {
+            throw new IllegalArgumentException("context shouldn't be null");
+        }
+        if (token == null) {
+            throw new IllegalArgumentException("token shouldn't be null");
+        }
+        if (token.getBinder() == null) {
+            throw new IllegalArgumentException("token.getBinder() shouldn't be null");
+        }
+        mSessionBinder = token.getBinder();
+        mTransportControls = new TransportControls();
+        mToken = token;
+        mContext = context;
+    }
+
+    /**
+     * Get a {@link TransportControls} instance to send transport actions to
+     * the associated session.
+     *
+     * @return A transport controls instance.
+     */
+    public @NonNull TransportControls getTransportControls() {
+        return mTransportControls;
+    }
+
+    /**
+     * Send the specified media button event to the session. Only media keys can
+     * be sent by this method, other keys will be ignored.
+     *
+     * @param keyEvent The media button event to dispatch.
+     * @return true if the event was sent to the session, false otherwise.
+     */
+    public boolean dispatchMediaButtonEvent(@NonNull KeyEvent keyEvent) {
+        if (keyEvent == null) {
+            throw new IllegalArgumentException("KeyEvent may not be null");
+        }
+        if (!KeyEvent.isMediaSessionKey(keyEvent.getKeyCode())) {
+            return false;
+        }
+        try {
+            return mSessionBinder.sendMediaButton(mContext.getPackageName(), keyEvent);
+        } catch (RemoteException e) {
+            // System is dead. =(
+        }
+        return false;
+    }
+
+    /**
+     * Get the current playback state for this session.
+     *
+     * @return The current PlaybackState or null
+     */
+    public @Nullable PlaybackState getPlaybackState() {
+        try {
+            return mSessionBinder.getPlaybackState();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getPlaybackState.", e);
+            return null;
+        }
+    }
+
+    /**
+     * Get the current metadata for this session.
+     *
+     * @return The current MediaMetadata or null.
+     */
+    public @Nullable MediaMetadata getMetadata() {
+        try {
+            return mSessionBinder.getMetadata();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getMetadata.", e);
+            return null;
+        }
+    }
+
+    /**
+     * Get the current play queue for this session if one is set. If you only
+     * care about the current item {@link #getMetadata()} should be used.
+     *
+     * @return The current play queue or null.
+     */
+    public @Nullable List<MediaSession.QueueItem> getQueue() {
+        try {
+            ParceledListSlice list = mSessionBinder.getQueue();
+            return list == null ? null : list.getList();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getQueue.", e);
+        }
+        return null;
+    }
+
+    /**
+     * Get the queue title for this session.
+     */
+    public @Nullable CharSequence getQueueTitle() {
+        try {
+            return mSessionBinder.getQueueTitle();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getQueueTitle", e);
+        }
+        return null;
+    }
+
+    /**
+     * Get the extras for this session.
+     */
+    public @Nullable Bundle getExtras() {
+        try {
+            return mSessionBinder.getExtras();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getExtras", e);
+        }
+        return null;
+    }
+
+    /**
+     * Get the rating type supported by the session. One of:
+     * <ul>
+     * <li>{@link Rating#RATING_NONE}</li>
+     * <li>{@link Rating#RATING_HEART}</li>
+     * <li>{@link Rating#RATING_THUMB_UP_DOWN}</li>
+     * <li>{@link Rating#RATING_3_STARS}</li>
+     * <li>{@link Rating#RATING_4_STARS}</li>
+     * <li>{@link Rating#RATING_5_STARS}</li>
+     * <li>{@link Rating#RATING_PERCENTAGE}</li>
+     * </ul>
+     *
+     * @return The supported rating type
+     */
+    public int getRatingType() {
+        try {
+            return mSessionBinder.getRatingType();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getRatingType.", e);
+            return Rating.RATING_NONE;
+        }
+    }
+
+    /**
+     * Get the flags for this session. Flags are defined in {@link MediaSession}.
+     *
+     * @return The current set of flags for the session.
+     */
+    public long getFlags() {
+        try {
+            return mSessionBinder.getFlags();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getFlags.", e);
+        }
+        return 0;
+    }
+
+    /**
+     * Get the current playback info for this session.
+     *
+     * @return The current playback info or null.
+     */
+    public @Nullable PlaybackInfo getPlaybackInfo() {
+        try {
+            return mSessionBinder.getVolumeAttributes();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getAudioInfo.", e);
+        }
+        return null;
+    }
+
+    /**
+     * Get an intent for launching UI associated with this session if one
+     * exists.
+     *
+     * @return A {@link PendingIntent} to launch UI or null.
+     */
+    public @Nullable PendingIntent getSessionActivity() {
+        try {
+            return mSessionBinder.getLaunchPendingIntent();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling getPendingIntent.", e);
+        }
+        return null;
+    }
+
+    /**
+     * Get the token for the session this is connected to.
+     *
+     * @return The token for the connected session.
+     */
+    public @NonNull MediaSession.Token getSessionToken() {
+        return mToken;
+    }
+
+    /**
+     * Set the volume of the output this session is playing on. The command will
+     * be ignored if it does not support
+     * {@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE}. The flags in
+     * {@link AudioManager} may be used to affect the handling.
+     *
+     * @see #getPlaybackInfo()
+     * @param value The value to set it to, between 0 and the reported max.
+     * @param flags Flags from {@link AudioManager} to include with the volume
+     *            request.
+     */
+    public void setVolumeTo(int value, int flags) {
+        try {
+            // Note: Need both package name and OP package name. Package name is used for
+            //       RemoteUserInfo, and OP package name is used for AudioService's internal
+            //       AppOpsManager usages.
+            mSessionBinder.setVolumeTo(mContext.getPackageName(), mContext.getOpPackageName(),
+                    value, flags);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling setVolumeTo.", e);
+        }
+    }
+
+    /**
+     * Adjust the volume of the output this session is playing on. The direction
+     * must be one of {@link AudioManager#ADJUST_LOWER},
+     * {@link AudioManager#ADJUST_RAISE}, or {@link AudioManager#ADJUST_SAME}.
+     * The command will be ignored if the session does not support
+     * {@link VolumeProvider#VOLUME_CONTROL_RELATIVE} or
+     * {@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE}. The flags in
+     * {@link AudioManager} may be used to affect the handling.
+     *
+     * @see #getPlaybackInfo()
+     * @param direction The direction to adjust the volume in.
+     * @param flags Any flags to pass with the command.
+     */
+    public void adjustVolume(int direction, int flags) {
+        try {
+            // Note: Need both package name and OP package name. Package name is used for
+            //       RemoteUserInfo, and OP package name is used for AudioService's internal
+            //       AppOpsManager usages.
+            mSessionBinder.adjustVolume(mContext.getPackageName(), mContext.getOpPackageName(),
+                    direction, flags);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling adjustVolumeBy.", e);
+        }
+    }
+
+    /**
+     * Registers a callback to receive updates from the Session. Updates will be
+     * posted on the caller's thread.
+     *
+     * @param callback The callback object, must not be null.
+     */
+    public void registerCallback(@NonNull Callback callback) {
+        registerCallback(callback, null);
+    }
+
+    /**
+     * Registers a callback to receive updates from the session. Updates will be
+     * posted on the specified handler's thread.
+     *
+     * @param callback The callback object, must not be null.
+     * @param handler The handler to post updates on. If null the callers thread
+     *            will be used.
+     */
+    public void registerCallback(@NonNull Callback callback, @Nullable Handler handler) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback must not be null");
+        }
+        if (handler == null) {
+            handler = new Handler();
+        }
+        synchronized (mLock) {
+            addCallbackLocked(callback, handler);
+        }
+    }
+
+    /**
+     * Unregisters the specified callback. If an update has already been posted
+     * you may still receive it after calling this method.
+     *
+     * @param callback The callback to remove.
+     */
+    public void unregisterCallback(@NonNull Callback callback) {
+        if (callback == null) {
+            throw new IllegalArgumentException("callback must not be null");
+        }
+        synchronized (mLock) {
+            removeCallbackLocked(callback);
+        }
+    }
+
+    /**
+     * Sends a generic command to the session. It is up to the session creator
+     * to decide what commands and parameters they will support. As such,
+     * commands should only be sent to sessions that the controller owns.
+     *
+     * @param command The command to send
+     * @param args Any parameters to include with the command
+     * @param cb The callback to receive the result on
+     */
+    public void sendCommand(@NonNull String command, @Nullable Bundle args,
+            @Nullable ResultReceiver cb) {
+        if (TextUtils.isEmpty(command)) {
+            throw new IllegalArgumentException("command cannot be null or empty");
+        }
+        try {
+            mSessionBinder.sendCommand(mContext.getPackageName(), command, args, cb);
+        } catch (RemoteException e) {
+            Log.d(TAG, "Dead object in sendCommand.", e);
+        }
+    }
+
+    /**
+     * Get the session owner's package name.
+     *
+     * @return The package name of of the session owner.
+     */
+    public String getPackageName() {
+        if (mPackageName == null) {
+            try {
+                mPackageName = mSessionBinder.getPackageName();
+            } catch (RemoteException e) {
+                Log.d(TAG, "Dead object in getPackageName.", e);
+            }
+        }
+        return mPackageName;
+    }
+
+    /**
+     * Gets the additional session information which was set when the session was created.
+     *
+     * @return The additional session information, or an empty {@link Bundle} if not set.
+     */
+    @NonNull
+    public Bundle getSessionInfo() {
+        if (mSessionInfo != null) {
+            return new Bundle(mSessionInfo);
+        }
+
+        // Get info from the connected session.
+        try {
+            mSessionInfo = mSessionBinder.getSessionInfo();
+        } catch (RemoteException e) {
+            Log.d(TAG, "Dead object in getSessionInfo.", e);
+        }
+
+        if (mSessionInfo == null) {
+            Log.d(TAG, "sessionInfo is not set.");
+            mSessionInfo = Bundle.EMPTY;
+        } else if (MediaSession.hasCustomParcelable(mSessionInfo)) {
+            Log.w(TAG, "sessionInfo contains custom parcelable. Ignoring.");
+            mSessionInfo = Bundle.EMPTY;
+        }
+        return new Bundle(mSessionInfo);
+    }
+
+    /**
+     * Get the session's tag for debugging purposes.
+     *
+     * @return The session's tag.
+     */
+    @NonNull
+    public String getTag() {
+        if (mTag == null) {
+            try {
+                mTag = mSessionBinder.getTag();
+            } catch (RemoteException e) {
+                Log.d(TAG, "Dead object in getTag.", e);
+            }
+        }
+        return mTag;
+    }
+
+    /**
+     * @hide
+     * Returns whether this and {@code other} media controller controls the same session.
+     */
+    @UnsupportedAppUsage(publicAlternatives = "Check equality of {@link #getSessionToken() tokens} "
+            + "instead.", maxTargetSdk = Build.VERSION_CODES.R)
+    public boolean controlsSameSession(@Nullable MediaController other) {
+        if (other == null) return false;
+        return mToken.equals(other.mToken);
+    }
+
+    private void addCallbackLocked(Callback cb, Handler handler) {
+        if (getHandlerForCallbackLocked(cb) != null) {
+            Log.w(TAG, "Callback is already added, ignoring");
+            return;
+        }
+        MessageHandler holder = new MessageHandler(handler.getLooper(), cb);
+        mCallbacks.add(holder);
+        holder.mRegistered = true;
+
+        if (!mCbRegistered) {
+            try {
+                mSessionBinder.registerCallback(mContext.getPackageName(), mCbStub);
+                mCbRegistered = true;
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in registerCallback", e);
+            }
+        }
+    }
+
+    private boolean removeCallbackLocked(Callback cb) {
+        boolean success = false;
+        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mCallbacks.get(i);
+            if (cb == handler.mCallback) {
+                mCallbacks.remove(i);
+                success = true;
+                handler.mRegistered = false;
+            }
+        }
+        if (mCbRegistered && mCallbacks.size() == 0) {
+            try {
+                mSessionBinder.unregisterCallback(mCbStub);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Dead object in removeCallbackLocked");
+            }
+            mCbRegistered = false;
+        }
+        return success;
+    }
+
+    /**
+     * Gets associated handler for the given callback.
+     * @hide
+     */
+    @VisibleForTesting
+    public Handler getHandlerForCallback(Callback cb) {
+        synchronized (mLock) {
+            return getHandlerForCallbackLocked(cb);
+        }
+    }
+
+    private MessageHandler getHandlerForCallbackLocked(Callback cb) {
+        if (cb == null) {
+            throw new IllegalArgumentException("Callback cannot be null");
+        }
+        for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+            MessageHandler handler = mCallbacks.get(i);
+            if (cb == handler.mCallback) {
+                return handler;
+            }
+        }
+        return null;
+    }
+
+    private void postMessage(int what, Object obj, Bundle data) {
+        synchronized (mLock) {
+            for (int i = mCallbacks.size() - 1; i >= 0; i--) {
+                mCallbacks.get(i).post(what, obj, data);
+            }
+        }
+    }
+
+    /**
+     * Callback for receiving updates from the session. A Callback can be
+     * registered using {@link #registerCallback}.
+     */
+    public abstract static class Callback {
+        /**
+         * Override to handle the session being destroyed. The session is no
+         * longer valid after this call and calls to it will be ignored.
+         */
+        public void onSessionDestroyed() {
+        }
+
+        /**
+         * Override to handle custom events sent by the session owner without a
+         * specified interface. Controllers should only handle these for
+         * sessions they own.
+         *
+         * @param event The event from the session.
+         * @param extras Optional parameters for the event, may be null.
+         */
+        public void onSessionEvent(@NonNull String event, @Nullable Bundle extras) {
+        }
+
+        /**
+         * Override to handle changes in playback state.
+         *
+         * @param state The new playback state of the session
+         */
+        public void onPlaybackStateChanged(@Nullable PlaybackState state) {
+        }
+
+        /**
+         * Override to handle changes to the current metadata.
+         *
+         * @param metadata The current metadata for the session or null if none.
+         * @see MediaMetadata
+         */
+        public void onMetadataChanged(@Nullable MediaMetadata metadata) {
+        }
+
+        /**
+         * Override to handle changes to items in the queue.
+         *
+         * @param queue A list of items in the current play queue. It should
+         *            include the currently playing item as well as previous and
+         *            upcoming items if applicable.
+         * @see MediaSession.QueueItem
+         */
+        public void onQueueChanged(@Nullable List<MediaSession.QueueItem> queue) {
+        }
+
+        /**
+         * Override to handle changes to the queue title.
+         *
+         * @param title The title that should be displayed along with the play queue such as
+         *              "Now Playing". May be null if there is no such title.
+         */
+        public void onQueueTitleChanged(@Nullable CharSequence title) {
+        }
+
+        /**
+         * Override to handle changes to the {@link MediaSession} extras.
+         *
+         * @param extras The extras that can include other information associated with the
+         *               {@link MediaSession}.
+         */
+        public void onExtrasChanged(@Nullable Bundle extras) {
+        }
+
+        /**
+         * Override to handle changes to the audio info.
+         *
+         * @param info The current audio info for this session.
+         */
+        public void onAudioInfoChanged(PlaybackInfo info) {
+        }
+    }
+
+    /**
+     * Interface for controlling media playback on a session. This allows an app
+     * to send media transport commands to the session.
+     */
+    public final class TransportControls {
+        private static final String TAG = "TransportController";
+
+        private TransportControls() {
+        }
+
+        /**
+         * Request that the player prepare its playback. In other words, other sessions can continue
+         * to play during the preparation of this session. This method can be used to speed up the
+         * start of the playback. Once the preparation is done, the session will change its playback
+         * state to {@link PlaybackState#STATE_PAUSED}. Afterwards, {@link #play} can be called to
+         * start playback.
+         */
+        public void prepare() {
+            try {
+                mSessionBinder.prepare(mContext.getPackageName());
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling prepare.", e);
+            }
+        }
+
+        /**
+         * Request that the player prepare playback for a specific media id. In other words, other
+         * sessions can continue to play during the preparation of this session. This method can be
+         * used to speed up the start of the playback. Once the preparation is done, the session
+         * will change its playback state to {@link PlaybackState#STATE_PAUSED}. Afterwards,
+         * {@link #play} can be called to start playback. If the preparation is not needed,
+         * {@link #playFromMediaId} can be directly called without this method.
+         *
+         * @param mediaId The id of the requested media.
+         * @param extras Optional extras that can include extra information about the media item
+         *               to be prepared.
+         */
+        public void prepareFromMediaId(String mediaId, Bundle extras) {
+            if (TextUtils.isEmpty(mediaId)) {
+                throw new IllegalArgumentException(
+                        "You must specify a non-empty String for prepareFromMediaId.");
+            }
+            try {
+                mSessionBinder.prepareFromMediaId(mContext.getPackageName(), mediaId, extras);
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling prepare(" + mediaId + ").", e);
+            }
+        }
+
+        /**
+         * Request that the player prepare playback for a specific search query. An empty or null
+         * query should be treated as a request to prepare any music. In other words, other sessions
+         * can continue to play during the preparation of this session. This method can be used to
+         * speed up the start of the playback. Once the preparation is done, the session will
+         * change its playback state to {@link PlaybackState#STATE_PAUSED}. Afterwards,
+         * {@link #play} can be called to start playback. If the preparation is not needed,
+         * {@link #playFromSearch} can be directly called without this method.
+         *
+         * @param query The search query.
+         * @param extras Optional extras that can include extra information
+         *               about the query.
+         */
+        public void prepareFromSearch(String query, Bundle extras) {
+            if (query == null) {
+                // This is to remain compatible with
+                // INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
+                query = "";
+            }
+            try {
+                mSessionBinder.prepareFromSearch(mContext.getPackageName(), query, extras);
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling prepare(" + query + ").", e);
+            }
+        }
+
+        /**
+         * Request that the player prepare playback for a specific {@link Uri}. In other words,
+         * other sessions can continue to play during the preparation of this session. This method
+         * can be used to speed up the start of the playback. Once the preparation is done, the
+         * session will change its playback state to {@link PlaybackState#STATE_PAUSED}. Afterwards,
+         * {@link #play} can be called to start playback. If the preparation is not needed,
+         * {@link #playFromUri} can be directly called without this method.
+         *
+         * @param uri The URI of the requested media.
+         * @param extras Optional extras that can include extra information about the media item
+         *               to be prepared.
+         */
+        public void prepareFromUri(Uri uri, Bundle extras) {
+            if (uri == null || Uri.EMPTY.equals(uri)) {
+                throw new IllegalArgumentException(
+                        "You must specify a non-empty Uri for prepareFromUri.");
+            }
+            try {
+                mSessionBinder.prepareFromUri(mContext.getPackageName(), uri, extras);
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling prepare(" + uri + ").", e);
+            }
+        }
+
+        /**
+         * Request that the player start its playback at its current position.
+         */
+        public void play() {
+            try {
+                mSessionBinder.play(mContext.getPackageName());
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling play.", e);
+            }
+        }
+
+        /**
+         * Request that the player start playback for a specific media id.
+         *
+         * @param mediaId The id of the requested media.
+         * @param extras Optional extras that can include extra information about the media item
+         *               to be played.
+         */
+        public void playFromMediaId(String mediaId, Bundle extras) {
+            if (TextUtils.isEmpty(mediaId)) {
+                throw new IllegalArgumentException(
+                        "You must specify a non-empty String for playFromMediaId.");
+            }
+            try {
+                mSessionBinder.playFromMediaId(mContext.getPackageName(), mediaId, extras);
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling play(" + mediaId + ").", e);
+            }
+        }
+
+        /**
+         * Request that the player start playback for a specific search query.
+         * An empty or null query should be treated as a request to play any
+         * music.
+         *
+         * @param query The search query.
+         * @param extras Optional extras that can include extra information
+         *               about the query.
+         */
+        public void playFromSearch(String query, Bundle extras) {
+            if (query == null) {
+                // This is to remain compatible with
+                // INTENT_ACTION_MEDIA_PLAY_FROM_SEARCH
+                query = "";
+            }
+            try {
+                mSessionBinder.playFromSearch(mContext.getPackageName(), query, extras);
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling play(" + query + ").", e);
+            }
+        }
+
+        /**
+         * Request that the player start playback for a specific {@link Uri}.
+         *
+         * @param uri The URI of the requested media.
+         * @param extras Optional extras that can include extra information about the media item
+         *               to be played.
+         */
+        public void playFromUri(Uri uri, Bundle extras) {
+            if (uri == null || Uri.EMPTY.equals(uri)) {
+                throw new IllegalArgumentException(
+                        "You must specify a non-empty Uri for playFromUri.");
+            }
+            try {
+                mSessionBinder.playFromUri(mContext.getPackageName(), uri, extras);
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling play(" + uri + ").", e);
+            }
+        }
+
+        /**
+         * Play an item with a specific id in the play queue. If you specify an
+         * id that is not in the play queue, the behavior is undefined.
+         */
+        public void skipToQueueItem(long id) {
+            try {
+                mSessionBinder.skipToQueueItem(mContext.getPackageName(), id);
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling skipToItem(" + id + ").", e);
+            }
+        }
+
+        /**
+         * Request that the player pause its playback and stay at its current
+         * position.
+         */
+        public void pause() {
+            try {
+                mSessionBinder.pause(mContext.getPackageName());
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling pause.", e);
+            }
+        }
+
+        /**
+         * Request that the player stop its playback; it may clear its state in
+         * whatever way is appropriate.
+         */
+        public void stop() {
+            try {
+                mSessionBinder.stop(mContext.getPackageName());
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling stop.", e);
+            }
+        }
+
+        /**
+         * Move to a new location in the media stream.
+         *
+         * @param pos Position to move to, in milliseconds.
+         */
+        public void seekTo(long pos) {
+            try {
+                mSessionBinder.seekTo(mContext.getPackageName(), pos);
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling seekTo.", e);
+            }
+        }
+
+        /**
+         * Start fast forwarding. If playback is already fast forwarding this
+         * may increase the rate.
+         */
+        public void fastForward() {
+            try {
+                mSessionBinder.fastForward(mContext.getPackageName());
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling fastForward.", e);
+            }
+        }
+
+        /**
+         * Skip to the next item.
+         */
+        public void skipToNext() {
+            try {
+                mSessionBinder.next(mContext.getPackageName());
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling next.", e);
+            }
+        }
+
+        /**
+         * Start rewinding. If playback is already rewinding this may increase
+         * the rate.
+         */
+        public void rewind() {
+            try {
+                mSessionBinder.rewind(mContext.getPackageName());
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling rewind.", e);
+            }
+        }
+
+        /**
+         * Skip to the previous item.
+         */
+        public void skipToPrevious() {
+            try {
+                mSessionBinder.previous(mContext.getPackageName());
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling previous.", e);
+            }
+        }
+
+        /**
+         * Rate the current content. This will cause the rating to be set for
+         * the current user. The Rating type must match the type returned by
+         * {@link #getRatingType()}.
+         *
+         * @param rating The rating to set for the current content
+         */
+        public void setRating(Rating rating) {
+            try {
+                mSessionBinder.rate(mContext.getPackageName(), rating);
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling rate.", e);
+            }
+        }
+
+        /**
+         * Sets the playback speed. A value of {@code 1.0f} is the default playback value,
+         * and a negative value indicates reverse playback. {@code 0.0f} is not allowed.
+         *
+         * @param speed The playback speed
+         * @throws IllegalArgumentException if the {@code speed} is equal to zero.
+         */
+        public void setPlaybackSpeed(float speed) {
+            if (speed == 0.0f) {
+                throw new IllegalArgumentException("speed must not be zero");
+            }
+            try {
+                mSessionBinder.setPlaybackSpeed(mContext.getPackageName(), speed);
+            } catch (RemoteException e) {
+                Log.wtf(TAG, "Error calling setPlaybackSpeed.", e);
+            }
+        }
+
+        /**
+         * Send a custom action back for the {@link MediaSession} to perform.
+         *
+         * @param customAction The action to perform.
+         * @param args Optional arguments to supply to the {@link MediaSession} for this
+         *             custom action.
+         */
+        public void sendCustomAction(@NonNull PlaybackState.CustomAction customAction,
+                @Nullable Bundle args) {
+            if (customAction == null) {
+                throw new IllegalArgumentException("CustomAction cannot be null.");
+            }
+            sendCustomAction(customAction.getAction(), args);
+        }
+
+        /**
+         * Send the id and args from a custom action back for the {@link MediaSession} to perform.
+         *
+         * @see #sendCustomAction(PlaybackState.CustomAction action, Bundle args)
+         * @param action The action identifier of the {@link PlaybackState.CustomAction} as
+         *               specified by the {@link MediaSession}.
+         * @param args Optional arguments to supply to the {@link MediaSession} for this
+         *             custom action.
+         */
+        public void sendCustomAction(@NonNull String action, @Nullable Bundle args) {
+            if (TextUtils.isEmpty(action)) {
+                throw new IllegalArgumentException("CustomAction cannot be null.");
+            }
+            try {
+                mSessionBinder.sendCustomAction(mContext.getPackageName(), action, args);
+            } catch (RemoteException e) {
+                Log.d(TAG, "Dead object in sendCustomAction.", e);
+            }
+        }
+    }
+
+    /**
+     * Holds information about the current playback and how audio is handled for
+     * this session.
+     */
+    public static final class PlaybackInfo implements Parcelable {
+
+        /**
+         * @hide
+         */
+        @IntDef({PLAYBACK_TYPE_LOCAL, PLAYBACK_TYPE_REMOTE})
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface PlaybackType {}
+
+        /**
+         * The session uses local playback.
+         */
+        public static final int PLAYBACK_TYPE_LOCAL = 1;
+        /**
+         * The session uses remote playback.
+         */
+        public static final int PLAYBACK_TYPE_REMOTE = 2;
+
+        private final int mPlaybackType;
+        private final int mVolumeControl;
+        private final int mMaxVolume;
+        private final int mCurrentVolume;
+        private final AudioAttributes mAudioAttrs;
+        private final String mVolumeControlId;
+
+        /**
+         * Creates a new playback info.
+         *
+         * @param playbackType The playback type. Should be {@link #PLAYBACK_TYPE_LOCAL} or
+         *                     {@link #PLAYBACK_TYPE_REMOTE}
+         * @param volumeControl The volume control. Should be one of:
+         *                      {@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE},
+         *                      {@link VolumeProvider#VOLUME_CONTROL_RELATIVE}, and
+         *                      {@link VolumeProvider#VOLUME_CONTROL_FIXED}.
+         * @param maxVolume The max volume. Should be equal or greater than zero.
+         * @param currentVolume The current volume. Should be in the interval [0, maxVolume].
+         * @param audioAttrs The audio attributes for this playback. Should not be null.
+         * @param volumeControlId The volume control ID. This is used for matching
+         *                        {@link RoutingSessionInfo} and {@link MediaSession}.
+         * @hide
+         */
+        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+        public PlaybackInfo(@PlaybackType int playbackType, @ControlType int volumeControl,
+                @IntRange(from = 0) int maxVolume, @IntRange(from = 0) int currentVolume,
+                @NonNull AudioAttributes audioAttrs, @Nullable String volumeControlId) {
+            mPlaybackType = playbackType;
+            mVolumeControl = volumeControl;
+            mMaxVolume = maxVolume;
+            mCurrentVolume = currentVolume;
+            mAudioAttrs = audioAttrs;
+            mVolumeControlId = volumeControlId;
+        }
+
+        PlaybackInfo(Parcel in) {
+            mPlaybackType = in.readInt();
+            mVolumeControl = in.readInt();
+            mMaxVolume = in.readInt();
+            mCurrentVolume = in.readInt();
+            mAudioAttrs = in.readParcelable(null);
+            mVolumeControlId = in.readString();
+        }
+
+        /**
+         * Get the type of playback which affects volume handling. One of:
+         * <ul>
+         * <li>{@link #PLAYBACK_TYPE_LOCAL}</li>
+         * <li>{@link #PLAYBACK_TYPE_REMOTE}</li>
+         * </ul>
+         *
+         * @return The type of playback this session is using.
+         */
+        public int getPlaybackType() {
+            return mPlaybackType;
+        }
+
+        /**
+         * Get the type of volume control that can be used. One of:
+         * <ul>
+         * <li>{@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE}</li>
+         * <li>{@link VolumeProvider#VOLUME_CONTROL_RELATIVE}</li>
+         * <li>{@link VolumeProvider#VOLUME_CONTROL_FIXED}</li>
+         * </ul>
+         *
+         * @return The type of volume control that may be used with this session.
+         */
+        public int getVolumeControl() {
+            return mVolumeControl;
+        }
+
+        /**
+         * Get the maximum volume that may be set for this session.
+         *
+         * @return The maximum allowed volume where this session is playing.
+         */
+        public int getMaxVolume() {
+            return mMaxVolume;
+        }
+
+        /**
+         * Get the current volume for this session.
+         *
+         * @return The current volume where this session is playing.
+         */
+        public int getCurrentVolume() {
+            return mCurrentVolume;
+        }
+
+        /**
+         * Get the audio attributes for this session. The attributes will affect
+         * volume handling for the session. When the volume type is
+         * {@link PlaybackInfo#PLAYBACK_TYPE_REMOTE} these may be ignored by the
+         * remote volume handler.
+         *
+         * @return The attributes for this session.
+         */
+        public AudioAttributes getAudioAttributes() {
+            return mAudioAttrs;
+        }
+
+        /**
+         * Gets the volume control ID for this session. It can be used to identify which
+         * volume provider is used by the session.
+         * <p>
+         * When the session starts to use {@link #PLAYBACK_TYPE_REMOTE remote volume handling},
+         * a volume provider should be set and it may set the volume control ID of the provider
+         * if the session wants to inform which volume provider is used.
+         * It can be {@code null} if the session didn't set the volume control ID or it uses
+         * {@link #PLAYBACK_TYPE_LOCAL local playback}.
+         * </p>
+         *
+         * @return the volume control ID for this session or {@code null} if it uses local playback
+         * or not set.
+         * @see VolumeProvider#getVolumeControlId()
+         */
+        @Nullable
+        public String getVolumeControlId() {
+            return mVolumeControlId;
+        }
+
+        @Override
+        public String toString() {
+            return "playbackType=" + mPlaybackType + ", volumeControlType=" + mVolumeControl
+                    + ", maxVolume=" + mMaxVolume + ", currentVolume=" + mCurrentVolume
+                    + ", audioAttrs=" + mAudioAttrs + ", volumeControlId=" + mVolumeControlId;
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(mPlaybackType);
+            dest.writeInt(mVolumeControl);
+            dest.writeInt(mMaxVolume);
+            dest.writeInt(mCurrentVolume);
+            dest.writeParcelable(mAudioAttrs, flags);
+            dest.writeString(mVolumeControlId);
+        }
+
+        public static final @android.annotation.NonNull Parcelable.Creator<PlaybackInfo> CREATOR =
+                new Parcelable.Creator<PlaybackInfo>() {
+            @Override
+            public PlaybackInfo createFromParcel(Parcel in) {
+                return new PlaybackInfo(in);
+            }
+
+            @Override
+            public PlaybackInfo[] newArray(int size) {
+                return new PlaybackInfo[size];
+            }
+        };
+    }
+
+    private static final class CallbackStub extends ISessionControllerCallback.Stub {
+        private final WeakReference<MediaController> mController;
+
+        CallbackStub(MediaController controller) {
+            mController = new WeakReference<MediaController>(controller);
+        }
+
+        @Override
+        public void onSessionDestroyed() {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                controller.postMessage(MSG_DESTROYED, null, null);
+            }
+        }
+
+        @Override
+        public void onEvent(String event, Bundle extras) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                controller.postMessage(MSG_EVENT, event, extras);
+            }
+        }
+
+        @Override
+        public void onPlaybackStateChanged(PlaybackState state) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                controller.postMessage(MSG_UPDATE_PLAYBACK_STATE, state, null);
+            }
+        }
+
+        @Override
+        public void onMetadataChanged(MediaMetadata metadata) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                controller.postMessage(MSG_UPDATE_METADATA, metadata, null);
+            }
+        }
+
+        @Override
+        public void onQueueChanged(ParceledListSlice queue) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                controller.postMessage(MSG_UPDATE_QUEUE, queue, null);
+            }
+        }
+
+        @Override
+        public void onQueueTitleChanged(CharSequence title) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                controller.postMessage(MSG_UPDATE_QUEUE_TITLE, title, null);
+            }
+        }
+
+        @Override
+        public void onExtrasChanged(Bundle extras) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                controller.postMessage(MSG_UPDATE_EXTRAS, extras, null);
+            }
+        }
+
+        @Override
+        public void onVolumeInfoChanged(PlaybackInfo info) {
+            MediaController controller = mController.get();
+            if (controller != null) {
+                controller.postMessage(MSG_UPDATE_VOLUME, info, null);
+            }
+        }
+    }
+
+    private static final class MessageHandler extends Handler {
+        private final MediaController.Callback mCallback;
+        private boolean mRegistered = false;
+
+        MessageHandler(Looper looper, MediaController.Callback cb) {
+            super(looper);
+            mCallback = cb;
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (!mRegistered) {
+                return;
+            }
+            switch (msg.what) {
+                case MSG_EVENT:
+                    mCallback.onSessionEvent((String) msg.obj, msg.getData());
+                    break;
+                case MSG_UPDATE_PLAYBACK_STATE:
+                    mCallback.onPlaybackStateChanged((PlaybackState) msg.obj);
+                    break;
+                case MSG_UPDATE_METADATA:
+                    mCallback.onMetadataChanged((MediaMetadata) msg.obj);
+                    break;
+                case MSG_UPDATE_QUEUE:
+                    mCallback.onQueueChanged(msg.obj == null ? null :
+                            (List<QueueItem>) ((ParceledListSlice) msg.obj).getList());
+                    break;
+                case MSG_UPDATE_QUEUE_TITLE:
+                    mCallback.onQueueTitleChanged((CharSequence) msg.obj);
+                    break;
+                case MSG_UPDATE_EXTRAS:
+                    mCallback.onExtrasChanged((Bundle) msg.obj);
+                    break;
+                case MSG_UPDATE_VOLUME:
+                    mCallback.onAudioInfoChanged((PlaybackInfo) msg.obj);
+                    break;
+                case MSG_DESTROYED:
+                    mCallback.onSessionDestroyed();
+                    break;
+            }
+        }
+
+        public void post(int what, Object obj, Bundle data) {
+            Message msg = obtainMessage(what, obj);
+            msg.setAsynchronous(true);
+            msg.setData(data);
+            msg.sendToTarget();
+        }
+    }
+
+}
diff --git a/android/media/session/MediaSession.java b/android/media/session/MediaSession.java
new file mode 100644
index 0000000..20fa53d
--- /dev/null
+++ b/android/media/session/MediaSession.java
@@ -0,0 +1,1674 @@
+/*
+ * Copyright (C) 2014 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.session;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.media.AudioAttributes;
+import android.media.MediaDescription;
+import android.media.MediaMetadata;
+import android.media.Rating;
+import android.media.VolumeProvider;
+import android.media.session.MediaSessionManager.RemoteUserInfo;
+import android.net.Uri;
+import android.os.BadParcelableException;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.service.media.MediaBrowserService;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
+import android.view.KeyEvent;
+import android.view.ViewConfiguration;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * Allows interaction with media controllers, volume keys, media buttons, and
+ * transport controls.
+ * <p>
+ * A MediaSession should be created when an app wants to publish media playback
+ * information or handle media keys. In general an app only needs one session
+ * for all playback, though multiple sessions can be created to provide finer
+ * grain controls of media.
+ * <p>
+ * Once a session is created the owner of the session may pass its
+ * {@link #getSessionToken() session token} to other processes to allow them to
+ * create a {@link MediaController} to interact with the session.
+ * <p>
+ * To receive commands, media keys, and other events a {@link Callback} must be
+ * set with {@link #setCallback(Callback)} and {@link #setActive(boolean)
+ * setActive(true)} must be called.
+ * <p>
+ * When an app is finished performing playback it must call {@link #release()}
+ * to clean up the session and notify any controllers.
+ * <p>
+ * MediaSession objects are thread safe.
+ */
+public final class MediaSession {
+    static final String TAG = "MediaSession";
+
+    /**
+     * Set this flag on the session to indicate that it can handle media button
+     * events.
+     * @deprecated This flag is no longer used. All media sessions are expected to handle media
+     * button events now.
+     */
+    @Deprecated
+    public static final int FLAG_HANDLES_MEDIA_BUTTONS = 1 << 0;
+
+    /**
+     * Set this flag on the session to indicate that it handles transport
+     * control commands through its {@link Callback}.
+     * @deprecated This flag is no longer used. All media sessions are expected to handle transport
+     * controls now.
+     */
+    @Deprecated
+    public static final int FLAG_HANDLES_TRANSPORT_CONTROLS = 1 << 1;
+
+    /**
+     * System only flag for a session that needs to have priority over all other
+     * sessions. This flag ensures this session will receive media button events
+     * regardless of the current ordering in the system.
+     * If there are two or more sessions with this flag, the last session that sets this flag
+     * will be the global priority session.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int FLAG_EXCLUSIVE_GLOBAL_PRIORITY = 1 << 16;
+
+    /**
+     * @hide
+     */
+    public static final int INVALID_UID = -1;
+
+    /**
+     * @hide
+     */
+    public static final int INVALID_PID = -1;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true, value = {
+            FLAG_HANDLES_MEDIA_BUTTONS,
+            FLAG_HANDLES_TRANSPORT_CONTROLS,
+            FLAG_EXCLUSIVE_GLOBAL_PRIORITY })
+    public @interface SessionFlags { }
+
+    private final Object mLock = new Object();
+    private Context mContext;
+    private final int mMaxBitmapSize;
+
+    private final Token mSessionToken;
+    private final MediaController mController;
+    private final ISession mBinder;
+    private final CallbackStub mCbStub;
+
+    // Do not change the name of mCallback. Support lib accesses this by using reflection.
+    @UnsupportedAppUsage
+    private CallbackMessageHandler mCallback;
+    private VolumeProvider mVolumeProvider;
+    private PlaybackState mPlaybackState;
+
+    private boolean mActive = false;
+
+    /**
+     * Creates a new session. The session will automatically be registered with
+     * the system but will not be published until {@link #setActive(boolean)
+     * setActive(true)} is called. You must call {@link #release()} when
+     * finished with the session.
+     * <p>
+     * Note that {@link RuntimeException} will be thrown if an app creates too many sessions.
+     *
+     * @param context The context to use to create the session.
+     * @param tag A short name for debugging purposes.
+     */
+    public MediaSession(@NonNull Context context, @NonNull String tag) {
+        this(context, tag, null);
+    }
+
+    /**
+     * Creates a new session. The session will automatically be registered with
+     * the system but will not be published until {@link #setActive(boolean)
+     * setActive(true)} is called. You must call {@link #release()} when
+     * finished with the session.
+     * <p>
+     * The {@code sessionInfo} can include additional unchanging information about this session.
+     * For example, it can include the version of the application, or the list of the custom
+     * commands that this session supports.
+     * <p>
+     * Note that {@link RuntimeException} will be thrown if an app creates too many sessions.
+     *
+     * @param context The context to use to create the session.
+     * @param tag A short name for debugging purposes.
+     * @param sessionInfo A bundle for additional information about this session.
+     *                    Controllers can get this information by calling
+     *                    {@link MediaController#getSessionInfo()}.
+     *                    An {@link IllegalArgumentException} will be thrown if this contains
+     *                    any non-framework Parcelable objects.
+     */
+    public MediaSession(@NonNull Context context, @NonNull String tag,
+            @Nullable Bundle sessionInfo) {
+        if (context == null) {
+            throw new IllegalArgumentException("context cannot be null.");
+        }
+        if (TextUtils.isEmpty(tag)) {
+            throw new IllegalArgumentException("tag cannot be null or empty");
+        }
+        if (hasCustomParcelable(sessionInfo)) {
+            throw new IllegalArgumentException("sessionInfo shouldn't contain any custom "
+                    + "parcelables");
+        }
+
+        mContext = context;
+        mMaxBitmapSize = context.getResources().getDimensionPixelSize(
+                com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize);
+        mCbStub = new CallbackStub(this);
+        MediaSessionManager manager = (MediaSessionManager) context
+                .getSystemService(Context.MEDIA_SESSION_SERVICE);
+        try {
+            mBinder = manager.createSession(mCbStub, tag, sessionInfo);
+            mSessionToken = new Token(Process.myUid(), mBinder.getController());
+            mController = new MediaController(context, mSessionToken);
+        } catch (RemoteException e) {
+            throw new RuntimeException("Remote error creating session.", e);
+        }
+    }
+
+    /**
+     * Set the callback to receive updates for the MediaSession. This includes
+     * media button events and transport controls. The caller's thread will be
+     * used to post updates.
+     * <p>
+     * Set the callback to null to stop receiving updates.
+     *
+     * @param callback The callback object
+     */
+    public void setCallback(@Nullable Callback callback) {
+        setCallback(callback, null);
+    }
+
+    /**
+     * Set the callback to receive updates for the MediaSession. This includes
+     * media button events and transport controls.
+     * <p>
+     * Set the callback to null to stop receiving updates.
+     *
+     * @param callback The callback to receive updates on.
+     * @param handler The handler that events should be posted on.
+     */
+    public void setCallback(@Nullable Callback callback, @Nullable Handler handler) {
+        synchronized (mLock) {
+            if (mCallback != null) {
+                // We're updating the callback, clear the session from the old one.
+                mCallback.mCallback.mSession = null;
+                mCallback.removeCallbacksAndMessages(null);
+            }
+            if (callback == null) {
+                mCallback = null;
+                return;
+            }
+            if (handler == null) {
+                handler = new Handler();
+            }
+            callback.mSession = this;
+            CallbackMessageHandler msgHandler = new CallbackMessageHandler(handler.getLooper(),
+                    callback);
+            mCallback = msgHandler;
+        }
+    }
+
+    /**
+     * Set an intent for launching UI for this Session. This can be used as a
+     * quick link to an ongoing media screen. The intent should be for an
+     * activity that may be started using {@link Activity#startActivity(Intent)}.
+     *
+     * @param pi The intent to launch to show UI for this Session.
+     */
+    public void setSessionActivity(@Nullable PendingIntent pi) {
+        try {
+            mBinder.setLaunchPendingIntent(pi);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Failure in setLaunchPendingIntent.", e);
+        }
+    }
+
+    /**
+     * Set a pending intent for your media button receiver to allow restarting
+     * playback after the session has been stopped. If your app is started in
+     * this way an {@link Intent#ACTION_MEDIA_BUTTON} intent will be sent via
+     * the pending intent.
+     * <p>
+     * The pending intent is recommended to be explicit to follow the security recommendation of
+     * {@link PendingIntent#getActivity}.
+     *
+     * @param mbr The {@link PendingIntent} to send the media button event to.
+     * @see PendingIntent#getActivity
+     *
+     * @deprecated Use {@link #setMediaButtonBroadcastReceiver(ComponentName)} instead.
+     */
+    @Deprecated
+    public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
+        try {
+            mBinder.setMediaButtonReceiver(mbr, mContext.getPackageName());
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
+        }
+    }
+
+    /**
+     * Set the component name of the manifest-declared {@link android.content.BroadcastReceiver}
+     * class that should receive media buttons. This allows restarting playback after the session
+     * has been stopped. If your app is started in this way an {@link Intent#ACTION_MEDIA_BUTTON}
+     * intent will be sent to the broadcast receiver.
+     * <p>
+     * Note: The given {@link android.content.BroadcastReceiver} should belong to the same package
+     * as the context that was given when creating {@link MediaSession}.
+     *
+     * @param broadcastReceiver the component name of the BroadcastReceiver class
+     */
+    public void setMediaButtonBroadcastReceiver(@Nullable ComponentName broadcastReceiver) {
+        try {
+            if (broadcastReceiver != null) {
+                if (!TextUtils.equals(broadcastReceiver.getPackageName(),
+                        mContext.getPackageName())) {
+                    throw new IllegalArgumentException("broadcastReceiver should belong to the same"
+                            + " package as the context given when creating MediaSession.");
+                }
+            }
+            mBinder.setMediaButtonBroadcastReceiver(broadcastReceiver);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Failure in setMediaButtonBroadcastReceiver.", e);
+        }
+    }
+
+    /**
+     * Set any flags for the session.
+     *
+     * @param flags The flags to set for this session.
+     */
+    public void setFlags(@SessionFlags int flags) {
+        try {
+            mBinder.setFlags(flags);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Failure in setFlags.", e);
+        }
+    }
+
+    /**
+     * Set the attributes for this session's audio. This will affect the
+     * system's volume handling for this session. If
+     * {@link #setPlaybackToRemote} was previously called it will stop receiving
+     * volume commands and the system will begin sending volume changes to the
+     * appropriate stream.
+     * <p>
+     * By default sessions use attributes for media.
+     *
+     * @param attributes The {@link AudioAttributes} for this session's audio.
+     */
+    public void setPlaybackToLocal(AudioAttributes attributes) {
+        if (attributes == null) {
+            throw new IllegalArgumentException("Attributes cannot be null for local playback.");
+        }
+        try {
+            mBinder.setPlaybackToLocal(attributes);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Failure in setPlaybackToLocal.", e);
+        }
+    }
+
+    /**
+     * Configure this session to use remote volume handling. This must be called
+     * to receive volume button events, otherwise the system will adjust the
+     * appropriate stream volume for this session. If
+     * {@link #setPlaybackToLocal} was previously called the system will stop
+     * handling volume changes for this session and pass them to the volume
+     * provider instead.
+     *
+     * @param volumeProvider The provider that will handle volume changes. May
+     *            not be null.
+     */
+    public void setPlaybackToRemote(@NonNull VolumeProvider volumeProvider) {
+        if (volumeProvider == null) {
+            throw new IllegalArgumentException("volumeProvider may not be null!");
+        }
+        synchronized (mLock) {
+            mVolumeProvider = volumeProvider;
+        }
+        volumeProvider.setCallback(new VolumeProvider.Callback() {
+            @Override
+            public void onVolumeChanged(VolumeProvider volumeProvider) {
+                notifyRemoteVolumeChanged(volumeProvider);
+            }
+        });
+
+        try {
+            mBinder.setPlaybackToRemote(volumeProvider.getVolumeControl(),
+                    volumeProvider.getMaxVolume(), volumeProvider.getVolumeControlId());
+            mBinder.setCurrentVolume(volumeProvider.getCurrentVolume());
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Failure in setPlaybackToRemote.", e);
+        }
+    }
+
+    /**
+     * Set if this session is currently active and ready to receive commands. If
+     * set to false your session's controller may not be discoverable. You must
+     * set the session to active before it can start receiving media button
+     * events or transport commands.
+     *
+     * @param active Whether this session is active or not.
+     */
+    public void setActive(boolean active) {
+        if (mActive == active) {
+            return;
+        }
+        try {
+            mBinder.setActive(active);
+            mActive = active;
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Failure in setActive.", e);
+        }
+    }
+
+    /**
+     * Get the current active state of this session.
+     *
+     * @return True if the session is active, false otherwise.
+     */
+    public boolean isActive() {
+        return mActive;
+    }
+
+    /**
+     * Send a proprietary event to all MediaControllers listening to this
+     * Session. It's up to the Controller/Session owner to determine the meaning
+     * of any events.
+     *
+     * @param event The name of the event to send
+     * @param extras Any extras included with the event
+     */
+    public void sendSessionEvent(@NonNull String event, @Nullable Bundle extras) {
+        if (TextUtils.isEmpty(event)) {
+            throw new IllegalArgumentException("event cannot be null or empty");
+        }
+        try {
+            mBinder.sendEvent(event, extras);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error sending event", e);
+        }
+    }
+
+    /**
+     * This must be called when an app has finished performing playback. If
+     * playback is expected to start again shortly the session can be left open,
+     * but it must be released if your activity or service is being destroyed.
+     */
+    public void release() {
+        try {
+            mBinder.destroySession();
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error releasing session: ", e);
+        }
+    }
+
+    /**
+     * Retrieve a token object that can be used by apps to create a
+     * {@link MediaController} for interacting with this session. The owner of
+     * the session is responsible for deciding how to distribute these tokens.
+     *
+     * @return A token that can be used to create a MediaController for this
+     *         session
+     */
+    public @NonNull Token getSessionToken() {
+        return mSessionToken;
+    }
+
+    /**
+     * Get a controller for this session. This is a convenience method to avoid
+     * having to cache your own controller in process.
+     *
+     * @return A controller for this session.
+     */
+    public @NonNull MediaController getController() {
+        return mController;
+    }
+
+    /**
+     * Update the current playback state.
+     *
+     * @param state The current state of playback
+     */
+    public void setPlaybackState(@Nullable PlaybackState state) {
+        mPlaybackState = state;
+        try {
+            mBinder.setPlaybackState(state);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Dead object in setPlaybackState.", e);
+        }
+    }
+
+    /**
+     * Update the current metadata. New metadata can be created using
+     * {@link android.media.MediaMetadata.Builder}. This operation may take time proportional to
+     * the size of the bitmap to replace large bitmaps with a scaled down copy.
+     *
+     * @param metadata The new metadata
+     * @see android.media.MediaMetadata.Builder#putBitmap
+     */
+    public void setMetadata(@Nullable MediaMetadata metadata) {
+        long duration = -1;
+        int fields = 0;
+        MediaDescription description = null;
+        if (metadata != null) {
+            metadata = new MediaMetadata.Builder(metadata)
+                    .setBitmapDimensionLimit(mMaxBitmapSize)
+                    .build();
+            if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
+                duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
+            }
+            fields = metadata.size();
+            description = metadata.getDescription();
+        }
+        String metadataDescription = "size=" + fields + ", description=" + description;
+
+        try {
+            mBinder.setMetadata(metadata, duration, metadataDescription);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Dead object in setPlaybackState.", e);
+        }
+    }
+
+    /**
+     * Update the list of items in the play queue. It is an ordered list and
+     * should contain the current item, and previous or upcoming items if they
+     * exist. Specify null if there is no current play queue.
+     * <p>
+     * The queue should be of reasonable size. If the play queue is unbounded
+     * within your app, it is better to send a reasonable amount in a sliding
+     * window instead.
+     *
+     * @param queue A list of items in the play queue.
+     */
+    public void setQueue(@Nullable List<QueueItem> queue) {
+        try {
+            if (queue == null) {
+                mBinder.resetQueue();
+            } else {
+                IBinder binder = mBinder.getBinderForSetQueue();
+                ParcelableListBinder.send(binder, queue);
+            }
+        } catch (RemoteException e) {
+            Log.wtf("Dead object in setQueue.", e);
+        }
+    }
+
+    /**
+     * Set the title of the play queue. The UI should display this title along
+     * with the play queue itself.
+     * e.g. "Play Queue", "Now Playing", or an album name.
+     *
+     * @param title The title of the play queue.
+     */
+    public void setQueueTitle(@Nullable CharSequence title) {
+        try {
+            mBinder.setQueueTitle(title);
+        } catch (RemoteException e) {
+            Log.wtf("Dead object in setQueueTitle.", e);
+        }
+    }
+
+    /**
+     * Set the style of rating used by this session. Apps trying to set the
+     * rating should use this style. Must be one of the following:
+     * <ul>
+     * <li>{@link Rating#RATING_NONE}</li>
+     * <li>{@link Rating#RATING_3_STARS}</li>
+     * <li>{@link Rating#RATING_4_STARS}</li>
+     * <li>{@link Rating#RATING_5_STARS}</li>
+     * <li>{@link Rating#RATING_HEART}</li>
+     * <li>{@link Rating#RATING_PERCENTAGE}</li>
+     * <li>{@link Rating#RATING_THUMB_UP_DOWN}</li>
+     * </ul>
+     */
+    public void setRatingType(@Rating.Style int type) {
+        try {
+            mBinder.setRatingType(type);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error in setRatingType.", e);
+        }
+    }
+
+    /**
+     * Set some extras that can be associated with the {@link MediaSession}. No assumptions should
+     * be made as to how a {@link MediaController} will handle these extras.
+     * Keys should be fully qualified (e.g. com.example.MY_EXTRA) to avoid conflicts.
+     *
+     * @param extras The extras associated with the {@link MediaSession}.
+     */
+    public void setExtras(@Nullable Bundle extras) {
+        try {
+            mBinder.setExtras(extras);
+        } catch (RemoteException e) {
+            Log.wtf("Dead object in setExtras.", e);
+        }
+    }
+
+    /**
+     * Gets the controller information who sent the current request.
+     * <p>
+     * Note: This is only valid while in a request callback, such as {@link Callback#onPlay}.
+     *
+     * @throws IllegalStateException If this method is called outside of {@link Callback} methods.
+     * @see MediaSessionManager#isTrustedForMediaControl(RemoteUserInfo)
+     */
+    public final @NonNull RemoteUserInfo getCurrentControllerInfo() {
+        if (mCallback == null || mCallback.mCurrentControllerInfo == null) {
+            throw new IllegalStateException(
+                    "This should be called inside of MediaSession.Callback methods");
+        }
+        return mCallback.mCurrentControllerInfo;
+    }
+
+    /**
+     * Notify the system that the remote volume changed.
+     *
+     * @param provider The provider that is handling volume changes.
+     * @hide
+     */
+    public void notifyRemoteVolumeChanged(VolumeProvider provider) {
+        synchronized (mLock) {
+            if (provider == null || provider != mVolumeProvider) {
+                Log.w(TAG, "Received update from stale volume provider");
+                return;
+            }
+        }
+        try {
+            mBinder.setCurrentVolume(provider.getCurrentVolume());
+        } catch (RemoteException e) {
+            Log.e(TAG, "Error in notifyVolumeChanged", e);
+        }
+    }
+
+    /**
+     * Returns the name of the package that sent the last media button, transport control, or
+     * command from controllers and the system. This is only valid while in a request callback, such
+     * as {@link Callback#onPlay}.
+     *
+     * @hide
+     */
+    @UnsupportedAppUsage
+    public String getCallingPackage() {
+        if (mCallback != null && mCallback.mCurrentControllerInfo != null) {
+            return mCallback.mCurrentControllerInfo.getPackageName();
+        }
+        return null;
+    }
+
+    /**
+     * Returns whether the given bundle includes non-framework Parcelables.
+     */
+    static boolean hasCustomParcelable(@Nullable Bundle bundle) {
+        if (bundle == null) {
+            return false;
+        }
+
+        // Try writing the bundle to parcel, and read it with framework classloader.
+        Parcel parcel = null;
+        try {
+            parcel = Parcel.obtain();
+            parcel.writeBundle(bundle);
+            parcel.setDataPosition(0);
+            Bundle out = parcel.readBundle(null);
+
+            // Calling Bundle#size() will trigger Bundle#unparcel().
+            out.size();
+        } catch (BadParcelableException e) {
+            Log.d(TAG, "Custom parcelable in bundle.", e);
+            return true;
+        } finally {
+            if (parcel != null) {
+                parcel.recycle();
+            }
+        }
+        return false;
+    }
+
+    void dispatchPrepare(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE, null, null);
+    }
+
+    void dispatchPrepareFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_MEDIA_ID, mediaId, extras);
+    }
+
+    void dispatchPrepareFromSearch(RemoteUserInfo caller, String query, Bundle extras) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_SEARCH, query, extras);
+    }
+
+    void dispatchPrepareFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_URI, uri, extras);
+    }
+
+    void dispatchPlay(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PLAY, null, null);
+    }
+
+    void dispatchPlayFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PLAY_MEDIA_ID, mediaId, extras);
+    }
+
+    void dispatchPlayFromSearch(RemoteUserInfo caller, String query, Bundle extras) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras);
+    }
+
+    void dispatchPlayFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PLAY_URI, uri, extras);
+    }
+
+    void dispatchSkipToItem(RemoteUserInfo caller, long id) {
+        postToCallback(caller, CallbackMessageHandler.MSG_SKIP_TO_ITEM, id, null);
+    }
+
+    void dispatchPause(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PAUSE, null, null);
+    }
+
+    void dispatchStop(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_STOP, null, null);
+    }
+
+    void dispatchNext(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_NEXT, null, null);
+    }
+
+    void dispatchPrevious(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PREVIOUS, null, null);
+    }
+
+    void dispatchFastForward(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_FAST_FORWARD, null, null);
+    }
+
+    void dispatchRewind(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_REWIND, null, null);
+    }
+
+    void dispatchSeekTo(RemoteUserInfo caller, long pos) {
+        postToCallback(caller, CallbackMessageHandler.MSG_SEEK_TO, pos, null);
+    }
+
+    void dispatchRate(RemoteUserInfo caller, Rating rating) {
+        postToCallback(caller, CallbackMessageHandler.MSG_RATE, rating, null);
+    }
+
+    void dispatchSetPlaybackSpeed(RemoteUserInfo caller, float speed) {
+        postToCallback(caller, CallbackMessageHandler.MSG_SET_PLAYBACK_SPEED, speed, null);
+    }
+
+    void dispatchCustomAction(RemoteUserInfo caller, String action, Bundle args) {
+        postToCallback(caller, CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args);
+    }
+
+    void dispatchMediaButton(RemoteUserInfo caller, Intent mediaButtonIntent) {
+        postToCallback(caller, CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent, null);
+    }
+
+    void dispatchMediaButtonDelayed(RemoteUserInfo info, Intent mediaButtonIntent,
+            long delay) {
+        postToCallbackDelayed(info, CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT,
+                mediaButtonIntent, null, delay);
+    }
+
+    void dispatchAdjustVolume(RemoteUserInfo caller, int direction) {
+        postToCallback(caller, CallbackMessageHandler.MSG_ADJUST_VOLUME, direction, null);
+    }
+
+    void dispatchSetVolumeTo(RemoteUserInfo caller, int volume) {
+        postToCallback(caller, CallbackMessageHandler.MSG_SET_VOLUME, volume, null);
+    }
+
+    void dispatchCommand(RemoteUserInfo caller, String command, Bundle args,
+            ResultReceiver resultCb) {
+        Command cmd = new Command(command, args, resultCb);
+        postToCallback(caller, CallbackMessageHandler.MSG_COMMAND, cmd, null);
+    }
+
+    void postToCallback(RemoteUserInfo caller, int what, Object obj, Bundle data) {
+        postToCallbackDelayed(caller, what, obj, data, 0);
+    }
+
+    void postToCallbackDelayed(RemoteUserInfo caller, int what, Object obj, Bundle data,
+            long delay) {
+        synchronized (mLock) {
+            if (mCallback != null) {
+                mCallback.post(caller, what, obj, data, delay);
+            }
+        }
+    }
+
+    /**
+     * Represents an ongoing session. This may be passed to apps by the session
+     * owner to allow them to create a {@link MediaController} to communicate with
+     * the session.
+     */
+    public static final class Token implements Parcelable {
+
+        private final int mUid;
+        private final ISessionController mBinder;
+
+        /**
+         * @hide
+         */
+        public Token(int uid, ISessionController binder) {
+            mUid = uid;
+            mBinder = binder;
+        }
+
+        Token(Parcel in) {
+            mUid = in.readInt();
+            mBinder = ISessionController.Stub.asInterface(in.readStrongBinder());
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeInt(mUid);
+            dest.writeStrongBinder(mBinder.asBinder());
+        }
+
+        @Override
+        public int hashCode() {
+            final int prime = 31;
+            int result = mUid;
+            result = prime * result + (mBinder == null ? 0 : mBinder.asBinder().hashCode());
+            return result;
+        }
+
+        @Override
+        public boolean equals(Object obj) {
+            if (this == obj)
+                return true;
+            if (obj == null)
+                return false;
+            if (getClass() != obj.getClass())
+                return false;
+            Token other = (Token) obj;
+            if (mUid != other.mUid) {
+                return false;
+            }
+            if (mBinder == null || other.mBinder == null) {
+                return mBinder == other.mBinder;
+            }
+            return Objects.equals(mBinder.asBinder(), other.mBinder.asBinder());
+        }
+
+        /**
+         * Gets the UID of the application that created the media session.
+         * @hide
+         */
+        @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+        public int getUid() {
+            return mUid;
+        }
+
+        /**
+         * Gets the controller binder in this token.
+         * @hide
+         */
+        public ISessionController getBinder() {
+            return mBinder;
+        }
+
+        public static final @android.annotation.NonNull Parcelable.Creator<Token> CREATOR =
+                new Parcelable.Creator<Token>() {
+            @Override
+            public Token createFromParcel(Parcel in) {
+                return new Token(in);
+            }
+
+            @Override
+            public Token[] newArray(int size) {
+                return new Token[size];
+            }
+        };
+    }
+
+    /**
+     * Receives media buttons, transport controls, and commands from controllers
+     * and the system. A callback may be set using {@link #setCallback}.
+     */
+    public abstract static class Callback {
+
+        private MediaSession mSession;
+        private CallbackMessageHandler mHandler;
+        private boolean mMediaPlayPauseKeyPending;
+
+        public Callback() {
+        }
+
+        /**
+         * Called when a controller has sent a command to this session.
+         * The owner of the session may handle custom commands but is not
+         * required to.
+         *
+         * @param command The command name.
+         * @param args Optional parameters for the command, may be null.
+         * @param cb A result receiver to which a result may be sent by the command, may be null.
+         */
+        public void onCommand(@NonNull String command, @Nullable Bundle args,
+                @Nullable ResultReceiver cb) {
+        }
+
+        /**
+         * Called when a media button is pressed and this session has the
+         * highest priority or a controller sends a media button event to the
+         * session. The default behavior will call the relevant method if the
+         * action for it was set.
+         * <p>
+         * The intent will be of type {@link Intent#ACTION_MEDIA_BUTTON} with a
+         * KeyEvent in {@link Intent#EXTRA_KEY_EVENT}
+         *
+         * @param mediaButtonIntent an intent containing the KeyEvent as an
+         *            extra
+         * @return True if the event was handled, false otherwise.
+         */
+        public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) {
+            if (mSession != null && mHandler != null
+                    && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) {
+                KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+                if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) {
+                    PlaybackState state = mSession.mPlaybackState;
+                    long validActions = state == null ? 0 : state.getActions();
+                    switch (ke.getKeyCode()) {
+                        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+                        case KeyEvent.KEYCODE_HEADSETHOOK:
+                            if (ke.getRepeatCount() > 0) {
+                                // Consider long-press as a single tap.
+                                handleMediaPlayPauseKeySingleTapIfPending();
+                            } else if (mMediaPlayPauseKeyPending) {
+                                // Consider double tap as the next.
+                                mHandler.removeMessages(CallbackMessageHandler
+                                        .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
+                                mMediaPlayPauseKeyPending = false;
+                                if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) {
+                                    onSkipToNext();
+                                }
+                            } else {
+                                mMediaPlayPauseKeyPending = true;
+                                mSession.dispatchMediaButtonDelayed(
+                                        mSession.getCurrentControllerInfo(),
+                                        mediaButtonIntent, ViewConfiguration.getDoubleTapTimeout());
+                            }
+                            return true;
+                        default:
+                            // If another key is pressed within double tap timeout, consider the
+                            // pending play/pause as a single tap to handle media keys in order.
+                            handleMediaPlayPauseKeySingleTapIfPending();
+                            break;
+                    }
+
+                    switch (ke.getKeyCode()) {
+                        case KeyEvent.KEYCODE_MEDIA_PLAY:
+                            if ((validActions & PlaybackState.ACTION_PLAY) != 0) {
+                                onPlay();
+                                return true;
+                            }
+                            break;
+                        case KeyEvent.KEYCODE_MEDIA_PAUSE:
+                            if ((validActions & PlaybackState.ACTION_PAUSE) != 0) {
+                                onPause();
+                                return true;
+                            }
+                            break;
+                        case KeyEvent.KEYCODE_MEDIA_NEXT:
+                            if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) {
+                                onSkipToNext();
+                                return true;
+                            }
+                            break;
+                        case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+                            if ((validActions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0) {
+                                onSkipToPrevious();
+                                return true;
+                            }
+                            break;
+                        case KeyEvent.KEYCODE_MEDIA_STOP:
+                            if ((validActions & PlaybackState.ACTION_STOP) != 0) {
+                                onStop();
+                                return true;
+                            }
+                            break;
+                        case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+                            if ((validActions & PlaybackState.ACTION_FAST_FORWARD) != 0) {
+                                onFastForward();
+                                return true;
+                            }
+                            break;
+                        case KeyEvent.KEYCODE_MEDIA_REWIND:
+                            if ((validActions & PlaybackState.ACTION_REWIND) != 0) {
+                                onRewind();
+                                return true;
+                            }
+                            break;
+                    }
+                }
+            }
+            return false;
+        }
+
+        private void handleMediaPlayPauseKeySingleTapIfPending() {
+            if (!mMediaPlayPauseKeyPending) {
+                return;
+            }
+            mMediaPlayPauseKeyPending = false;
+            mHandler.removeMessages(CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
+            PlaybackState state = mSession.mPlaybackState;
+            long validActions = state == null ? 0 : state.getActions();
+            boolean isPlaying = state != null
+                    && state.getState() == PlaybackState.STATE_PLAYING;
+            boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
+                    | PlaybackState.ACTION_PLAY)) != 0;
+            boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
+                    | PlaybackState.ACTION_PAUSE)) != 0;
+            if (isPlaying && canPause) {
+                onPause();
+            } else if (!isPlaying && canPlay) {
+                onPlay();
+            }
+        }
+
+        /**
+         * Override to handle requests to prepare playback. During the preparation, a session should
+         * not hold audio focus in order to allow other sessions play seamlessly. The state of
+         * playback should be updated to {@link PlaybackState#STATE_PAUSED} after the preparation is
+         * done.
+         */
+        public void onPrepare() {
+        }
+
+        /**
+         * Override to handle requests to prepare for playing a specific mediaId that was provided
+         * by your app's {@link MediaBrowserService}. During the preparation, a session should not
+         * hold audio focus in order to allow other sessions play seamlessly. The state of playback
+         * should be updated to {@link PlaybackState#STATE_PAUSED} after the preparation is done.
+         * The playback of the prepared content should start in the implementation of
+         * {@link #onPlay}. Override {@link #onPlayFromMediaId} to handle requests for starting
+         * playback without preparation.
+         */
+        public void onPrepareFromMediaId(String mediaId, Bundle extras) {
+        }
+
+        /**
+         * Override to handle requests to prepare playback from a search query. An empty query
+         * indicates that the app may prepare any music. The implementation should attempt to make a
+         * smart choice about what to play. During the preparation, a session should not hold audio
+         * focus in order to allow other sessions play seamlessly. The state of playback should be
+         * updated to {@link PlaybackState#STATE_PAUSED} after the preparation is done. The playback
+         * of the prepared content should start in the implementation of {@link #onPlay}. Override
+         * {@link #onPlayFromSearch} to handle requests for starting playback without preparation.
+         */
+        public void onPrepareFromSearch(String query, Bundle extras) {
+        }
+
+        /**
+         * Override to handle requests to prepare a specific media item represented by a URI.
+         * During the preparation, a session should not hold audio focus in order to allow
+         * other sessions play seamlessly. The state of playback should be updated to
+         * {@link PlaybackState#STATE_PAUSED} after the preparation is done.
+         * The playback of the prepared content should start in the implementation of
+         * {@link #onPlay}. Override {@link #onPlayFromUri} to handle requests
+         * for starting playback without preparation.
+         */
+        public void onPrepareFromUri(Uri uri, Bundle extras) {
+        }
+
+        /**
+         * Override to handle requests to begin playback.
+         */
+        public void onPlay() {
+        }
+
+        /**
+         * Override to handle requests to begin playback from a search query. An
+         * empty query indicates that the app may play any music. The
+         * implementation should attempt to make a smart choice about what to
+         * play.
+         */
+        public void onPlayFromSearch(String query, Bundle extras) {
+        }
+
+        /**
+         * Override to handle requests to play a specific mediaId that was
+         * provided by your app's {@link MediaBrowserService}.
+         */
+        public void onPlayFromMediaId(String mediaId, Bundle extras) {
+        }
+
+        /**
+         * Override to handle requests to play a specific media item represented by a URI.
+         */
+        public void onPlayFromUri(Uri uri, Bundle extras) {
+        }
+
+        /**
+         * Override to handle requests to play an item with a given id from the
+         * play queue.
+         */
+        public void onSkipToQueueItem(long id) {
+        }
+
+        /**
+         * Override to handle requests to pause playback.
+         */
+        public void onPause() {
+        }
+
+        /**
+         * Override to handle requests to skip to the next media item.
+         */
+        public void onSkipToNext() {
+        }
+
+        /**
+         * Override to handle requests to skip to the previous media item.
+         */
+        public void onSkipToPrevious() {
+        }
+
+        /**
+         * Override to handle requests to fast forward.
+         */
+        public void onFastForward() {
+        }
+
+        /**
+         * Override to handle requests to rewind.
+         */
+        public void onRewind() {
+        }
+
+        /**
+         * Override to handle requests to stop playback.
+         */
+        public void onStop() {
+        }
+
+        /**
+         * Override to handle requests to seek to a specific position in ms.
+         *
+         * @param pos New position to move to, in milliseconds.
+         */
+        public void onSeekTo(long pos) {
+        }
+
+        /**
+         * Override to handle the item being rated.
+         *
+         * @param rating
+         */
+        public void onSetRating(@NonNull Rating rating) {
+        }
+
+        /**
+         * Override to handle the playback speed change.
+         * To update the new playback speed, create a new {@link PlaybackState} by using {@link
+         * PlaybackState.Builder#setState(int, long, float)}, and set it with
+         * {@link #setPlaybackState(PlaybackState)}.
+         * <p>
+         * A value of {@code 1.0f} is the default playback value, and a negative value indicates
+         * reverse playback. The {@code speed} will not be equal to zero.
+         *
+         * @param speed the playback speed
+         * @see #setPlaybackState(PlaybackState)
+         * @see PlaybackState.Builder#setState(int, long, float)
+         */
+        public void onSetPlaybackSpeed(float speed) {
+        }
+
+        /**
+         * Called when a {@link MediaController} wants a {@link PlaybackState.CustomAction} to be
+         * performed.
+         *
+         * @param action The action that was originally sent in the
+         *               {@link PlaybackState.CustomAction}.
+         * @param extras Optional extras specified by the {@link MediaController}.
+         */
+        public void onCustomAction(@NonNull String action, @Nullable Bundle extras) {
+        }
+    }
+
+    /**
+     * @hide
+     */
+    public static class CallbackStub extends ISessionCallback.Stub {
+        private WeakReference<MediaSession> mMediaSession;
+
+        public CallbackStub(MediaSession session) {
+            mMediaSession = new WeakReference<>(session);
+        }
+
+        private static RemoteUserInfo createRemoteUserInfo(String packageName, int pid, int uid) {
+            return new RemoteUserInfo(packageName, pid, uid);
+        }
+
+        @Override
+        public void onCommand(String packageName, int pid, int uid, String command, Bundle args,
+                ResultReceiver cb) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchCommand(createRemoteUserInfo(packageName, pid, uid),
+                        command, args, cb);
+            }
+        }
+
+        @Override
+        public void onMediaButton(String packageName, int pid, int uid, Intent mediaButtonIntent,
+                int sequenceNumber, ResultReceiver cb) {
+            MediaSession session = mMediaSession.get();
+            try {
+                if (session != null) {
+                    session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid),
+                            mediaButtonIntent);
+                }
+            } finally {
+                if (cb != null) {
+                    cb.send(sequenceNumber, null);
+                }
+            }
+        }
+
+        @Override
+        public void onMediaButtonFromController(String packageName, int pid, int uid,
+                Intent mediaButtonIntent) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid),
+                        mediaButtonIntent);
+            }
+        }
+
+        @Override
+        public void onPrepare(String packageName, int pid, int uid) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid));
+            }
+        }
+
+        @Override
+        public void onPrepareFromMediaId(String packageName, int pid, int uid, String mediaId,
+                Bundle extras) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPrepareFromMediaId(
+                        createRemoteUserInfo(packageName, pid, uid), mediaId, extras);
+            }
+        }
+
+        @Override
+        public void onPrepareFromSearch(String packageName, int pid, int uid, String query,
+                Bundle extras) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPrepareFromSearch(
+                        createRemoteUserInfo(packageName, pid, uid), query, extras);
+            }
+        }
+
+        @Override
+        public void onPrepareFromUri(String packageName, int pid, int uid, Uri uri, Bundle extras) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPrepareFromUri(createRemoteUserInfo(packageName, pid, uid),
+                        uri, extras);
+            }
+        }
+
+        @Override
+        public void onPlay(String packageName, int pid, int uid) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPlay(createRemoteUserInfo(packageName, pid, uid));
+            }
+        }
+
+        @Override
+        public void onPlayFromMediaId(String packageName, int pid, int uid, String mediaId,
+                Bundle extras) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPlayFromMediaId(createRemoteUserInfo(packageName, pid, uid),
+                        mediaId, extras);
+            }
+        }
+
+        @Override
+        public void onPlayFromSearch(String packageName, int pid, int uid, String query,
+                Bundle extras) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPlayFromSearch(createRemoteUserInfo(packageName, pid, uid),
+                        query, extras);
+            }
+        }
+
+        @Override
+        public void onPlayFromUri(String packageName, int pid, int uid, Uri uri, Bundle extras) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPlayFromUri(createRemoteUserInfo(packageName, pid, uid),
+                        uri, extras);
+            }
+        }
+
+        @Override
+        public void onSkipToTrack(String packageName, int pid, int uid, long id) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchSkipToItem(createRemoteUserInfo(packageName, pid, uid), id);
+            }
+        }
+
+        @Override
+        public void onPause(String packageName, int pid, int uid) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPause(createRemoteUserInfo(packageName, pid, uid));
+            }
+        }
+
+        @Override
+        public void onStop(String packageName, int pid, int uid) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchStop(createRemoteUserInfo(packageName, pid, uid));
+            }
+        }
+
+        @Override
+        public void onNext(String packageName, int pid, int uid) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchNext(createRemoteUserInfo(packageName, pid, uid));
+            }
+        }
+
+        @Override
+        public void onPrevious(String packageName, int pid, int uid) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid));
+            }
+        }
+
+        @Override
+        public void onFastForward(String packageName, int pid, int uid) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchFastForward(createRemoteUserInfo(packageName, pid, uid));
+            }
+        }
+
+        @Override
+        public void onRewind(String packageName, int pid, int uid) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchRewind(createRemoteUserInfo(packageName, pid, uid));
+            }
+        }
+
+        @Override
+        public void onSeekTo(String packageName, int pid, int uid, long pos) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchSeekTo(createRemoteUserInfo(packageName, pid, uid), pos);
+            }
+        }
+
+        @Override
+        public void onRate(String packageName, int pid, int uid, Rating rating) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchRate(createRemoteUserInfo(packageName, pid, uid), rating);
+            }
+        }
+
+        @Override
+        public void onSetPlaybackSpeed(String packageName, int pid, int uid, float speed) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchSetPlaybackSpeed(
+                        createRemoteUserInfo(packageName, pid, uid), speed);
+            }
+        }
+
+        @Override
+        public void onCustomAction(String packageName, int pid, int uid, String action,
+                Bundle args) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchCustomAction(createRemoteUserInfo(packageName, pid, uid),
+                        action, args);
+            }
+        }
+
+        @Override
+        public void onAdjustVolume(String packageName, int pid, int uid, int direction) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchAdjustVolume(createRemoteUserInfo(packageName, pid, uid),
+                        direction);
+            }
+        }
+
+        @Override
+        public void onSetVolumeTo(String packageName, int pid, int uid, int value) {
+            MediaSession session = mMediaSession.get();
+            if (session != null) {
+                session.dispatchSetVolumeTo(createRemoteUserInfo(packageName, pid, uid),
+                        value);
+            }
+        }
+    }
+
+    /**
+     * A single item that is part of the play queue. It contains a description
+     * of the item and its id in the queue.
+     */
+    public static final class QueueItem implements Parcelable {
+        /**
+         * This id is reserved. No items can be explicitly assigned this id.
+         */
+        public static final int UNKNOWN_ID = -1;
+
+        private final MediaDescription mDescription;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private final long mId;
+
+        /**
+         * Create a new {@link MediaSession.QueueItem}.
+         *
+         * @param description The {@link MediaDescription} for this item.
+         * @param id An identifier for this item. It must be unique within the
+         *            play queue and cannot be {@link #UNKNOWN_ID}.
+         */
+        public QueueItem(MediaDescription description, long id) {
+            if (description == null) {
+                throw new IllegalArgumentException("Description cannot be null.");
+            }
+            if (id == UNKNOWN_ID) {
+                throw new IllegalArgumentException("Id cannot be QueueItem.UNKNOWN_ID");
+            }
+            mDescription = description;
+            mId = id;
+        }
+
+        private QueueItem(Parcel in) {
+            mDescription = MediaDescription.CREATOR.createFromParcel(in);
+            mId = in.readLong();
+        }
+
+        /**
+         * Get the description for this item.
+         */
+        public MediaDescription getDescription() {
+            return mDescription;
+        }
+
+        /**
+         * Get the queue id for this item.
+         */
+        public long getQueueId() {
+            return mId;
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            mDescription.writeToParcel(dest, flags);
+            dest.writeLong(mId);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final @android.annotation.NonNull Creator<MediaSession.QueueItem> CREATOR =
+                new Creator<MediaSession.QueueItem>() {
+
+                    @Override
+                    public MediaSession.QueueItem createFromParcel(Parcel p) {
+                        return new MediaSession.QueueItem(p);
+                    }
+
+                    @Override
+                    public MediaSession.QueueItem[] newArray(int size) {
+                        return new MediaSession.QueueItem[size];
+                    }
+                };
+
+        @Override
+        public String toString() {
+            return "MediaSession.QueueItem {" + "Description=" + mDescription + ", Id=" + mId
+                    + " }";
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null) {
+                return false;
+            }
+
+            if (!(o instanceof QueueItem)) {
+                return false;
+            }
+
+            final QueueItem item = (QueueItem) o;
+            if (mId != item.mId) {
+                return false;
+            }
+
+            if (!Objects.equals(mDescription, item.mDescription)) {
+                return false;
+            }
+
+            return true;
+        }
+    }
+
+    private static final class Command {
+        public final String command;
+        public final Bundle extras;
+        public final ResultReceiver stub;
+
+        Command(String command, Bundle extras, ResultReceiver stub) {
+            this.command = command;
+            this.extras = extras;
+            this.stub = stub;
+        }
+    }
+
+    private class CallbackMessageHandler extends Handler {
+        private static final int MSG_COMMAND = 1;
+        private static final int MSG_MEDIA_BUTTON = 2;
+        private static final int MSG_PREPARE = 3;
+        private static final int MSG_PREPARE_MEDIA_ID = 4;
+        private static final int MSG_PREPARE_SEARCH = 5;
+        private static final int MSG_PREPARE_URI = 6;
+        private static final int MSG_PLAY = 7;
+        private static final int MSG_PLAY_MEDIA_ID = 8;
+        private static final int MSG_PLAY_SEARCH = 9;
+        private static final int MSG_PLAY_URI = 10;
+        private static final int MSG_SKIP_TO_ITEM = 11;
+        private static final int MSG_PAUSE = 12;
+        private static final int MSG_STOP = 13;
+        private static final int MSG_NEXT = 14;
+        private static final int MSG_PREVIOUS = 15;
+        private static final int MSG_FAST_FORWARD = 16;
+        private static final int MSG_REWIND = 17;
+        private static final int MSG_SEEK_TO = 18;
+        private static final int MSG_RATE = 19;
+        private static final int MSG_SET_PLAYBACK_SPEED = 20;
+        private static final int MSG_CUSTOM_ACTION = 21;
+        private static final int MSG_ADJUST_VOLUME = 22;
+        private static final int MSG_SET_VOLUME = 23;
+        private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 24;
+
+        private MediaSession.Callback mCallback;
+        private RemoteUserInfo mCurrentControllerInfo;
+
+        CallbackMessageHandler(Looper looper, MediaSession.Callback callback) {
+            super(looper);
+            mCallback = callback;
+            mCallback.mHandler = this;
+        }
+
+        void post(RemoteUserInfo caller, int what, Object obj, Bundle data, long delayMs) {
+            Pair<RemoteUserInfo, Object> objWithCaller = Pair.create(caller, obj);
+            Message msg = obtainMessage(what, objWithCaller);
+            msg.setAsynchronous(true);
+            msg.setData(data);
+            if (delayMs > 0) {
+                sendMessageDelayed(msg, delayMs);
+            } else {
+                sendMessage(msg);
+            }
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            mCurrentControllerInfo = ((Pair<RemoteUserInfo, Object>) msg.obj).first;
+
+            VolumeProvider vp;
+            Object obj = ((Pair<RemoteUserInfo, Object>) msg.obj).second;
+
+            switch (msg.what) {
+                case MSG_COMMAND:
+                    Command cmd = (Command) obj;
+                    mCallback.onCommand(cmd.command, cmd.extras, cmd.stub);
+                    break;
+                case MSG_MEDIA_BUTTON:
+                    mCallback.onMediaButtonEvent((Intent) obj);
+                    break;
+                case MSG_PREPARE:
+                    mCallback.onPrepare();
+                    break;
+                case MSG_PREPARE_MEDIA_ID:
+                    mCallback.onPrepareFromMediaId((String) obj, msg.getData());
+                    break;
+                case MSG_PREPARE_SEARCH:
+                    mCallback.onPrepareFromSearch((String) obj, msg.getData());
+                    break;
+                case MSG_PREPARE_URI:
+                    mCallback.onPrepareFromUri((Uri) obj, msg.getData());
+                    break;
+                case MSG_PLAY:
+                    mCallback.onPlay();
+                    break;
+                case MSG_PLAY_MEDIA_ID:
+                    mCallback.onPlayFromMediaId((String) obj, msg.getData());
+                    break;
+                case MSG_PLAY_SEARCH:
+                    mCallback.onPlayFromSearch((String) obj, msg.getData());
+                    break;
+                case MSG_PLAY_URI:
+                    mCallback.onPlayFromUri((Uri) obj, msg.getData());
+                    break;
+                case MSG_SKIP_TO_ITEM:
+                    mCallback.onSkipToQueueItem((Long) obj);
+                    break;
+                case MSG_PAUSE:
+                    mCallback.onPause();
+                    break;
+                case MSG_STOP:
+                    mCallback.onStop();
+                    break;
+                case MSG_NEXT:
+                    mCallback.onSkipToNext();
+                    break;
+                case MSG_PREVIOUS:
+                    mCallback.onSkipToPrevious();
+                    break;
+                case MSG_FAST_FORWARD:
+                    mCallback.onFastForward();
+                    break;
+                case MSG_REWIND:
+                    mCallback.onRewind();
+                    break;
+                case MSG_SEEK_TO:
+                    mCallback.onSeekTo((Long) obj);
+                    break;
+                case MSG_RATE:
+                    mCallback.onSetRating((Rating) obj);
+                    break;
+                case MSG_SET_PLAYBACK_SPEED:
+                    mCallback.onSetPlaybackSpeed((Float) obj);
+                    break;
+                case MSG_CUSTOM_ACTION:
+                    mCallback.onCustomAction((String) obj, msg.getData());
+                    break;
+                case MSG_ADJUST_VOLUME:
+                    synchronized (mLock) {
+                        vp = mVolumeProvider;
+                    }
+                    if (vp != null) {
+                        vp.onAdjustVolume((int) obj);
+                    }
+                    break;
+                case MSG_SET_VOLUME:
+                    synchronized (mLock) {
+                        vp = mVolumeProvider;
+                    }
+                    if (vp != null) {
+                        vp.onSetVolumeTo((int) obj);
+                    }
+                    break;
+                case MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT:
+                    mCallback.handleMediaPlayPauseKeySingleTapIfPending();
+                    break;
+            }
+            mCurrentControllerInfo = null;
+        }
+    }
+}
diff --git a/android/media/session/MediaSessionLegacyHelper.java b/android/media/session/MediaSessionLegacyHelper.java
new file mode 100644
index 0000000..0d506f0
--- /dev/null
+++ b/android/media/session/MediaSessionLegacyHelper.java
@@ -0,0 +1,513 @@
+/*
+ * Copyright (C) 2014 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.session;
+
+import android.app.PendingIntent;
+import android.app.PendingIntent.CanceledException;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.media.MediaMetadata;
+import android.media.MediaMetadataEditor;
+import android.media.MediaMetadataRetriever;
+import android.media.Rating;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.view.KeyEvent;
+
+/**
+ * Helper for connecting existing APIs up to the new session APIs. This can be
+ * used by RCC, AudioFocus, etc. to create a single session that translates to
+ * all those components.
+ *
+ * @hide
+ */
+public class MediaSessionLegacyHelper {
+    private static final String TAG = "MediaSessionHelper";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    private static final Object sLock = new Object();
+    private static MediaSessionLegacyHelper sInstance;
+
+    private Context mContext;
+    private MediaSessionManager mSessionManager;
+    private Handler mHandler = new Handler(Looper.getMainLooper());
+    // The legacy APIs use PendingIntents to register/unregister media button
+    // receivers and these are associated with RCC.
+    private ArrayMap<PendingIntent, SessionHolder> mSessions
+            = new ArrayMap<PendingIntent, SessionHolder>();
+
+    private MediaSessionLegacyHelper(Context context) {
+        mContext = context;
+        mSessionManager = (MediaSessionManager) context
+                .getSystemService(Context.MEDIA_SESSION_SERVICE);
+    }
+
+    @UnsupportedAppUsage
+    public static MediaSessionLegacyHelper getHelper(Context context) {
+        synchronized (sLock) {
+            if (sInstance == null) {
+                sInstance = new MediaSessionLegacyHelper(context.getApplicationContext());
+            }
+        }
+        return sInstance;
+    }
+
+    public static Bundle getOldMetadata(MediaMetadata metadata, int artworkWidth,
+            int artworkHeight) {
+        boolean includeArtwork = artworkWidth != -1 && artworkHeight != -1;
+        Bundle oldMetadata = new Bundle();
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ALBUM),
+                    metadata.getString(MediaMetadata.METADATA_KEY_ALBUM));
+        }
+        if (includeArtwork && metadata.containsKey(MediaMetadata.METADATA_KEY_ART)) {
+            Bitmap art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
+            oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK),
+                    scaleBitmapIfTooBig(art, artworkWidth, artworkHeight));
+        } else if (includeArtwork && metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART)) {
+            // Fall back to album art if the track art wasn't available
+            Bitmap art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
+            oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK),
+                    scaleBitmapIfTooBig(art, artworkWidth, artworkHeight));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ARTIST)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST),
+                    metadata.getString(MediaMetadata.METADATA_KEY_ALBUM_ARTIST));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_ARTIST)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ARTIST),
+                    metadata.getString(MediaMetadata.METADATA_KEY_ARTIST));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_AUTHOR)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_AUTHOR),
+                    metadata.getString(MediaMetadata.METADATA_KEY_AUTHOR));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_COMPILATION)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_COMPILATION),
+                    metadata.getString(MediaMetadata.METADATA_KEY_COMPILATION));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_COMPOSER)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_COMPOSER),
+                    metadata.getString(MediaMetadata.METADATA_KEY_COMPOSER));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_DATE)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DATE),
+                    metadata.getString(MediaMetadata.METADATA_KEY_DATE));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_DISC_NUMBER)) {
+            oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER),
+                    metadata.getLong(MediaMetadata.METADATA_KEY_DISC_NUMBER));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
+            oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DURATION),
+                    metadata.getLong(MediaMetadata.METADATA_KEY_DURATION));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_GENRE)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_GENRE),
+                    metadata.getString(MediaMetadata.METADATA_KEY_GENRE));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_NUM_TRACKS)) {
+            oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS),
+                    metadata.getLong(MediaMetadata.METADATA_KEY_NUM_TRACKS));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_RATING)) {
+            oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.RATING_KEY_BY_OTHERS),
+                    metadata.getRating(MediaMetadata.METADATA_KEY_RATING));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_USER_RATING)) {
+            oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER),
+                    metadata.getRating(MediaMetadata.METADATA_KEY_USER_RATING));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_TITLE)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_TITLE),
+                    metadata.getString(MediaMetadata.METADATA_KEY_TITLE));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_TRACK_NUMBER)) {
+            oldMetadata.putLong(
+                    String.valueOf(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER),
+                    metadata.getLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_WRITER)) {
+            oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_WRITER),
+                    metadata.getString(MediaMetadata.METADATA_KEY_WRITER));
+        }
+        if (metadata.containsKey(MediaMetadata.METADATA_KEY_YEAR)) {
+            oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_YEAR),
+                    metadata.getLong(MediaMetadata.METADATA_KEY_YEAR));
+        }
+        return oldMetadata;
+    }
+
+    public MediaSession getSession(PendingIntent pi) {
+        SessionHolder holder = mSessions.get(pi);
+        return holder == null ? null : holder.mSession;
+    }
+
+    public void sendMediaButtonEvent(KeyEvent keyEvent, boolean needWakeLock) {
+        if (keyEvent == null) {
+            Log.w(TAG, "Tried to send a null key event. Ignoring.");
+            return;
+        }
+        mSessionManager.dispatchMediaKeyEvent(keyEvent, needWakeLock);
+        if (DEBUG) {
+            Log.d(TAG, "dispatched media key " + keyEvent);
+        }
+    }
+
+    public void sendVolumeKeyEvent(KeyEvent keyEvent, int stream, boolean musicOnly) {
+        if (keyEvent == null) {
+            Log.w(TAG, "Tried to send a null key event. Ignoring.");
+            return;
+        }
+        mSessionManager.dispatchVolumeKeyEvent(keyEvent, stream, musicOnly);
+    }
+
+    public void sendAdjustVolumeBy(int suggestedStream, int delta, int flags) {
+        mSessionManager.dispatchAdjustVolume(suggestedStream, delta, flags);
+        if (DEBUG) {
+            Log.d(TAG, "dispatched volume adjustment");
+        }
+    }
+
+    public boolean isGlobalPriorityActive() {
+        return mSessionManager.isGlobalPriorityActive();
+    }
+
+    public void addRccListener(PendingIntent pi, MediaSession.Callback listener) {
+        if (pi == null) {
+            Log.w(TAG, "Pending intent was null, can't add rcc listener.");
+            return;
+        }
+        SessionHolder holder = getHolder(pi, true);
+        if (holder == null) {
+            return;
+        }
+        if (holder.mRccListener != null) {
+            if (holder.mRccListener == listener) {
+                if (DEBUG) {
+                    Log.d(TAG, "addRccListener listener already added.");
+                }
+                // This is already the registered listener, ignore
+                return;
+            }
+        }
+        holder.mRccListener = listener;
+        holder.mFlags |= MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS;
+        holder.mSession.setFlags(holder.mFlags);
+        holder.update();
+        if (DEBUG) {
+            Log.d(TAG, "Added rcc listener for " + pi + ".");
+        }
+    }
+
+    public void removeRccListener(PendingIntent pi) {
+        if (pi == null) {
+            return;
+        }
+        SessionHolder holder = getHolder(pi, false);
+        if (holder != null && holder.mRccListener != null) {
+            holder.mRccListener = null;
+            holder.mFlags &= ~MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS;
+            holder.mSession.setFlags(holder.mFlags);
+            holder.update();
+            if (DEBUG) {
+                Log.d(TAG, "Removed rcc listener for " + pi + ".");
+            }
+        }
+    }
+
+    public void addMediaButtonListener(PendingIntent pi, ComponentName mbrComponent,
+            Context context) {
+        if (pi == null) {
+            Log.w(TAG, "Pending intent was null, can't addMediaButtonListener.");
+            return;
+        }
+        SessionHolder holder = getHolder(pi, true);
+        if (holder == null) {
+            return;
+        }
+        if (holder.mMediaButtonListener != null) {
+            // Already have this listener registered
+            if (DEBUG) {
+                Log.d(TAG, "addMediaButtonListener already added " + pi);
+            }
+        }
+        holder.mMediaButtonListener = new MediaButtonListener(pi, context);
+        // TODO determine if handling transport performer commands should also
+        // set this flag
+        holder.mFlags |= MediaSession.FLAG_HANDLES_MEDIA_BUTTONS;
+        holder.mSession.setFlags(holder.mFlags);
+        holder.mSession.setMediaButtonReceiver(pi);
+        holder.update();
+        if (DEBUG) {
+            Log.d(TAG, "addMediaButtonListener added " + pi);
+        }
+    }
+
+    public void removeMediaButtonListener(PendingIntent pi) {
+        if (pi == null) {
+            return;
+        }
+        SessionHolder holder = getHolder(pi, false);
+        if (holder != null && holder.mMediaButtonListener != null) {
+            holder.mFlags &= ~MediaSession.FLAG_HANDLES_MEDIA_BUTTONS;
+            holder.mSession.setFlags(holder.mFlags);
+            holder.mMediaButtonListener = null;
+
+            holder.update();
+            if (DEBUG) {
+                Log.d(TAG, "removeMediaButtonListener removed " + pi);
+            }
+        }
+    }
+
+    /**
+     * Scale a bitmap to fit the smallest dimension by uniformly scaling the
+     * incoming bitmap. If the bitmap fits, then do nothing and return the
+     * original.
+     *
+     * @param bitmap
+     * @param maxWidth
+     * @param maxHeight
+     * @return
+     */
+    private static Bitmap scaleBitmapIfTooBig(Bitmap bitmap, int maxWidth, int maxHeight) {
+        if (bitmap != null) {
+            final int width = bitmap.getWidth();
+            final int height = bitmap.getHeight();
+            if (width > maxWidth || height > maxHeight) {
+                float scale = Math.min((float) maxWidth / width, (float) maxHeight / height);
+                int newWidth = Math.round(scale * width);
+                int newHeight = Math.round(scale * height);
+                Bitmap.Config newConfig = bitmap.getConfig();
+                if (newConfig == null) {
+                    newConfig = Bitmap.Config.ARGB_8888;
+                }
+                Bitmap outBitmap = Bitmap.createBitmap(newWidth, newHeight, newConfig);
+                Canvas canvas = new Canvas(outBitmap);
+                Paint paint = new Paint();
+                paint.setAntiAlias(true);
+                paint.setFilterBitmap(true);
+                canvas.drawBitmap(bitmap, null,
+                        new RectF(0, 0, outBitmap.getWidth(), outBitmap.getHeight()), paint);
+                bitmap = outBitmap;
+            }
+        }
+        return bitmap;
+    }
+
+    private SessionHolder getHolder(PendingIntent pi, boolean createIfMissing) {
+        SessionHolder holder = mSessions.get(pi);
+        if (holder == null && createIfMissing) {
+            MediaSession session;
+            session = new MediaSession(mContext, TAG + "-" + pi.getCreatorPackage());
+            session.setActive(true);
+            holder = new SessionHolder(session, pi);
+            mSessions.put(pi, holder);
+        }
+        return holder;
+    }
+
+    private static void sendKeyEvent(PendingIntent pi, Context context, Intent intent) {
+        try {
+            pi.send(context, 0, intent);
+        } catch (CanceledException e) {
+            Log.e(TAG, "Error sending media key down event:", e);
+            // Don't bother sending up if down failed
+            return;
+        }
+    }
+
+    private static final class MediaButtonListener extends MediaSession.Callback {
+        private final PendingIntent mPendingIntent;
+        private final Context mContext;
+
+        public MediaButtonListener(PendingIntent pi, Context context) {
+            mPendingIntent = pi;
+            mContext = context;
+        }
+
+        @Override
+        public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
+            MediaSessionLegacyHelper.sendKeyEvent(mPendingIntent, mContext, mediaButtonIntent);
+            return true;
+        }
+
+        @Override
+        public void onPlay() {
+            sendKeyEvent(KeyEvent.KEYCODE_MEDIA_PLAY);
+        }
+
+        @Override
+        public void onPause() {
+            sendKeyEvent(KeyEvent.KEYCODE_MEDIA_PAUSE);
+        }
+
+        @Override
+        public void onSkipToNext() {
+            sendKeyEvent(KeyEvent.KEYCODE_MEDIA_NEXT);
+        }
+
+        @Override
+        public void onSkipToPrevious() {
+            sendKeyEvent(KeyEvent.KEYCODE_MEDIA_PREVIOUS);
+        }
+
+        @Override
+        public void onFastForward() {
+            sendKeyEvent(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD);
+        }
+
+        @Override
+        public void onRewind() {
+            sendKeyEvent(KeyEvent.KEYCODE_MEDIA_REWIND);
+        }
+
+        @Override
+        public void onStop() {
+            sendKeyEvent(KeyEvent.KEYCODE_MEDIA_STOP);
+        }
+
+        private void sendKeyEvent(int keyCode) {
+            KeyEvent ke = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
+            Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
+            intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
+
+            intent.putExtra(Intent.EXTRA_KEY_EVENT, ke);
+            MediaSessionLegacyHelper.sendKeyEvent(mPendingIntent, mContext, intent);
+
+            ke = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
+            intent.putExtra(Intent.EXTRA_KEY_EVENT, ke);
+            MediaSessionLegacyHelper.sendKeyEvent(mPendingIntent, mContext, intent);
+
+            if (DEBUG) {
+                Log.d(TAG, "Sent " + keyCode + " to pending intent " + mPendingIntent);
+            }
+        }
+    }
+
+    private class SessionHolder {
+        public final MediaSession mSession;
+        public final PendingIntent mPi;
+        public MediaButtonListener mMediaButtonListener;
+        public MediaSession.Callback mRccListener;
+        public int mFlags;
+
+        public SessionCallback mCb;
+
+        public SessionHolder(MediaSession session, PendingIntent pi) {
+            mSession = session;
+            mPi = pi;
+        }
+
+        public void update() {
+            if (mMediaButtonListener == null && mRccListener == null) {
+                mSession.setCallback(null);
+                mSession.release();
+                mCb = null;
+                mSessions.remove(mPi);
+            } else if (mCb == null) {
+                mCb = new SessionCallback();
+                Handler handler = new Handler(Looper.getMainLooper());
+                mSession.setCallback(mCb, handler);
+            }
+        }
+
+        private class SessionCallback extends MediaSession.Callback {
+
+            @Override
+            public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
+                if (mMediaButtonListener != null) {
+                    mMediaButtonListener.onMediaButtonEvent(mediaButtonIntent);
+                }
+                return true;
+            }
+
+            @Override
+            public void onPlay() {
+                if (mMediaButtonListener != null) {
+                    mMediaButtonListener.onPlay();
+                }
+            }
+
+            @Override
+            public void onPause() {
+                if (mMediaButtonListener != null) {
+                    mMediaButtonListener.onPause();
+                }
+            }
+
+            @Override
+            public void onSkipToNext() {
+                if (mMediaButtonListener != null) {
+                    mMediaButtonListener.onSkipToNext();
+                }
+            }
+
+            @Override
+            public void onSkipToPrevious() {
+                if (mMediaButtonListener != null) {
+                    mMediaButtonListener.onSkipToPrevious();
+                }
+            }
+
+            @Override
+            public void onFastForward() {
+                if (mMediaButtonListener != null) {
+                    mMediaButtonListener.onFastForward();
+                }
+            }
+
+            @Override
+            public void onRewind() {
+                if (mMediaButtonListener != null) {
+                    mMediaButtonListener.onRewind();
+                }
+            }
+
+            @Override
+            public void onStop() {
+                if (mMediaButtonListener != null) {
+                    mMediaButtonListener.onStop();
+                }
+            }
+
+            @Override
+            public void onSeekTo(long pos) {
+                if (mRccListener != null) {
+                    mRccListener.onSeekTo(pos);
+                }
+            }
+
+            @Override
+            public void onSetRating(Rating rating) {
+                if (mRccListener != null) {
+                    mRccListener.onSetRating(rating);
+                }
+            }
+        }
+    }
+}
diff --git a/android/media/session/MediaSessionManager.java b/android/media/session/MediaSessionManager.java
new file mode 100644
index 0000000..269b70b
--- /dev/null
+++ b/android/media/session/MediaSessionManager.java
@@ -0,0 +1,1436 @@
+/*
+ * Copyright (C) 2014 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.session;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.content.ComponentName;
+import android.content.Context;
+import android.media.AudioManager;
+import android.media.IRemoteSessionCallback;
+import android.media.MediaCommunicationManager;
+import android.media.MediaFrameworkPlatformInitializer;
+import android.media.MediaSession2;
+import android.media.Session2Token;
+import android.media.VolumeProvider;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.RemoteException;
+import android.os.ResultReceiver;
+import android.os.UserHandle;
+import android.service.media.MediaBrowserService;
+import android.service.notification.NotificationListenerService;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.view.KeyEvent;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * Provides support for interacting with {@link MediaSession media sessions}
+ * that applications have published to express their ongoing media playback
+ * state.
+ *
+ * @see MediaSession
+ * @see MediaController
+ */
+// TODO: (jinpark) Add API for getting and setting session policies from MediaSessionService once
+//  b/149006225 is fixed.
+@SystemService(Context.MEDIA_SESSION_SERVICE)
+public final class MediaSessionManager {
+    private static final String TAG = "SessionManager";
+
+    /**
+     * Used to indicate that the media key event isn't handled.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int RESULT_MEDIA_KEY_NOT_HANDLED = 0;
+
+    /**
+     * Used to indicate that the media key event is handled.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public static final int RESULT_MEDIA_KEY_HANDLED = 1;
+
+    private final ISessionManager mService;
+    private final MediaCommunicationManager mCommunicationManager;
+    private final OnMediaKeyEventDispatchedListenerStub mOnMediaKeyEventDispatchedListenerStub =
+            new OnMediaKeyEventDispatchedListenerStub();
+    private final OnMediaKeyEventSessionChangedListenerStub
+            mOnMediaKeyEventSessionChangedListenerStub =
+            new OnMediaKeyEventSessionChangedListenerStub();
+    private final RemoteSessionCallbackStub mRemoteSessionCallbackStub =
+            new RemoteSessionCallbackStub();
+
+    private final Object mLock = new Object();
+    @GuardedBy("mLock")
+    private final ArrayMap<OnActiveSessionsChangedListener, SessionsChangedWrapper> mListeners =
+            new ArrayMap<OnActiveSessionsChangedListener, SessionsChangedWrapper>();
+    @GuardedBy("mLock")
+    private final ArrayMap<OnSession2TokensChangedListener, Session2TokensChangedWrapper>
+            mSession2TokensListeners = new ArrayMap<>();
+    @GuardedBy("mLock")
+    private final Map<OnMediaKeyEventDispatchedListener, Executor>
+            mOnMediaKeyEventDispatchedListeners = new HashMap<>();
+    @GuardedBy("mLock")
+    private final Map<OnMediaKeyEventSessionChangedListener, Executor>
+            mMediaKeyEventSessionChangedCallbacks = new HashMap<>();
+    @GuardedBy("mLock")
+    private String mCurMediaKeyEventSessionPackage;
+    @GuardedBy("mLock")
+    private MediaSession.Token mCurMediaKeyEventSession;
+    @GuardedBy("mLock")
+    private final Map<RemoteSessionCallback, Executor>
+            mRemoteSessionCallbacks = new ArrayMap<>();
+
+    private Context mContext;
+    private OnVolumeKeyLongPressListenerImpl mOnVolumeKeyLongPressListener;
+    private OnMediaKeyListenerImpl mOnMediaKeyListener;
+
+    /**
+     * @hide
+     */
+    public MediaSessionManager(Context context) {
+        // Consider rewriting like DisplayManagerGlobal
+        // Decide if we need context
+        mContext = context;
+        mService = ISessionManager.Stub.asInterface(MediaFrameworkPlatformInitializer
+                .getMediaServiceManager()
+                .getMediaSessionServiceRegisterer()
+                .get());
+        mCommunicationManager = (MediaCommunicationManager) context
+                .getSystemService(Context.MEDIA_COMMUNICATION_SERVICE);
+    }
+
+    /**
+     * Create a new session in the system and get the binder for it.
+     *
+     * @param tag A short name for debugging purposes.
+     * @param sessionInfo A bundle for additional information about this session.
+     * @return The binder object from the system
+     * @hide
+     */
+    @NonNull
+    public ISession createSession(@NonNull MediaSession.CallbackStub cbStub, @NonNull String tag,
+            @Nullable Bundle sessionInfo) {
+        Objects.requireNonNull(cbStub, "cbStub shouldn't be null");
+        Objects.requireNonNull(tag, "tag shouldn't be null");
+        try {
+            return mService.createSession(mContext.getPackageName(), cbStub, tag, sessionInfo,
+                    UserHandle.myUserId());
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Notifies that a new {@link MediaSession2} with type {@link Session2Token#TYPE_SESSION} is
+     * created.
+     * <p>
+     * Do not use this API directly, but create a new instance through the
+     * {@link MediaSession2.Builder} instead.
+     *
+     * @param token newly created session2 token
+     * @deprecated Don't use this method. A new media session is notified automatically.
+     */
+    @Deprecated
+    public void notifySession2Created(@NonNull Session2Token token) {
+        // Does nothing
+    }
+
+    /**
+     * Get a list of controllers for all ongoing sessions. The controllers will
+     * be provided in priority order with the most important controller at index
+     * 0.
+     * <p>
+     * This requires the {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL}
+     * permission be held by the calling app. You may also retrieve this list if
+     * your app is an enabled notification listener using the
+     * {@link NotificationListenerService} APIs, in which case you must pass the
+     * {@link ComponentName} of your enabled listener.
+     *
+     * @param notificationListener The enabled notification listener component.
+     *            May be null.
+     * @return A list of controllers for ongoing sessions.
+     */
+    public @NonNull List<MediaController> getActiveSessions(
+            @Nullable ComponentName notificationListener) {
+        return getActiveSessionsForUser(notificationListener, UserHandle.myUserId());
+    }
+
+    /**
+     * Gets the media key event session, which would receive a media key event unless specified.
+     * @return The media key event session, which would receive key events by default, unless
+     *          the caller has specified the target. Can be {@code null}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
+    @Nullable
+    public MediaSession.Token getMediaKeyEventSession() {
+        try {
+            return mService.getMediaKeyEventSession();
+        } catch (RemoteException ex) {
+            Log.e(TAG, "Failed to get media key event session", ex);
+        }
+        return null;
+    }
+
+    /**
+     * Gets the package name of the media key event session.
+     * @return The package name of the media key event session or the last session's media button
+     *          receiver if the media key event session is {@code null}.
+     * @see #getMediaKeyEventSession()
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
+    @NonNull
+    public String getMediaKeyEventSessionPackageName() {
+        try {
+            String packageName = mService.getMediaKeyEventSessionPackageName();
+            return (packageName != null) ? packageName : "";
+        } catch (RemoteException ex) {
+            Log.e(TAG, "Failed to get media key event session", ex);
+        }
+        return "";
+    }
+
+    /**
+     * Get active sessions for the given user.
+     * <p>
+     * This requires the {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL} permission be
+     * held by the calling app. You may also retrieve this list if your app is an enabled
+     * notification listener using the {@link NotificationListenerService} APIs, in which case you
+     * must pass the {@link ComponentName} of your enabled listener.
+     * <p>
+     * The calling application needs to hold the
+     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission in order to
+     * retrieve sessions for user ids that do not belong to current process.
+     *
+     * @param notificationListener The enabled notification listener component. May be null.
+     * @param userHandle The user handle to fetch sessions for.
+     * @return A list of controllers for ongoing sessions.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    @SuppressLint("UserHandle")
+    public @NonNull List<MediaController> getActiveSessionsForUser(
+            @Nullable ComponentName notificationListener, @NonNull UserHandle userHandle) {
+        Objects.requireNonNull(userHandle, "userHandle shouldn't be null");
+        return getActiveSessionsForUser(notificationListener, userHandle.getIdentifier());
+    }
+
+    private List<MediaController> getActiveSessionsForUser(ComponentName notificationListener,
+            int userId) {
+        ArrayList<MediaController> controllers = new ArrayList<MediaController>();
+        try {
+            List<MediaSession.Token> tokens = mService.getSessions(notificationListener,
+                    userId);
+            int size = tokens.size();
+            for (int i = 0; i < size; i++) {
+                MediaController controller = new MediaController(mContext, tokens.get(i));
+                controllers.add(controller);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to get active sessions: ", e);
+        }
+        return controllers;
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Gets a list of {@link Session2Token} with type {@link Session2Token#TYPE_SESSION} for the
+     * current user.
+     * <p>
+     * Although this API can be used without any restriction, each session owners can accept or
+     * reject your uses of {@link MediaSession2}.
+     *
+     * @return A list of {@link Session2Token}.
+     */
+    @NonNull
+    public List<Session2Token> getSession2Tokens() {
+        return mCommunicationManager.getSession2Tokens();
+    }
+
+    /**
+     * Add a listener to be notified when the list of active sessions changes.
+     * <p>
+     * This requires the {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL} permission be
+     * held by the calling app. You may also retrieve this list if your app is an enabled
+     * notificationlistener using the {@link NotificationListenerService} APIs, in which case you
+     * must pass the {@link ComponentName} of your enabled listener.
+     *
+     * @param sessionListener The listener to add.
+     * @param notificationListener The enabled notification listener component. May be null.
+     */
+    public void addOnActiveSessionsChangedListener(
+            @NonNull OnActiveSessionsChangedListener sessionListener,
+            @Nullable ComponentName notificationListener) {
+        addOnActiveSessionsChangedListener(sessionListener, notificationListener, null);
+    }
+
+    /**
+     * Add a listener to be notified when the list of active sessions changes.
+     * <p>
+     * This requires the {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL} permission be
+     * held by the calling app. You may also retrieve this list if your app is an enabled
+     * notification listener using the {@link NotificationListenerService} APIs, in which case you
+     * must pass the {@link ComponentName} of your enabled listener. Updates will be posted to the
+     * handler specified or to the caller's thread if the handler is null.
+     *
+     * @param sessionListener The listener to add.
+     * @param notificationListener The enabled notification listener component. May be null.
+     * @param handler The handler to post events to.
+     */
+    public void addOnActiveSessionsChangedListener(
+            @NonNull OnActiveSessionsChangedListener sessionListener,
+            @Nullable ComponentName notificationListener, @Nullable Handler handler) {
+        addOnActiveSessionsChangedListener(sessionListener, notificationListener,
+                UserHandle.myUserId(), handler == null ? null : new HandlerExecutor(handler));
+    }
+
+    /**
+     * Add a listener to be notified when the list of active sessions changes.
+     * <p>
+     * This requires the {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL} permission be
+     * held by the calling app. You may also retrieve this list if your app is an enabled
+     * notification listener using the {@link NotificationListenerService} APIs, in which case you
+     * must pass the {@link ComponentName} of your enabled listener. Updates will be posted to the
+     * handler specified or to the caller's thread if the handler is null.
+     * <p>
+     * The calling application needs to hold the
+     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission in order to
+     * add listeners for user ids that do not belong to current process.
+     *
+     * @param notificationListener The enabled notification listener component. May be null.
+     * @param userHandle The user handle to listen for changes on.
+     * @param executor The executor on which the listener should be invoked
+     * @param sessionListener The listener to add.
+     * @hide
+     */
+    @SuppressLint("UserHandle")
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void addOnActiveSessionsChangedListener(
+            @Nullable ComponentName notificationListener,
+            @NonNull UserHandle userHandle, @NonNull Executor executor,
+            @NonNull OnActiveSessionsChangedListener sessionListener) {
+        Objects.requireNonNull(userHandle, "userHandle shouldn't be null");
+        Objects.requireNonNull(executor, "executor shouldn't be null");
+        addOnActiveSessionsChangedListener(sessionListener, notificationListener,
+                userHandle.getIdentifier(), executor);
+    }
+
+    private void addOnActiveSessionsChangedListener(
+            @NonNull OnActiveSessionsChangedListener sessionListener,
+            @Nullable ComponentName notificationListener, int userId,
+            @Nullable Executor executor) {
+        Objects.requireNonNull(sessionListener, "sessionListener shouldn't be null");
+        if (executor == null) {
+            executor = new HandlerExecutor(new Handler());
+        }
+
+        synchronized (mLock) {
+            if (mListeners.get(sessionListener) != null) {
+                Log.w(TAG, "Attempted to add session listener twice, ignoring.");
+                return;
+            }
+            SessionsChangedWrapper wrapper = new SessionsChangedWrapper(mContext, sessionListener,
+                    executor);
+            try {
+                mService.addSessionsListener(wrapper.mStub, notificationListener, userId);
+                mListeners.put(sessionListener, wrapper);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error in addOnActiveSessionsChangedListener.", e);
+            }
+        }
+    }
+
+    /**
+     * Stop receiving active sessions updates on the specified listener.
+     *
+     * @param sessionListener The listener to remove.
+     */
+    public void removeOnActiveSessionsChangedListener(
+            @NonNull OnActiveSessionsChangedListener sessionListener) {
+        Objects.requireNonNull(sessionListener, "sessionListener shouldn't be null");
+        synchronized (mLock) {
+            SessionsChangedWrapper wrapper = mListeners.remove(sessionListener);
+            if (wrapper != null) {
+                try {
+                    mService.removeSessionsListener(wrapper.mStub);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "Error in removeOnActiveSessionsChangedListener.", e);
+                } finally {
+                    wrapper.release();
+                }
+            }
+        }
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Adds a listener to be notified when the {@link #getSession2Tokens()} changes.
+     *
+     * @param listener The listener to add
+     */
+    public void addOnSession2TokensChangedListener(
+            @NonNull OnSession2TokensChangedListener listener) {
+        addOnSession2TokensChangedListener(UserHandle.myUserId(), listener,
+                new HandlerExecutor(new Handler()));
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Adds a listener to be notified when the {@link #getSession2Tokens()} changes.
+     *
+     * @param listener The listener to add
+     * @param handler The handler to call listener on.
+     */
+    public void addOnSession2TokensChangedListener(
+            @NonNull OnSession2TokensChangedListener listener, @NonNull Handler handler) {
+        Objects.requireNonNull(handler, "handler shouldn't be null");
+        addOnSession2TokensChangedListener(UserHandle.myUserId(), listener,
+                new HandlerExecutor(handler));
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Adds a listener to be notified when the {@link #getSession2Tokens()} changes.
+     * <p>
+     * The calling application needs to hold the
+     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} permission in order to
+     * add listeners for user ids that do not belong to current process.
+     *
+     * @param userHandle The userHandle to listen for changes on
+     * @param listener The listener to add
+     * @param executor The executor on which the listener should be invoked
+     * @hide
+     */
+    @SuppressLint("UserHandle")
+    public void addOnSession2TokensChangedListener(@NonNull UserHandle userHandle,
+            @NonNull OnSession2TokensChangedListener listener, @NonNull Executor executor) {
+        Objects.requireNonNull(userHandle, "userHandle shouldn't be null");
+        Objects.requireNonNull(executor, "executor shouldn't be null");
+        addOnSession2TokensChangedListener(userHandle.getIdentifier(), listener, executor);
+    }
+
+    private void addOnSession2TokensChangedListener(int userId,
+            OnSession2TokensChangedListener listener, Executor executor) {
+        Objects.requireNonNull(listener, "listener shouldn't be null");
+        synchronized (mLock) {
+            if (mSession2TokensListeners.get(listener) != null) {
+                Log.w(TAG, "Attempted to add session listener twice, ignoring.");
+                return;
+            }
+            Session2TokensChangedWrapper wrapper =
+                    new Session2TokensChangedWrapper(listener, executor);
+            try {
+                mService.addSession2TokensListener(wrapper.getStub(), userId);
+                mSession2TokensListeners.put(listener, wrapper);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error in addSessionTokensListener.", e);
+                e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Removes the {@link OnSession2TokensChangedListener} to stop receiving session token updates.
+     *
+     * @param listener The listener to remove.
+     */
+    public void removeOnSession2TokensChangedListener(
+            @NonNull OnSession2TokensChangedListener listener) {
+        Objects.requireNonNull(listener, "listener shouldn't be null");
+        final Session2TokensChangedWrapper wrapper;
+        synchronized (mLock) {
+            wrapper = mSession2TokensListeners.remove(listener);
+        }
+        if (wrapper != null) {
+            try {
+                mService.removeSession2TokensListener(wrapper.getStub());
+            } catch (RemoteException e) {
+                Log.e(TAG, "Error in removeSessionTokensListener.", e);
+                e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    /**
+     * Set the remote volume controller callback to receive volume updates on.
+     * Only for use by System UI and Settings application.
+     *
+     * @param executor The executor on which the callback should be invoked
+     * @param callback The volume controller callback to receive updates on.
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void registerRemoteSessionCallback(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull RemoteSessionCallback callback) {
+        Objects.requireNonNull(executor, "executor shouldn't be null");
+        Objects.requireNonNull(callback, "callback shouldn't be null");
+        boolean shouldRegisterCallback = false;
+        synchronized (mLock) {
+            int prevCallbackCount = mRemoteSessionCallbacks.size();
+            mRemoteSessionCallbacks.put(callback, executor);
+            if (prevCallbackCount == 0 && mRemoteSessionCallbacks.size() == 1) {
+                shouldRegisterCallback = true;
+            }
+        }
+        if (shouldRegisterCallback) {
+            try {
+                mService.registerRemoteSessionCallback(mRemoteSessionCallbackStub);
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to register remote volume controller callback", e);
+            }
+        }
+    }
+
+    /**
+     * Unregisters the remote volume controller callback which was previously registered with
+     * {@link #registerRemoteSessionCallback(Executor, RemoteSessionCallback)}.
+     * Only for use by System UI and Settings application.
+     *
+     * @param callback The volume controller callback to receive updates on.
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void unregisterRemoteSessionCallback(
+            @NonNull RemoteSessionCallback callback) {
+        Objects.requireNonNull(callback, "callback shouldn't be null");
+        boolean shouldUnregisterCallback = false;
+        synchronized (mLock) {
+            if (mRemoteSessionCallbacks.remove(callback) != null
+                    && mRemoteSessionCallbacks.size() == 0) {
+                shouldUnregisterCallback = true;
+            }
+        }
+        try {
+            if (shouldUnregisterCallback) {
+                mService.unregisterRemoteSessionCallback(
+                        mRemoteSessionCallbackStub);
+            }
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to unregister remote volume controller callback", e);
+        }
+    }
+
+    /**
+     * Sends a media key event. The receiver will be selected automatically.
+     *
+     * @param keyEvent the key event to send
+     * @param needWakeLock true if a wake lock should be held while sending the key
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void dispatchMediaKeyEvent(@NonNull KeyEvent keyEvent, boolean needWakeLock) {
+        dispatchMediaKeyEventInternal(keyEvent, /*asSystemService=*/false, needWakeLock);
+    }
+
+    /**
+     * Sends a media key event as system service. The receiver will be selected automatically.
+     * <p>
+     * Should be only called by the {@link com.android.internal.policy.PhoneWindow} or
+     * {@link android.view.FallbackEventHandler} when the foreground activity didn't consume the key
+     * from the hardware devices.
+     *
+     * @param keyEvent the key event to send
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void dispatchMediaKeyEventAsSystemService(@NonNull KeyEvent keyEvent) {
+        dispatchMediaKeyEventInternal(keyEvent, /*asSystemService=*/true, /*needWakeLock=*/false);
+    }
+
+    private void dispatchMediaKeyEventInternal(KeyEvent keyEvent, boolean asSystemService,
+            boolean needWakeLock) {
+        Objects.requireNonNull(keyEvent, "keyEvent shouldn't be null");
+        try {
+            mService.dispatchMediaKeyEvent(mContext.getPackageName(), asSystemService, keyEvent,
+                    needWakeLock);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to send key event.", e);
+        }
+    }
+
+    /**
+     * Sends a media key event as system service to the given session.
+     * <p>
+     * Should be only called by the {@link com.android.internal.policy.PhoneWindow} when the
+     * foreground activity didn't consume the key from the hardware devices.
+     *
+     * @param keyEvent the key event to send
+     * @param sessionToken the session token to which the key event should be dispatched
+     * @return {@code true} if the event was sent to the session, {@code false} otherwise
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public boolean dispatchMediaKeyEventToSessionAsSystemService(@NonNull KeyEvent keyEvent,
+            @NonNull MediaSession.Token sessionToken) {
+        Objects.requireNonNull(sessionToken, "sessionToken shouldn't be null");
+        Objects.requireNonNull(keyEvent, "keyEvent shouldn't be null");
+        if (!KeyEvent.isMediaSessionKey(keyEvent.getKeyCode())) {
+            return false;
+        }
+        try {
+            return mService.dispatchMediaKeyEventToSessionAsSystemService(
+                    mContext.getPackageName(), keyEvent, sessionToken);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to send key event.", e);
+        }
+        return false;
+    }
+
+    /**
+     * Sends a volume key event. The receiver will be selected automatically.
+     *
+     * @param keyEvent the volume key event to send
+     * @param streamType type of stream
+     * @param musicOnly true if key event should only be sent to music stream
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void dispatchVolumeKeyEvent(@NonNull KeyEvent keyEvent, int streamType,
+            boolean musicOnly) {
+        dispatchVolumeKeyEventInternal(keyEvent, streamType, musicOnly, /*asSystemService=*/false);
+    }
+
+    /**
+     * Dispatches the volume button event as system service to the session. This only effects the
+     * {@link MediaSession.Callback#getCurrentControllerInfo()} and doesn't bypass any permission
+     * check done by the system service.
+     * <p>
+     * Should be only called by the {@link com.android.internal.policy.PhoneWindow} or
+     * {@link android.view.FallbackEventHandler} when the foreground activity didn't consume the key
+     * from the hardware devices.
+     * <p>
+     * Valid stream types include {@link AudioManager.PublicStreamTypes} and
+     * {@link AudioManager#USE_DEFAULT_STREAM_TYPE}.
+     *
+     * @param keyEvent the volume key event to send
+     * @param streamType type of stream
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void dispatchVolumeKeyEventAsSystemService(@NonNull KeyEvent keyEvent, int streamType) {
+        dispatchVolumeKeyEventInternal(keyEvent, streamType, /*musicOnly=*/false,
+                /*asSystemService=*/true);
+    }
+
+    private void dispatchVolumeKeyEventInternal(@NonNull KeyEvent keyEvent, int stream,
+            boolean musicOnly, boolean asSystemService) {
+        Objects.requireNonNull(keyEvent, "keyEvent shouldn't be null");
+        try {
+            mService.dispatchVolumeKeyEvent(mContext.getPackageName(), mContext.getOpPackageName(),
+                    asSystemService, keyEvent, stream, musicOnly);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to send volume key event.", e);
+        }
+    }
+
+    /**
+     * Dispatches the volume key event as system service to the session.
+     * <p>
+     * Should be only called by the {@link com.android.internal.policy.PhoneWindow} when the
+     * foreground activity didn't consume the key from the hardware devices.
+     *
+     * @param keyEvent the volume key event to send
+     * @param sessionToken the session token to which the key event should be dispatched
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public void dispatchVolumeKeyEventToSessionAsSystemService(@NonNull KeyEvent keyEvent,
+            @NonNull MediaSession.Token sessionToken) {
+        Objects.requireNonNull(sessionToken, "sessionToken shouldn't be null");
+        Objects.requireNonNull(keyEvent, "keyEvent shouldn't be null");
+        try {
+            mService.dispatchVolumeKeyEventToSessionAsSystemService(mContext.getPackageName(),
+                    mContext.getOpPackageName(), keyEvent, sessionToken);
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Error calling dispatchVolumeKeyEventAsSystemService", e);
+        }
+    }
+
+    /**
+     * Dispatch an adjust volume request to the system. It will be sent to the
+     * most relevant audio stream or media session. The direction must be one of
+     * {@link AudioManager#ADJUST_LOWER}, {@link AudioManager#ADJUST_RAISE},
+     * {@link AudioManager#ADJUST_SAME}.
+     *
+     * @param suggestedStream The stream to fall back to if there isn't a
+     *            relevant stream
+     * @param direction The direction to adjust volume in.
+     * @param flags Any flags to include with the volume change.
+     * @hide
+     */
+    public void dispatchAdjustVolume(int suggestedStream, int direction, int flags) {
+        try {
+            mService.dispatchAdjustVolume(mContext.getPackageName(), mContext.getOpPackageName(),
+                    suggestedStream, direction, flags);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to send adjust volume.", e);
+        }
+    }
+
+    /**
+     * Checks whether the remote user is a trusted app.
+     * <p>
+     * An app is trusted if the app holds the
+     * {@link android.Manifest.permission#MEDIA_CONTENT_CONTROL} permission or has an enabled
+     * notification listener.
+     *
+     * @param userInfo The remote user info from either
+     *            {@link MediaSession#getCurrentControllerInfo()} or
+     *            {@link MediaBrowserService#getCurrentBrowserInfo()}.
+     * @return {@code true} if the remote user is trusted and its package name matches with the UID.
+     *            {@code false} otherwise.
+     */
+    public boolean isTrustedForMediaControl(@NonNull RemoteUserInfo userInfo) {
+        Objects.requireNonNull(userInfo, "userInfo shouldn't be null");
+        if (userInfo.getPackageName() == null) {
+            return false;
+        }
+        try {
+            return mService.isTrusted(
+                    userInfo.getPackageName(), userInfo.getPid(), userInfo.getUid());
+        } catch (RemoteException e) {
+            Log.wtf(TAG, "Cannot communicate with the service.", e);
+        }
+        return false;
+    }
+
+    /**
+     * Check if the global priority session is currently active. This can be
+     * used to decide if media keys should be sent to the session or to the app.
+     *
+     * @hide
+     */
+    public boolean isGlobalPriorityActive() {
+        try {
+            return mService.isGlobalPriorityActive();
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to check if the global priority is active.", e);
+        }
+        return false;
+    }
+
+    /**
+     * Set the volume key long-press listener. While the listener is set, the listener
+     * gets the volume key long-presses instead of changing volume.
+     *
+     * <p>System can only have a single volume key long-press listener.
+     *
+     * @param listener The volume key long-press listener. {@code null} to reset.
+     * @param handler The handler on which the listener should be invoked, or {@code null}
+     *            if the listener should be invoked on the calling thread's looper.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER)
+    public void setOnVolumeKeyLongPressListener(
+            OnVolumeKeyLongPressListener listener, @Nullable Handler handler) {
+        synchronized (mLock) {
+            try {
+                if (listener == null) {
+                    mOnVolumeKeyLongPressListener = null;
+                    mService.setOnVolumeKeyLongPressListener(null);
+                } else {
+                    if (handler == null) {
+                        handler = new Handler();
+                    }
+                    mOnVolumeKeyLongPressListener =
+                            new OnVolumeKeyLongPressListenerImpl(listener, handler);
+                    mService.setOnVolumeKeyLongPressListener(mOnVolumeKeyLongPressListener);
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to set volume key long press listener", e);
+            }
+        }
+    }
+
+    /**
+     * Set the media key listener. While the listener is set, the listener
+     * gets the media key before any other media sessions but after the global priority session.
+     * If the listener handles the key (i.e. returns {@code true}),
+     * other sessions will not get the event.
+     *
+     * <p>System can only have a single media key listener.
+     *
+     * @param listener The media key listener. {@code null} to reset.
+     * @param handler The handler on which the listener should be invoked, or {@code null}
+     *            if the listener should be invoked on the calling thread's looper.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.SET_MEDIA_KEY_LISTENER)
+    public void setOnMediaKeyListener(OnMediaKeyListener listener, @Nullable Handler handler) {
+        synchronized (mLock) {
+            try {
+                if (listener == null) {
+                    mOnMediaKeyListener = null;
+                    mService.setOnMediaKeyListener(null);
+                } else {
+                    if (handler == null) {
+                        handler = new Handler();
+                    }
+                    mOnMediaKeyListener = new OnMediaKeyListenerImpl(listener, handler);
+                    mService.setOnMediaKeyListener(mOnMediaKeyListener);
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to set media key listener", e);
+            }
+        }
+    }
+
+    /**
+     * Add a {@link OnMediaKeyEventDispatchedListener}.
+     *
+     * @param executor The executor on which the listener should be invoked
+     * @param listener A {@link OnMediaKeyEventDispatchedListener}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
+    public void addOnMediaKeyEventDispatchedListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnMediaKeyEventDispatchedListener listener) {
+        Objects.requireNonNull(executor, "executor shouldn't be null");
+        Objects.requireNonNull(listener, "listener shouldn't be null");
+        synchronized (mLock) {
+            try {
+                mOnMediaKeyEventDispatchedListeners.put(listener, executor);
+                if (mOnMediaKeyEventDispatchedListeners.size() == 1) {
+                    mService.addOnMediaKeyEventDispatchedListener(
+                            mOnMediaKeyEventDispatchedListenerStub);
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to set media key listener", e);
+            }
+        }
+    }
+
+    /**
+     * Remove a {@link OnMediaKeyEventDispatchedListener}.
+     *
+     * @param listener A {@link OnMediaKeyEventDispatchedListener}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
+    public void removeOnMediaKeyEventDispatchedListener(
+            @NonNull OnMediaKeyEventDispatchedListener listener) {
+        Objects.requireNonNull(listener, "listener shouldn't be null");
+        synchronized (mLock) {
+            try {
+                mOnMediaKeyEventDispatchedListeners.remove(listener);
+                if (mOnMediaKeyEventDispatchedListeners.size() == 0) {
+                    mService.removeOnMediaKeyEventDispatchedListener(
+                            mOnMediaKeyEventDispatchedListenerStub);
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to set media key event dispatched listener", e);
+            }
+        }
+    }
+
+    /**
+     * Add a {@link OnMediaKeyEventSessionChangedListener}.
+     *
+     * @param executor The executor on which the listener should be invoked
+     * @param listener A {@link OnMediaKeyEventSessionChangedListener}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
+    public void addOnMediaKeyEventSessionChangedListener(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OnMediaKeyEventSessionChangedListener listener) {
+        Objects.requireNonNull(executor, "executor shouldn't be null");
+        Objects.requireNonNull(listener, "listener shouldn't be null");
+        synchronized (mLock) {
+            try {
+                mMediaKeyEventSessionChangedCallbacks.put(listener, executor);
+                executor.execute(
+                        () -> listener.onMediaKeyEventSessionChanged(
+                                mCurMediaKeyEventSessionPackage, mCurMediaKeyEventSession));
+                if (mMediaKeyEventSessionChangedCallbacks.size() == 1) {
+                    mService.addOnMediaKeyEventSessionChangedListener(
+                            mOnMediaKeyEventSessionChangedListenerStub);
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to set media key listener", e);
+            }
+        }
+    }
+
+    /**
+     * Remove a {@link OnMediaKeyEventSessionChangedListener}.
+     *
+     * @param listener A {@link OnMediaKeyEventSessionChangedListener}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(value = android.Manifest.permission.MEDIA_CONTENT_CONTROL)
+    public void removeOnMediaKeyEventSessionChangedListener(
+            @NonNull OnMediaKeyEventSessionChangedListener listener) {
+        Objects.requireNonNull(listener, "listener shouldn't be null");
+        synchronized (mLock) {
+            try {
+                mMediaKeyEventSessionChangedCallbacks.remove(listener);
+                if (mMediaKeyEventSessionChangedCallbacks.size() == 0) {
+                    mService.removeOnMediaKeyEventSessionChangedListener(
+                            mOnMediaKeyEventSessionChangedListenerStub);
+                }
+            } catch (RemoteException e) {
+                Log.e(TAG, "Failed to set media key listener", e);
+            }
+        }
+    }
+
+    /**
+     * Set the component name for the custom
+     * {@link com.android.server.media.MediaKeyDispatcher} class. Set to null to restore to the
+     * custom {@link com.android.server.media.MediaKeyDispatcher} class name retrieved from the
+     * config value.
+     *
+     * @hide
+     */
+    @VisibleForTesting
+    public void setCustomMediaKeyDispatcher(@Nullable String name) {
+        try {
+            mService.setCustomMediaKeyDispatcher(name);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to set custom media key dispatcher name", e);
+        }
+    }
+
+    /**
+     * Set the component name for the custom
+     * {@link com.android.server.media.MediaSessionPolicyProvider} class. Set to null to restore to
+     * the custom {@link com.android.server.media.MediaSessionPolicyProvider} class name retrieved
+     * from the config value.
+     *
+     * @hide
+     */
+    @VisibleForTesting
+    public void setCustomMediaSessionPolicyProvider(@Nullable String name) {
+        try {
+            mService.setCustomMediaSessionPolicyProvider(name);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to set custom session policy provider name", e);
+        }
+    }
+
+    /**
+     * Get the component name for the custom {@link com.android.server.media.MediaKeyDispatcher}
+     * class.
+     *
+     * @hide
+     */
+    @VisibleForTesting
+    public boolean hasCustomMediaKeyDispatcher(@NonNull String componentName) {
+        Objects.requireNonNull(componentName, "componentName shouldn't be null");
+        try {
+            return mService.hasCustomMediaKeyDispatcher(componentName);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to check if custom media key dispatcher with given component"
+                    + " name exists", e);
+        }
+        return false;
+    }
+
+    /**
+     * Get the component name for the custom
+     * {@link com.android.server.media.MediaSessionPolicyProvider} class.
+     *
+     * @hide
+     */
+    @VisibleForTesting
+    public boolean hasCustomMediaSessionPolicyProvider(@NonNull String componentName) {
+        Objects.requireNonNull(componentName, "componentName shouldn't be null");
+        try {
+            return mService.hasCustomMediaSessionPolicyProvider(componentName);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to check if custom media session policy provider with given"
+                    + " component name exists", e);
+        }
+        return false;
+    }
+
+    /**
+     * Get session policies of the specified {@link MediaSession.Token}.
+     *
+     * @hide
+     */
+    @Nullable
+    public int getSessionPolicies(@NonNull MediaSession.Token token) {
+        try {
+            return mService.getSessionPolicies(token);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to get session policies", e);
+        }
+        return 0;
+    }
+
+    /**
+     * Set new session policies to the specified {@link MediaSession.Token}.
+     *
+     * @hide
+     */
+    public void setSessionPolicies(@NonNull MediaSession.Token token, @Nullable int policies) {
+        try {
+            mService.setSessionPolicies(token, policies);
+        } catch (RemoteException e) {
+            Log.e(TAG, "Failed to set session policies", e);
+        }
+    }
+
+    /**
+     * Listens for changes to the list of active sessions. This can be added
+     * using {@link #addOnActiveSessionsChangedListener}.
+     */
+    public interface OnActiveSessionsChangedListener {
+        public void onActiveSessionsChanged(@Nullable List<MediaController> controllers);
+    }
+
+    /**
+     * This API is not generally intended for third party application developers.
+     * Use the <a href="{@docRoot}jetpack/androidx.html">AndroidX</a>
+     * <a href="{@docRoot}reference/androidx/media2/session/package-summary.html">Media2 session
+     * Library</a> for consistent behavior across all devices.
+     * <p>
+     * Listens for changes to the {@link #getSession2Tokens()}. This can be added
+     * using {@link #addOnSession2TokensChangedListener(OnSession2TokensChangedListener, Handler)}.
+     */
+    public interface OnSession2TokensChangedListener {
+        /**
+         * Called when the {@link #getSession2Tokens()} is changed.
+         *
+         * @param tokens list of {@link Session2Token}
+         */
+        void onSession2TokensChanged(@NonNull List<Session2Token> tokens);
+    }
+
+    /**
+     * Listens the volume key long-presses.
+     * @hide
+     */
+    @SystemApi
+    public interface OnVolumeKeyLongPressListener {
+        /**
+         * Called when the volume key is long-pressed.
+         * <p>This will be called for both down and up events.
+         */
+        void onVolumeKeyLongPress(KeyEvent event);
+    }
+
+    /**
+     * Listens the media key.
+     * @hide
+     */
+    @SystemApi
+    public interface OnMediaKeyListener {
+        /**
+         * Called when the media key is pressed.
+         * <p>If the listener consumes the initial down event (i.e. ACTION_DOWN with
+         * repeat count zero), it must also comsume all following key events.
+         * (i.e. ACTION_DOWN with repeat count more than zero, and ACTION_UP).
+         * <p>If it takes more than 1s to return, the key event will be sent to
+         * other media sessions.
+         */
+        boolean onMediaKey(KeyEvent event);
+    }
+
+    /**
+     * Listener to be called when the media session service dispatches a media key event.
+     * @hide
+     */
+    @SystemApi
+    public interface OnMediaKeyEventDispatchedListener {
+        /**
+         * Called when a media key event is dispatched through the media session service. The
+         * session token can be {@link null} if the framework has sent the media key event to the
+         * media button receiver to revive the media app's playback after the corresponding session
+         * is released.
+         *
+         * @param event Dispatched media key event.
+         * @param packageName The package name
+         * @param sessionToken The media session's token. Can be {@code null}.
+         */
+        void onMediaKeyEventDispatched(@NonNull KeyEvent event, @NonNull String packageName,
+                @Nullable MediaSession.Token sessionToken);
+    }
+
+    /**
+     * Listener to receive changes in the media key event session, which would receive a media key
+     * event unless specified.
+     * @hide
+     */
+    @SystemApi
+    public interface OnMediaKeyEventSessionChangedListener {
+        /**
+         * Called when the media key session is changed to the given media session. The key event
+         * session is the media session which would receive key event by default, unless the caller
+         * has specified the target.
+         * <p>
+         * The session token can be {@link null} if the media button session is unset. In that case,
+         * packageName will return the package name of the last session's media button receiver, or
+         * an empty string if the last session didn't set a media button receiver.
+         *
+         * @param packageName The package name of the component that will receive the media key
+         *                    event. Can be empty.
+         * @param sessionToken The media session's token. Can be {@code null}.
+         */
+        void onMediaKeyEventSessionChanged(@NonNull String packageName,
+                @Nullable MediaSession.Token sessionToken);
+    }
+
+    /**
+     * Callback to receive changes in the existing remote sessions. A remote session is a
+     * {@link MediaSession} that is connected to a remote player via
+     * {@link MediaSession#setPlaybackToRemote(VolumeProvider)}
+     *
+     * @hide
+     */
+    @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+    public interface RemoteSessionCallback {
+        /**
+         * Called when the volume is changed for the given session. Flags that are defined in
+         * {@link AudioManager} will also be sent and will contain information about how to
+         * handle the volume change. For example, {@link AudioManager#FLAG_SHOW_UI} indicates that a
+         * toast showing the volume should be shown.
+         *
+         * @param sessionToken the remote media session token
+         * @param flags flags containing extra action or information regarding the volume change
+         */
+        void onVolumeChanged(@NonNull MediaSession.Token sessionToken,
+                @AudioManager.Flags int flags);
+
+        /**
+         * Called when the default remote session is changed where the default remote session
+         * denotes an active remote session that has the highest priority for receiving key events.
+         * Null will be sent if there are currently no active remote sessions.
+         *
+         * @param sessionToken the token of the default remote session, a session with the highest
+         *                     priority for receiving key events.
+         */
+        void onDefaultRemoteSessionChanged(@Nullable MediaSession.Token sessionToken);
+    }
+
+    /**
+     * Information of a remote user of {@link MediaSession} or {@link MediaBrowserService}.
+     * This can be used to decide whether the remote user is trusted app, and also differentiate
+     * caller of {@link MediaSession} and {@link MediaBrowserService} callbacks.
+     * <p>
+     * See {@link #equals(Object)} to take a look at how it differentiate media controller.
+     *
+     * @see #isTrustedForMediaControl(RemoteUserInfo)
+     */
+    public static final class RemoteUserInfo {
+        private final String mPackageName;
+        private final int mPid;
+        private final int mUid;
+
+        /**
+         * Create a new remote user information.
+         *
+         * @param packageName The package name of the remote user
+         * @param pid The pid of the remote user
+         * @param uid The uid of the remote user
+         */
+        public RemoteUserInfo(@NonNull String packageName, int pid, int uid) {
+            mPackageName = packageName;
+            mPid = pid;
+            mUid = uid;
+        }
+
+        /**
+         * @return package name of the controller
+         */
+        public String getPackageName() {
+            return mPackageName;
+        }
+
+        /**
+         * @return pid of the controller
+         */
+        public int getPid() {
+            return mPid;
+        }
+
+        /**
+         * @return uid of the controller
+         */
+        public int getUid() {
+            return mUid;
+        }
+
+        /**
+         * Returns equality of two RemoteUserInfo. Two RemoteUserInfo objects are equal
+         * if and only if they have the same package name, same pid, and same uid.
+         *
+         * @param obj the reference object with which to compare.
+         * @return {@code true} if equals, {@code false} otherwise
+         */
+        @Override
+        public boolean equals(@Nullable Object obj) {
+            if (!(obj instanceof RemoteUserInfo)) {
+                return false;
+            }
+            if (this == obj) {
+                return true;
+            }
+            RemoteUserInfo otherUserInfo = (RemoteUserInfo) obj;
+            return TextUtils.equals(mPackageName, otherUserInfo.mPackageName)
+                    && mPid == otherUserInfo.mPid
+                    && mUid == otherUserInfo.mUid;
+        }
+
+        @Override
+        public int hashCode() {
+            return Objects.hash(mPackageName, mPid, mUid);
+        }
+    }
+
+    private static final class SessionsChangedWrapper {
+        private Context mContext;
+        private OnActiveSessionsChangedListener mListener;
+        private Executor mExecutor;
+
+        public SessionsChangedWrapper(Context context, OnActiveSessionsChangedListener listener,
+                Executor executor) {
+            mContext = context;
+            mListener = listener;
+            mExecutor = executor;
+        }
+
+        private final IActiveSessionsListener.Stub mStub = new IActiveSessionsListener.Stub() {
+            @Override
+            public void onActiveSessionsChanged(final List<MediaSession.Token> tokens) {
+                if (mExecutor != null) {
+                    final Executor executor = mExecutor;
+                    executor.execute(() -> callOnActiveSessionsChangedListener(tokens));
+                }
+            }
+        };
+
+        private void callOnActiveSessionsChangedListener(final List<MediaSession.Token> tokens) {
+            final Context context = mContext;
+            if (context != null) {
+                ArrayList<MediaController> controllers = new ArrayList<>();
+                int size = tokens.size();
+                for (int i = 0; i < size; i++) {
+                    controllers.add(new MediaController(context, tokens.get(i)));
+                }
+                final OnActiveSessionsChangedListener listener = mListener;
+                if (listener != null) {
+                    listener.onActiveSessionsChanged(controllers);
+                }
+            }
+        }
+
+        private void release() {
+            mListener = null;
+            mContext = null;
+            mExecutor = null;
+        }
+    }
+
+    private static final class Session2TokensChangedWrapper {
+        private final OnSession2TokensChangedListener mListener;
+        private final Executor mExecutor;
+        private final ISession2TokensListener.Stub mStub =
+                new ISession2TokensListener.Stub() {
+                    @Override
+                    public void onSession2TokensChanged(final List<Session2Token> tokens) {
+                        mExecutor.execute(() -> mListener.onSession2TokensChanged(tokens));
+                    }
+                };
+
+        Session2TokensChangedWrapper(OnSession2TokensChangedListener listener, Executor executor) {
+            mListener = listener;
+            mExecutor = executor;
+        }
+
+        public ISession2TokensListener.Stub getStub() {
+            return mStub;
+        }
+    }
+
+    private static final class OnVolumeKeyLongPressListenerImpl
+            extends IOnVolumeKeyLongPressListener.Stub {
+        private OnVolumeKeyLongPressListener mListener;
+        private Handler mHandler;
+
+        public OnVolumeKeyLongPressListenerImpl(
+                OnVolumeKeyLongPressListener listener, Handler handler) {
+            mListener = listener;
+            mHandler = handler;
+        }
+
+        @Override
+        public void onVolumeKeyLongPress(KeyEvent event) {
+            if (mListener == null || mHandler == null) {
+                Log.w(TAG, "Failed to call volume key long-press listener." +
+                        " Either mListener or mHandler is null");
+                return;
+            }
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mListener.onVolumeKeyLongPress(event);
+                }
+            });
+        }
+    }
+
+    private static final class OnMediaKeyListenerImpl extends IOnMediaKeyListener.Stub {
+        private OnMediaKeyListener mListener;
+        private Handler mHandler;
+
+        public OnMediaKeyListenerImpl(OnMediaKeyListener listener, Handler handler) {
+            mListener = listener;
+            mHandler = handler;
+        }
+
+        @Override
+        public void onMediaKey(KeyEvent event, ResultReceiver result) {
+            if (mListener == null || mHandler == null) {
+                Log.w(TAG, "Failed to call media key listener." +
+                        " Either mListener or mHandler is null");
+                return;
+            }
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    boolean handled = mListener.onMediaKey(event);
+                    Log.d(TAG, "The media key listener is returned " + handled);
+                    if (result != null) {
+                        result.send(
+                                handled ? RESULT_MEDIA_KEY_HANDLED : RESULT_MEDIA_KEY_NOT_HANDLED,
+                                null);
+                    }
+                }
+            });
+        }
+    }
+
+    private final class OnMediaKeyEventDispatchedListenerStub
+            extends IOnMediaKeyEventDispatchedListener.Stub {
+
+        @Override
+        public void onMediaKeyEventDispatched(KeyEvent event, String packageName,
+                MediaSession.Token sessionToken) {
+            synchronized (mLock) {
+                for (Map.Entry<OnMediaKeyEventDispatchedListener, Executor> e
+                        : mOnMediaKeyEventDispatchedListeners.entrySet()) {
+                    e.getValue().execute(
+                            () -> e.getKey().onMediaKeyEventDispatched(event, packageName,
+                                    sessionToken));
+                }
+            }
+        }
+    }
+
+    private final class OnMediaKeyEventSessionChangedListenerStub
+            extends IOnMediaKeyEventSessionChangedListener.Stub {
+        @Override
+        public void onMediaKeyEventSessionChanged(String packageName,
+                MediaSession.Token sessionToken) {
+            synchronized (mLock) {
+                mCurMediaKeyEventSessionPackage = packageName;
+                mCurMediaKeyEventSession = sessionToken;
+                for (Map.Entry<OnMediaKeyEventSessionChangedListener, Executor> e
+                        : mMediaKeyEventSessionChangedCallbacks.entrySet()) {
+                    e.getValue().execute(() -> e.getKey().onMediaKeyEventSessionChanged(packageName,
+                            sessionToken));
+                }
+            }
+        }
+    }
+
+    private final class RemoteSessionCallbackStub
+            extends IRemoteSessionCallback.Stub {
+        @Override
+        public void onVolumeChanged(MediaSession.Token sessionToken, int flags) {
+            Map<RemoteSessionCallback, Executor> callbacks = new ArrayMap<>();
+            synchronized (mLock) {
+                callbacks.putAll(mRemoteSessionCallbacks);
+            }
+            for (Map.Entry<RemoteSessionCallback, Executor> e : callbacks.entrySet()) {
+                e.getValue().execute(() -> e.getKey().onVolumeChanged(sessionToken, flags));
+            }
+        }
+
+        @Override
+        public void onSessionChanged(MediaSession.Token sessionToken) {
+            Map<RemoteSessionCallback, Executor> callbacks = new ArrayMap<>();
+            synchronized (mLock) {
+                callbacks.putAll(mRemoteSessionCallbacks);
+            }
+            for (Map.Entry<RemoteSessionCallback, Executor> e : callbacks.entrySet()) {
+                e.getValue().execute(() -> e.getKey().onDefaultRemoteSessionChanged(sessionToken));
+            }
+        }
+    }
+}
diff --git a/android/media/session/ParcelableListBinder.java b/android/media/session/ParcelableListBinder.java
new file mode 100644
index 0000000..bbf1e08
--- /dev/null
+++ b/android/media/session/ParcelableListBinder.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2020 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.session;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Consumer;
+
+/**
+ * Binder to receive a list that has a large number of {@link Parcelable} items.
+ *
+ * It's similar to {@link android.content.pm.ParceledListSlice}, but transactions are performed in
+ * the opposite direction.
+ *
+ * @param <T> the type of {@link Parcelable}
+ * @hide
+ */
+public class ParcelableListBinder<T extends Parcelable> extends Binder {
+
+    private static final int SUGGESTED_MAX_IPC_SIZE = IBinder.getSuggestedMaxIpcSizeBytes();
+
+    private static final int END_OF_PARCEL = 0;
+    private static final int ITEM_CONTINUED = 1;
+
+    private final Consumer<List<T>> mConsumer;
+
+    private final Object mLock = new Object();
+
+    @GuardedBy("mLock")
+    private final List<T> mList = new ArrayList<>();
+
+    @GuardedBy("mLock")
+    private int mCount;
+
+    @GuardedBy("mLock")
+    private boolean mConsumed;
+
+    /**
+     * Creates an instance.
+     *
+     * @param consumer a consumer that consumes the list received
+     */
+    public ParcelableListBinder(@NonNull Consumer<List<T>> consumer) {
+        mConsumer = consumer;
+    }
+
+    @Override
+    protected boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+            throws RemoteException {
+        if (code != FIRST_CALL_TRANSACTION) {
+            return super.onTransact(code, data, reply, flags);
+        }
+        List<T> listToBeConsumed;
+        synchronized (mLock) {
+            if (mConsumed) {
+                return false;
+            }
+            int i = mList.size();
+            if (i == 0) {
+                mCount = data.readInt();
+            }
+            while (i < mCount && data.readInt() != END_OF_PARCEL) {
+                mList.add(data.readParcelable(null));
+                i++;
+            }
+            if (i >= mCount) {
+                listToBeConsumed = mList;
+                mConsumed = true;
+            } else {
+                listToBeConsumed = null;
+            }
+        }
+        if (listToBeConsumed != null) {
+            mConsumer.accept(listToBeConsumed);
+        }
+        return true;
+    }
+
+    /**
+     * Sends a list of {@link Parcelable} to a binder.
+     *
+     * @param binder a binder interface backed by {@link ParcelableListBinder}
+     * @param list a list to send
+     */
+    public static <T extends Parcelable> void send(@NonNull IBinder binder, @NonNull List<T> list)
+            throws RemoteException {
+        int count = list.size();
+        int i = 0;
+        do {
+            Parcel data = Parcel.obtain();
+            Parcel reply = Parcel.obtain();
+            if (i == 0) {
+                data.writeInt(count);
+            }
+            while (i < count && data.dataSize() < SUGGESTED_MAX_IPC_SIZE) {
+                data.writeInt(ITEM_CONTINUED);
+                data.writeParcelable(list.get(i), 0);
+                i++;
+            }
+            if (i < count) {
+                data.writeInt(END_OF_PARCEL);
+            }
+            binder.transact(FIRST_CALL_TRANSACTION, data, reply, 0);
+            reply.recycle();
+            data.recycle();
+        } while (i < count);
+    }
+}
diff --git a/android/media/session/PlaybackState.java b/android/media/session/PlaybackState.java
new file mode 100644
index 0000000..9eacc74
--- /dev/null
+++ b/android/media/session/PlaybackState.java
@@ -0,0 +1,961 @@
+/*
+ * Copyright (C) 2014 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.session;
+
+import android.annotation.DrawableRes;
+import android.annotation.IntDef;
+import android.annotation.LongDef;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.SystemClock;
+import android.text.TextUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Playback state for a {@link MediaSession}. This includes a state like
+ * {@link PlaybackState#STATE_PLAYING}, the current playback position,
+ * and the current control capabilities.
+ */
+public final class PlaybackState implements Parcelable {
+    private static final String TAG = "PlaybackState";
+
+    /**
+     * @hide
+     */
+    @LongDef(flag = true, value = {ACTION_STOP, ACTION_PAUSE, ACTION_PLAY, ACTION_REWIND,
+            ACTION_SKIP_TO_PREVIOUS, ACTION_SKIP_TO_NEXT, ACTION_FAST_FORWARD, ACTION_SET_RATING,
+            ACTION_SEEK_TO, ACTION_PLAY_PAUSE, ACTION_PLAY_FROM_MEDIA_ID, ACTION_PLAY_FROM_SEARCH,
+            ACTION_SKIP_TO_QUEUE_ITEM, ACTION_PLAY_FROM_URI, ACTION_PREPARE,
+            ACTION_PREPARE_FROM_MEDIA_ID, ACTION_PREPARE_FROM_SEARCH, ACTION_PREPARE_FROM_URI,
+            ACTION_SET_PLAYBACK_SPEED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Actions {}
+
+    /**
+     * Indicates this session supports the stop command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_STOP = 1 << 0;
+
+    /**
+     * Indicates this session supports the pause command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_PAUSE = 1 << 1;
+
+    /**
+     * Indicates this session supports the play command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_PLAY = 1 << 2;
+
+    /**
+     * Indicates this session supports the rewind command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_REWIND = 1 << 3;
+
+    /**
+     * Indicates this session supports the previous command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_SKIP_TO_PREVIOUS = 1 << 4;
+
+    /**
+     * Indicates this session supports the next command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_SKIP_TO_NEXT = 1 << 5;
+
+    /**
+     * Indicates this session supports the fast forward command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_FAST_FORWARD = 1 << 6;
+
+    /**
+     * Indicates this session supports the set rating command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_SET_RATING = 1 << 7;
+
+    /**
+     * Indicates this session supports the seek to command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_SEEK_TO = 1 << 8;
+
+    /**
+     * Indicates this session supports the play/pause toggle command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_PLAY_PAUSE = 1 << 9;
+
+    /**
+     * Indicates this session supports the play from media id command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_PLAY_FROM_MEDIA_ID = 1 << 10;
+
+    /**
+     * Indicates this session supports the play from search command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_PLAY_FROM_SEARCH = 1 << 11;
+
+    /**
+     * Indicates this session supports the skip to queue item command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_SKIP_TO_QUEUE_ITEM = 1 << 12;
+
+    /**
+     * Indicates this session supports the play from URI command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_PLAY_FROM_URI = 1 << 13;
+
+    /**
+     * Indicates this session supports the prepare command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_PREPARE = 1 << 14;
+
+    /**
+     * Indicates this session supports the prepare from media id command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_PREPARE_FROM_MEDIA_ID = 1 << 15;
+
+    /**
+     * Indicates this session supports the prepare from search command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_PREPARE_FROM_SEARCH = 1 << 16;
+
+    /**
+     * Indicates this session supports the prepare from URI command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_PREPARE_FROM_URI = 1 << 17;
+
+    // Note: The value jumps from 1 << 17 to 1 << 22 for matching same value with AndroidX.
+    /**
+     * Indicates this session supports the set playback speed command.
+     *
+     * @see Builder#setActions(long)
+     */
+    public static final long ACTION_SET_PLAYBACK_SPEED = 1 << 22;
+
+    /**
+     * @hide
+     */
+    @IntDef({STATE_NONE, STATE_STOPPED, STATE_PAUSED, STATE_PLAYING, STATE_FAST_FORWARDING,
+            STATE_REWINDING, STATE_BUFFERING, STATE_ERROR, STATE_CONNECTING,
+            STATE_SKIPPING_TO_PREVIOUS, STATE_SKIPPING_TO_NEXT, STATE_SKIPPING_TO_QUEUE_ITEM})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface State {}
+
+    /**
+     * This is the default playback state and indicates that no media has been
+     * added yet, or the performer has been reset and has no content to play.
+     *
+     * @see Builder#setState(int, long, float)
+     * @see Builder#setState(int, long, float, long)
+     */
+    public static final int STATE_NONE = 0;
+
+    /**
+     * State indicating this item is currently stopped.
+     *
+     * @see Builder#setState
+     */
+    public static final int STATE_STOPPED = 1;
+
+    /**
+     * State indicating this item is currently paused.
+     *
+     * @see Builder#setState
+     */
+    public static final int STATE_PAUSED = 2;
+
+    /**
+     * State indicating this item is currently playing.
+     *
+     * @see Builder#setState
+     */
+    public static final int STATE_PLAYING = 3;
+
+    /**
+     * State indicating this item is currently fast forwarding.
+     *
+     * @see Builder#setState
+     */
+    public static final int STATE_FAST_FORWARDING = 4;
+
+    /**
+     * State indicating this item is currently rewinding.
+     *
+     * @see Builder#setState
+     */
+    public static final int STATE_REWINDING = 5;
+
+    /**
+     * State indicating this item is currently buffering and will begin playing
+     * when enough data has buffered.
+     *
+     * @see Builder#setState
+     */
+    public static final int STATE_BUFFERING = 6;
+
+    /**
+     * State indicating this item is currently in an error state. The error
+     * message should also be set when entering this state.
+     *
+     * @see Builder#setState
+     */
+    public static final int STATE_ERROR = 7;
+
+    /**
+     * State indicating the class doing playback is currently connecting to a
+     * new destination.  Depending on the implementation you may return to the previous
+     * state when the connection finishes or enter {@link #STATE_NONE}.
+     * If the connection failed {@link #STATE_ERROR} should be used.
+     *
+     * @see Builder#setState
+     */
+    public static final int STATE_CONNECTING = 8;
+
+    /**
+     * State indicating the player is currently skipping to the previous item.
+     *
+     * @see Builder#setState
+     */
+    public static final int STATE_SKIPPING_TO_PREVIOUS = 9;
+
+    /**
+     * State indicating the player is currently skipping to the next item.
+     *
+     * @see Builder#setState
+     */
+    public static final int STATE_SKIPPING_TO_NEXT = 10;
+
+    /**
+     * State indicating the player is currently skipping to a specific item in
+     * the queue.
+     *
+     * @see Builder#setState
+     */
+    public static final int STATE_SKIPPING_TO_QUEUE_ITEM = 11;
+
+    /**
+     * Use this value for the position to indicate the position is not known.
+     */
+    public static final long PLAYBACK_POSITION_UNKNOWN = -1;
+
+    private final int mState;
+    private final long mPosition;
+    private final long mBufferedPosition;
+    private final float mSpeed;
+    private final long mActions;
+    private List<PlaybackState.CustomAction> mCustomActions;
+    private final CharSequence mErrorMessage;
+    private final long mUpdateTime;
+    private final long mActiveItemId;
+    private final Bundle mExtras;
+
+    private PlaybackState(int state, long position, long updateTime, float speed,
+            long bufferedPosition, long transportControls,
+            List<PlaybackState.CustomAction> customActions, long activeItemId,
+            CharSequence error, Bundle extras) {
+        mState = state;
+        mPosition = position;
+        mSpeed = speed;
+        mUpdateTime = updateTime;
+        mBufferedPosition = bufferedPosition;
+        mActions = transportControls;
+        mCustomActions = new ArrayList<>(customActions);
+        mActiveItemId = activeItemId;
+        mErrorMessage = error;
+        mExtras = extras;
+    }
+
+    private PlaybackState(Parcel in) {
+        mState = in.readInt();
+        mPosition = in.readLong();
+        mSpeed = in.readFloat();
+        mUpdateTime = in.readLong();
+        mBufferedPosition = in.readLong();
+        mActions = in.readLong();
+        mCustomActions = in.createTypedArrayList(CustomAction.CREATOR);
+        mActiveItemId = in.readLong();
+        mErrorMessage = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+        mExtras = in.readBundle();
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder bob = new StringBuilder("PlaybackState {");
+        bob.append("state=").append(mState);
+        bob.append(", position=").append(mPosition);
+        bob.append(", buffered position=").append(mBufferedPosition);
+        bob.append(", speed=").append(mSpeed);
+        bob.append(", updated=").append(mUpdateTime);
+        bob.append(", actions=").append(mActions);
+        bob.append(", custom actions=").append(mCustomActions);
+        bob.append(", active item id=").append(mActiveItemId);
+        bob.append(", error=").append(mErrorMessage);
+        bob.append("}");
+        return bob.toString();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mState);
+        dest.writeLong(mPosition);
+        dest.writeFloat(mSpeed);
+        dest.writeLong(mUpdateTime);
+        dest.writeLong(mBufferedPosition);
+        dest.writeLong(mActions);
+        dest.writeTypedList(mCustomActions);
+        dest.writeLong(mActiveItemId);
+        TextUtils.writeToParcel(mErrorMessage, dest, 0);
+        dest.writeBundle(mExtras);
+    }
+
+    /**
+     * Get the current state of playback. One of the following:
+     * <ul>
+     * <li> {@link PlaybackState#STATE_NONE}</li>
+     * <li> {@link PlaybackState#STATE_STOPPED}</li>
+     * <li> {@link PlaybackState#STATE_PLAYING}</li>
+     * <li> {@link PlaybackState#STATE_PAUSED}</li>
+     * <li> {@link PlaybackState#STATE_FAST_FORWARDING}</li>
+     * <li> {@link PlaybackState#STATE_REWINDING}</li>
+     * <li> {@link PlaybackState#STATE_BUFFERING}</li>
+     * <li> {@link PlaybackState#STATE_ERROR}</li>
+     * <li> {@link PlaybackState#STATE_CONNECTING}</li>
+     * <li> {@link PlaybackState#STATE_SKIPPING_TO_PREVIOUS}</li>
+     * <li> {@link PlaybackState#STATE_SKIPPING_TO_NEXT}</li>
+     * <li> {@link PlaybackState#STATE_SKIPPING_TO_QUEUE_ITEM}</li>
+     * </ul>
+     */
+    @State
+    public int getState() {
+        return mState;
+    }
+
+    /**
+     * Get the current playback position in ms.
+     */
+    public long getPosition() {
+        return mPosition;
+    }
+
+    /**
+     * Get the current buffered position in ms. This is the farthest playback
+     * point that can be reached from the current position using only buffered
+     * content.
+     */
+    public long getBufferedPosition() {
+        return mBufferedPosition;
+    }
+
+    /**
+     * Get the current playback speed as a multiple of normal playback. This
+     * should be negative when rewinding. A value of 1 means normal playback and
+     * 0 means paused.
+     *
+     * @return The current speed of playback.
+     */
+    public float getPlaybackSpeed() {
+        return mSpeed;
+    }
+
+    /**
+     * Get the current actions available on this session. This should use a
+     * bitmask of the available actions.
+     * <ul>
+     * <li> {@link PlaybackState#ACTION_SKIP_TO_PREVIOUS}</li>
+     * <li> {@link PlaybackState#ACTION_REWIND}</li>
+     * <li> {@link PlaybackState#ACTION_PLAY}</li>
+     * <li> {@link PlaybackState#ACTION_PAUSE}</li>
+     * <li> {@link PlaybackState#ACTION_STOP}</li>
+     * <li> {@link PlaybackState#ACTION_FAST_FORWARD}</li>
+     * <li> {@link PlaybackState#ACTION_SKIP_TO_NEXT}</li>
+     * <li> {@link PlaybackState#ACTION_SEEK_TO}</li>
+     * <li> {@link PlaybackState#ACTION_SET_RATING}</li>
+     * <li> {@link PlaybackState#ACTION_PLAY_PAUSE}</li>
+     * <li> {@link PlaybackState#ACTION_PLAY_FROM_MEDIA_ID}</li>
+     * <li> {@link PlaybackState#ACTION_PLAY_FROM_SEARCH}</li>
+     * <li> {@link PlaybackState#ACTION_SKIP_TO_QUEUE_ITEM}</li>
+     * <li> {@link PlaybackState#ACTION_PLAY_FROM_URI}</li>
+     * <li> {@link PlaybackState#ACTION_PREPARE}</li>
+     * <li> {@link PlaybackState#ACTION_PREPARE_FROM_MEDIA_ID}</li>
+     * <li> {@link PlaybackState#ACTION_PREPARE_FROM_SEARCH}</li>
+     * <li> {@link PlaybackState#ACTION_PREPARE_FROM_URI}</li>
+     * <li> {@link PlaybackState#ACTION_SET_PLAYBACK_SPEED}</li>
+     * </ul>
+     */
+    @Actions
+    public long getActions() {
+        return mActions;
+    }
+
+    /**
+     * Get the list of custom actions.
+     */
+    public List<PlaybackState.CustomAction> getCustomActions() {
+        return mCustomActions;
+    }
+
+    /**
+     * Get a user readable error message. This should be set when the state is
+     * {@link PlaybackState#STATE_ERROR}.
+     */
+    public CharSequence getErrorMessage() {
+        return mErrorMessage;
+    }
+
+    /**
+     * Get the elapsed real time at which position was last updated. If the
+     * position has never been set this will return 0;
+     *
+     * @return The last time the position was updated.
+     */
+    public long getLastPositionUpdateTime() {
+        return mUpdateTime;
+    }
+
+    /**
+     * Get the id of the currently active item in the queue. If there is no
+     * queue or a queue is not supported by the session this will be
+     * {@link MediaSession.QueueItem#UNKNOWN_ID}.
+     *
+     * @return The id of the currently active item in the queue or
+     *         {@link MediaSession.QueueItem#UNKNOWN_ID}.
+     */
+    public long getActiveQueueItemId() {
+        return mActiveItemId;
+    }
+
+    /**
+     * Get any custom extras that were set on this playback state.
+     *
+     * @return The extras for this state or null.
+     */
+    public @Nullable Bundle getExtras() {
+        return mExtras;
+    }
+
+    /**
+     * Returns whether this is considered as an active playback state.
+     * <p>
+     * The playback state is considered as an active if the state is one of the following:
+     * <ul>
+     * <li>{@link #STATE_BUFFERING}</li>
+     * <li>{@link #STATE_CONNECTING}</li>
+     * <li>{@link #STATE_FAST_FORWARDING}</li>
+     * <li>{@link #STATE_PLAYING}</li>
+     * <li>{@link #STATE_REWINDING}</li>
+     * <li>{@link #STATE_SKIPPING_TO_NEXT}</li>
+     * <li>{@link #STATE_SKIPPING_TO_PREVIOUS}</li>
+     * <li>{@link #STATE_SKIPPING_TO_QUEUE_ITEM}</li>
+     * </ul>
+     */
+    public boolean isActive() {
+        switch (mState) {
+            case PlaybackState.STATE_FAST_FORWARDING:
+            case PlaybackState.STATE_REWINDING:
+            case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
+            case PlaybackState.STATE_SKIPPING_TO_NEXT:
+            case PlaybackState.STATE_SKIPPING_TO_QUEUE_ITEM:
+            case PlaybackState.STATE_BUFFERING:
+            case PlaybackState.STATE_CONNECTING:
+            case PlaybackState.STATE_PLAYING:
+                return true;
+        }
+        return false;
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<PlaybackState> CREATOR =
+            new Parcelable.Creator<PlaybackState>() {
+        @Override
+        public PlaybackState createFromParcel(Parcel in) {
+            return new PlaybackState(in);
+        }
+
+        @Override
+        public PlaybackState[] newArray(int size) {
+            return new PlaybackState[size];
+        }
+    };
+
+    /**
+     * {@link PlaybackState.CustomAction CustomActions} can be used to extend the capabilities of
+     * the standard transport controls by exposing app specific actions to
+     * {@link MediaController MediaControllers}.
+     */
+    public static final class CustomAction implements Parcelable {
+        private final String mAction;
+        private final CharSequence mName;
+        private final int mIcon;
+        private final Bundle mExtras;
+
+        /**
+         * Use {@link PlaybackState.CustomAction.Builder#build()}.
+         */
+        private CustomAction(String action, CharSequence name, int icon, Bundle extras) {
+            mAction = action;
+            mName = name;
+            mIcon = icon;
+            mExtras = extras;
+        }
+
+        private CustomAction(Parcel in) {
+            mAction = in.readString();
+            mName = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+            mIcon = in.readInt();
+            mExtras = in.readBundle();
+        }
+
+        @Override
+        public void writeToParcel(Parcel dest, int flags) {
+            dest.writeString(mAction);
+            TextUtils.writeToParcel(mName, dest, flags);
+            dest.writeInt(mIcon);
+            dest.writeBundle(mExtras);
+        }
+
+        @Override
+        public int describeContents() {
+            return 0;
+        }
+
+        public static final @android.annotation.NonNull Parcelable.Creator<PlaybackState.CustomAction> CREATOR =
+                new Parcelable.Creator<PlaybackState.CustomAction>() {
+
+                    @Override
+                    public PlaybackState.CustomAction createFromParcel(Parcel p) {
+                        return new PlaybackState.CustomAction(p);
+                    }
+
+                    @Override
+                    public PlaybackState.CustomAction[] newArray(int size) {
+                        return new PlaybackState.CustomAction[size];
+                    }
+                };
+
+        /**
+         * Returns the action of the {@link CustomAction}.
+         *
+         * @return The action of the {@link CustomAction}.
+         */
+        public String getAction() {
+            return mAction;
+        }
+
+        /**
+         * Returns the display name of this action. e.g. "Favorite"
+         *
+         * @return The display name of this {@link CustomAction}.
+         */
+        public CharSequence getName() {
+            return mName;
+        }
+
+        /**
+         * Returns the resource id of the icon in the {@link MediaSession MediaSession's} package.
+         *
+         * @return The resource id of the icon in the {@link MediaSession MediaSession's} package.
+         */
+        public int getIcon() {
+            return mIcon;
+        }
+
+        /**
+         * Returns extras which provide additional application-specific information about the
+         * action, or null if none. These arguments are meant to be consumed by a
+         * {@link MediaController} if it knows how to handle them.
+         *
+         * @return Optional arguments for the {@link CustomAction}.
+         */
+        public Bundle getExtras() {
+            return mExtras;
+        }
+
+        @Override
+        public String toString() {
+            return "Action:" + "mName='" + mName + ", mIcon=" + mIcon + ", mExtras=" + mExtras;
+        }
+
+        /**
+         * Builder for {@link CustomAction} objects.
+         */
+        public static final class Builder {
+            private final String mAction;
+            private final CharSequence mName;
+            private final int mIcon;
+            private Bundle mExtras;
+
+            /**
+             * Creates a {@link CustomAction} builder with the id, name, and icon set.
+             *
+             * @param action The action of the {@link CustomAction}.
+             * @param name The display name of the {@link CustomAction}. This name will be displayed
+             *             along side the action if the UI supports it.
+             * @param icon The icon resource id of the {@link CustomAction}. This resource id
+             *             must be in the same package as the {@link MediaSession}. It will be
+             *             displayed with the custom action if the UI supports it.
+             */
+            public Builder(String action, CharSequence name, @DrawableRes int icon) {
+                if (TextUtils.isEmpty(action)) {
+                    throw new IllegalArgumentException(
+                            "You must specify an action to build a CustomAction.");
+                }
+                if (TextUtils.isEmpty(name)) {
+                    throw new IllegalArgumentException(
+                            "You must specify a name to build a CustomAction.");
+                }
+                if (icon == 0) {
+                    throw new IllegalArgumentException(
+                            "You must specify an icon resource id to build a CustomAction.");
+                }
+                mAction = action;
+                mName = name;
+                mIcon = icon;
+            }
+
+            /**
+             * Set optional extras for the {@link CustomAction}. These extras are meant to be
+             * consumed by a {@link MediaController} if it knows how to handle them.
+             * Keys should be fully qualified (e.g. "com.example.MY_ARG") to avoid collisions.
+             *
+             * @param extras Optional extras for the {@link CustomAction}.
+             * @return this.
+             */
+            public Builder setExtras(Bundle extras) {
+                mExtras = extras;
+                return this;
+            }
+
+            /**
+             * Build and return the {@link CustomAction} instance with the specified values.
+             *
+             * @return A new {@link CustomAction} instance.
+             */
+            public CustomAction build() {
+                return new CustomAction(mAction, mName, mIcon, mExtras);
+            }
+        }
+    }
+
+    /**
+     * Builder for {@link PlaybackState} objects.
+     */
+    public static final class Builder {
+        private final List<PlaybackState.CustomAction> mCustomActions = new ArrayList<>();
+
+        private int mState;
+        private long mPosition;
+        private long mBufferedPosition;
+        private float mSpeed;
+        private long mActions;
+        private CharSequence mErrorMessage;
+        private long mUpdateTime;
+        private long mActiveItemId = MediaSession.QueueItem.UNKNOWN_ID;
+        private Bundle mExtras;
+
+        /**
+         * Creates an initially empty state builder.
+         */
+        public Builder() {
+        }
+
+        /**
+         * Creates a builder with the same initial values as those in the from
+         * state.
+         *
+         * @param from The state to use for initializing the builder.
+         */
+        public Builder(PlaybackState from) {
+            if (from == null) {
+                return;
+            }
+            mState = from.mState;
+            mPosition = from.mPosition;
+            mBufferedPosition = from.mBufferedPosition;
+            mSpeed = from.mSpeed;
+            mActions = from.mActions;
+            if (from.mCustomActions != null) {
+                mCustomActions.addAll(from.mCustomActions);
+            }
+            mErrorMessage = from.mErrorMessage;
+            mUpdateTime = from.mUpdateTime;
+            mActiveItemId = from.mActiveItemId;
+            mExtras = from.mExtras;
+        }
+
+        /**
+         * Set the current state of playback.
+         * <p>
+         * The position must be in ms and indicates the current playback
+         * position within the item. If the position is unknown use
+         * {@link #PLAYBACK_POSITION_UNKNOWN}. When not using an unknown
+         * position the time at which the position was updated must be provided.
+         * It is okay to use {@link SystemClock#elapsedRealtime()} if the
+         * current position was just retrieved.
+         * <p>
+         * The speed is a multiple of normal playback and should be 0 when
+         * paused and negative when rewinding. Normal playback speed is 1.0.
+         * <p>
+         * The state must be one of the following:
+         * <ul>
+         * <li> {@link PlaybackState#STATE_NONE}</li>
+         * <li> {@link PlaybackState#STATE_STOPPED}</li>
+         * <li> {@link PlaybackState#STATE_PLAYING}</li>
+         * <li> {@link PlaybackState#STATE_PAUSED}</li>
+         * <li> {@link PlaybackState#STATE_FAST_FORWARDING}</li>
+         * <li> {@link PlaybackState#STATE_REWINDING}</li>
+         * <li> {@link PlaybackState#STATE_BUFFERING}</li>
+         * <li> {@link PlaybackState#STATE_ERROR}</li>
+         * <li> {@link PlaybackState#STATE_CONNECTING}</li>
+         * <li> {@link PlaybackState#STATE_SKIPPING_TO_PREVIOUS}</li>
+         * <li> {@link PlaybackState#STATE_SKIPPING_TO_NEXT}</li>
+         * <li> {@link PlaybackState#STATE_SKIPPING_TO_QUEUE_ITEM}</li>
+         * </ul>
+         *
+         * @param state The current state of playback.
+         * @param position The position in the current item in ms.
+         * @param playbackSpeed The current speed of playback as a multiple of
+         *            normal playback.
+         * @param updateTime The time in the {@link SystemClock#elapsedRealtime}
+         *            timebase that the position was updated at.
+         * @return this
+         */
+        public Builder setState(@State int state, long position, float playbackSpeed,
+                long updateTime) {
+            mState = state;
+            mPosition = position;
+            mUpdateTime = updateTime;
+            mSpeed = playbackSpeed;
+            return this;
+        }
+
+        /**
+         * Set the current state of playback.
+         * <p>
+         * The position must be in ms and indicates the current playback
+         * position within the item. If the position is unknown use
+         * {@link #PLAYBACK_POSITION_UNKNOWN}. The update time will be set to
+         * the current {@link SystemClock#elapsedRealtime()}.
+         * <p>
+         * The speed is a multiple of normal playback and should be 0 when
+         * paused and negative when rewinding. Normal playback speed is 1.0.
+         * <p>
+         * The state must be one of the following:
+         * <ul>
+         * <li> {@link PlaybackState#STATE_NONE}</li>
+         * <li> {@link PlaybackState#STATE_STOPPED}</li>
+         * <li> {@link PlaybackState#STATE_PLAYING}</li>
+         * <li> {@link PlaybackState#STATE_PAUSED}</li>
+         * <li> {@link PlaybackState#STATE_FAST_FORWARDING}</li>
+         * <li> {@link PlaybackState#STATE_REWINDING}</li>
+         * <li> {@link PlaybackState#STATE_BUFFERING}</li>
+         * <li> {@link PlaybackState#STATE_ERROR}</li>
+         * <li> {@link PlaybackState#STATE_CONNECTING}</li>
+         * <li> {@link PlaybackState#STATE_SKIPPING_TO_PREVIOUS}</li>
+         * <li> {@link PlaybackState#STATE_SKIPPING_TO_NEXT}</li>
+         * <li> {@link PlaybackState#STATE_SKIPPING_TO_QUEUE_ITEM}</li>
+         * </ul>
+         *
+         * @param state The current state of playback.
+         * @param position The position in the current item in ms.
+         * @param playbackSpeed The current speed of playback as a multiple of
+         *            normal playback.
+         * @return this
+         */
+        public Builder setState(@State int state, long position, float playbackSpeed) {
+            return setState(state, position, playbackSpeed, SystemClock.elapsedRealtime());
+        }
+
+        /**
+         * Set the current actions available on this session. This should use a
+         * bitmask of possible actions.
+         * <ul>
+         * <li> {@link PlaybackState#ACTION_SKIP_TO_PREVIOUS}</li>
+         * <li> {@link PlaybackState#ACTION_REWIND}</li>
+         * <li> {@link PlaybackState#ACTION_PLAY}</li>
+         * <li> {@link PlaybackState#ACTION_PAUSE}</li>
+         * <li> {@link PlaybackState#ACTION_STOP}</li>
+         * <li> {@link PlaybackState#ACTION_FAST_FORWARD}</li>
+         * <li> {@link PlaybackState#ACTION_SKIP_TO_NEXT}</li>
+         * <li> {@link PlaybackState#ACTION_SEEK_TO}</li>
+         * <li> {@link PlaybackState#ACTION_SET_RATING}</li>
+         * <li> {@link PlaybackState#ACTION_PLAY_PAUSE}</li>
+         * <li> {@link PlaybackState#ACTION_PLAY_FROM_MEDIA_ID}</li>
+         * <li> {@link PlaybackState#ACTION_PLAY_FROM_SEARCH}</li>
+         * <li> {@link PlaybackState#ACTION_SKIP_TO_QUEUE_ITEM}</li>
+         * <li> {@link PlaybackState#ACTION_PLAY_FROM_URI}</li>
+         * <li> {@link PlaybackState#ACTION_PREPARE}</li>
+         * <li> {@link PlaybackState#ACTION_PREPARE_FROM_MEDIA_ID}</li>
+         * <li> {@link PlaybackState#ACTION_PREPARE_FROM_SEARCH}</li>
+         * <li> {@link PlaybackState#ACTION_PREPARE_FROM_URI}</li>
+         * <li> {@link PlaybackState#ACTION_SET_PLAYBACK_SPEED}</li>
+         * </ul>
+         *
+         * @param actions The set of actions allowed.
+         * @return this
+         */
+        public Builder setActions(@Actions long actions) {
+            mActions = actions;
+            return this;
+        }
+
+        /**
+         * Add a custom action to the playback state. Actions can be used to
+         * expose additional functionality to {@link MediaController
+         * MediaControllers} beyond what is offered by the standard transport
+         * controls.
+         * <p>
+         * e.g. start a radio station based on the current item or skip ahead by
+         * 30 seconds.
+         *
+         * @param action An identifier for this action. It can be sent back to
+         *            the {@link MediaSession} through
+         *            {@link MediaController.TransportControls#sendCustomAction(String, Bundle)}.
+         * @param name The display name for the action. If text is shown with
+         *            the action or used for accessibility, this is what should
+         *            be used.
+         * @param icon The resource action of the icon that should be displayed
+         *            for the action. The resource should be in the package of
+         *            the {@link MediaSession}.
+         * @return this
+         */
+        public Builder addCustomAction(String action, String name, int icon) {
+            return addCustomAction(new PlaybackState.CustomAction(action, name, icon, null));
+        }
+
+        /**
+         * Add a custom action to the playback state. Actions can be used to expose additional
+         * functionality to {@link MediaController MediaControllers} beyond what is offered by the
+         * standard transport controls.
+         * <p>
+         * An example of an action would be to start a radio station based on the current item
+         * or to skip ahead by 30 seconds.
+         *
+         * @param customAction The custom action to add to the {@link PlaybackState}.
+         * @return this
+         */
+        public Builder addCustomAction(PlaybackState.CustomAction customAction) {
+            if (customAction == null) {
+                throw new IllegalArgumentException(
+                        "You may not add a null CustomAction to PlaybackState.");
+            }
+            mCustomActions.add(customAction);
+            return this;
+        }
+
+        /**
+         * Set the current buffered position in ms. This is the farthest
+         * playback point that can be reached from the current position using
+         * only buffered content.
+         *
+         * @param bufferedPosition The position in ms that playback is buffered
+         *            to.
+         * @return this
+         */
+        public Builder setBufferedPosition(long bufferedPosition) {
+            mBufferedPosition = bufferedPosition;
+            return this;
+        }
+
+        /**
+         * Set the active item in the play queue by specifying its id. The
+         * default value is {@link MediaSession.QueueItem#UNKNOWN_ID}
+         *
+         * @param id The id of the active item.
+         * @return this
+         */
+        public Builder setActiveQueueItemId(long id) {
+            mActiveItemId = id;
+            return this;
+        }
+
+        /**
+         * Set a user readable error message. This should be set when the state
+         * is {@link PlaybackState#STATE_ERROR}.
+         *
+         * @param error The error message for display to the user.
+         * @return this
+         */
+        public Builder setErrorMessage(CharSequence error) {
+            mErrorMessage = error;
+            return this;
+        }
+
+        /**
+         * Set any custom extras to be included with the playback state.
+         *
+         * @param extras The extras to include.
+         * @return this
+         */
+        public Builder setExtras(Bundle extras) {
+            mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Build and return the {@link PlaybackState} instance with these
+         * values.
+         *
+         * @return A new state instance.
+         */
+        public PlaybackState build() {
+            return new PlaybackState(mState, mPosition, mUpdateTime, mSpeed, mBufferedPosition,
+                    mActions, mCustomActions, mActiveItemId, mErrorMessage, mExtras);
+        }
+    }
+}
diff --git a/android/media/soundtrigger/SoundTriggerDetectionService.java b/android/media/soundtrigger/SoundTriggerDetectionService.java
new file mode 100644
index 0000000..55cd1ab
--- /dev/null
+++ b/android/media/soundtrigger/SoundTriggerDetectionService.java
@@ -0,0 +1,293 @@
+/*
+ * Copyright (C) 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.soundtrigger;
+
+import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+
+import android.annotation.CallSuper;
+import android.annotation.MainThread;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Log;
+
+import com.android.internal.annotations.GuardedBy;
+
+import java.util.UUID;
+
+/**
+ * A service that allows interaction with the actual sound trigger detection on the system.
+ *
+ * <p> Sound trigger detection refers to detectors that match generic sound patterns that are
+ * not voice-based. The voice-based recognition models should utilize the {@link
+ * android.service.voice.VoiceInteractionService} instead. Access to this class needs to be
+ * protected by the {@value android.Manifest.permission.BIND_SOUND_TRIGGER_DETECTION_SERVICE}
+ * permission granted only to the system.
+ *
+ * <p>This service has to be explicitly started by an app, the system does not scan for and start
+ * these services.
+ *
+ * <p>If an operation ({@link #onGenericRecognitionEvent}, {@link #onError},
+ * {@link #onRecognitionPaused}, {@link #onRecognitionResumed}) is triggered the service is
+ * considered as running in the foreground. Once the operation is processed the service should call
+ * {@link #operationFinished(UUID, int)}. If this does not happen in
+ * {@link SoundTriggerManager#getDetectionServiceOperationsTimeout()} milliseconds
+ * {@link #onStopOperation(UUID, Bundle, int)} is called and the service is unbound.
+ *
+ * <p>The total amount of operations per day might be limited.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class SoundTriggerDetectionService extends Service {
+    private static final String LOG_TAG = SoundTriggerDetectionService.class.getSimpleName();
+
+    private static final boolean DEBUG = false;
+
+    private final Object mLock = new Object();
+
+    /**
+     * Client indexed by model uuid. This is needed for the {@link #operationFinished(UUID, int)}
+     * callbacks.
+     */
+    @GuardedBy("mLock")
+    private final ArrayMap<UUID, ISoundTriggerDetectionServiceClient> mClients =
+            new ArrayMap<>();
+
+    private Handler mHandler;
+
+    /**
+     * @hide
+     */
+    @Override
+    protected final void attachBaseContext(Context base) {
+        super.attachBaseContext(base);
+        mHandler = new Handler(base.getMainLooper());
+    }
+
+    private void setClient(@NonNull UUID uuid, @Nullable Bundle params,
+            @NonNull ISoundTriggerDetectionServiceClient client) {
+        if (DEBUG) Log.i(LOG_TAG, uuid + ": handle setClient");
+
+        synchronized (mLock) {
+            mClients.put(uuid, client);
+        }
+        onConnected(uuid, params);
+    }
+
+    private void removeClient(@NonNull UUID uuid, @Nullable Bundle params) {
+        if (DEBUG) Log.i(LOG_TAG, uuid + ": handle removeClient");
+
+        synchronized (mLock) {
+            mClients.remove(uuid);
+        }
+        onDisconnected(uuid, params);
+    }
+
+    /**
+     * The system has connected to this service for the recognition registered for the model
+     * {@code uuid}.
+     *
+     * <p> This is called before any operations are delivered.
+     *
+     * @param uuid   The {@code uuid} of the model the recognitions is registered for
+     * @param params The {@code params} passed when the recognition was started
+     */
+    @MainThread
+    public void onConnected(@NonNull UUID uuid, @Nullable Bundle params) {
+        /* do nothing */
+    }
+
+    /**
+     * The system has disconnected from this service for the recognition registered for the model
+     * {@code uuid}.
+     *
+     * <p>Once this is called {@link #operationFinished} cannot be called anymore for
+     * {@code uuid}.
+     *
+     * <p> {@link #onConnected(UUID, Bundle)} is called before any further operations are delivered.
+     *
+     * @param uuid   The {@code uuid} of the model the recognitions is registered for
+     * @param params The {@code params} passed when the recognition was started
+     */
+    @MainThread
+    public void onDisconnected(@NonNull UUID uuid, @Nullable Bundle params) {
+        /* do nothing */
+    }
+
+    /**
+     * A new generic sound trigger event has been detected.
+     *
+     * @param uuid   The {@code uuid} of the model the recognition is registered for
+     * @param params The {@code params} passed when the recognition was started
+     * @param opId The id of this operation. Once the operation is done, this service needs to call
+     *             {@link #operationFinished(UUID, int)}
+     * @param event The event that has been detected
+     */
+    @MainThread
+    public void onGenericRecognitionEvent(@NonNull UUID uuid, @Nullable Bundle params, int opId,
+            @NonNull SoundTrigger.RecognitionEvent event) {
+        operationFinished(uuid, opId);
+    }
+
+    /**
+     * A error has been detected.
+     *
+     * @param uuid   The {@code uuid} of the model the recognition is registered for
+     * @param params The {@code params} passed when the recognition was started
+     * @param opId The id of this operation. Once the operation is done, this service needs to call
+     *             {@link #operationFinished(UUID, int)}
+     * @param status The error code detected
+     */
+    @MainThread
+    public void onError(@NonNull UUID uuid, @Nullable Bundle params, int opId, int status) {
+        operationFinished(uuid, opId);
+    }
+
+    /**
+     * An operation took too long and should be stopped.
+     *
+     * @param uuid   The {@code uuid} of the model the recognition is registered for
+     * @param params The {@code params} passed when the recognition was started
+     * @param opId The id of the operation that took too long
+     */
+    @MainThread
+    public abstract void onStopOperation(@NonNull UUID uuid, @Nullable Bundle params, int opId);
+
+    /**
+     * Tell that the system that an operation has been fully processed.
+     *
+     * @param uuid The {@code uuid} of the model the recognition is registered for
+     * @param opId The id of the operation that is processed
+     */
+    public final void operationFinished(@Nullable UUID uuid, int opId) {
+        try {
+            ISoundTriggerDetectionServiceClient client;
+            synchronized (mLock) {
+                client = mClients.get(uuid);
+
+                if (client == null) {
+                    Log.w(LOG_TAG, "operationFinished called, but no client for "
+                            + uuid + ". Was this called after onDisconnected?");
+                    return;
+                }
+            }
+            client.onOpFinished(opId);
+        } catch (RemoteException e) {
+            Log.e(LOG_TAG, "operationFinished, remote exception for client " + uuid, e);
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @Override
+    public final IBinder onBind(Intent intent) {
+        return new ISoundTriggerDetectionService.Stub() {
+            private final Object mBinderLock = new Object();
+
+            /** Cached params bundles indexed by the model uuid */
+            @GuardedBy("mBinderLock")
+            public final ArrayMap<UUID, Bundle> mParams = new ArrayMap<>();
+
+            @Override
+            public void setClient(ParcelUuid puuid, Bundle params,
+                    ISoundTriggerDetectionServiceClient client) {
+                UUID uuid = puuid.getUuid();
+                synchronized (mBinderLock) {
+                    mParams.put(uuid, params);
+                }
+
+                if (DEBUG) Log.i(LOG_TAG, uuid + ": setClient(" + params + ")");
+                mHandler.sendMessage(obtainMessage(SoundTriggerDetectionService::setClient,
+                        SoundTriggerDetectionService.this, uuid, params, client));
+            }
+
+            @Override
+            public void removeClient(ParcelUuid puuid) {
+                UUID uuid = puuid.getUuid();
+                Bundle params;
+                synchronized (mBinderLock) {
+                    params = mParams.remove(uuid);
+                }
+
+                if (DEBUG) Log.i(LOG_TAG, uuid + ": removeClient");
+                mHandler.sendMessage(obtainMessage(SoundTriggerDetectionService::removeClient,
+                        SoundTriggerDetectionService.this, uuid, params));
+            }
+
+            @Override
+            public void onGenericRecognitionEvent(ParcelUuid puuid, int opId,
+                    SoundTrigger.GenericRecognitionEvent event) {
+                UUID uuid = puuid.getUuid();
+                Bundle params;
+                synchronized (mBinderLock) {
+                    params = mParams.get(uuid);
+                }
+
+                if (DEBUG) Log.i(LOG_TAG, uuid + "(" + opId + "): onGenericRecognitionEvent");
+                mHandler.sendMessage(
+                        obtainMessage(SoundTriggerDetectionService::onGenericRecognitionEvent,
+                                SoundTriggerDetectionService.this, uuid, params, opId, event));
+            }
+
+            @Override
+            public void onError(ParcelUuid puuid, int opId, int status) {
+                UUID uuid = puuid.getUuid();
+                Bundle params;
+                synchronized (mBinderLock) {
+                    params = mParams.get(uuid);
+                }
+
+                if (DEBUG) Log.i(LOG_TAG, uuid + "(" + opId + "): onError(" + status + ")");
+                mHandler.sendMessage(obtainMessage(SoundTriggerDetectionService::onError,
+                        SoundTriggerDetectionService.this, uuid, params, opId, status));
+            }
+
+            @Override
+            public void onStopOperation(ParcelUuid puuid, int opId) {
+                UUID uuid = puuid.getUuid();
+                Bundle params;
+                synchronized (mBinderLock) {
+                    params = mParams.get(uuid);
+                }
+
+                if (DEBUG) Log.i(LOG_TAG, uuid + "(" + opId + "): onStopOperation");
+                mHandler.sendMessage(obtainMessage(SoundTriggerDetectionService::onStopOperation,
+                        SoundTriggerDetectionService.this, uuid, params, opId));
+            }
+        };
+    }
+
+    @CallSuper
+    @Override
+    public boolean onUnbind(Intent intent) {
+        mClients.clear();
+
+        return false;
+    }
+}
diff --git a/android/media/soundtrigger/SoundTriggerDetector.java b/android/media/soundtrigger/SoundTriggerDetector.java
new file mode 100644
index 0000000..d9c8a24
--- /dev/null
+++ b/android/media/soundtrigger/SoundTriggerDetector.java
@@ -0,0 +1,445 @@
+/**
+ * Copyright (C) 2014 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.soundtrigger;
+import static android.hardware.soundtrigger.SoundTrigger.STATUS_OK;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.hardware.soundtrigger.IRecognitionStatusCallback;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.ModuleProperties;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.media.AudioFormat;
+import android.os.Build;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.util.Slog;
+
+import com.android.internal.app.ISoundTriggerSession;
+
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.UUID;
+
+/**
+ * A class that allows interaction with the actual sound trigger detection on the system.
+ * Sound trigger detection refers to a detectors that match generic sound patterns that are
+ * not voice-based. The voice-based recognition models should utilize the {@link
+ * VoiceInteractionService} instead. Access to this class is protected by a permission
+ * granted only to system or privileged apps.
+ *
+ * @hide
+ */
+@SystemApi
+public final class SoundTriggerDetector {
+    private static final boolean DBG = false;
+    private static final String TAG = "SoundTriggerDetector";
+
+    private static final int MSG_AVAILABILITY_CHANGED = 1;
+    private static final int MSG_SOUND_TRIGGER_DETECTED = 2;
+    private static final int MSG_DETECTION_ERROR = 3;
+    private static final int MSG_DETECTION_PAUSE = 4;
+    private static final int MSG_DETECTION_RESUME = 5;
+
+    private final Object mLock = new Object();
+
+    private final ISoundTriggerSession mSoundTriggerSession;
+    private final UUID mSoundModelId;
+    private final Callback mCallback;
+    private final Handler mHandler;
+    private final RecognitionCallback mRecognitionCallback;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true,
+            value = {
+                RECOGNITION_FLAG_NONE,
+                RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO,
+                RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS,
+                RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION,
+                RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION,
+                RECOGNITION_FLAG_RUN_IN_BATTERY_SAVER,
+            })
+    public @interface RecognitionFlags {}
+
+    /**
+     * Empty flag for {@link #startRecognition(int)}.
+     *
+     *  @hide
+     */
+    public static final int RECOGNITION_FLAG_NONE = 0;
+
+    /**
+     * Recognition flag for {@link #startRecognition(int)} that indicates
+     * whether the trigger audio for hotword needs to be captured.
+     */
+    public static final int RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO = 0x1;
+
+    /**
+     * Recognition flag for {@link #startRecognition(int)} that indicates
+     * whether the recognition should keep going on even after the
+     * model triggers.
+     * If this flag is specified, it's possible to get multiple
+     * triggers after a call to {@link #startRecognition(int)}, if the model
+     * triggers multiple times.
+     * When this isn't specified, the default behavior is to stop recognition once the
+     * trigger happens, till the caller starts recognition again.
+     */
+    public static final int RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS = 0x2;
+
+    /**
+     * Audio capabilities flag for {@link #startRecognition(int)} that indicates
+     * if the underlying recognition should use AEC.
+     * This capability may or may not be supported by the system, and support can be queried
+     * by calling {@link SoundTriggerManager#getModuleProperties()} and checking
+     * {@link ModuleProperties#audioCapabilities}. The corresponding capabilities field for
+     * this flag is {@link SoundTrigger.ModuleProperties#AUDIO_CAPABILITY_ECHO_CANCELLATION}.
+     * If this flag is passed without the audio capability supported, there will be no audio effect
+     * applied.
+     */
+    public static final int RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION = 0x4;
+
+    /**
+     * Audio capabilities flag for {@link #startRecognition(int)} that indicates
+     * if the underlying recognition should use noise suppression.
+     * This capability may or may not be supported by the system, and support can be queried
+     * by calling {@link SoundTriggerManager#getModuleProperties()} and checking
+     * {@link ModuleProperties#audioCapabilities}. The corresponding capabilities field for
+     * this flag is {@link SoundTrigger.ModuleProperties#AUDIO_CAPABILITY_NOISE_SUPPRESSION}.
+     * If this flag is passed without the audio capability supported, there will be no audio effect
+     * applied.
+     */
+    public static final int RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION = 0x8;
+
+    /**
+     * Recognition flag for {@link #startRecognition(int)} that indicates whether the recognition
+     * should continue after battery saver mode is enabled.
+     * When this flag is specified, the caller will be checked for
+     * {@link android.Manifest.permission#SOUND_TRIGGER_RUN_IN_BATTERY_SAVER} permission granted.
+     */
+    public static final int RECOGNITION_FLAG_RUN_IN_BATTERY_SAVER = 0x10;
+
+    /**
+     * Additional payload for {@link Callback#onDetected}.
+     */
+    public static class EventPayload {
+        private final boolean mTriggerAvailable;
+
+        // Indicates if {@code captureSession} can be used to continue capturing more audio
+        // from the DSP hardware.
+        private final boolean mCaptureAvailable;
+        // The session to use when attempting to capture more audio from the DSP hardware.
+        private final int mCaptureSession;
+        private final AudioFormat mAudioFormat;
+        // Raw data associated with the event.
+        // This is the audio that triggered the keyphrase if {@code isTriggerAudio} is true.
+        private final byte[] mData;
+
+        private EventPayload(boolean triggerAvailable, boolean captureAvailable,
+                AudioFormat audioFormat, int captureSession, byte[] data) {
+            mTriggerAvailable = triggerAvailable;
+            mCaptureAvailable = captureAvailable;
+            mCaptureSession = captureSession;
+            mAudioFormat = audioFormat;
+            mData = data;
+        }
+
+        /**
+         * Gets the format of the audio obtained using {@link #getTriggerAudio()}.
+         * May be null if there's no audio present.
+         */
+        @Nullable
+        public AudioFormat getCaptureAudioFormat() {
+            return mAudioFormat;
+        }
+
+        /**
+         * Gets the raw audio that triggered the detector.
+         * This may be null if the trigger audio isn't available.
+         * If non-null, the format of the audio can be obtained by calling
+         * {@link #getCaptureAudioFormat()}.
+         *
+         * @see AlwaysOnHotwordDetector#RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO
+         */
+        @Nullable
+        public byte[] getTriggerAudio() {
+            if (mTriggerAvailable) {
+                return mData;
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets the opaque data passed from the detection engine for the event.
+         * This may be null if it was not populated by the engine, or if the data is known to
+         * contain the trigger audio.
+         *
+         * @see #getTriggerAudio
+         *
+         * @hide
+         */
+        @Nullable
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public byte[] getData() {
+            if (!mTriggerAvailable) {
+                return mData;
+            } else {
+                return null;
+            }
+        }
+
+        /**
+         * Gets the session ID to start a capture from the DSP.
+         * This may be null if streaming capture isn't possible.
+         * If non-null, the format of the audio that can be captured can be
+         * obtained using {@link #getCaptureAudioFormat()}.
+         *
+         * TODO: Candidate for Public API when the API to start capture with a session ID
+         * is made public.
+         *
+         * TODO: Add this to {@link #getCaptureAudioFormat()}:
+         * "Gets the format of the audio obtained using {@link #getTriggerAudio()}
+         * or {@link #getCaptureSession()}. May be null if no audio can be obtained
+         * for either the trigger or a streaming session."
+         *
+         * TODO: Should this return a known invalid value instead?
+         *
+         * @hide
+         */
+        @Nullable
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        public Integer getCaptureSession() {
+            if (mCaptureAvailable) {
+                return mCaptureSession;
+            } else {
+                return null;
+            }
+        }
+    }
+
+    public static abstract class Callback {
+        /**
+         * Called when the availability of the sound model changes.
+         */
+        public abstract void onAvailabilityChanged(int status);
+
+        /**
+         * Called when the sound model has triggered (such as when it matched a
+         * given sound pattern).
+         */
+        public abstract void onDetected(@NonNull EventPayload eventPayload);
+
+        /**
+         *  Called when the detection fails due to an error.
+         */
+        public abstract void onError();
+
+        /**
+         * Called when the recognition is paused temporarily for some reason.
+         * This is an informational callback, and the clients shouldn't be doing anything here
+         * except showing an indication on their UI if they have to.
+         */
+        public abstract void onRecognitionPaused();
+
+        /**
+         * Called when the recognition is resumed after it was temporarily paused.
+         * This is an informational callback, and the clients shouldn't be doing anything here
+         * except showing an indication on their UI if they have to.
+         */
+        public abstract void onRecognitionResumed();
+    }
+
+    /**
+     * This class should be constructed by the {@link SoundTriggerManager}.
+     * @hide
+     */
+    SoundTriggerDetector(ISoundTriggerSession soundTriggerSession, UUID soundModelId,
+            @NonNull Callback callback, @Nullable Handler handler) {
+        mSoundTriggerSession = soundTriggerSession;
+        mSoundModelId = soundModelId;
+        mCallback = callback;
+        if (handler == null) {
+            mHandler = new MyHandler();
+        } else {
+            mHandler = new MyHandler(handler.getLooper());
+        }
+        mRecognitionCallback = new RecognitionCallback();
+    }
+
+    /**
+     * Starts recognition on the associated sound model. Result is indicated via the
+     * {@link Callback}.
+     * @return Indicates whether the call succeeded or not.
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public boolean startRecognition(@RecognitionFlags int recognitionFlags) {
+        if (DBG) {
+            Slog.d(TAG, "startRecognition()");
+        }
+        boolean captureTriggerAudio =
+                (recognitionFlags & RECOGNITION_FLAG_CAPTURE_TRIGGER_AUDIO) != 0;
+
+        boolean allowMultipleTriggers =
+                (recognitionFlags & RECOGNITION_FLAG_ALLOW_MULTIPLE_TRIGGERS) != 0;
+
+        boolean runInBatterySaver = (recognitionFlags & RECOGNITION_FLAG_RUN_IN_BATTERY_SAVER) != 0;
+
+        int audioCapabilities = 0;
+        if ((recognitionFlags & RECOGNITION_FLAG_ENABLE_AUDIO_ECHO_CANCELLATION) != 0) {
+            audioCapabilities |= SoundTrigger.ModuleProperties.AUDIO_CAPABILITY_ECHO_CANCELLATION;
+        }
+        if ((recognitionFlags & RECOGNITION_FLAG_ENABLE_AUDIO_NOISE_SUPPRESSION) != 0) {
+            audioCapabilities |= SoundTrigger.ModuleProperties.AUDIO_CAPABILITY_NOISE_SUPPRESSION;
+        }
+
+        int status;
+        try {
+            status = mSoundTriggerSession.startRecognition(new ParcelUuid(mSoundModelId),
+                    mRecognitionCallback, new RecognitionConfig(captureTriggerAudio,
+                            allowMultipleTriggers, null, null, audioCapabilities),
+                    runInBatterySaver);
+        } catch (RemoteException e) {
+            return false;
+        }
+        return status == STATUS_OK;
+    }
+
+    /**
+     * Stops recognition for the associated model.
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public boolean stopRecognition() {
+        int status = STATUS_OK;
+        try {
+            status = mSoundTriggerSession.stopRecognition(new ParcelUuid(mSoundModelId),
+                    mRecognitionCallback);
+        } catch (RemoteException e) {
+            return false;
+        }
+        return status == STATUS_OK;
+    }
+
+    /**
+     * @hide
+     */
+    public void dump(String prefix, PrintWriter pw) {
+        synchronized (mLock) {
+            // TODO: Dump useful debug information.
+        }
+    }
+
+    /**
+     * Callback that handles events from the lower sound trigger layer.
+     *
+     * Note that these callbacks will be called synchronously from the SoundTriggerService
+     * layer and thus should do minimal work (such as sending a message on a handler to do
+     * the real work).
+     * @hide
+     */
+    private class RecognitionCallback extends IRecognitionStatusCallback.Stub {
+
+        /**
+         * @hide
+         */
+        @Override
+        public void onGenericSoundTriggerDetected(SoundTrigger.GenericRecognitionEvent event) {
+            Slog.d(TAG, "onGenericSoundTriggerDetected()" + event);
+            Message.obtain(mHandler,
+                    MSG_SOUND_TRIGGER_DETECTED,
+                    new EventPayload(event.triggerInData, event.captureAvailable,
+                            event.captureFormat, event.captureSession, event.data))
+                    .sendToTarget();
+        }
+
+        @Override
+        public void onKeyphraseDetected(SoundTrigger.KeyphraseRecognitionEvent event) {
+            Slog.e(TAG, "Ignoring onKeyphraseDetected() called for " + event);
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public void onError(int status) {
+            Slog.d(TAG, "onError()" + status);
+            mHandler.sendEmptyMessage(MSG_DETECTION_ERROR);
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public void onRecognitionPaused() {
+            Slog.d(TAG, "onRecognitionPaused()");
+            mHandler.sendEmptyMessage(MSG_DETECTION_PAUSE);
+        }
+
+        /**
+         * @hide
+         */
+        @Override
+        public void onRecognitionResumed() {
+            Slog.d(TAG, "onRecognitionResumed()");
+            mHandler.sendEmptyMessage(MSG_DETECTION_RESUME);
+        }
+    }
+
+    private class MyHandler extends Handler {
+
+        MyHandler() {
+            super();
+        }
+
+        MyHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            if (mCallback == null) {
+                  Slog.w(TAG, "Received message: " + msg.what + " for NULL callback.");
+                  return;
+            }
+            switch (msg.what) {
+                case MSG_SOUND_TRIGGER_DETECTED:
+                    mCallback.onDetected((EventPayload) msg.obj);
+                    break;
+                case MSG_DETECTION_ERROR:
+                    mCallback.onError();
+                    break;
+                case MSG_DETECTION_PAUSE:
+                    mCallback.onRecognitionPaused();
+                    break;
+                case MSG_DETECTION_RESUME:
+                    mCallback.onRecognitionResumed();
+                    break;
+                default:
+                    super.handleMessage(msg);
+
+            }
+        }
+    }
+}
diff --git a/android/media/soundtrigger/SoundTriggerManager.java b/android/media/soundtrigger/SoundTriggerManager.java
new file mode 100644
index 0000000..f60c708
--- /dev/null
+++ b/android/media/soundtrigger/SoundTriggerManager.java
@@ -0,0 +1,555 @@
+/**
+ * Copyright (C) 2014 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.soundtrigger;
+
+import static android.hardware.soundtrigger.SoundTrigger.STATUS_ERROR;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.app.ActivityThread;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
+import android.content.Context;
+import android.hardware.soundtrigger.ModelParams;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.hardware.soundtrigger.SoundTrigger.GenericSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.KeyphraseSoundModel;
+import android.hardware.soundtrigger.SoundTrigger.ModelParamRange;
+import android.hardware.soundtrigger.SoundTrigger.RecognitionConfig;
+import android.hardware.soundtrigger.SoundTrigger.SoundModel;
+import android.media.permission.ClearCallingIdentityContext;
+import android.media.permission.Identity;
+import android.media.permission.SafeCloseable;
+import android.os.Binder;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.ParcelUuid;
+import android.os.RemoteException;
+import android.provider.Settings;
+import android.util.Slog;
+
+import com.android.internal.app.ISoundTriggerService;
+import com.android.internal.app.ISoundTriggerSession;
+import com.android.internal.util.Preconditions;
+
+import java.util.HashMap;
+import java.util.Objects;
+import java.util.UUID;
+
+/**
+ * This class provides management of non-voice (general sound trigger) based sound recognition
+ * models. Usage of this class is restricted to system or signature applications only. This allows
+ * OEMs to write apps that can manage non-voice based sound trigger models.
+ *
+ * @hide
+ */
+@SystemApi
+@SystemService(Context.SOUND_TRIGGER_SERVICE)
+public final class SoundTriggerManager {
+    private static final boolean DBG = false;
+    private static final String TAG = "SoundTriggerManager";
+
+    private final Context mContext;
+    private final ISoundTriggerSession mSoundTriggerSession;
+    private final IBinder mBinderToken = new Binder();
+
+    // Stores a mapping from the sound model UUID to the SoundTriggerInstance created by
+    // the createSoundTriggerDetector() call.
+    private final HashMap<UUID, SoundTriggerDetector> mReceiverInstanceMap;
+
+    /**
+     * @hide
+     */
+    public SoundTriggerManager(Context context, ISoundTriggerService soundTriggerService) {
+        if (DBG) {
+            Slog.i(TAG, "SoundTriggerManager created.");
+        }
+        try {
+            // This assumes that whoever is calling this ctor is the originator of the operations,
+            // as opposed to a service acting on behalf of a separate identity.
+            // Services acting on behalf of some other identity should not be using this class at
+            // all, but rather directly connect to the server and attach with explicit credentials.
+            Identity originatorIdentity = new Identity();
+            originatorIdentity.packageName = ActivityThread.currentOpPackageName();
+
+            try (SafeCloseable ignored = ClearCallingIdentityContext.create()) {
+                mSoundTriggerSession = soundTriggerService.attachAsOriginator(originatorIdentity,
+                        mBinderToken);
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowAsRuntimeException();
+        }
+        mContext = context;
+        mReceiverInstanceMap = new HashMap<UUID, SoundTriggerDetector>();
+    }
+
+    /**
+     * Updates the given sound trigger model.
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public void updateModel(Model model) {
+        try {
+            mSoundTriggerSession.updateSoundModel(model.getGenericSoundModel());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Get {@link SoundTriggerManager.Model} which is registered with the passed UUID
+     *
+     * @param soundModelId UUID associated with a loaded model
+     * @return {@link SoundTriggerManager.Model} associated with UUID soundModelId
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    @Nullable
+    public Model getModel(UUID soundModelId) {
+        try {
+            GenericSoundModel model =
+                    mSoundTriggerSession.getSoundModel(new ParcelUuid(soundModelId));
+            if (model == null) {
+                return null;
+            }
+
+            return new Model(model);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Deletes the sound model represented by the provided UUID.
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public void deleteModel(UUID soundModelId) {
+        try {
+            mSoundTriggerSession.deleteSoundModel(new ParcelUuid(soundModelId));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Creates an instance of {@link SoundTriggerDetector} which can be used to start/stop
+     * recognition on the model and register for triggers from the model. Note that this call
+     * invalidates any previously returned instances for the same sound model Uuid.
+     *
+     * @param soundModelId UUID of the sound model to create the receiver object for.
+     * @param callback Instance of the {@link SoundTriggerDetector#Callback} object for the
+     * callbacks for the given sound model.
+     * @param handler The Handler to use for the callback operations. A null value will use the
+     * current thread's Looper.
+     * @return Instance of {@link SoundTriggerDetector} or null on error.
+     */
+    @Nullable
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public SoundTriggerDetector createSoundTriggerDetector(UUID soundModelId,
+            @NonNull SoundTriggerDetector.Callback callback, @Nullable Handler handler) {
+        if (soundModelId == null) {
+            return null;
+        }
+
+        SoundTriggerDetector oldInstance = mReceiverInstanceMap.get(soundModelId);
+        if (oldInstance != null) {
+            // Shutdown old instance.
+        }
+        SoundTriggerDetector newInstance = new SoundTriggerDetector(mSoundTriggerSession,
+                soundModelId, callback, handler);
+        mReceiverInstanceMap.put(soundModelId, newInstance);
+        return newInstance;
+    }
+
+    /**
+     * Class captures the data and fields that represent a non-keyphrase sound model. Use the
+     * factory constructor {@link Model#create()} to create an instance.
+     */
+    // We use encapsulation to expose the SoundTrigger.GenericSoundModel as a SystemApi. This
+    // prevents us from exposing SoundTrigger.GenericSoundModel as an Api.
+    public static class Model {
+
+        private SoundTrigger.GenericSoundModel mGenericSoundModel;
+
+        /**
+         * @hide
+         */
+        Model(SoundTrigger.GenericSoundModel soundTriggerModel) {
+            mGenericSoundModel = soundTriggerModel;
+        }
+
+        /**
+         * Factory constructor to a voice model to be used with {@link SoundTriggerManager}
+         *
+         * @param modelUuid Unique identifier associated with the model.
+         * @param vendorUuid Unique identifier associated the calling vendor.
+         * @param data Model's data.
+         * @param version Version identifier for the model.
+         * @return Voice model
+         */
+        @NonNull
+        public static Model create(@NonNull UUID modelUuid, @NonNull UUID vendorUuid,
+                @Nullable byte[] data, int version) {
+            Objects.requireNonNull(modelUuid);
+            Objects.requireNonNull(vendorUuid);
+            return new Model(new SoundTrigger.GenericSoundModel(modelUuid, vendorUuid, data,
+                    version));
+        }
+
+        /**
+         * Factory constructor to a voice model to be used with {@link SoundTriggerManager}
+         *
+         * @param modelUuid Unique identifier associated with the model.
+         * @param vendorUuid Unique identifier associated the calling vendor.
+         * @param data Model's data.
+         * @return Voice model
+         */
+        @NonNull
+        public static Model create(@NonNull UUID modelUuid, @NonNull UUID vendorUuid,
+                @Nullable byte[] data) {
+            return create(modelUuid, vendorUuid, data, -1);
+        }
+
+        /**
+         * Get the model's unique identifier
+         *
+         * @return UUID associated with the model
+         */
+        @NonNull
+        public UUID getModelUuid() {
+            return mGenericSoundModel.getUuid();
+        }
+
+        /**
+         * Get the model's vendor identifier
+         *
+         * @return UUID associated with the vendor of the model
+         */
+        @NonNull
+        public UUID getVendorUuid() {
+            return mGenericSoundModel.getVendorUuid();
+        }
+
+        /**
+         * Get the model's version
+         *
+         * @return Version associated with the model
+         */
+        public int getVersion() {
+            return mGenericSoundModel.getVersion();
+        }
+
+        /**
+         * Get the underlying model data
+         *
+         * @return Backing data of the model
+         */
+        @Nullable
+        public byte[] getModelData() {
+            return mGenericSoundModel.getData();
+        }
+
+        /**
+         * @hide
+         */
+        SoundTrigger.GenericSoundModel getGenericSoundModel() {
+            return mGenericSoundModel;
+        }
+    }
+
+
+    /**
+     * Default message type.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_UNKNOWN = -1;
+    /**
+     * Contents of EXTRA_MESSAGE_TYPE extra for a RecognitionEvent.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_RECOGNITION_EVENT = 0;
+    /**
+     * Contents of EXTRA_MESSAGE_TYPE extra for recognition error events.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_RECOGNITION_ERROR = 1;
+    /**
+     * Contents of EXTRA_MESSAGE_TYPE extra for a recognition paused events.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_RECOGNITION_PAUSED = 2;
+    /**
+     * Contents of EXTRA_MESSAGE_TYPE extra for recognition resumed events.
+     * @hide
+     */
+    public static final int FLAG_MESSAGE_TYPE_RECOGNITION_RESUMED = 3;
+
+    /**
+     * Extra key in the intent for the type of the message.
+     * @hide
+     */
+    public static final String EXTRA_MESSAGE_TYPE = "android.media.soundtrigger.MESSAGE_TYPE";
+    /**
+     * Extra key in the intent that holds the RecognitionEvent parcelable.
+     * @hide
+     */
+    public static final String EXTRA_RECOGNITION_EVENT = "android.media.soundtrigger.RECOGNITION_EVENT";
+    /**
+     * Extra key in the intent that holds the status in an error message.
+     * @hide
+     */
+    public static final String EXTRA_STATUS = "android.media.soundtrigger.STATUS";
+
+    /**
+     * Loads a given sound model into the sound trigger. Note the model will be unloaded if there is
+     * an error/the system service is restarted.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    @UnsupportedAppUsage
+    public int loadSoundModel(SoundModel soundModel) {
+        if (soundModel == null) {
+            return STATUS_ERROR;
+        }
+
+        try {
+            switch (soundModel.getType()) {
+                case SoundModel.TYPE_GENERIC_SOUND:
+                    return mSoundTriggerSession.loadGenericSoundModel(
+                            (GenericSoundModel) soundModel);
+                case SoundModel.TYPE_KEYPHRASE:
+                    return mSoundTriggerSession.loadKeyphraseSoundModel(
+                            (KeyphraseSoundModel) soundModel);
+                default:
+                    Slog.e(TAG, "Unkown model type");
+                    return STATUS_ERROR;
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Starts recognition for the given model id. All events from the model will be sent to the
+     * service.
+     *
+     * <p>This only supports generic sound trigger events. For keyphrase events, please use
+     * {@link android.service.voice.VoiceInteractionService}.
+     *
+     * @param soundModelId Id of the sound model
+     * @param params Opaque data sent to each service call of the service as the {@code params}
+     *               argument
+     * @param detectionService The component name of the service that should receive the events.
+     *                         Needs to subclass {@link SoundTriggerDetectionService}
+     * @param config Configures the recognition
+     *
+     * @return {@link SoundTrigger#STATUS_OK} if the recognition could be started, error code
+     *         otherwise
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    @UnsupportedAppUsage
+    public int startRecognition(@NonNull UUID soundModelId, @Nullable Bundle params,
+        @NonNull ComponentName detectionService, @NonNull RecognitionConfig config) {
+        Preconditions.checkNotNull(soundModelId);
+        Preconditions.checkNotNull(detectionService);
+        Preconditions.checkNotNull(config);
+
+        try {
+            return mSoundTriggerSession.startRecognitionForService(new ParcelUuid(soundModelId),
+                params, detectionService, config);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Stops the given model's recognition.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public int stopRecognition(UUID soundModelId) {
+        if (soundModelId == null) {
+            return STATUS_ERROR;
+        }
+        try {
+            return mSoundTriggerSession.stopRecognitionForService(new ParcelUuid(soundModelId));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Removes the given model from memory. Will also stop any pending recognitions.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public int unloadSoundModel(UUID soundModelId) {
+        if (soundModelId == null) {
+            return STATUS_ERROR;
+        }
+        try {
+            return mSoundTriggerSession.unloadSoundModel(
+                    new ParcelUuid(soundModelId));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns true if the given model has had detection started on it.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    @UnsupportedAppUsage
+    public boolean isRecognitionActive(UUID soundModelId) {
+        if (soundModelId == null) {
+            return false;
+        }
+        try {
+            return mSoundTriggerSession.isRecognitionActive(
+                    new ParcelUuid(soundModelId));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Get the amount of time (in milliseconds) an operation of the
+     * {@link ISoundTriggerDetectionService} is allowed to ask.
+     *
+     * @return The amount of time an sound trigger detection service operation is allowed to last
+     */
+    public int getDetectionServiceOperationsTimeout() {
+        try {
+            return Settings.Global.getInt(mContext.getContentResolver(),
+                    Settings.Global.SOUND_TRIGGER_DETECTION_SERVICE_OP_TIMEOUT);
+        } catch (Settings.SettingNotFoundException e) {
+            return Integer.MAX_VALUE;
+        }
+    }
+
+    /**
+     * Asynchronously get state of the indicated model.  The model state is returned as
+     * a recognition event in the callback that was registered in the startRecognition
+     * method.
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    @UnsupportedAppUsage
+    public int getModelState(UUID soundModelId) {
+        if (soundModelId == null) {
+            return STATUS_ERROR;
+        }
+        try {
+            return mSoundTriggerSession.getModelState(new ParcelUuid(soundModelId));
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Get the hardware sound trigger module properties currently loaded.
+     *
+     * @return The properties currently loaded. Returns null if no supported hardware loaded.
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    @Nullable
+    public SoundTrigger.ModuleProperties getModuleProperties() {
+
+        try {
+            return mSoundTriggerSession.getModuleProperties();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Set a model specific {@link ModelParams} with the given value. This
+     * parameter will keep its value for the duration the model is loaded regardless of starting and
+     * stopping recognition. Once the model is unloaded, the value will be lost.
+     * {@link SoundTriggerManager#queryParameter} should be checked first before calling this
+     * method.
+     *
+     * @param soundModelId UUID of model to apply the parameter value to.
+     * @param modelParam   {@link ModelParams}
+     * @param value        Value to set
+     * @return - {@link SoundTrigger#STATUS_OK} in case of success
+     *         - {@link SoundTrigger#STATUS_NO_INIT} if the native service cannot be reached
+     *         - {@link SoundTrigger#STATUS_BAD_VALUE} invalid input parameter
+     *         - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence or
+     *           if API is not supported by HAL
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public int setParameter(@Nullable UUID soundModelId,
+            @ModelParams int modelParam, int value) {
+        try {
+            return mSoundTriggerSession.setParameter(new ParcelUuid(soundModelId), modelParam,
+                    value);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Get a model specific {@link ModelParams}. This parameter will keep its value
+     * for the duration the model is loaded regardless of starting and stopping recognition.
+     * Once the model is unloaded, the value will be lost. If the value is not set, a default
+     * value is returned. See {@link ModelParams} for parameter default values.
+     * {@link SoundTriggerManager#queryParameter} should be checked first before
+     * calling this method. Otherwise, an exception can be thrown.
+     *
+     * @param soundModelId UUID of model to get parameter
+     * @param modelParam   {@link ModelParams}
+     * @return value of parameter
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    public int getParameter(@NonNull UUID soundModelId,
+            @ModelParams int modelParam) {
+        try {
+            return mSoundTriggerSession.getParameter(new ParcelUuid(soundModelId), modelParam);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Determine if parameter control is supported for the given model handle.
+     * This method should be checked prior to calling {@link SoundTriggerManager#setParameter} or
+     * {@link SoundTriggerManager#getParameter}.
+     *
+     * @param soundModelId handle of model to get parameter
+     * @param modelParam {@link ModelParams}
+     * @return supported range of parameter, null if not supported
+     */
+    @RequiresPermission(android.Manifest.permission.MANAGE_SOUND_TRIGGER)
+    @Nullable
+    public ModelParamRange queryParameter(@Nullable UUID soundModelId,
+            @ModelParams int modelParam) {
+        try {
+            return mSoundTriggerSession.queryParameter(new ParcelUuid(soundModelId), modelParam);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+}
diff --git a/android/media/tv/DvbDeviceInfo.java b/android/media/tv/DvbDeviceInfo.java
new file mode 100644
index 0000000..54fc39e
--- /dev/null
+++ b/android/media/tv/DvbDeviceInfo.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2015 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.tv;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * A digital video broadcasting (DVB) device.
+ *
+ * <p> Simple wrapper around a <a href="https://www.linuxtv.org/docs/dvbapi/dvbapi.html">Linux DVB
+ * v3</a> device.
+ *
+ * @see TvInputManager#getDvbDeviceList()
+ * @see TvInputManager#openDvbDevice(DvbDeviceInfo, int)
+ * @hide
+ */
+@SystemApi
+public final class DvbDeviceInfo implements Parcelable {
+    static final String TAG = "DvbDeviceInfo";
+
+    public static final @NonNull Parcelable.Creator<DvbDeviceInfo> CREATOR =
+            new Parcelable.Creator<DvbDeviceInfo>() {
+                @Override
+                public DvbDeviceInfo createFromParcel(Parcel source) {
+                    try {
+                        return new DvbDeviceInfo(source);
+                    } catch (Exception e) {
+                        Log.e(TAG, "Exception creating DvbDeviceInfo from parcel", e);
+                        return null;
+                    }
+                }
+
+                @Override
+                public DvbDeviceInfo[] newArray(int size) {
+                    return new DvbDeviceInfo[size];
+                }
+            };
+
+    private final int mAdapterId;
+    private final int mDeviceId;
+
+    private DvbDeviceInfo(Parcel source) {
+        mAdapterId = source.readInt();
+        mDeviceId = source.readInt();
+    }
+
+    /**
+     * Constructs a new {@link DvbDeviceInfo} with the given adapter ID and device ID.
+     */
+    public DvbDeviceInfo(int adapterId, int deviceId) {
+        mAdapterId = adapterId;
+        mDeviceId = deviceId;
+    }
+
+    /**
+     * Returns the adapter ID.
+     *
+     * <p>DVB Adapters contain one or more devices.
+     */
+    @IntRange(from = 0)
+    public int getAdapterId() {
+        return mAdapterId;
+    }
+
+    /**
+     * Returns the device ID.
+     */
+    @IntRange(from = 0)
+    public int getDeviceId() {
+        return mDeviceId;
+    }
+
+    // Parcelable
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeInt(mAdapterId);
+        dest.writeInt(mDeviceId);
+    }
+}
diff --git a/android/media/tv/ITvInputSessionWrapper.java b/android/media/tv/ITvInputSessionWrapper.java
new file mode 100644
index 0000000..abccf8d
--- /dev/null
+++ b/android/media/tv/ITvInputSessionWrapper.java
@@ -0,0 +1,405 @@
+/*
+ * Copyright (C) 2014 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.tv;
+
+import android.annotation.Nullable;
+import android.content.Context;
+import android.graphics.Rect;
+import android.media.PlaybackParams;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.util.Log;
+import android.view.InputChannel;
+import android.view.InputEvent;
+import android.view.InputEventReceiver;
+import android.view.Surface;
+
+import com.android.internal.os.HandlerCaller;
+import com.android.internal.os.SomeArgs;
+
+/**
+ * Implements the internal ITvInputSession interface to convert incoming calls on to it back to
+ * calls on the public TvInputSession interface, scheduling them on the main thread of the process.
+ *
+ * @hide
+ */
+public class ITvInputSessionWrapper extends ITvInputSession.Stub implements HandlerCaller.Callback {
+    private static final String TAG = "TvInputSessionWrapper";
+
+    private static final int EXECUTE_MESSAGE_TIMEOUT_SHORT_MILLIS = 50;
+    private static final int EXECUTE_MESSAGE_TUNE_TIMEOUT_MILLIS = 2000;
+    private static final int EXECUTE_MESSAGE_TIMEOUT_LONG_MILLIS = 5 * 1000;
+
+    private static final int DO_RELEASE = 1;
+    private static final int DO_SET_MAIN = 2;
+    private static final int DO_SET_SURFACE = 3;
+    private static final int DO_DISPATCH_SURFACE_CHANGED = 4;
+    private static final int DO_SET_STREAM_VOLUME = 5;
+    private static final int DO_TUNE = 6;
+    private static final int DO_SET_CAPTION_ENABLED = 7;
+    private static final int DO_SELECT_TRACK = 8;
+    private static final int DO_APP_PRIVATE_COMMAND = 9;
+    private static final int DO_CREATE_OVERLAY_VIEW = 10;
+    private static final int DO_RELAYOUT_OVERLAY_VIEW = 11;
+    private static final int DO_REMOVE_OVERLAY_VIEW = 12;
+    private static final int DO_UNBLOCK_CONTENT = 13;
+    private static final int DO_TIME_SHIFT_PLAY = 14;
+    private static final int DO_TIME_SHIFT_PAUSE = 15;
+    private static final int DO_TIME_SHIFT_RESUME = 16;
+    private static final int DO_TIME_SHIFT_SEEK_TO = 17;
+    private static final int DO_TIME_SHIFT_SET_PLAYBACK_PARAMS = 18;
+    private static final int DO_TIME_SHIFT_ENABLE_POSITION_TRACKING = 19;
+    private static final int DO_START_RECORDING = 20;
+    private static final int DO_STOP_RECORDING = 21;
+    private static final int DO_PAUSE_RECORDING = 22;
+    private static final int DO_RESUME_RECORDING = 23;
+
+    private final boolean mIsRecordingSession;
+    private final HandlerCaller mCaller;
+
+    private TvInputService.Session mTvInputSessionImpl;
+    private TvInputService.RecordingSession mTvInputRecordingSessionImpl;
+
+    private InputChannel mChannel;
+    private TvInputEventReceiver mReceiver;
+
+    public ITvInputSessionWrapper(Context context, TvInputService.Session sessionImpl,
+            InputChannel channel) {
+        mIsRecordingSession = false;
+        mCaller = new HandlerCaller(context, null, this, true /* asyncHandler */);
+        mTvInputSessionImpl = sessionImpl;
+        mChannel = channel;
+        if (channel != null) {
+            mReceiver = new TvInputEventReceiver(channel, context.getMainLooper());
+        }
+    }
+
+    // For the recording session
+    public ITvInputSessionWrapper(Context context,
+            TvInputService.RecordingSession recordingSessionImpl) {
+        mIsRecordingSession = true;
+        mCaller = new HandlerCaller(context, null, this, true /* asyncHandler */);
+        mTvInputRecordingSessionImpl = recordingSessionImpl;
+    }
+
+    @Override
+    public void executeMessage(Message msg) {
+        if ((mIsRecordingSession && mTvInputRecordingSessionImpl == null)
+                || (!mIsRecordingSession && mTvInputSessionImpl == null)) {
+            return;
+        }
+
+        long startTime = System.nanoTime();
+        switch (msg.what) {
+            case DO_RELEASE: {
+                if (mIsRecordingSession) {
+                    mTvInputRecordingSessionImpl.release();
+                    mTvInputRecordingSessionImpl = null;
+                } else {
+                    mTvInputSessionImpl.release();
+                    mTvInputSessionImpl = null;
+                    if (mReceiver != null) {
+                        mReceiver.dispose();
+                        mReceiver = null;
+                    }
+                    if (mChannel != null) {
+                        mChannel.dispose();
+                        mChannel = null;
+                    }
+                }
+                break;
+            }
+            case DO_SET_MAIN: {
+                mTvInputSessionImpl.setMain((Boolean) msg.obj);
+                break;
+            }
+            case DO_SET_SURFACE: {
+                mTvInputSessionImpl.setSurface((Surface) msg.obj);
+                break;
+            }
+            case DO_DISPATCH_SURFACE_CHANGED: {
+                SomeArgs args = (SomeArgs) msg.obj;
+                mTvInputSessionImpl.dispatchSurfaceChanged(args.argi1, args.argi2, args.argi3);
+                args.recycle();
+                break;
+            }
+            case DO_SET_STREAM_VOLUME: {
+                mTvInputSessionImpl.setStreamVolume((Float) msg.obj);
+                break;
+            }
+            case DO_TUNE: {
+                SomeArgs args = (SomeArgs) msg.obj;
+                if (mIsRecordingSession) {
+                    mTvInputRecordingSessionImpl.tune((Uri) args.arg1, (Bundle) args.arg2);
+                } else {
+                    mTvInputSessionImpl.tune((Uri) args.arg1, (Bundle) args.arg2);
+                }
+                args.recycle();
+                break;
+            }
+            case DO_SET_CAPTION_ENABLED: {
+                mTvInputSessionImpl.setCaptionEnabled((Boolean) msg.obj);
+                break;
+            }
+            case DO_SELECT_TRACK: {
+                SomeArgs args = (SomeArgs) msg.obj;
+                mTvInputSessionImpl.selectTrack((Integer) args.arg1, (String) args.arg2);
+                args.recycle();
+                break;
+            }
+            case DO_APP_PRIVATE_COMMAND: {
+                SomeArgs args = (SomeArgs) msg.obj;
+                if (mIsRecordingSession) {
+                    mTvInputRecordingSessionImpl.appPrivateCommand(
+                            (String) args.arg1, (Bundle) args.arg2);
+                } else {
+                    mTvInputSessionImpl.appPrivateCommand((String) args.arg1, (Bundle) args.arg2);
+                }
+                args.recycle();
+                break;
+            }
+            case DO_CREATE_OVERLAY_VIEW: {
+                SomeArgs args = (SomeArgs) msg.obj;
+                mTvInputSessionImpl.createOverlayView((IBinder) args.arg1, (Rect) args.arg2);
+                args.recycle();
+                break;
+            }
+            case DO_RELAYOUT_OVERLAY_VIEW: {
+                mTvInputSessionImpl.relayoutOverlayView((Rect) msg.obj);
+                break;
+            }
+            case DO_REMOVE_OVERLAY_VIEW: {
+                mTvInputSessionImpl.removeOverlayView(true);
+                break;
+            }
+            case DO_UNBLOCK_CONTENT: {
+                mTvInputSessionImpl.unblockContent((String) msg.obj);
+                break;
+            }
+            case DO_TIME_SHIFT_PLAY: {
+                mTvInputSessionImpl.timeShiftPlay((Uri) msg.obj);
+                break;
+            }
+            case DO_TIME_SHIFT_PAUSE: {
+                mTvInputSessionImpl.timeShiftPause();
+                break;
+            }
+            case DO_TIME_SHIFT_RESUME: {
+                mTvInputSessionImpl.timeShiftResume();
+                break;
+            }
+            case DO_TIME_SHIFT_SEEK_TO: {
+                mTvInputSessionImpl.timeShiftSeekTo((Long) msg.obj);
+                break;
+            }
+            case DO_TIME_SHIFT_SET_PLAYBACK_PARAMS: {
+                mTvInputSessionImpl.timeShiftSetPlaybackParams((PlaybackParams) msg.obj);
+                break;
+            }
+            case DO_TIME_SHIFT_ENABLE_POSITION_TRACKING: {
+                mTvInputSessionImpl.timeShiftEnablePositionTracking((Boolean) msg.obj);
+                break;
+            }
+            case DO_START_RECORDING: {
+                SomeArgs args = (SomeArgs) msg.obj;
+                mTvInputRecordingSessionImpl.startRecording((Uri) args.arg1, (Bundle) args.arg2);
+                break;
+            }
+            case DO_STOP_RECORDING: {
+                mTvInputRecordingSessionImpl.stopRecording();
+                break;
+            }
+            case DO_PAUSE_RECORDING: {
+                mTvInputRecordingSessionImpl.pauseRecording((Bundle) msg.obj);
+                break;
+            }
+            case DO_RESUME_RECORDING: {
+                mTvInputRecordingSessionImpl.resumeRecording((Bundle) msg.obj);
+                break;
+            }
+            default: {
+                Log.w(TAG, "Unhandled message code: " + msg.what);
+                break;
+            }
+        }
+        long durationMs = (System.nanoTime() - startTime) / (1000 * 1000);
+        if (durationMs > EXECUTE_MESSAGE_TIMEOUT_SHORT_MILLIS) {
+            Log.w(TAG, "Handling message (" + msg.what + ") took too long time (duration="
+                    + durationMs + "ms)");
+            if (msg.what == DO_TUNE && durationMs > EXECUTE_MESSAGE_TUNE_TIMEOUT_MILLIS) {
+                throw new RuntimeException("Too much time to handle tune request. (" + durationMs
+                        + "ms > " + EXECUTE_MESSAGE_TUNE_TIMEOUT_MILLIS + "ms) "
+                        + "Consider handling the tune request in a separate thread.");
+            }
+            if (durationMs > EXECUTE_MESSAGE_TIMEOUT_LONG_MILLIS) {
+                throw new RuntimeException("Too much time to handle a request. (type=" + msg.what +
+                        ", " + durationMs + "ms > " + EXECUTE_MESSAGE_TIMEOUT_LONG_MILLIS + "ms).");
+            }
+        }
+    }
+
+    @Override
+    public void release() {
+        if (!mIsRecordingSession) {
+            mTvInputSessionImpl.scheduleOverlayViewCleanup();
+        }
+        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_RELEASE));
+    }
+
+    @Override
+    public void setMain(boolean isMain) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_MAIN, isMain));
+    }
+
+    @Override
+    public void setSurface(Surface surface) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_SURFACE, surface));
+    }
+
+    @Override
+    public void dispatchSurfaceChanged(int format, int width, int height) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageIIII(DO_DISPATCH_SURFACE_CHANGED,
+                format, width, height, 0));
+    }
+
+    @Override
+    public final void setVolume(float volume) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_STREAM_VOLUME, volume));
+    }
+
+    @Override
+    public void tune(Uri channelUri, Bundle params) {
+        // Clear the pending tune requests.
+        mCaller.removeMessages(DO_TUNE);
+        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_TUNE, channelUri, params));
+    }
+
+    @Override
+    public void setCaptionEnabled(boolean enabled) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_SET_CAPTION_ENABLED, enabled));
+    }
+
+    @Override
+    public void selectTrack(int type, String trackId) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_SELECT_TRACK, type, trackId));
+    }
+
+    @Override
+    public void appPrivateCommand(String action, Bundle data) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_APP_PRIVATE_COMMAND, action,
+                data));
+    }
+
+    @Override
+    public void createOverlayView(IBinder windowToken, Rect frame) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_CREATE_OVERLAY_VIEW, windowToken,
+                frame));
+    }
+
+    @Override
+    public void relayoutOverlayView(Rect frame) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_RELAYOUT_OVERLAY_VIEW, frame));
+    }
+
+    @Override
+    public void removeOverlayView() {
+        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_REMOVE_OVERLAY_VIEW));
+    }
+
+    @Override
+    public void unblockContent(String unblockedRating) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(
+                DO_UNBLOCK_CONTENT, unblockedRating));
+    }
+
+    @Override
+    public void timeShiftPlay(Uri recordedProgramUri) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(
+                DO_TIME_SHIFT_PLAY, recordedProgramUri));
+    }
+
+    @Override
+    public void timeShiftPause() {
+        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_TIME_SHIFT_PAUSE));
+    }
+
+    @Override
+    public void timeShiftResume() {
+        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_TIME_SHIFT_RESUME));
+    }
+
+    @Override
+    public void timeShiftSeekTo(long timeMs) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_TIME_SHIFT_SEEK_TO, timeMs));
+    }
+
+    @Override
+    public void timeShiftSetPlaybackParams(PlaybackParams params) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_TIME_SHIFT_SET_PLAYBACK_PARAMS,
+                params));
+    }
+
+    @Override
+    public void timeShiftEnablePositionTracking(boolean enable) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(
+                DO_TIME_SHIFT_ENABLE_POSITION_TRACKING, enable));
+    }
+
+    @Override
+    public void startRecording(@Nullable Uri programUri, @Nullable Bundle params) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_START_RECORDING, programUri,
+                params));
+    }
+
+    @Override
+    public void stopRecording() {
+        mCaller.executeOrSendMessage(mCaller.obtainMessage(DO_STOP_RECORDING));
+    }
+
+    @Override
+    public void pauseRecording(@Nullable Bundle params) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_PAUSE_RECORDING, params));
+    }
+
+    @Override
+    public void resumeRecording(@Nullable Bundle params) {
+        mCaller.executeOrSendMessage(mCaller.obtainMessageO(DO_RESUME_RECORDING, params));
+    }
+
+    private final class TvInputEventReceiver extends InputEventReceiver {
+        public TvInputEventReceiver(InputChannel inputChannel, Looper looper) {
+            super(inputChannel, looper);
+        }
+
+        @Override
+        public void onInputEvent(InputEvent event) {
+            if (mTvInputSessionImpl == null) {
+                // The session has been finished.
+                finishInputEvent(event, false);
+                return;
+            }
+
+            int handled = mTvInputSessionImpl.dispatchInputEvent(event, this);
+            if (handled != TvInputManager.Session.DISPATCH_IN_PROGRESS) {
+                finishInputEvent(event, handled == TvInputManager.Session.DISPATCH_HANDLED);
+            }
+        }
+    }
+}
diff --git a/android/media/tv/TunedInfo.java b/android/media/tv/TunedInfo.java
new file mode 100644
index 0000000..20acefa
--- /dev/null
+++ b/android/media/tv/TunedInfo.java
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2020 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.tv;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Surface;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+
+/**
+ * Contains information about a {@link TvInputService.Session} that is currently tuned to a channel
+ * or pass-through input.
+ * @hide
+ */
+@SystemApi
+public final class TunedInfo implements Parcelable {
+    static final String TAG = "TunedInfo";
+
+    /**
+     * App tag for {@link #getAppTag()}: the corresponding application of the channel is the same as
+     * the caller.
+     * <p>{@link #getAppType()} returns {@link #APP_TYPE_SELF} if and only if the app tag is
+     * {@link #APP_TAG_SELF}.
+     */
+    public static final int APP_TAG_SELF = 0;
+    /**
+     * App tag for {@link #getAppType()}: the corresponding application of the channel is the same
+     * as the caller.
+     * <p>{@link #getAppType()} returns {@link #APP_TYPE_SELF} if and only if the app tag is
+     * {@link #APP_TAG_SELF}.
+     */
+    public static final int APP_TYPE_SELF = 1;
+    /**
+     * App tag for {@link #getAppType()}: the corresponding app of the channel is a system
+     * application.
+     */
+    public static final int APP_TYPE_SYSTEM = 2;
+    /**
+     * App tag for {@link #getAppType()}: the corresponding app of the channel is not a system
+     * application.
+     */
+    public static final int APP_TYPE_NON_SYSTEM = 3;
+
+    /** @hide */
+    @IntDef(prefix = "APP_TYPE_", value = {APP_TYPE_SELF, APP_TYPE_SYSTEM, APP_TYPE_NON_SYSTEM})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AppType {}
+
+    public static final @NonNull Parcelable.Creator<TunedInfo> CREATOR =
+            new Parcelable.Creator<TunedInfo>() {
+                @Override
+                public TunedInfo createFromParcel(Parcel source) {
+                    try {
+                        return new TunedInfo(source);
+                    } catch (Exception e) {
+                        Log.e(TAG, "Exception creating TunedInfo from parcel", e);
+                        return null;
+                    }
+                }
+
+                @Override
+                public TunedInfo[] newArray(int size) {
+                    return new TunedInfo[size];
+                }
+            };
+
+
+    private final String mInputId;
+    @Nullable private final Uri mChannelUri;
+    private final boolean mIsRecordingSession;
+    private final boolean mIsVisible;
+    private final boolean mIsMainSession;
+    @AppType private final int mAppType;
+    private final int mAppTag;
+
+    /** @hide */
+    public TunedInfo(
+            String inputId, @Nullable Uri channelUri, boolean isRecordingSession,
+            boolean isVisible, boolean isMainSession, @AppType int appType, int appTag) {
+        mInputId = inputId;
+        mChannelUri = channelUri;
+        mIsRecordingSession = isRecordingSession;
+        mIsVisible = isVisible;
+        mIsMainSession = isMainSession;
+        mAppType = appType;
+        mAppTag = appTag;
+    }
+
+
+    private TunedInfo(Parcel source) {
+        mInputId = source.readString();
+        String uriString = source.readString();
+        mChannelUri = uriString == null ? null : Uri.parse(uriString);
+        mIsRecordingSession = (source.readInt() == 1);
+        mIsVisible = (source.readInt() == 1);
+        mIsMainSession = (source.readInt() == 1);
+        mAppType = source.readInt();
+        mAppTag = source.readInt();
+    }
+
+    /**
+     * Returns the TV input ID of the channel.
+     */
+    @NonNull
+    public String getInputId() {
+        return mInputId;
+    }
+
+    /**
+     * Returns the channel URI of the channel.
+     * <p>Returns {@code null} if it's a passthrough input or the permission is not granted.
+     */
+    @Nullable
+    public Uri getChannelUri() {
+        return mChannelUri;
+    }
+
+    /**
+     * Returns {@code true} if the channel session is a recording session.
+     * @see TvInputService.RecordingSession
+     */
+    public boolean isRecordingSession() {
+        return mIsRecordingSession;
+    }
+
+    /**
+     * Returns {@code true} if the corresponding session is visible.
+     * <p>The system checks whether the {@link Surface} of the session is {@code null} or not. When
+     * it becomes invisible, the surface is destroyed and set to null.
+     * @see TvInputService.Session#onSetSurface(Surface)
+     * @see android.view.SurfaceView#notifySurfaceDestroyed
+     */
+    public boolean isVisible() {
+        return mIsVisible;
+    }
+
+    /**
+     * Returns {@code true} if the corresponding session is set as main session.
+     * @see TvView#setMain
+     * @see TvInputService.Session#onSetMain
+     */
+    public boolean isMainSession() {
+        return mIsMainSession;
+    }
+
+    /**
+     * Returns the app tag.
+     * <p>App tag is used to differentiate one app from another.
+     * {@link #APP_TAG_SELF} is for current app.
+     */
+    public int getAppTag() {
+        return mAppTag;
+    }
+
+    /**
+     * Returns the app type.
+     */
+    @AppType
+    public int getAppType() {
+        return mAppType;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeString(mInputId);
+        String uriString = mChannelUri == null ? null : mChannelUri.toString();
+        dest.writeString(uriString);
+        dest.writeInt(mIsRecordingSession ? 1 : 0);
+        dest.writeInt(mIsVisible ? 1 : 0);
+        dest.writeInt(mIsMainSession ? 1 : 0);
+        dest.writeInt(mAppType);
+        dest.writeInt(mAppTag);
+    }
+
+    @Override
+    public String toString() {
+        return "inputID=" + mInputId
+                + ";channelUri=" + mChannelUri
+                + ";isRecording=" + mIsRecordingSession
+                + ";isVisible=" + mIsVisible
+                + ";isMainSession=" + mIsMainSession
+                + ";appType=" + mAppType
+                + ";appTag=" + mAppTag;
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (!(o instanceof TunedInfo)) {
+            return false;
+        }
+
+        TunedInfo other = (TunedInfo) o;
+
+        return TextUtils.equals(mInputId, other.getInputId())
+                && Objects.equals(mChannelUri, other.mChannelUri)
+                && mIsRecordingSession == other.mIsRecordingSession
+                && mIsVisible == other.mIsVisible
+                && mIsMainSession == other.mIsMainSession
+                && mAppType == other.mAppType
+                && mAppTag == other.mAppTag;
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(
+                mInputId, mChannelUri, mIsRecordingSession, mIsVisible, mIsMainSession, mAppType,
+                mAppTag);
+    }
+}
diff --git a/android/media/tv/TvContentRating.java b/android/media/tv/TvContentRating.java
new file mode 100644
index 0000000..5babb16
--- /dev/null
+++ b/android/media/tv/TvContentRating.java
@@ -0,0 +1,1096 @@
+/*
+ * Copyright (C) 2014 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.tv;
+
+import android.annotation.NonNull;
+import android.text.TextUtils;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * A class representing a TV content rating. When a TV input service inserts the content rating
+ * information on a program into the database, this class can be used to generate the formatted
+ * string for
+ * {@link TvContract.Programs#COLUMN_CONTENT_RATING TvContract.Programs.COLUMN_CONTENT_RATING}.
+ * To create a {@code TvContentRating} object, use the
+ * {@link #createRating TvContentRating.createRating} method with valid rating system string
+ * constants.
+ *
+ * <p>It is possible for an application to define its own content rating system by supplying a
+ * content rating system definition XML resource (see example below) and declaring a broadcast
+ * receiver that filters {@link TvInputManager#ACTION_QUERY_CONTENT_RATING_SYSTEMS} in its manifest.
+ *
+ * <h3> Example: Rating system definition for the TV Parental Guidelines</h3>
+ * The following XML example shows how the TV Parental Guidelines in the United States can be
+ * defined:
+ * <p><pre class="prettyprint">
+ * {@literal
+ * <rating-system-definitions xmlns:android="http://schemas.android.com/apk/res/android"
+ *     android:versionCode="1">
+ *     <rating-system-definition android:name="US_TV"
+ *         android:country="US"
+ *         android:description="@string/description_us_tv">
+ *         <sub-rating-definition android:name="US_TV_D"
+ *             android:title="D"
+ *             android:description="@string/description_us_tv_d" />
+ *         <sub-rating-definition android:name="US_TV_L"
+ *             android:title="L"
+ *             android:description="@string/description_us_tv_l" />
+ *         <sub-rating-definition android:name="US_TV_S"
+ *             android:title="S"
+ *             android:description="@string/description_us_tv_s" />
+ *         <sub-rating-definition android:name="US_TV_V"
+ *             android:title="V"
+ *             android:description="@string/description_us_tv_v" />
+ *         <sub-rating-definition android:name="US_TV_FV"
+ *             android:title="FV"
+ *             android:description="@string/description_us_tv_fv" />
+ *
+ *         <rating-definition android:name="US_TV_Y"
+ *             android:title="TV-Y"
+ *             android:description="@string/description_us_tv_y"
+ *             android:icon="@drawable/icon_us_tv_y"
+ *             android:contentAgeHint="0" />
+ *         <rating-definition android:name="US_TV_Y7"
+ *             android:title="TV-Y7"
+ *             android:description="@string/description_us_tv_y7"
+ *             android:icon="@drawable/icon_us_tv_y7"
+ *             android:contentAgeHint="7">
+ *             <sub-rating android:name="US_TV_FV" />
+ *         </rating-definition>
+ *         <rating-definition android:name="US_TV_G"
+ *             android:title="TV-G"
+ *             android:description="@string/description_us_tv_g"
+ *             android:icon="@drawable/icon_us_tv_g"
+ *             android:contentAgeHint="0" />
+ *         <rating-definition android:name="US_TV_PG"
+ *             android:title="TV-PG"
+ *             android:description="@string/description_us_tv_pg"
+ *             android:icon="@drawable/icon_us_tv_pg"
+ *             android:contentAgeHint="14">
+ *             <sub-rating android:name="US_TV_D" />
+ *             <sub-rating android:name="US_TV_L" />
+ *             <sub-rating android:name="US_TV_S" />
+ *             <sub-rating android:name="US_TV_V" />
+ *         </rating-definition>
+ *         <rating-definition android:name="US_TV_14"
+ *             android:title="TV-14"
+ *             android:description="@string/description_us_tv_14"
+ *             android:icon="@drawable/icon_us_tv_14"
+ *             android:contentAgeHint="14">
+ *             <sub-rating android:name="US_TV_D" />
+ *             <sub-rating android:name="US_TV_L" />
+ *             <sub-rating android:name="US_TV_S" />
+ *             <sub-rating android:name="US_TV_V" />
+ *         </rating-definition>
+ *         <rating-definition android:name="US_TV_MA"
+ *             android:title="TV-MA"
+ *             android:description="@string/description_us_tv_ma"
+ *             android:icon="@drawable/icon_us_tv_ma"
+ *             android:contentAgeHint="17">
+ *             <sub-rating android:name="US_TV_L" />
+ *             <sub-rating android:name="US_TV_S" />
+ *             <sub-rating android:name="US_TV_V" />
+ *         </rating-definition>
+ *         <rating-order>
+ *             <rating android:name="US_TV_Y" />
+ *             <rating android:name="US_TV_Y7" />
+ *         </rating-order>
+ *         <rating-order>
+ *             <rating android:name="US_TV_G" />
+ *             <rating android:name="US_TV_PG" />
+ *             <rating android:name="US_TV_14" />
+ *             <rating android:name="US_TV_MA" />
+ *         </rating-order>
+ *     </rating-system-definition>
+ * </rating-system-definitions>}</pre>
+ *
+ * <h3>System defined rating strings</h3>
+ * The following strings are defined by the system to provide a standard way to create
+ * {@code TvContentRating} objects.
+ *
+ * <p>For example, to create an object that represents TV-PG rating with suggestive dialogue and
+ * coarse language from the TV Parental Guidelines in the United States, one can use the following
+ * code snippet:
+ *
+ * <pre>
+ * TvContentRating rating = TvContentRating.createRating(
+ *         "com.android.tv",
+ *         "US_TV",
+ *         "US_TV_PG",
+ *         "US_TV_D", "US_TV_L");
+ * </pre>
+ * <h4>System defined string for domains</h4>
+ * <table>
+ *     <tr>
+ *         <th>Constant Value</th>
+ *         <th>Description</th>
+ *     </tr>
+ *     <tr>
+ *         <td>com.android.tv</td>
+ *         <td>Used for creating system defined content ratings</td>
+ *     </tr>
+ * </table>
+ *
+ * <h4>System defined strings for rating systems</h4>
+ * <table>
+ *     <tr>
+ *         <th>Constant Value</th>
+ *         <th>Description</th>
+ *     </tr>
+ *     <tr>
+ *         <td>AR_TV</td>
+ *         <td>TV content rating system for Argentina</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV</td>
+ *         <td>TV content rating system for Australia</td>
+ *     </tr>
+ *     <tr>
+ *         <td>BR_TV</td>
+ *         <td>TV content rating system for Brazil</td>
+ *     </tr>
+ *     <tr>
+ *         <td>CA_TV_EN</td>
+ *         <td>TV content rating system for Canada (English)</td>
+ *     </tr>
+ *     <tr>
+ *         <td>CA_TV_FR</td>
+ *         <td>TV content rating system for Canada (French)</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB</td>
+ *         <td>DTMB content rating system</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB</td>
+ *         <td>DVB content rating system</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB</td>
+ *         <td>DVB content rating system for Spain</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB</td>
+ *         <td>DVB content rating system for France</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB</td>
+ *         <td>ISDB content rating system</td>
+ *     </tr>
+ *     <tr>
+ *         <td>KR_TV</td>
+ *         <td>TV content rating system for South Korea</td>
+ *     </tr>
+ *     <tr>
+ *         <td>NZ_TV</td>
+ *         <td>TV content rating system for New Zealand</td>
+ *     </tr>
+ *     <tr>
+ *         <td>SG_TV</td>
+ *         <td>TV content rating system for Singapore</td>
+ *     </tr>
+ *     <tr>
+ *         <td>TH_TV</td>
+ *         <td>TV content rating system for Thailand</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_MV</td>
+ *         <td>Movie content rating system for the United States</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_TV</td>
+ *         <td>TV content rating system for the United States</td>
+ *     </tr>
+ * </table>
+ *
+ * <h4>System defined strings for ratings</h4>
+ * <table>
+ *     <tr>
+ *         <th>Rating System</th>
+ *         <th>Constant Value</th>
+ *         <th>Description</th>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="4">AR_TV</td>
+ *         <td>AR_TV_ATP</td>
+ *         <td>Suitable for all audiences. Programs may contain mild violence, language and mature
+ *         situations</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AR_TV_SAM_13</td>
+ *         <td>Suitable for ages 13 and up. Programs may contain mild to moderate language and mild
+ *         violence and sexual references</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AR_TV_SAM_16</td>
+ *         <td>Suitable for ages 16 and up. Programs may contain more intensive violence and coarse
+ *         language, partial nudity and moderate sexual references</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AR_TV_SAM_18</td>
+ *         <td>Suitable for mature audiences only. Programs contain strong violence, coarse language
+ *         and explicit sexual references</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="8">AU_TV</td>
+ *         <td>AU_TV_P</td>
+ *         <td>Recommended for younger children aged between 2 and 11 years</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV_C</td>
+ *         <td>Recommended for older children aged between 5 and 14 years</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV_G</td>
+ *         <td>Recommended for all ages</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV_PG</td>
+ *         <td>Parental guidance is recommended for young viewers under 15</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV_M</td>
+ *         <td>Recommended for mature audiences aged 15 years and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV_MA</td>
+ *         <td>Not suitable for children and teens under 15, due to sexual descriptions, course
+ *         language, adult themes or drug use</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV_AV</td>
+ *         <td>Not suitable for children and teens under 15. This category is used specifically for
+ *         violent programs</td>
+ *     </tr>
+ *     <tr>
+ *         <td>AU_TV_R</td>
+ *         <td>Not for children under 18. Content may include graphic violence, sexual situations,
+ *         coarse language and explicit drug use</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="6">BR_TV</td>
+ *         <td>BR_TV_L</td>
+ *         <td>Content is suitable for all audiences</td>
+ *     </tr>
+ *     <tr>
+ *         <td>BR_TV_10</td>
+ *         <td>Content suitable for viewers over the age of 10</td>
+ *     </tr>
+ *     <tr>
+ *         <td>BR_TV_12</td>
+ *         <td>Content suitable for viewers over the age of 12</td>
+ *     </tr>
+ *     <tr>
+ *         <td>BR_TV_14</td>
+ *         <td>Content suitable for viewers over the age of 14</td>
+ *     </tr>
+ *     <tr>
+ *         <td>BR_TV_16</td>
+ *         <td>Content suitable for viewers over the age of 16</td>
+ *     </tr>
+ *     <tr>
+ *         <td>BR_TV_18</td>
+ *         <td>Content suitable for viewers over the age of 18</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="7">CA_TV_EN</td>
+ *         <td>CA_TV_EN_EXEMPT</td>
+ *         <td>Exempt from ratings</td>
+ *     </tr>
+ *     <tr>
+ *         <td>CA_TV_EN_C</td>
+ *         <td>Suitable for children ages 2&#8211;7</td>
+ *     </tr>
+ *     <tr>
+ *         <td>CA_TV_EN_C8</td>
+ *         <td>Suitable for children ages 8 and older</td>
+ *     </tr>
+ *     <tr>
+ *         <td>CA_TV_EN_G</td>
+ *         <td>Suitable for the entire family</td>
+ *     </tr>
+ *     <tr>
+ *         <td>CA_TV_EN_PG</td>
+ *         <td>May contain moderate violence, profanity, nudity, and sexual references</td>
+ *     </tr>
+ *     <tr>
+ *         <td>CA_TV_EN_14</td>
+ *         <td>Intended for viewers ages 14 and older</td>
+ *     </tr>
+ *     <tr>
+ *         <td>CA_TV_EN_18</td>
+ *         <td>Intended for viewers ages 18 and older</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="6">CA_TV_FR</td>
+ *         <td>CA_TV_FR_E</td>
+ *         <td>Exempt from ratings</td>
+ *     </tr>
+ *     <tr>
+ *         <td>CA_TV_FR_G</td>
+ *         <td>Appropriate for all ages</td>
+ *     </tr>
+ *     <tr>
+ *         <td>CA_TV_FR_8</td>
+ *         <td>Appropriate for children 8</td>
+ *     </tr>
+ *     <tr>
+ *         <td>CA_TV_FR_13</td>
+ *         <td>Suitable for children 13</td>
+ *     </tr>
+ *     <tr>
+ *         <td>CA_TV_FR_16</td>
+ *         <td>Recommended for children over the age of 16</td>
+ *     </tr>
+ *     <tr>
+ *         <td>CA_TV_FR_18</td>
+ *         <td>Only to be viewed by adults</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="15">DTMB</td>
+ *         <td>DTMB_4</td>
+ *         <td>Recommended for ages 4 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_5</td>
+ *         <td>Recommended for ages 5 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_6</td>
+ *         <td>Recommended for ages 6 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_7</td>
+ *         <td>Recommended for ages 7 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_8</td>
+ *         <td>Recommended for ages 8 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_9</td>
+ *         <td>Recommended for ages 9 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_10</td>
+ *         <td>Recommended for ages 10 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_11</td>
+ *         <td>Recommended for ages 11 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_12</td>
+ *         <td>Recommended for ages 12 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_13</td>
+ *         <td>Recommended for ages 13 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_14</td>
+ *         <td>Recommended for ages 14 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_15</td>
+ *         <td>Recommended for ages 15 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_16</td>
+ *         <td>Recommended for ages 16 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_17</td>
+ *         <td>Recommended for ages 17 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DTMB_18</td>
+ *         <td>Recommended for ages 18 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="15">DVB</td>
+ *         <td>DVB_4</td>
+ *         <td>Recommended for ages 4 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_5</td>
+ *         <td>Recommended for ages 5 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_6</td>
+ *         <td>Recommended for ages 6 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_7</td>
+ *         <td>Recommended for ages 7 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_8</td>
+ *         <td>Recommended for ages 8 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_9</td>
+ *         <td>Recommended for ages 9 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_10</td>
+ *         <td>Recommended for ages 10 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_11</td>
+ *         <td>Recommended for ages 11 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_12</td>
+ *         <td>Recommended for ages 12 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_13</td>
+ *         <td>Recommended for ages 13 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_14</td>
+ *         <td>Recommended for ages 14 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_15</td>
+ *         <td>Recommended for ages 15 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_16</td>
+ *         <td>Recommended for ages 16 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_17</td>
+ *         <td>Recommended for ages 17 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>DVB_18</td>
+ *         <td>Recommended for ages 18 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="18">ES_DVB</td>
+ *         <td>ES_DVB_ALL</td>
+ *         <td>Recommended for all ages</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_C</td>
+ *         <td>Recommended for children</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_X</td>
+ *         <td>Recommended for adults</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_4</td>
+ *         <td>Recommended for ages 4 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_5</td>
+ *         <td>Recommended for ages 5 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_6</td>
+ *         <td>Recommended for ages 6 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_7</td>
+ *         <td>Recommended for ages 7 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_8</td>
+ *         <td>Recommended for ages 8 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_9</td>
+ *         <td>Recommended for ages 9 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_10</td>
+ *         <td>Recommended for ages 10 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_11</td>
+ *         <td>Recommended for ages 11 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_12</td>
+ *         <td>Recommended for ages 12 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_13</td>
+ *         <td>Recommended for ages 13 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_14</td>
+ *         <td>Recommended for ages 14 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_15</td>
+ *         <td>Recommended for ages 15 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_16</td>
+ *         <td>Recommended for ages 16 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_17</td>
+ *         <td>Recommended for ages 17 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ES_DVB_18</td>
+ *         <td>Recommended for ages 18 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="16">FR_DVB</td>
+ *         <td>FR_DVB_U</td>
+ *         <td>Recommended for all ages</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_4</td>
+ *         <td>Recommended for ages 4 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_5</td>
+ *         <td>Recommended for ages 5 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_6</td>
+ *         <td>Recommended for ages 6 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_7</td>
+ *         <td>Recommended for ages 7 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_8</td>
+ *         <td>Recommended for ages 8 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_9</td>
+ *         <td>Recommended for ages 9 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_10</td>
+ *         <td>Recommended for ages 10 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_11</td>
+ *         <td>Recommended for ages 11 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_12</td>
+ *         <td>Recommended for ages 12 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_13</td>
+ *         <td>Recommended for ages 13 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_14</td>
+ *         <td>Recommended for ages 14 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_15</td>
+ *         <td>Recommended for ages 15 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_16</td>
+ *         <td>Recommended for ages 16 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_17</td>
+ *         <td>Recommended for ages 17 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>FR_DVB_18</td>
+ *         <td>Recommended for ages 18 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="17">ISDB</td>
+ *         <td>ISDB_4</td>
+ *         <td>Recommended for ages 4 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_5</td>
+ *         <td>Recommended for ages 5 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_6</td>
+ *         <td>Recommended for ages 6 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_7</td>
+ *         <td>Recommended for ages 7 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_8</td>
+ *         <td>Recommended for ages 8 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_9</td>
+ *         <td>Recommended for ages 9 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_10</td>
+ *         <td>Recommended for ages 10 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_11</td>
+ *         <td>Recommended for ages 11 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_12</td>
+ *         <td>Recommended for ages 12 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_13</td>
+ *         <td>Recommended for ages 13 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_14</td>
+ *         <td>Recommended for ages 14 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_15</td>
+ *         <td>Recommended for ages 15 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_16</td>
+ *         <td>Recommended for ages 16 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_17</td>
+ *         <td>Recommended for ages 17 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_18</td>
+ *         <td>Recommended for ages 18 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_19</td>
+ *         <td>Recommended for ages 19 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td>ISDB_20</td>
+ *         <td>Recommended for ages 20 and over</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="5">KR_TV</td>
+ *         <td>KR_TV_ALL</td>
+ *         <td>Appropriate for all ages</td>
+ *     </tr>
+ *     <tr>
+ *         <td>KR_TV_7</td>
+ *         <td>May contain material inappropriate for children younger than 7, and parental
+ *         discretion should be used</td>
+ *     </tr>
+ *     <tr>
+ *         <td>KR_TV_12</td>
+ *         <td>May deemed inappropriate for those younger than 12, and parental discretion should be
+ *         used</td>
+ *     </tr>
+ *     <tr>
+ *         <td>KR_TV_15</td>
+ *         <td>May be inappropriate for children under 15, and that parental discretion should be
+ *         used</td>
+ *     </tr>
+ *     <tr>
+ *         <td>KR_TV_19</td>
+ *         <td>For adults only</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="3">NZ_TV</td>
+ *         <td>NZ_TV_G</td>
+ *         <td>Programmes which exclude material likely to be unsuitable for children. Programmes
+ *         may not necessarily be designed for child viewers but should not contain material likely
+ *         to alarm or distress them</td>
+ *     </tr>
+ *     <tr>
+ *         <td>NZ_TV_PGR</td>
+ *         <td>Programmes containing material more suited for mature audiences but not necessarily
+ *         unsuitable for child viewers when subject to the guidance of a parent or an adult</td>
+ *     </tr>
+ *     <tr>
+ *         <td>NZ_TV_AO</td>
+ *         <td>Programmes containing adult themes and directed primarily at mature audiences</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="6">SG_TV</td>
+ *         <td>SG_TV_G</td>
+ *         <td>Suitable for all ages</td>
+ *     </tr>
+ *     <tr>
+ *         <td>SG_TV_PG</td>
+ *         <td>Suitable for all but parents should guide their young</td>
+ *     </tr>
+ *     <tr>
+ *         <td>SG_TV_PG13</td>
+ *         <td>Suitable for persons aged 13 and above but parental guidance is advised for children
+ *         below 13</td>
+ *     </tr>
+ *     <tr>
+ *         <td>SG_TV_NC16</td>
+ *         <td>Suitable for persons aged 16 and above</td>
+ *     </tr>
+ *     <tr>
+ *         <td>SG_TV_M18</td>
+ *         <td>Suitable for persons aged 18 and above</td>
+ *     </tr>
+ *     <tr>
+ *         <td>SG_TV_R21</td>
+ *         <td>Suitable for adults aged 21 and above</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="6">TH_TV</td>
+ *         <td>TH_TV_4</td>
+ *         <td>Suitable for audiences 3 to 5 years of age</td>
+ *     </tr>
+ *     <tr>
+ *         <td>TH_TV_6</td>
+ *         <td>Suitable for audiences 6 to 12 years of age</td>
+ *     </tr>
+ *     <tr>
+ *         <td>TH_TV_10</td>
+ *         <td>Suitable for all audiences</td>
+ *     </tr>
+ *     <tr>
+ *         <td>TH_TV_13</td>
+ *         <td>Parental guidance suggested for viewers age below 13</td>
+ *     </tr>
+ *     <tr>
+ *         <td>TH_TV_18</td>
+ *         <td>Parental guidance suggested for viewers age below 18</td>
+ *     </tr>
+ *     <tr>
+ *         <td>TH_TV_19</td>
+ *         <td>Not suitable for children and teenagers</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="5">US_MV</td>
+ *         <td>US_MV_G</td>
+ *         <td>General audiences</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_MV_PG</td>
+ *         <td>Parental guidance suggested</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_MV_PG13</td>
+ *         <td>Parents strongly cautioned</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_MV_R</td>
+ *         <td>Restricted, under 17 requires accompanying parent or adult guardian</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_MV_NC17</td>
+ *         <td>No one 17 and under admitted</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="6">US_TV</td>
+ *         <td>US_TV_Y</td>
+ *         <td>This program is designed to be appropriate for all children</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_TV_Y7</td>
+ *         <td>This program is designed for children age 7 and above</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_TV_G</td>
+ *         <td>Most parents would find this program suitable for all ages</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_TV_PG</td>
+ *         <td>This program contains material that parents may find unsuitable for younger children
+ *         </td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_TV_14</td>
+ *         <td>This program contains some material that many parents would find unsuitable for
+ *         children under 14 years of age</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_TV_MA</td>
+ *         <td>This program is specifically designed to be viewed by adults and therefore may be
+ *         unsuitable for children under 17</td>
+ *     </tr>
+ * </table>
+ *
+ * <h4>System defined strings for sub-ratings</h4>
+ * <table>
+ *     <tr>
+ *         <th>Rating System</th>
+ *         <th>Constant Value</th>
+ *         <th>Description</th>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="3">BR_TV</td>
+ *         <td>BR_TV_D</td>
+ *         <td>Drugs<br/>Applicable to BR_TV_L, BR_TV_10, BR_TV_12, BR_TV_14, BR_TV_16, and BR_TV_18
+ *         </td>
+ *     </tr>
+ *     <tr>
+ *         <td>BR_TV_S</td>
+ *         <td>Sex<br/>Applicable to BR_TV_L, BR_TV_10, BR_TV_12, BR_TV_14, BR_TV_16, and BR_TV_18
+ *         </td>
+ *     </tr>
+ *     <tr>
+ *         <td>BR_TV_V</td>
+ *         <td>Violence<br/>Applicable to BR_TV_L, BR_TV_10, BR_TV_12, BR_TV_14, BR_TV_16, and
+ *         BR_TV_18</td>
+ *     </tr>
+ *     <tr>
+ *         <td valign="top" rowspan="5">US_TV</td>
+ *         <td>US_TV_D</td>
+ *         <td>Suggestive dialogue (Usually means talks about sex)<br/>Applicable to US_TV_PG, and
+ *         US_TV_14</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_TV_L</td>
+ *         <td>Coarse language<br/>Applicable to US_TV_PG, US_TV_14, and US_TV_MA</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_TV_S</td>
+ *         <td>Sexual content<br/>Applicable to US_TV_PG, US_TV_14, and US_TV_MA</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_TV_V</td>
+ *         <td>Violence<br/>Applicable to US_TV_PG, US_TV_14, and US_TV_MA</td>
+ *     </tr>
+ *     <tr>
+ *         <td>US_TV_FV</td>
+ *         <td>Fantasy violence (Children's programming only)<br/>Applicable to US_TV_Y7</td>
+ *     </tr>
+ * </table>
+ */
+public final class TvContentRating {
+    // TODO: Consider to use other DELIMITER. In some countries such as India may use this delimiter
+    // in the main ratings.
+    private static final String DELIMITER = "/";
+
+    private final String mDomain;
+    private final String mRatingSystem;
+    private final String mRating;
+    private final String[] mSubRatings;
+    private final int mHashCode;
+
+    /**
+     * Rating constant denoting unrated content. Used to handle the case where the content rating
+     * information is missing.
+     *
+     * <p>TV input services can call {@link TvInputManager#isRatingBlocked} with this constant to
+     * determine whether they should block unrated content. The subsequent call to
+     * {@link TvInputService.Session#notifyContentBlocked} with the same constant notifies
+     * applications that the current program content is blocked by parental controls.
+     */
+    public static final TvContentRating UNRATED = new TvContentRating("null", "null", "null", null);
+
+    /**
+     * Creates a {@code TvContentRating} object with predefined content rating strings.
+     *
+     * @param domain The domain string. For example, "com.android.tv".
+     * @param ratingSystem The rating system string. For example, "US_TV".
+     * @param rating The content rating string. For example, "US_TV_PG".
+     * @param subRatings The sub-rating strings. For example, "US_TV_D" and "US_TV_L".
+     * @return A {@code TvContentRating} object.
+     * @throws IllegalArgumentException If {@code domain}, {@code ratingSystem} or {@code rating} is
+     *             {@code null}.
+     */
+    public static TvContentRating createRating(String domain, String ratingSystem,
+            String rating, String... subRatings) {
+        if (TextUtils.isEmpty(domain)) {
+            throw new IllegalArgumentException("domain cannot be empty");
+        }
+        if (TextUtils.isEmpty(ratingSystem)) {
+            throw new IllegalArgumentException("ratingSystem cannot be empty");
+        }
+        if (TextUtils.isEmpty(rating)) {
+            throw new IllegalArgumentException("rating cannot be empty");
+        }
+        return new TvContentRating(domain, ratingSystem, rating, subRatings);
+    }
+
+    /**
+     * Recovers a {@code TvContentRating} object from the string that was previously created from
+     * {@link #flattenToString}.
+     *
+     * @param ratingString The string returned by {@link #flattenToString}.
+     * @return the {@code TvContentRating} object containing the domain, rating system, rating and
+     *         sub-ratings information encoded in {@code ratingString}.
+     * @see #flattenToString
+     */
+    public static TvContentRating unflattenFromString(String ratingString) {
+        if (TextUtils.isEmpty(ratingString)) {
+            throw new IllegalArgumentException("ratingString cannot be empty");
+        }
+        String[] strs = ratingString.split(DELIMITER);
+        if (strs.length < 3) {
+            throw new IllegalArgumentException("Invalid rating string: " + ratingString);
+        }
+        if (strs.length > 3) {
+            String[] subRatings = new String[strs.length - 3];
+            System.arraycopy(strs, 3, subRatings, 0, subRatings.length);
+            return new TvContentRating(strs[0], strs[1], strs[2], subRatings);
+        }
+        return new TvContentRating(strs[0], strs[1], strs[2], null);
+    }
+
+    /**
+     * Constructs a TvContentRating object from a given rating and sub-rating constants.
+     *
+     * @param domain The string for domain of the content rating system such as "com.android.tv".
+     * @param ratingSystem The rating system string such as "US_TV".
+     * @param rating The content rating string such as "US_TV_PG".
+     * @param subRatings The sub-rating strings such as "US_TV_D" and "US_TV_L".
+     */
+    private TvContentRating(
+            String domain, String ratingSystem, String rating, String[] subRatings) {
+        mDomain = domain;
+        mRatingSystem = ratingSystem;
+        mRating = rating;
+        if (subRatings == null || subRatings.length == 0) {
+            mSubRatings = null;
+        } else {
+            Arrays.sort(subRatings);
+            mSubRatings = subRatings;
+        }
+        mHashCode = 31 * Objects.hash(mDomain, mRating) + Arrays.hashCode(mSubRatings);
+    }
+
+    /**
+     * Returns the domain of this {@code TvContentRating} object.
+     */
+    public String getDomain() {
+        return mDomain;
+    }
+
+    /**
+     * Returns the rating system of this {@code TvContentRating} object.
+     */
+    public String getRatingSystem() {
+        return mRatingSystem;
+    }
+
+    /**
+     * Returns the main rating of this {@code TvContentRating} object.
+     */
+    public String getMainRating() {
+        return mRating;
+    }
+
+    /**
+     * Returns the unmodifiable sub-rating string {@link List} of this {@code TvContentRating}
+     * object.
+     */
+    public List<String> getSubRatings() {
+        if (mSubRatings == null) {
+            return null;
+        }
+        return Collections.unmodifiableList(Arrays.asList(mSubRatings));
+    }
+
+    /**
+     * Returns a string that unambiguously describes the rating information contained in a
+     * {@code TvContentRating} object. One can later recover the object from this string through
+     * {@link #unflattenFromString}.
+     *
+     * @return a string containing the rating information, which can later be stored in the
+     *         database.
+     * @see #unflattenFromString
+     */
+    public String flattenToString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append(mDomain);
+        builder.append(DELIMITER);
+        builder.append(mRatingSystem);
+        builder.append(DELIMITER);
+        builder.append(mRating);
+        if (mSubRatings != null) {
+            for (String subRating : mSubRatings) {
+                builder.append(DELIMITER);
+                builder.append(subRating);
+            }
+        }
+        return builder.toString();
+    }
+
+    /**
+     * Returns {@code true} if this rating has the same main rating as the specified rating and when
+     * this rating's sub-ratings contain the other's.
+     *
+     * <p>For example, a {@code TvContentRating} object that represents TV-PG with
+     * S(Sexual content) and V(Violence) contains TV-PG, TV-PG/S, TV-PG/V and itself.
+     *
+     * @param rating The {@link TvContentRating} to check.
+     * @return {@code true} if this object contains {@code rating}, {@code false} otherwise.
+     */
+    public final boolean contains(@NonNull TvContentRating rating) {
+        Preconditions.checkNotNull(rating);
+        if (!rating.getMainRating().equals(mRating)) {
+            return false;
+        }
+        if (!rating.getDomain().equals(mDomain) ||
+                !rating.getRatingSystem().equals(mRatingSystem) ||
+                !rating.getMainRating().equals(mRating)) {
+            return false;
+        }
+        List<String> subRatings = getSubRatings();
+        List<String> subRatingsOther = rating.getSubRatings();
+        if (subRatings == null && subRatingsOther == null) {
+            return true;
+        } else if (subRatings == null && subRatingsOther != null) {
+            return false;
+        } else if (subRatings != null && subRatingsOther == null) {
+            return true;
+        } else {
+            return subRatings.containsAll(subRatingsOther);
+        }
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (!(obj instanceof TvContentRating)) {
+            return false;
+        }
+        TvContentRating other = (TvContentRating) obj;
+        if (mHashCode != other.mHashCode) {
+            return false;
+        }
+        if (!TextUtils.equals(mDomain, other.mDomain)) {
+            return false;
+        }
+        if (!TextUtils.equals(mRatingSystem, other.mRatingSystem)) {
+            return false;
+        }
+        if (!TextUtils.equals(mRating, other.mRating)) {
+            return false;
+        }
+        return Arrays.equals(mSubRatings, other.mSubRatings);
+    }
+
+    @Override
+    public int hashCode() {
+        return mHashCode;
+    }
+}
diff --git a/android/media/tv/TvContentRatingSystemInfo.java b/android/media/tv/TvContentRatingSystemInfo.java
new file mode 100644
index 0000000..f44ded3
--- /dev/null
+++ b/android/media/tv/TvContentRatingSystemInfo.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2014 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.tv;
+
+import android.annotation.SystemApi;
+import android.content.ContentResolver;
+import android.content.pm.ApplicationInfo;
+import android.net.Uri;
+import android.os.Parcel;
+import android.os.Parcelable;
+
+/**
+ * TvContentRatingSystemInfo class provides information about a specific TV content rating system
+ * defined either by a system app or by a third-party app.
+ *
+ * @hide
+ */
+@SystemApi
+public final class TvContentRatingSystemInfo implements Parcelable {
+    private final Uri mXmlUri;
+
+    private final ApplicationInfo mApplicationInfo;
+
+    /**
+     * Creates a TvContentRatingSystemInfo object with given resource ID and receiver info.
+     *
+     * @param xmlResourceId The ID of an XML resource whose root element is
+     *            <code> &lt;rating-system-definitions&gt;</code>
+     * @param applicationInfo Information about the application that provides the TV content rating
+     *            system definition.
+     */
+    public static final TvContentRatingSystemInfo createTvContentRatingSystemInfo(int xmlResourceId,
+            ApplicationInfo applicationInfo) {
+        Uri uri = new Uri.Builder()
+                .scheme(ContentResolver.SCHEME_ANDROID_RESOURCE)
+                .authority(applicationInfo.packageName)
+                .appendPath(String.valueOf(xmlResourceId))
+                .build();
+        return new TvContentRatingSystemInfo(uri, applicationInfo);
+    }
+
+    private TvContentRatingSystemInfo(Uri xmlUri, ApplicationInfo applicationInfo) {
+        mXmlUri = xmlUri;
+        mApplicationInfo = applicationInfo;
+    }
+
+    /**
+     * Returns {@code true} if the TV content rating system is defined by a system app,
+     * {@code false} otherwise.
+     */
+    public final boolean isSystemDefined() {
+        return (mApplicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+    }
+
+    /**
+     * Returns the URI to the XML resource that defines the TV content rating system.
+     *
+     * TODO: Remove. Instead, parse the XML resource and provide an interface to directly access
+     * parsed information.
+     */
+    public final Uri getXmlUri() {
+        return mXmlUri;
+    }
+
+    /**
+     * Used to make this class parcelable.
+     * @hide
+     */
+    public static final @android.annotation.NonNull Parcelable.Creator<TvContentRatingSystemInfo> CREATOR =
+            new Parcelable.Creator<TvContentRatingSystemInfo>() {
+        @Override
+        public TvContentRatingSystemInfo createFromParcel(Parcel in) {
+            return new TvContentRatingSystemInfo(in);
+        }
+
+        @Override
+        public TvContentRatingSystemInfo[] newArray(int size) {
+            return new TvContentRatingSystemInfo[size];
+        }
+    };
+
+    private TvContentRatingSystemInfo(Parcel in) {
+        mXmlUri = in.readParcelable(null);
+        mApplicationInfo = in.readParcelable(null);
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeParcelable(mXmlUri, flags);
+        dest.writeParcelable(mApplicationInfo, flags);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+}
diff --git a/android/media/tv/TvContract.java b/android/media/tv/TvContract.java
new file mode 100644
index 0000000..30a14c8
--- /dev/null
+++ b/android/media/tv/TvContract.java
@@ -0,0 +1,3300 @@
+/*
+ * Copyright (C) 2014 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.tv;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SdkConstant;
+import android.annotation.SdkConstant.SdkConstantType;
+import android.annotation.StringDef;
+import android.annotation.SystemApi;
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.provider.BaseColumns;
+import android.text.TextUtils;
+import android.util.ArraySet;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * The contract between the TV provider and applications. Contains definitions for the supported
+ * URIs and columns.
+ * <h3>Overview</h3>
+ *
+ * <p>TvContract defines a basic database of TV content metadata such as channel and program
+ * information. The information is stored in {@link Channels} and {@link Programs} tables.
+ *
+ * <ul>
+ *     <li>A row in the {@link Channels} table represents information about a TV channel. The data
+ *         format can vary greatly from standard to standard or according to service provider, thus
+ *         the columns here are mostly comprised of basic entities that are usually seen to users
+ *         regardless of standard such as channel number and name.</li>
+ *     <li>A row in the {@link Programs} table represents a set of data describing a TV program such
+ *         as program title and start time.</li>
+ * </ul>
+ */
+public final class TvContract {
+    /** The authority for the TV provider. */
+    public static final String AUTHORITY = "android.media.tv";
+
+    /**
+     * Permission to read TV listings. This is required to read all the TV channel and program
+     * information available on the system.
+     * @hide
+     */
+    public static final String PERMISSION_READ_TV_LISTINGS = "android.permission.READ_TV_LISTINGS";
+
+    private static final String PATH_CHANNEL = "channel";
+    private static final String PATH_PROGRAM = "program";
+    private static final String PATH_RECORDED_PROGRAM = "recorded_program";
+    private static final String PATH_PREVIEW_PROGRAM = "preview_program";
+    private static final String PATH_WATCH_NEXT_PROGRAM = "watch_next_program";
+    private static final String PATH_PASSTHROUGH = "passthrough";
+
+    /**
+     * Broadcast Action: sent when an application requests the system to make the given channel
+     * browsable.  The operation is performed in the background without user interaction. This
+     * is only relevant to channels with {@link Channels#TYPE_PREVIEW} type.
+     *
+     * <p>The intent must contain the following bundle parameters:
+     * <ul>
+     *     <li>{@link #EXTRA_CHANNEL_ID}: ID for the {@link Channels#TYPE_PREVIEW} channel as a long
+     *     integer.</li>
+     *     <li>{@link #EXTRA_PACKAGE_NAME}: the package name of the requesting application.</li>
+     * </ul>
+     * @hide
+     */
+    @SystemApi
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_CHANNEL_BROWSABLE_REQUESTED =
+            "android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED";
+
+    /**
+     * Activity Action: sent by an application telling the system to make the given channel
+     * browsable with user interaction. The system may show UI to ask user to approve the channel.
+     * This is only relevant to channels with {@link Channels#TYPE_PREVIEW} type. Use
+     * {@link Activity#startActivityForResult} to get the result of the request.
+     *
+     * <p>The intent must contain the following bundle parameters:
+     * <ul>
+     *     <li>{@link #EXTRA_CHANNEL_ID}: ID for the {@link Channels#TYPE_PREVIEW} channel as a long
+     *     integer.</li>
+     * </ul>
+     */
+    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+    public static final String ACTION_REQUEST_CHANNEL_BROWSABLE =
+            "android.media.tv.action.REQUEST_CHANNEL_BROWSABLE";
+
+    /**
+     * Broadcast Action: sent by the system to tell the target TV input that one of its preview
+     * program's browsable state is disabled, i.e., it will no longer be shown to users, which, for
+     * example, might be a result of users' interaction with UI. The input is expected to delete the
+     * preview program from the content provider.
+     *
+     * <p>The intent must contain the following bundle parameter:
+     * <ul>
+     *     <li>{@link #EXTRA_PREVIEW_PROGRAM_ID}: the disabled preview program ID.</li>
+     * </ul>
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED =
+            "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED";
+
+    /**
+     * Broadcast Action: sent by the system to tell the target TV input that one of its "watch next"
+     * program's browsable state is disabled, i.e., it will no longer be shown to users, which, for
+     * example, might be a result of users' interaction with UI. The input is expected to delete the
+     * "watch next" program from the content provider.
+     *
+     * <p>The intent must contain the following bundle parameter:
+     * <ul>
+     *     <li>{@link #EXTRA_WATCH_NEXT_PROGRAM_ID}: the disabled "watch next" program ID.</li>
+     * </ul>
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED =
+            "android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED";
+
+    /**
+     * Broadcast Action: sent by the system to tell the target TV input that one of its existing
+     * preview programs is added to the watch next programs table by user.
+     *
+     * <p>The intent must contain the following bundle parameters:
+     * <ul>
+     *     <li>{@link #EXTRA_PREVIEW_PROGRAM_ID}: the ID of the existing preview program.</li>
+     *     <li>{@link #EXTRA_WATCH_NEXT_PROGRAM_ID}: the ID of the new watch next program.</li>
+     * </ul>
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT =
+            "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT";
+
+    /**
+     * Broadcast Action: sent to the target TV input after it is first installed to notify the input
+     * to initialize its channels and programs to the system content provider.
+     *
+     * <p>Note that this intent is sent only on devices with
+     * {@link android.content.pm.PackageManager#FEATURE_LEANBACK} enabled. Besides that, in order
+     * to receive this intent, the target TV input must:
+     * <ul>
+     *     <li>Declare a broadcast receiver for this intent in its
+     *         <code>AndroidManifest.xml</code>.</li>
+     *     <li>Declare appropriate permissions to write channel and program data in its
+     *         <code>AndroidManifest.xml</code>.</li>
+     * </ul>
+     */
+    @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
+    public static final String ACTION_INITIALIZE_PROGRAMS =
+            "android.media.tv.action.INITIALIZE_PROGRAMS";
+
+    /**
+     * The key for a bundle parameter containing a channel ID as a long integer
+     */
+    public static final String EXTRA_CHANNEL_ID = "android.media.tv.extra.CHANNEL_ID";
+
+    /**
+     * The key for a bundle parameter containing a package name as a string.
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_PACKAGE_NAME = "android.media.tv.extra.PACKAGE_NAME";
+
+    /** The key for a bundle parameter containing a program ID as a long integer. */
+    public static final String EXTRA_PREVIEW_PROGRAM_ID =
+            "android.media.tv.extra.PREVIEW_PROGRAM_ID";
+
+    /** The key for a bundle parameter containing a watch next program ID as a long integer. */
+    public static final String EXTRA_WATCH_NEXT_PROGRAM_ID =
+            "android.media.tv.extra.WATCH_NEXT_PROGRAM_ID";
+
+    /**
+     * The key for a bundle parameter containing the result code of a method call as an integer.
+     *
+     * @see #RESULT_OK
+     * @see #RESULT_ERROR_IO
+     * @see #RESULT_ERROR_INVALID_ARGUMENT
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_RESULT_CODE = "android.media.tv.extra.RESULT_CODE";
+
+    /**
+     * The result code for a successful execution without error.
+     * @hide
+     */
+    @SystemApi
+    public static final int RESULT_OK = 0;
+
+    /**
+     * The result code for a failure from I/O operation.
+     * @hide
+     */
+    @SystemApi
+    public static final int RESULT_ERROR_IO = 1;
+
+    /**
+     * The result code for a failure from invalid argument.
+     * @hide
+     */
+    @SystemApi
+    public static final int RESULT_ERROR_INVALID_ARGUMENT = 2;
+
+    /**
+     * The method name to get existing columns in the given table of the specified content provider.
+     *
+     * <p>The method caller must provide the following parameter:
+     * <ul>
+     *     <li>{@code arg}: The content URI of the target table as a {@link String}.</li>
+     * </ul>
+
+     * <p>On success, the returned {@link android.os.Bundle} will include existing column names
+     * with the key {@link #EXTRA_EXISTING_COLUMN_NAMES}. Otherwise, the return value will be {@code null}.
+     *
+     * @see ContentResolver#call(Uri, String, String, Bundle)
+     * @see #EXTRA_EXISTING_COLUMN_NAMES
+     * @hide
+     */
+    @SystemApi
+    public static final String METHOD_GET_COLUMNS = "get_columns";
+
+    /**
+     * The method name to add a new column in the given table of the specified content provider.
+     *
+     * <p>The method caller must provide the following parameter:
+     * <ul>
+     *     <li>{@code arg}: The content URI of the target table as a {@link String}.</li>
+     *     <li>{@code extra}: Name, data type, and default value of the new column in a Bundle:
+     *         <ul>
+     *             <li>{@link #EXTRA_COLUMN_NAME} the column name as a {@link String}.</li>
+     *             <li>{@link #EXTRA_DATA_TYPE} the data type as a {@link String}.</li>
+     *             <li>{@link #EXTRA_DEFAULT_VALUE} the default value as a {@link String}.
+     *                 (optional)</li>
+     *         </ul>
+     *     </li>
+     * </ul>
+     *
+     * <p>On success, the returned {@link android.os.Bundle} will include current colum names after
+     * the addition operation with the key {@link #EXTRA_EXISTING_COLUMN_NAMES}. Otherwise, the
+     * return value will be {@code null}.
+     *
+     * @see ContentResolver#call(Uri, String, String, Bundle)
+     * @see #EXTRA_COLUMN_NAME
+     * @see #EXTRA_DATA_TYPE
+     * @see #EXTRA_DEFAULT_VALUE
+     * @see #EXTRA_EXISTING_COLUMN_NAMES
+     * @hide
+     */
+    @SystemApi
+    public static final String METHOD_ADD_COLUMN = "add_column";
+
+    /**
+     * The method name to get all the blocked packages. When a package is blocked, all the data for
+     * preview programs/channels and watch next programs belonging to this package in the content
+     * provider will be cleared. Once a package is blocked, {@link SecurityException} will be thrown
+     * for all the requests to preview programs/channels and watch next programs via
+     * {@link android.content.ContentProvider} from it.
+     *
+     * <p>The returned {@link android.os.Bundle} will include all the blocked package names with the
+     * key {@link #EXTRA_BLOCKED_PACKAGES}.
+     *
+     * @see ContentResolver#call(Uri, String, String, Bundle)
+     * @see #EXTRA_BLOCKED_PACKAGES
+     * @see #METHOD_BLOCK_PACKAGE
+     * @see #METHOD_UNBLOCK_PACKAGE
+     * @hide
+     */
+    @SystemApi
+    public static final String METHOD_GET_BLOCKED_PACKAGES = "get_blocked_packages";
+
+    /**
+     * The method name to block the access from the given package. When a package is blocked, all
+     * the data for preview programs/channels and watch next programs belonging to this package in
+     * the content provider will be cleared. Once a package is blocked, {@link SecurityException}
+     * will be thrown for all the requests to preview programs/channels and watch next programs via
+     * {@link android.content.ContentProvider} from it.
+     *
+     * <p>The method caller must provide the following parameter:
+     * <ul>
+     *     <li>{@code arg}: The package name to be added as blocked package {@link String}.</li>
+     * </ul>
+     *
+     * <p>The returned {@link android.os.Bundle} will include an integer code denoting whether the
+     * execution is successful or not with the key {@link #EXTRA_RESULT_CODE}. If {@code arg} is
+     * empty, the result code will be {@link #RESULT_ERROR_INVALID_ARGUMENT}. If success, the result
+     * code will be {@link #RESULT_OK}. Otherwise, the result code will be {@link #RESULT_ERROR_IO}.
+     *
+     * @see ContentResolver#call(Uri, String, String, Bundle)
+     * @see #EXTRA_RESULT_CODE
+     * @see #METHOD_GET_BLOCKED_PACKAGES
+     * @see #METHOD_UNBLOCK_PACKAGE
+     * @hide
+     */
+    @SystemApi
+    public static final String METHOD_BLOCK_PACKAGE = "block_package";
+
+    /**
+     * The method name to unblock the access from the given package. When a package is blocked, all
+     * the data for preview programs/channels and watch next programs belonging to this package in
+     * the content provider will be cleared. Once a package is blocked, {@link SecurityException}
+     * will be thrown for all the requests to preview programs/channels and watch next programs via
+     * {@link android.content.ContentProvider} from it.
+     *
+     * <p>The method caller must provide the following parameter:
+     * <ul>
+     *     <li>{@code arg}: The package name to be removed from blocked list as a {@link String}.
+     *     </li>
+     * </ul>
+     *
+     * <p>The returned {@link android.os.Bundle} will include an integer code denoting whether the
+     * execution is successful or not with the key {@link #EXTRA_RESULT_CODE}. If {@code arg} is
+     * empty, the result code will be {@link #RESULT_ERROR_INVALID_ARGUMENT}. If success, the result
+     * code will be {@link #RESULT_OK}. Otherwise, the result code will be {@link #RESULT_ERROR_IO}.
+     *
+     * @see ContentResolver#call(Uri, String, String, Bundle)
+     * @see #EXTRA_RESULT_CODE
+     * @see #METHOD_GET_BLOCKED_PACKAGES
+     * @see #METHOD_BLOCK_PACKAGE
+     * @hide
+     */
+    @SystemApi
+    public static final String METHOD_UNBLOCK_PACKAGE = "unblock_package";
+
+    /**
+     * The key for a returned {@link Bundle} value containing existing column names in the given
+     * table as an {@link ArrayList} of {@link String}.
+     *
+     * @see #METHOD_GET_COLUMNS
+     * @see #METHOD_ADD_COLUMN
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_EXISTING_COLUMN_NAMES =
+            "android.media.tv.extra.EXISTING_COLUMN_NAMES";
+
+    /**
+     * The key for a {@link Bundle} parameter containing the new column name to be added in the
+     * given table as a non-empty {@link CharSequence}.
+     *
+     * @see #METHOD_ADD_COLUMN
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_COLUMN_NAME = "android.media.tv.extra.COLUMN_NAME";
+
+    /**
+     * The key for a {@link Bundle} parameter containing the data type of the new column to be added
+     * in the given table as a non-empty {@link CharSequence}, which should be one of the following
+     * values: {@code "TEXT"}, {@code "INTEGER"}, {@code "REAL"}, or {@code "BLOB"}.
+     *
+     * @see #METHOD_ADD_COLUMN
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_DATA_TYPE = "android.media.tv.extra.DATA_TYPE";
+
+    /**
+     * The key for a {@link Bundle} parameter containing the default value of the new column to be
+     * added in the given table as a {@link CharSequence}, which represents a valid default value
+     * according to the data type provided with {@link #EXTRA_DATA_TYPE}.
+     *
+     * @see #METHOD_ADD_COLUMN
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_DEFAULT_VALUE = "android.media.tv.extra.DEFAULT_VALUE";
+
+    /**
+     * The key for a returned {@link Bundle} value containing all the blocked package names as an
+     * {@link ArrayList} of {@link String}.
+     *
+     * @see #METHOD_GET_BLOCKED_PACKAGES
+     * @hide
+     */
+    @SystemApi
+    public static final String EXTRA_BLOCKED_PACKAGES = "android.media.tv.extra.BLOCKED_PACKAGES";
+
+    /**
+     * An optional query, update or delete URI parameter that allows the caller to specify TV input
+     * ID to filter channels.
+     * @hide
+     */
+    public static final String PARAM_INPUT = "input";
+
+    /**
+     * An optional query, update or delete URI parameter that allows the caller to specify channel
+     * ID to filter programs.
+     * @hide
+     */
+    public static final String PARAM_CHANNEL = "channel";
+
+    /**
+     * An optional query, update or delete URI parameter that allows the caller to specify start
+     * time (in milliseconds since the epoch) to filter programs.
+     * @hide
+     */
+    public static final String PARAM_START_TIME = "start_time";
+
+    /**
+     * An optional query, update or delete URI parameter that allows the caller to specify end time
+     * (in milliseconds since the epoch) to filter programs.
+     * @hide
+     */
+    public static final String PARAM_END_TIME = "end_time";
+
+    /**
+     * A query, update or delete URI parameter that allows the caller to operate on all or
+     * browsable-only channels. If set to "true", the rows that contain non-browsable channels are
+     * not affected.
+     * @hide
+     */
+    public static final String PARAM_BROWSABLE_ONLY = "browsable_only";
+
+    /**
+     * An optional query, update or delete URI parameter that allows the caller to specify canonical
+     * genre to filter programs.
+     * @hide
+     */
+    public static final String PARAM_CANONICAL_GENRE = "canonical_genre";
+
+    /**
+     * A query, update or delete URI parameter that allows the caller to operate only on preview or
+     * non-preview channels. If set to "true", the operation affects the rows for preview channels
+     * only. If set to "false", the operation affects the rows for non-preview channels only.
+     * @hide
+     */
+    public static final String PARAM_PREVIEW = "preview";
+
+    /**
+     * An optional query, update or delete URI parameter that allows the caller to specify package
+     * name to filter channels.
+     * @hide
+     */
+    public static final String PARAM_PACKAGE = "package";
+
+    /**
+     * Builds an ID that uniquely identifies a TV input service.
+     *
+     * @param name The {@link ComponentName} of the TV input service to build ID for.
+     * @return the ID for the given TV input service.
+     */
+    public static String buildInputId(ComponentName name) {
+        return name.flattenToShortString();
+    }
+
+    /**
+     * Builds a URI that points to a specific channel.
+     *
+     * @param channelId The ID of the channel to point to.
+     */
+    public static Uri buildChannelUri(long channelId) {
+        return ContentUris.withAppendedId(Channels.CONTENT_URI, channelId);
+    }
+
+    /**
+     * Build a special channel URI intended to be used with pass-through inputs. (e.g. HDMI)
+     *
+     * @param inputId The ID of the pass-through input to build a channels URI for.
+     * @see TvInputInfo#isPassthroughInput()
+     */
+    public static Uri buildChannelUriForPassthroughInput(String inputId) {
+        return new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT).authority(AUTHORITY)
+                .appendPath(PATH_PASSTHROUGH).appendPath(inputId).build();
+    }
+
+    /**
+     * Builds a URI that points to a channel logo. See {@link Channels.Logo}.
+     *
+     * @param channelId The ID of the channel whose logo is pointed to.
+     */
+    public static Uri buildChannelLogoUri(long channelId) {
+        return buildChannelLogoUri(buildChannelUri(channelId));
+    }
+
+    /**
+     * Builds a URI that points to a channel logo. See {@link Channels.Logo}.
+     *
+     * @param channelUri The URI of the channel whose logo is pointed to.
+     */
+    public static Uri buildChannelLogoUri(Uri channelUri) {
+        if (!isChannelUriForTunerInput(channelUri)) {
+            throw new IllegalArgumentException("Not a channel: " + channelUri);
+        }
+        return Uri.withAppendedPath(channelUri, Channels.Logo.CONTENT_DIRECTORY);
+    }
+
+    /**
+     * Builds a URI that points to all channels from a given TV input.
+     *
+     * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a
+     *            URI for all the TV inputs.
+     */
+    public static Uri buildChannelsUriForInput(@Nullable String inputId) {
+        return buildChannelsUriForInput(inputId, false);
+    }
+
+    /**
+     * Builds a URI that points to all or browsable-only channels from a given TV input.
+     *
+     * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a
+     *            URI for all the TV inputs.
+     * @param browsableOnly If set to {@code true} the URI points to only browsable channels. If set
+     *            to {@code false} the URI points to all channels regardless of whether they are
+     *            browsable or not.
+     * @hide
+     */
+    @SystemApi
+    public static Uri buildChannelsUriForInput(@Nullable String inputId,
+            boolean browsableOnly) {
+        Uri.Builder builder = Channels.CONTENT_URI.buildUpon();
+        if (inputId != null) {
+            builder.appendQueryParameter(PARAM_INPUT, inputId);
+        }
+        return builder.appendQueryParameter(PARAM_BROWSABLE_ONLY, String.valueOf(browsableOnly))
+                .build();
+    }
+
+    /**
+     * Builds a URI that points to all or browsable-only channels which have programs with the given
+     * genre from the given TV input.
+     *
+     * @param inputId The ID of the TV input to build a channels URI for. If {@code null}, builds a
+     *            URI for all the TV inputs.
+     * @param genre {@link Programs.Genres} to search. If {@code null}, builds a URI for all genres.
+     * @param browsableOnly If set to {@code true} the URI points to only browsable channels. If set
+     *            to {@code false} the URI points to all channels regardless of whether they are
+     *            browsable or not.
+     * @hide
+     */
+    @SystemApi
+    public static Uri buildChannelsUriForInput(@Nullable String inputId,
+            @Nullable String genre, boolean browsableOnly) {
+        if (genre == null) {
+            return buildChannelsUriForInput(inputId, browsableOnly);
+        }
+        if (!Programs.Genres.isCanonical(genre)) {
+            throw new IllegalArgumentException("Not a canonical genre: '" + genre + "'");
+        }
+        return buildChannelsUriForInput(inputId, browsableOnly).buildUpon()
+                .appendQueryParameter(PARAM_CANONICAL_GENRE, genre).build();
+    }
+
+    /**
+     * Builds a URI that points to a specific program.
+     *
+     * @param programId The ID of the program to point to.
+     */
+    public static Uri buildProgramUri(long programId) {
+        return ContentUris.withAppendedId(Programs.CONTENT_URI, programId);
+    }
+
+    /**
+     * Builds a URI that points to all programs on a given channel.
+     *
+     * @param channelId The ID of the channel to return programs for.
+     */
+    public static Uri buildProgramsUriForChannel(long channelId) {
+        return Programs.CONTENT_URI.buildUpon()
+                .appendQueryParameter(PARAM_CHANNEL, String.valueOf(channelId)).build();
+    }
+
+    /**
+     * Builds a URI that points to all programs on a given channel.
+     *
+     * @param channelUri The URI of the channel to return programs for.
+     */
+    public static Uri buildProgramsUriForChannel(Uri channelUri) {
+        if (!isChannelUriForTunerInput(channelUri)) {
+            throw new IllegalArgumentException("Not a channel: " + channelUri);
+        }
+        return buildProgramsUriForChannel(ContentUris.parseId(channelUri));
+    }
+
+    /**
+     * Builds a URI that points to programs on a specific channel whose schedules overlap with the
+     * given time frame.
+     *
+     * @param channelId The ID of the channel to return programs for.
+     * @param startTime The start time used to filter programs. The returned programs will have a
+     *            {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than or equal to
+                  {@code startTime}.
+     * @param endTime The end time used to filter programs. The returned programs will have
+     *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than or equal to
+     *            {@code endTime}.
+     */
+    public static Uri buildProgramsUriForChannel(long channelId, long startTime,
+            long endTime) {
+        Uri uri = buildProgramsUriForChannel(channelId);
+        return uri.buildUpon().appendQueryParameter(PARAM_START_TIME, String.valueOf(startTime))
+                .appendQueryParameter(PARAM_END_TIME, String.valueOf(endTime)).build();
+    }
+
+    /**
+     * Builds a URI that points to programs on a specific channel whose schedules overlap with the
+     * given time frame.
+     *
+     * @param channelUri The URI of the channel to return programs for.
+     * @param startTime The start time used to filter programs. The returned programs should have
+     *            {@link Programs#COLUMN_END_TIME_UTC_MILLIS} that is greater than this time.
+     * @param endTime The end time used to filter programs. The returned programs should have
+     *            {@link Programs#COLUMN_START_TIME_UTC_MILLIS} that is less than this time.
+     */
+    public static Uri buildProgramsUriForChannel(Uri channelUri, long startTime,
+            long endTime) {
+        if (!isChannelUriForTunerInput(channelUri)) {
+            throw new IllegalArgumentException("Not a channel: " + channelUri);
+        }
+        return buildProgramsUriForChannel(ContentUris.parseId(channelUri), startTime, endTime);
+    }
+
+    /**
+     * Builds a URI that points to a specific recorded program.
+     *
+     * @param recordedProgramId The ID of the recorded program to point to.
+     */
+    public static Uri buildRecordedProgramUri(long recordedProgramId) {
+        return ContentUris.withAppendedId(RecordedPrograms.CONTENT_URI, recordedProgramId);
+    }
+
+    /**
+     * Builds a URI that points to a specific preview program.
+     *
+     * @param previewProgramId The ID of the preview program to point to.
+     */
+    public static Uri buildPreviewProgramUri(long previewProgramId) {
+        return ContentUris.withAppendedId(PreviewPrograms.CONTENT_URI, previewProgramId);
+    }
+
+    /**
+     * Builds a URI that points to all preview programs on a given channel.
+     *
+     * @param channelId The ID of the channel to return preview programs for.
+     */
+    public static Uri buildPreviewProgramsUriForChannel(long channelId) {
+        return PreviewPrograms.CONTENT_URI.buildUpon()
+                .appendQueryParameter(PARAM_CHANNEL, String.valueOf(channelId)).build();
+    }
+
+    /**
+     * Builds a URI that points to all preview programs on a given channel.
+     *
+     * @param channelUri The URI of the channel to return preview programs for.
+     */
+    public static Uri buildPreviewProgramsUriForChannel(Uri channelUri) {
+        if (!isChannelUriForTunerInput(channelUri)) {
+            throw new IllegalArgumentException("Not a channel: " + channelUri);
+        }
+        return buildPreviewProgramsUriForChannel(ContentUris.parseId(channelUri));
+    }
+
+    /**
+     * Builds a URI that points to a specific watch next program.
+     *
+     * @param watchNextProgramId The ID of the watch next program to point to.
+     */
+    public static Uri buildWatchNextProgramUri(long watchNextProgramId) {
+        return ContentUris.withAppendedId(WatchNextPrograms.CONTENT_URI, watchNextProgramId);
+    }
+
+    /**
+     * Builds a URI that points to a specific program the user watched.
+     *
+     * @param watchedProgramId The ID of the watched program to point to.
+     * @hide
+     */
+    public static Uri buildWatchedProgramUri(long watchedProgramId) {
+        return ContentUris.withAppendedId(WatchedPrograms.CONTENT_URI, watchedProgramId);
+    }
+
+    private static boolean isTvUri(Uri uri) {
+        return uri != null && ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())
+                && AUTHORITY.equals(uri.getAuthority());
+    }
+
+    private static boolean isTwoSegmentUriStartingWith(Uri uri, String pathSegment) {
+        List<String> pathSegments = uri.getPathSegments();
+        return pathSegments.size() == 2 && pathSegment.equals(pathSegments.get(0));
+    }
+
+    /**
+     * @return {@code true} if {@code uri} is a channel URI.
+     */
+    public static boolean isChannelUri(@NonNull Uri uri) {
+        return isChannelUriForTunerInput(uri) || isChannelUriForPassthroughInput(uri);
+    }
+
+    /**
+     * @return {@code true} if {@code uri} is a channel URI for a tuner input.
+     */
+    public static boolean isChannelUriForTunerInput(@NonNull Uri uri) {
+        return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_CHANNEL);
+    }
+
+    /**
+     * @return {@code true} if {@code uri} is a channel URI for a pass-through input.
+     */
+    public static boolean isChannelUriForPassthroughInput(@NonNull Uri uri) {
+        return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PASSTHROUGH);
+    }
+
+    /**
+     * @return {@code true} if {@code uri} is a program URI.
+     */
+    public static boolean isProgramUri(@NonNull Uri uri) {
+        return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_PROGRAM);
+    }
+
+    /**
+     * @return {@code true} if {@code uri} is a recorded program URI.
+     */
+    public static boolean isRecordedProgramUri(@NonNull Uri uri) {
+        return isTvUri(uri) && isTwoSegmentUriStartingWith(uri, PATH_RECORDED_PROGRAM);
+    }
+
+    /**
+     * Requests to make a channel browsable.
+     *
+     * <p>Once called, the system will review the request and make the channel browsable based on
+     * its policy. The first request from a package is guaranteed to be approved. This is only
+     * relevant to channels with {@link Channels#TYPE_PREVIEW} type.
+     *
+     * @param context The context for accessing content provider.
+     * @param channelId The channel ID to be browsable.
+     * @see Channels#COLUMN_BROWSABLE
+     */
+    public static void requestChannelBrowsable(Context context, long channelId) {
+        TvInputManager manager = (TvInputManager) context.getSystemService(
+            Context.TV_INPUT_SERVICE);
+        if (manager != null) {
+            manager.requestChannelBrowsable(buildChannelUri(channelId));
+        }
+    }
+
+    private TvContract() {}
+
+    /**
+     * Common base for the tables of TV channels/programs.
+     */
+    public interface BaseTvColumns extends BaseColumns {
+        /**
+         * The name of the package that owns the current row.
+         *
+         * <p>The TV provider fills in this column with the name of the package that provides the
+         * initial data of the row. If the package is later uninstalled, the rows it owns are
+         * automatically removed from the tables.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_PACKAGE_NAME = "package_name";
+    }
+
+    /**
+     * Common columns for the tables of TV programs.
+     * @hide
+     */
+    interface ProgramColumns {
+        /** @hide */
+        @IntDef({
+                REVIEW_RATING_STYLE_STARS,
+                REVIEW_RATING_STYLE_THUMBS_UP_DOWN,
+                REVIEW_RATING_STYLE_PERCENTAGE,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        @interface ReviewRatingStyle {}
+
+        /**
+         * The review rating style for five star rating.
+         *
+         * @see #COLUMN_REVIEW_RATING_STYLE
+         */
+        int REVIEW_RATING_STYLE_STARS = 0;
+
+        /**
+         * The review rating style for thumbs-up and thumbs-down rating.
+         *
+         * @see #COLUMN_REVIEW_RATING_STYLE
+         */
+        int REVIEW_RATING_STYLE_THUMBS_UP_DOWN = 1;
+
+        /**
+         * The review rating style for 0 to 100 point system.
+         *
+         * @see #COLUMN_REVIEW_RATING_STYLE
+         */
+        int REVIEW_RATING_STYLE_PERCENTAGE = 2;
+
+        /**
+         * The title of this TV program.
+         *
+         * <p>If this program is an episodic TV show, it is recommended that the title is the series
+         * title and its related fields ({@link #COLUMN_SEASON_TITLE} and/or
+         * {@link #COLUMN_SEASON_DISPLAY_NUMBER}, {@link #COLUMN_SEASON_DISPLAY_NUMBER},
+         * {@link #COLUMN_EPISODE_DISPLAY_NUMBER}, and {@link #COLUMN_EPISODE_TITLE}) are filled in.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_TITLE = "title";
+
+        /**
+         * The season display number of this TV program for episodic TV shows.
+         *
+         * <p>This is used to indicate the season number. (e.g. 1, 2 or 3) Note that the value
+         * does not necessarily be numeric. (e.g. 12B)
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_SEASON_DISPLAY_NUMBER = "season_display_number";
+
+        /**
+         * The title of the season for this TV program for episodic TV shows.
+         *
+         * <p>This is an optional field supplied only when the season has a special title
+         * (e.g. The Final Season). If provided, the applications should display it instead of
+         * {@link #COLUMN_SEASON_DISPLAY_NUMBER}, and should display it without alterations.
+         * (e.g. for "The Final Season", displayed string should be "The Final Season", not
+         * "Season The Final Season"). When displaying multiple programs, the order should be based
+         * on {@link #COLUMN_SEASON_DISPLAY_NUMBER}, even when {@link #COLUMN_SEASON_TITLE} exists.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_SEASON_TITLE = "season_title";
+
+        /**
+         * The episode display number of this TV program for episodic TV shows.
+         *
+         * <p>This is used to indicate the episode number. (e.g. 1, 2 or 3) Note that the value
+         * does not necessarily be numeric. (e.g. 12B)
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_EPISODE_DISPLAY_NUMBER = "episode_display_number";
+
+        /**
+         * The episode title of this TV program for episodic TV shows.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_EPISODE_TITLE = "episode_title";
+
+        /**
+         * The comma-separated canonical genre string of this TV program.
+         *
+         * <p>Canonical genres are defined in {@link Genres}. Use {@link Genres#encode} to create a
+         * text that can be stored in this column. Use {@link Genres#decode} to get the canonical
+         * genre strings from the text stored in the column.
+         *
+         * <p>Type: TEXT
+         * @see Genres
+         * @see Genres#encode
+         * @see Genres#decode
+         */
+        String COLUMN_CANONICAL_GENRE = "canonical_genre";
+
+        /**
+         * The short description of this TV program that is displayed to the user by default.
+         *
+         * <p>It is recommended to limit the length of the descriptions to 256 characters.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_SHORT_DESCRIPTION = "short_description";
+
+        /**
+         * The detailed, lengthy description of this TV program that is displayed only when the user
+         * wants to see more information.
+         *
+         * <p>TV input services should leave this field empty if they have no additional details
+         * beyond {@link #COLUMN_SHORT_DESCRIPTION}.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_LONG_DESCRIPTION = "long_description";
+
+        /**
+         * The width of the video for this TV program, in the unit of pixels.
+         *
+         * <p>Together with {@link #COLUMN_VIDEO_HEIGHT} this is used to determine the video
+         * resolution of the current TV program. Can be empty if it is not known initially or the
+         * program does not convey any video such as the programs from type
+         * {@link Channels#SERVICE_TYPE_AUDIO} channels.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_VIDEO_WIDTH = "video_width";
+
+        /**
+         * The height of the video for this TV program, in the unit of pixels.
+         *
+         * <p>Together with {@link #COLUMN_VIDEO_WIDTH} this is used to determine the video
+         * resolution of the current TV program. Can be empty if it is not known initially or the
+         * program does not convey any video such as the programs from type
+         * {@link Channels#SERVICE_TYPE_AUDIO} channels.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_VIDEO_HEIGHT = "video_height";
+
+        /**
+         * The comma-separated audio languages of this TV program.
+         *
+         * <p>This is used to describe available audio languages included in the program. Use either
+         * ISO 639-1 or 639-2/T codes.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_AUDIO_LANGUAGE = "audio_language";
+
+        /**
+         * The comma-separated content ratings of this TV program.
+         *
+         * <p>This is used to describe the content rating(s) of this program. Each comma-separated
+         * content rating sub-string should be generated by calling
+         * {@link TvContentRating#flattenToString}. Note that in most cases the program content is
+         * rated by a single rating system, thus resulting in a corresponding single sub-string that
+         * does not require comma separation and multiple sub-strings appear only when the program
+         * content is rated by two or more content rating systems. If any of those ratings is
+         * specified as "blocked rating" in the user's parental control settings, the TV input
+         * service should block the current content and wait for the signal that it is okay to
+         * unblock.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_CONTENT_RATING = "content_rating";
+
+        /**
+         * The URI for the poster art of this TV program.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_POSTER_ART_URI = "poster_art_uri";
+
+        /**
+         * The URI for the thumbnail of this TV program.
+         *
+         * <p>The system can generate a thumbnail from the poster art if this column is not
+         * specified. Thus it is not necessary for TV input services to include a thumbnail if it is
+         * just a scaled image of the poster art.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_THUMBNAIL_URI = "thumbnail_uri";
+
+        /**
+         * The flag indicating whether this TV program is searchable or not.
+         *
+         * <p>The columns of searchable programs can be read by other applications that have proper
+         * permission. Care must be taken not to open sensitive data.
+         *
+         * <p>A value of 1 indicates that the program is searchable and its columns can be read by
+         * other applications, a value of 0 indicates that the program is hidden and its columns can
+         * be read only by the package that owns the program and the system. If not specified, this
+         * value is set to 1 (searchable) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         */
+        String COLUMN_SEARCHABLE = "searchable";
+
+        /**
+         * Internal data used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: BLOB
+         */
+        String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+
+        /**
+         * The version number of this row entry used by TV input services.
+         *
+         * <p>This is best used by sync adapters to identify the rows to update. The number can be
+         * defined by individual TV input services. One may assign the same value as
+         * {@code version_number} in ETSI EN 300 468 or ATSC A/65, if the data are coming from a TV
+         * broadcast.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_VERSION_NUMBER = "version_number";
+
+        /**
+         * The review rating score style used for {@link #COLUMN_REVIEW_RATING}.
+         *
+         * <p> The value should match one of the followings: {@link #REVIEW_RATING_STYLE_STARS},
+         * {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN}, and {@link #REVIEW_RATING_STYLE_PERCENTAGE}.
+         *
+         * <p>Type: INTEGER
+         * @see #COLUMN_REVIEW_RATING
+         */
+        String COLUMN_REVIEW_RATING_STYLE = "review_rating_style";
+
+        /**
+         * The review rating score for this program.
+         *
+         * <p>The format of the value is dependent on {@link #COLUMN_REVIEW_RATING_STYLE}. If the
+         * style is {@link #REVIEW_RATING_STYLE_STARS}, the value should be a real number between
+         * 0.0 and 5.0. (e.g. "4.5") If the style is {@link #REVIEW_RATING_STYLE_THUMBS_UP_DOWN},
+         * the value should be two integers, one for thumbs-up count and the other for thumbs-down
+         * count, with a comma between them. (e.g. "200,40") If the style is
+         * {@link #REVIEW_RATING_STYLE_PERCENTAGE}, the value shoule be a real number between 0 and
+         * 100. (e.g. "99.9")
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_REVIEW_RATING_STYLE
+         */
+        String COLUMN_REVIEW_RATING = "review_rating";
+
+        /**
+         * The series ID of this TV program for episodic TV shows.
+         *
+         * <p>This is used to indicate the series ID. Programs in the same series share a series ID.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_SERIES_ID = "series_id";
+
+        /**
+         * The split ID of this TV program for multi-part content, as a URI.
+         *
+         * <p>A content may consist of multiple programs within the same channel or over several
+         * channels. For example, a film might be divided into two parts interrupted by a news in
+         * the middle or a longer sport event might be split into several parts over several
+         * channels. The split ID is used to identify all the programs in the same multi-part
+         * content. Suitable URIs include
+         * <ul>
+         * <li>{@code crid://<CRIDauthority>/<data>#<IMI>} from ETSI TS 102 323
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_SPLIT_ID = "split_id";
+    }
+
+    /**
+     * Common columns for the tables of preview programs.
+     * @hide
+     */
+    interface PreviewProgramColumns {
+
+        /** @hide */
+        @IntDef({
+                TYPE_MOVIE,
+                TYPE_TV_SERIES,
+                TYPE_TV_SEASON,
+                TYPE_TV_EPISODE,
+                TYPE_CLIP,
+                TYPE_EVENT,
+                TYPE_CHANNEL,
+                TYPE_TRACK,
+                TYPE_ALBUM,
+                TYPE_ARTIST,
+                TYPE_PLAYLIST,
+                TYPE_STATION,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Type {}
+
+        /**
+         * The program type for movie.
+         *
+         * @see #COLUMN_TYPE
+         */
+        int TYPE_MOVIE = 0;
+
+        /**
+         * The program type for TV series.
+         *
+         * @see #COLUMN_TYPE
+         */
+        int TYPE_TV_SERIES = 1;
+
+        /**
+         * The program type for TV season.
+         *
+         * @see #COLUMN_TYPE
+         */
+        int TYPE_TV_SEASON = 2;
+
+        /**
+         * The program type for TV episode.
+         *
+         * @see #COLUMN_TYPE
+         */
+        int TYPE_TV_EPISODE = 3;
+
+        /**
+         * The program type for clip.
+         *
+         * @see #COLUMN_TYPE
+         */
+        int TYPE_CLIP = 4;
+
+        /**
+         * The program type for event.
+         *
+         * @see #COLUMN_TYPE
+         */
+        int TYPE_EVENT = 5;
+
+        /**
+         * The program type for channel.
+         *
+         * @see #COLUMN_TYPE
+         */
+        int TYPE_CHANNEL = 6;
+
+        /**
+         * The program type for track.
+         *
+         * @see #COLUMN_TYPE
+         */
+        int TYPE_TRACK = 7;
+
+        /**
+         * The program type for album.
+         *
+         * @see #COLUMN_TYPE
+         */
+        int TYPE_ALBUM = 8;
+
+        /**
+         * The program type for artist.
+         *
+         * @see #COLUMN_TYPE
+         */
+        int TYPE_ARTIST = 9;
+
+        /**
+         * The program type for playlist.
+         *
+         * @see #COLUMN_TYPE
+         */
+        int TYPE_PLAYLIST = 10;
+
+        /**
+         * The program type for station.
+         *
+         * @see #COLUMN_TYPE
+         */
+        int TYPE_STATION = 11;
+
+        /** @hide */
+        @IntDef({
+                ASPECT_RATIO_16_9,
+                ASPECT_RATIO_3_2,
+                ASPECT_RATIO_1_1,
+                ASPECT_RATIO_2_3,
+                ASPECT_RATIO_4_3,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface AspectRatio {}
+
+        /**
+         * The aspect ratio for 16:9.
+         *
+         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+         */
+        int ASPECT_RATIO_16_9 = 0;
+
+        /**
+         * The aspect ratio for 3:2.
+         *
+         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+         */
+        int ASPECT_RATIO_3_2 = 1;
+
+        /**
+         * The aspect ratio for 4:3.
+         *
+         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+         */
+        int ASPECT_RATIO_4_3 = 2;
+
+        /**
+         * The aspect ratio for 1:1.
+         *
+         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+         */
+        int ASPECT_RATIO_1_1 = 3;
+
+        /**
+         * The aspect ratio for 2:3.
+         *
+         * @see #COLUMN_POSTER_ART_ASPECT_RATIO
+         * @see #COLUMN_THUMBNAIL_ASPECT_RATIO
+         */
+        int ASPECT_RATIO_2_3 = 4;
+
+        /** @hide */
+        @IntDef({
+                AVAILABILITY_AVAILABLE,
+                AVAILABILITY_FREE_WITH_SUBSCRIPTION,
+                AVAILABILITY_PAID_CONTENT,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Availability {}
+
+        /**
+         * The availability for "available to this user".
+         *
+         * @see #COLUMN_AVAILABILITY
+         */
+        int AVAILABILITY_AVAILABLE = 0;
+
+        /**
+         * The availability for "free with subscription".
+         *
+         * @see #COLUMN_AVAILABILITY
+         */
+        int AVAILABILITY_FREE_WITH_SUBSCRIPTION = 1;
+
+        /**
+         * The availability for "paid content, either to-own or rental
+         * (user has not purchased/rented).
+         *
+         * @see #COLUMN_AVAILABILITY
+         */
+        int AVAILABILITY_PAID_CONTENT = 2;
+
+        /** @hide */
+        @IntDef({
+                INTERACTION_TYPE_VIEWS,
+                INTERACTION_TYPE_LISTENS,
+                INTERACTION_TYPE_FOLLOWERS,
+                INTERACTION_TYPE_FANS,
+                INTERACTION_TYPE_LIKES,
+                INTERACTION_TYPE_THUMBS,
+                INTERACTION_TYPE_VIEWERS,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface InteractionType {}
+
+        /**
+         * The interaction type for "views".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        int INTERACTION_TYPE_VIEWS = 0;
+
+        /**
+         * The interaction type for "listens".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        int INTERACTION_TYPE_LISTENS = 1;
+
+        /**
+         * The interaction type for "followers".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        int INTERACTION_TYPE_FOLLOWERS = 2;
+
+        /**
+         * The interaction type for "fans".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        int INTERACTION_TYPE_FANS = 3;
+
+        /**
+         * The interaction type for "likes".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        int INTERACTION_TYPE_LIKES = 4;
+
+        /**
+         * The interaction type for "thumbs".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        int INTERACTION_TYPE_THUMBS = 5;
+
+        /**
+         * The interaction type for "viewers".
+         *
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        int INTERACTION_TYPE_VIEWERS = 6;
+
+        /**
+         * The type of this program content.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #TYPE_MOVIE},
+         * {@link #TYPE_TV_SERIES},
+         * {@link #TYPE_TV_SEASON},
+         * {@link #TYPE_TV_EPISODE},
+         * {@link #TYPE_CLIP},
+         * {@link #TYPE_EVENT},
+         * {@link #TYPE_CHANNEL},
+         * {@link #TYPE_TRACK},
+         * {@link #TYPE_ALBUM},
+         * {@link #TYPE_ARTIST},
+         * {@link #TYPE_PLAYLIST}, and
+         * {@link #TYPE_STATION}.
+         *
+         * <p>This is a required field if the program is from a {@link Channels#TYPE_PREVIEW}
+         * channel.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_TYPE = "type";
+
+        /**
+         * The aspect ratio of the poster art for this TV program.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #ASPECT_RATIO_16_9},
+         * {@link #ASPECT_RATIO_3_2},
+         * {@link #ASPECT_RATIO_4_3},
+         * {@link #ASPECT_RATIO_1_1}, and
+         * {@link #ASPECT_RATIO_2_3}.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_POSTER_ART_ASPECT_RATIO = "poster_art_aspect_ratio";
+
+        /**
+         * The aspect ratio of the thumbnail for this TV program.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #ASPECT_RATIO_16_9},
+         * {@link #ASPECT_RATIO_3_2},
+         * {@link #ASPECT_RATIO_4_3},
+         * {@link #ASPECT_RATIO_1_1}, and
+         * {@link #ASPECT_RATIO_2_3}.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_THUMBNAIL_ASPECT_RATIO = "poster_thumbnail_aspect_ratio";
+
+        /**
+         * The URI for the logo of this TV program.
+         *
+         * <p>This is a small badge shown on top of the poster art or thumbnail representing the
+         * source of the content.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_LOGO_URI = "logo_uri";
+
+        /**
+         * The availability of this TV program.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #AVAILABILITY_AVAILABLE},
+         * {@link #AVAILABILITY_FREE_WITH_SUBSCRIPTION}, and
+         * {@link #AVAILABILITY_PAID_CONTENT}.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_AVAILABILITY = "availability";
+
+        /**
+         * The starting price of this TV program.
+         *
+         * <p>This indicates the lowest regular acquisition cost of the content. It is only used
+         * if the availability of the program is {@link #AVAILABILITY_PAID_CONTENT}.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_OFFER_PRICE
+         */
+        String COLUMN_STARTING_PRICE = "starting_price";
+
+        /**
+         * The offer price of this TV program.
+         *
+         * <p>This is the promotional cost of the content. It is only used if the availability of
+         * the program is {@link #AVAILABILITY_PAID_CONTENT}.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_STARTING_PRICE
+         */
+        String COLUMN_OFFER_PRICE = "offer_price";
+
+        /**
+         * The release date of this TV program.
+         *
+         * <p>The value should be in one of the following formats:
+         * "yyyy", "yyyy-MM-dd", and "yyyy-MM-ddTHH:mm:ssZ" (UTC in ISO 8601).
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_RELEASE_DATE = "release_date";
+
+        /**
+         * The count of the items included in this TV program.
+         *
+         * <p>This is only relevant if the program represents a collection of items such as series,
+         * episodes, or music tracks.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_ITEM_COUNT = "item_count";
+
+        /**
+         * The flag indicating whether this TV program is live or not.
+         *
+         * <p>A value of 1 indicates that the content is airing and should be consumed now, a value
+         * of 0 indicates that the content is off the air and does not need to be consumed at the
+         * present time. If not specified, the value is set to 0 (not live) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         */
+        String COLUMN_LIVE = "live";
+
+        /**
+         * The internal ID used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+
+        /**
+         * The URI for the preview video.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_PREVIEW_VIDEO_URI = "preview_video_uri";
+
+        /**
+         * The last playback position (in milliseconds) of the original content of this preview
+         * program.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_LAST_PLAYBACK_POSITION_MILLIS =
+                "last_playback_position_millis";
+
+        /**
+         * The duration (in milliseconds) of the original content of this preview program.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         */
+        String COLUMN_DURATION_MILLIS = "duration_millis";
+
+        /**
+         * The intent URI which is launched when the preview program is selected.
+         *
+         * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME}
+         * and converted back to the original intent with {@link Intent#parseUri}. The intent is
+         * launched when the user selects the preview program item.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_INTENT_URI = "intent_uri";
+
+        /**
+         * The flag indicating whether this program is transient or not.
+         *
+         * <p>A value of 1 indicates that the channel will be automatically removed by the system on
+         * reboot, and a value of 0 indicates that the channel is persistent across reboot. If not
+         * specified, this value is set to 0 (not transient) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         * @see Channels#COLUMN_TRANSIENT
+         */
+        String COLUMN_TRANSIENT = "transient";
+
+        /**
+         * The type of interaction for this TV program.
+         *
+         * <p> The value should match one of the followings:
+         * {@link #INTERACTION_TYPE_VIEWS},
+         * {@link #INTERACTION_TYPE_LISTENS},
+         * {@link #INTERACTION_TYPE_FOLLOWERS},
+         * {@link #INTERACTION_TYPE_FANS},
+         * {@link #INTERACTION_TYPE_LIKES},
+         * {@link #INTERACTION_TYPE_THUMBS}, and
+         * {@link #INTERACTION_TYPE_VIEWERS}.
+         *
+         * <p>Type: INTEGER
+         * @see #COLUMN_INTERACTION_COUNT
+         */
+        String COLUMN_INTERACTION_TYPE = "interaction_type";
+
+        /**
+         * The interaction count for this program.
+         *
+         * <p>This indicates the number of times interaction has happened.
+         *
+         * <p>Type: INTEGER (long)
+         * @see #COLUMN_INTERACTION_TYPE
+         */
+        String COLUMN_INTERACTION_COUNT = "interaction_count";
+
+        /**
+         * The author or artist of this content.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_AUTHOR = "author";
+
+        /**
+         * The flag indicating whether this TV program is browsable or not.
+         *
+         * <p>This column can only be set by applications having proper system permission. For
+         * other applications, this is a read-only column.
+         *
+         * <p>A value of 1 indicates that the program is browsable and can be shown to users in
+         * the UI. A value of 0 indicates that the program should be hidden from users and the
+         * application who changes this value to 0 should send
+         * {@link #ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED} to the owner of the program
+         * to notify this change.
+         *
+         * <p>This value is set to 1 (browsable) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         */
+        String COLUMN_BROWSABLE = "browsable";
+
+        /**
+         * The content ID of this TV program.
+         *
+         * <p>A public ID of the content which allows the application to apply the same operation to
+         * all the program copies in different channels.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        String COLUMN_CONTENT_ID = "content_id";
+
+    }
+
+    /** Column definitions for the TV channels table. */
+    public static final class Channels implements BaseTvColumns {
+
+        /**
+         * The content:// style URI for this table.
+         *
+         * <p>SQL selection is not supported for {@link ContentResolver#query},
+         * {@link ContentResolver#update} and {@link ContentResolver#delete} operations.
+         */
+        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
+                + PATH_CHANNEL);
+
+        /** The MIME type of a directory of TV channels. */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/channel";
+
+        /** The MIME type of a single TV channel. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";
+
+        /** @hide */
+        @StringDef(prefix = { "TYPE_" }, value = {
+                TYPE_OTHER,
+                TYPE_NTSC,
+                TYPE_PAL,
+                TYPE_SECAM,
+                TYPE_DVB_T,
+                TYPE_DVB_T2,
+                TYPE_DVB_S,
+                TYPE_DVB_S2,
+                TYPE_DVB_C,
+                TYPE_DVB_C2,
+                TYPE_DVB_H,
+                TYPE_DVB_SH,
+                TYPE_ATSC_T,
+                TYPE_ATSC_C,
+                TYPE_ATSC_M_H,
+                TYPE_ATSC3_T,
+                TYPE_ISDB_T,
+                TYPE_ISDB_TB,
+                TYPE_ISDB_S,
+                TYPE_ISDB_S3,
+                TYPE_ISDB_C,
+                TYPE_1SEG,
+                TYPE_DTMB,
+                TYPE_CMMB,
+                TYPE_T_DMB,
+                TYPE_S_DMB,
+                TYPE_PREVIEW,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface Type {}
+
+        /**
+         * A generic channel type.
+         *
+         * Use this if the current channel is streaming-based or its broadcast system type does not
+         * fit under any other types. This is the default channel type.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_OTHER = "TYPE_OTHER";
+
+        /**
+         * The channel type for NTSC.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_NTSC = "TYPE_NTSC";
+
+        /**
+         * The channel type for PAL.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_PAL = "TYPE_PAL";
+
+        /**
+         * The channel type for SECAM.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_SECAM = "TYPE_SECAM";
+
+        /**
+         * The channel type for DVB-T (terrestrial).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_T = "TYPE_DVB_T";
+
+        /**
+         * The channel type for DVB-T2 (terrestrial).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_T2 = "TYPE_DVB_T2";
+
+        /**
+         * The channel type for DVB-S (satellite).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_S = "TYPE_DVB_S";
+
+        /**
+         * The channel type for DVB-S2 (satellite).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_S2 = "TYPE_DVB_S2";
+
+        /**
+         * The channel type for DVB-C (cable).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_C = "TYPE_DVB_C";
+
+        /**
+         * The channel type for DVB-C2 (cable).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_C2 = "TYPE_DVB_C2";
+
+        /**
+         * The channel type for DVB-H (handheld).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_H = "TYPE_DVB_H";
+
+        /**
+         * The channel type for DVB-SH (satellite).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DVB_SH = "TYPE_DVB_SH";
+
+        /**
+         * The channel type for ATSC (terrestrial).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ATSC_T = "TYPE_ATSC_T";
+
+        /**
+         * The channel type for ATSC (cable).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ATSC_C = "TYPE_ATSC_C";
+
+        /**
+         * The channel type for ATSC-M/H (mobile/handheld).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ATSC_M_H = "TYPE_ATSC_M_H";
+
+        /**
+         * The channel type for ATSC3.0 (terrestrial).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ATSC3_T = "TYPE_ATSC3_T";
+
+        /**
+         * The channel type for ISDB-T (terrestrial).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ISDB_T = "TYPE_ISDB_T";
+
+        /**
+         * The channel type for ISDB-Tb (Brazil).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ISDB_TB = "TYPE_ISDB_TB";
+
+        /**
+         * The channel type for ISDB-S (satellite).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ISDB_S = "TYPE_ISDB_S";
+
+        /**
+         * The channel type for ISDB-S3 (satellite).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ISDB_S3 = "TYPE_ISDB_S3";
+
+        /**
+         * The channel type for ISDB-C (cable).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_ISDB_C = "TYPE_ISDB_C";
+
+        /**
+         * The channel type for 1seg (handheld).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_1SEG = "TYPE_1SEG";
+
+        /**
+         * The channel type for DTMB (terrestrial).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_DTMB = "TYPE_DTMB";
+
+        /**
+         * The channel type for CMMB (handheld).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_CMMB = "TYPE_CMMB";
+
+        /**
+         * The channel type for T-DMB (terrestrial).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_T_DMB = "TYPE_T_DMB";
+
+        /**
+         * The channel type for S-DMB (satellite).
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_S_DMB = "TYPE_S_DMB";
+
+        /**
+         * The channel type for preview videos.
+         *
+         * <P>Unlike other broadcast TV channel types, the programs in the preview channel usually
+         * are promotional videos. The UI may treat the preview channels differently from the other
+         * broadcast channels.
+         *
+         * @see #COLUMN_TYPE
+         */
+        public static final String TYPE_PREVIEW = "TYPE_PREVIEW";
+
+        /** @hide */
+        @StringDef(prefix = { "SERVICE_TYPE_" }, value = {
+                SERVICE_TYPE_OTHER,
+                SERVICE_TYPE_AUDIO_VIDEO,
+                SERVICE_TYPE_AUDIO,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface ServiceType {}
+
+        /** A generic service type. */
+        public static final String SERVICE_TYPE_OTHER = "SERVICE_TYPE_OTHER";
+
+        /** The service type for regular TV channels that have both audio and video. */
+        public static final String SERVICE_TYPE_AUDIO_VIDEO = "SERVICE_TYPE_AUDIO_VIDEO";
+
+        /** The service type for radio channels that have audio only. */
+        public static final String SERVICE_TYPE_AUDIO = "SERVICE_TYPE_AUDIO";
+
+        /** @hide */
+        @StringDef(prefix = { "VIDEO_FORMAT_" }, value = {
+                VIDEO_FORMAT_240P,
+                VIDEO_FORMAT_360P,
+                VIDEO_FORMAT_480I,
+                VIDEO_FORMAT_576I,
+                VIDEO_FORMAT_576P,
+                VIDEO_FORMAT_720P,
+                VIDEO_FORMAT_1080I,
+                VIDEO_FORMAT_1080P,
+                VIDEO_FORMAT_2160P,
+                VIDEO_FORMAT_4320P,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface VideoFormat {}
+
+        /** The video format for 240p. */
+        public static final String VIDEO_FORMAT_240P = "VIDEO_FORMAT_240P";
+
+        /** The video format for 360p. */
+        public static final String VIDEO_FORMAT_360P = "VIDEO_FORMAT_360P";
+
+        /** The video format for 480i. */
+        public static final String VIDEO_FORMAT_480I = "VIDEO_FORMAT_480I";
+
+        /** The video format for 480p. */
+        public static final String VIDEO_FORMAT_480P = "VIDEO_FORMAT_480P";
+
+        /** The video format for 576i. */
+        public static final String VIDEO_FORMAT_576I = "VIDEO_FORMAT_576I";
+
+        /** The video format for 576p. */
+        public static final String VIDEO_FORMAT_576P = "VIDEO_FORMAT_576P";
+
+        /** The video format for 720p. */
+        public static final String VIDEO_FORMAT_720P = "VIDEO_FORMAT_720P";
+
+        /** The video format for 1080i. */
+        public static final String VIDEO_FORMAT_1080I = "VIDEO_FORMAT_1080I";
+
+        /** The video format for 1080p. */
+        public static final String VIDEO_FORMAT_1080P = "VIDEO_FORMAT_1080P";
+
+        /** The video format for 2160p. */
+        public static final String VIDEO_FORMAT_2160P = "VIDEO_FORMAT_2160P";
+
+        /** The video format for 4320p. */
+        public static final String VIDEO_FORMAT_4320P = "VIDEO_FORMAT_4320P";
+
+        /** @hide */
+        @StringDef(prefix = { "VIDEO_RESOLUTION_" }, value = {
+                VIDEO_RESOLUTION_SD,
+                VIDEO_RESOLUTION_ED,
+                VIDEO_RESOLUTION_HD,
+                VIDEO_RESOLUTION_FHD,
+                VIDEO_RESOLUTION_UHD,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface VideoResolution {}
+
+        /** The video resolution for standard-definition. */
+        public static final String VIDEO_RESOLUTION_SD = "VIDEO_RESOLUTION_SD";
+
+        /** The video resolution for enhanced-definition. */
+        public static final String VIDEO_RESOLUTION_ED = "VIDEO_RESOLUTION_ED";
+
+        /** The video resolution for high-definition. */
+        public static final String VIDEO_RESOLUTION_HD = "VIDEO_RESOLUTION_HD";
+
+        /** The video resolution for full high-definition. */
+        public static final String VIDEO_RESOLUTION_FHD = "VIDEO_RESOLUTION_FHD";
+
+        /** The video resolution for ultra high-definition. */
+        public static final String VIDEO_RESOLUTION_UHD = "VIDEO_RESOLUTION_UHD";
+
+        private static final Map<String, String> VIDEO_FORMAT_TO_RESOLUTION_MAP = new HashMap<>();
+
+        static {
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480I, VIDEO_RESOLUTION_SD);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_480P, VIDEO_RESOLUTION_ED);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576I, VIDEO_RESOLUTION_SD);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_576P, VIDEO_RESOLUTION_ED);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_720P, VIDEO_RESOLUTION_HD);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080I, VIDEO_RESOLUTION_HD);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_1080P, VIDEO_RESOLUTION_FHD);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_2160P, VIDEO_RESOLUTION_UHD);
+            VIDEO_FORMAT_TO_RESOLUTION_MAP.put(VIDEO_FORMAT_4320P, VIDEO_RESOLUTION_UHD);
+        }
+
+        /**
+         * Returns the video resolution (definition) for a given video format.
+         *
+         * @param videoFormat The video format defined in {@link Channels}.
+         * @return the corresponding video resolution string. {@code null} if the resolution string
+         *         is not defined for the given video format.
+         * @see #COLUMN_VIDEO_FORMAT
+         */
+        @Nullable
+        public static final String getVideoResolution(@VideoFormat String videoFormat) {
+            return VIDEO_FORMAT_TO_RESOLUTION_MAP.get(videoFormat);
+        }
+
+        /**
+         * The ID of the TV input service that provides this TV channel.
+         *
+         * <p>Use {@link #buildInputId} to build the ID.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_INPUT_ID = "input_id";
+
+        /**
+         * The broadcast system type of this TV channel.
+         *
+         * <p>This is used to indicate the broadcast standard (e.g. ATSC, DVB or ISDB) the current
+         * channel conforms to. Use {@link #TYPE_OTHER} for streaming-based channels, which is the
+         * default channel type. The value should match one of the followings:
+         * {@link #TYPE_1SEG},
+         * {@link #TYPE_ATSC_C},
+         * {@link #TYPE_ATSC_M_H},
+         * {@link #TYPE_ATSC_T},
+         * {@link #TYPE_ATSC3_T},
+         * {@link #TYPE_CMMB},
+         * {@link #TYPE_DTMB},
+         * {@link #TYPE_DVB_C},
+         * {@link #TYPE_DVB_C2},
+         * {@link #TYPE_DVB_H},
+         * {@link #TYPE_DVB_S},
+         * {@link #TYPE_DVB_S2},
+         * {@link #TYPE_DVB_SH},
+         * {@link #TYPE_DVB_T},
+         * {@link #TYPE_DVB_T2},
+         * {@link #TYPE_ISDB_C},
+         * {@link #TYPE_ISDB_S},
+         * {@link #TYPE_ISDB_S3},
+         * {@link #TYPE_ISDB_T},
+         * {@link #TYPE_ISDB_TB},
+         * {@link #TYPE_NTSC},
+         * {@link #TYPE_OTHER},
+         * {@link #TYPE_PAL},
+         * {@link #TYPE_SECAM},
+         * {@link #TYPE_S_DMB},
+         * {@link #TYPE_T_DMB}, and
+         * {@link #TYPE_PREVIEW}.
+         *
+         * <p>This value cannot be changed once it's set. Trying to modify it will make the update
+         * fail.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_TYPE = "type";
+
+        /**
+         * The predefined service type of this TV channel.
+         *
+         * <p>This is primarily used to indicate whether the current channel is a regular TV channel
+         * or a radio-like channel. Use the same coding for {@code service_type} in the underlying
+         * broadcast standard if it is defined there (e.g. ATSC A/53, ETSI EN 300 468 and ARIB
+         * STD-B10). Otherwise use one of the followings: {@link #SERVICE_TYPE_OTHER},
+         * {@link #SERVICE_TYPE_AUDIO_VIDEO}, {@link #SERVICE_TYPE_AUDIO}
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_SERVICE_TYPE = "service_type";
+
+        /**
+         * The original network ID of this TV channel.
+         *
+         * <p>It is used to identify the originating delivery system, if applicable. Use the same
+         * coding for {@code original_network_id} for ETSI EN 300 468/TR 101 211 and ARIB STD-B10.
+         *
+         * <p>This is a required field only if the underlying broadcast standard defines the same
+         * name field. Otherwise, leave empty.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_ORIGINAL_NETWORK_ID = "original_network_id";
+
+        /**
+         * The transport stream ID of this channel.
+         *
+         * <p>It is used to identify the Transport Stream that contains the current channel from any
+         * other multiplex within a network, if applicable. Use the same coding for
+         * {@code transport_stream_id} defined in ISO/IEC 13818-1 if the channel is transmitted via
+         * the MPEG Transport Stream.
+         *
+         * <p>This is a required field only if the current channel is transmitted via the MPEG
+         * Transport Stream. Leave empty otherwise.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_TRANSPORT_STREAM_ID = "transport_stream_id";
+
+        /**
+         * The service ID of this channel.
+         *
+         * <p>It is used to identify the current service, or channel from any other services within
+         * a given Transport Stream, if applicable. Use the same coding for {@code service_id} in
+         * ETSI EN 300 468 and ARIB STD-B10 or {@code program_number} in ISO/IEC 13818-1.
+         *
+         * <p>This is a required field only if the underlying broadcast standard defines the same
+         * name field, or the current channel is transmitted via the MPEG Transport Stream. Leave
+         * empty otherwise.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_SERVICE_ID = "service_id";
+
+        /**
+         * The channel number that is displayed to the user.
+         *
+         * <p>The format can vary depending on broadcast standard and product specification.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_DISPLAY_NUMBER = "display_number";
+
+        /**
+         * The channel name that is displayed to the user.
+         *
+         * <p>A call sign is a good candidate to use for this purpose but any name that helps the
+         * user recognize the current channel will be enough. Can also be empty depending on
+         * broadcast standard.
+         *
+         * <p> Type: TEXT
+         */
+        public static final String COLUMN_DISPLAY_NAME = "display_name";
+
+        /**
+         * The network affiliation for this TV channel.
+         *
+         * <p>This is used to identify a channel that is commonly called by its network affiliation
+         * instead of the display name. Examples include ABC for the channel KGO-HD, FOX for the
+         * channel KTVU-HD and NBC for the channel KNTV-HD. Can be empty if not applicable.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_NETWORK_AFFILIATION = "network_affiliation";
+
+        /**
+         * The description of this TV channel.
+         *
+         * <p>Can be empty initially.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_DESCRIPTION = "description";
+
+        /**
+         * The typical video format for programs from this TV channel.
+         *
+         * <p>This is primarily used to filter out channels based on video format by applications.
+         * The value should match one of the followings: {@link #VIDEO_FORMAT_240P},
+         * {@link #VIDEO_FORMAT_360P}, {@link #VIDEO_FORMAT_480I}, {@link #VIDEO_FORMAT_480P},
+         * {@link #VIDEO_FORMAT_576I}, {@link #VIDEO_FORMAT_576P}, {@link #VIDEO_FORMAT_720P},
+         * {@link #VIDEO_FORMAT_1080I}, {@link #VIDEO_FORMAT_1080P}, {@link #VIDEO_FORMAT_2160P},
+         * {@link #VIDEO_FORMAT_4320P}. Note that the actual video resolution of each program from a
+         * given channel can vary thus one should use {@link Programs#COLUMN_VIDEO_WIDTH} and
+         * {@link Programs#COLUMN_VIDEO_HEIGHT} to get more accurate video resolution.
+         *
+         * <p>Type: TEXT
+         *
+         * @see #getVideoResolution
+         */
+        public static final String COLUMN_VIDEO_FORMAT = "video_format";
+
+        /**
+         * The flag indicating whether this TV channel is browsable or not.
+         *
+         * <p>This column can only be set by applications having proper system permission. For
+         * other applications, this is a read-only column.
+         *
+         * <p>A value of 1 indicates the channel is included in the channel list that applications
+         * use to browse channels, a value of 0 indicates the channel is not included in the list.
+         * If not specified, this value is set to 0 (not browsable) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         */
+        public static final String COLUMN_BROWSABLE = "browsable";
+
+        /**
+         * The flag indicating whether this TV channel is searchable or not.
+         *
+         * <p>The columns of searchable channels can be read by other applications that have proper
+         * permission. Care must be taken not to open sensitive data.
+         *
+         * <p>A value of 1 indicates that the channel is searchable and its columns can be read by
+         * other applications, a value of 0 indicates that the channel is hidden and its columns can
+         * be read only by the package that owns the channel and the system. If not specified, this
+         * value is set to 1 (searchable) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         */
+        public static final String COLUMN_SEARCHABLE = "searchable";
+
+        /**
+         * The flag indicating whether this TV channel is locked or not.
+         *
+         * <p>This is primarily used for alternative parental control to prevent unauthorized users
+         * from watching the current channel regardless of the content rating. A value of 1
+         * indicates the channel is locked and the user is required to enter passcode to unlock it
+         * in order to watch the current program from the channel, a value of 0 indicates the
+         * channel is not locked thus the user is not prompted to enter passcode If not specified,
+         * this value is set to 0 (not locked) by default.
+         *
+         * <p>This column can only be set by applications having proper system permission to
+         * modify parental control settings. For other applications, this is a read-only column.
+
+         * <p>Type: INTEGER (boolean)
+         */
+        public static final String COLUMN_LOCKED = "locked";
+
+        /**
+         * The URI for the app badge icon of the app link template for this channel.
+         *
+         * <p>This small icon is overlaid at the bottom of the poster art specified by
+         * {@link #COLUMN_APP_LINK_POSTER_ART_URI}. The data in the column must be a URI in one of
+         * the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>The app-linking allows channel input sources to provide activity links from their live
+         * channel programming to another activity. This enables content providers to increase user
+         * engagement by offering the viewer other content or actions.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_APP_LINK_COLOR
+         * @see #COLUMN_APP_LINK_INTENT_URI
+         * @see #COLUMN_APP_LINK_POSTER_ART_URI
+         * @see #COLUMN_APP_LINK_TEXT
+         */
+        public static final String COLUMN_APP_LINK_ICON_URI = "app_link_icon_uri";
+
+        /**
+         * The URI for the poster art used as the background of the app link template for this
+         * channel.
+         *
+         * <p>The data in the column must be a URL, or a URI in one of the following formats:
+         *
+         * <ul>
+         * <li>content ({@link android.content.ContentResolver#SCHEME_CONTENT})</li>
+         * <li>android.resource ({@link android.content.ContentResolver#SCHEME_ANDROID_RESOURCE})
+         * </li>
+         * <li>file ({@link android.content.ContentResolver#SCHEME_FILE})</li>
+         * </ul>
+         *
+         * <p>The app-linking allows channel input sources to provide activity links from their live
+         * channel programming to another activity. This enables content providers to increase user
+         * engagement by offering the viewer other content or actions.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_APP_LINK_COLOR
+         * @see #COLUMN_APP_LINK_ICON_URI
+         * @see #COLUMN_APP_LINK_INTENT_URI
+         * @see #COLUMN_APP_LINK_TEXT
+         */
+        public static final String COLUMN_APP_LINK_POSTER_ART_URI = "app_link_poster_art_uri";
+
+        /**
+         * The link text of the app link template for this channel.
+         *
+         * <p>This provides a short description of the action that happens when the corresponding
+         * app link is clicked.
+         *
+         * <p>The app-linking allows channel input sources to provide activity links from their live
+         * channel programming to another activity. This enables content providers to increase user
+         * engagement by offering the viewer other content or actions.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_APP_LINK_COLOR
+         * @see #COLUMN_APP_LINK_ICON_URI
+         * @see #COLUMN_APP_LINK_INTENT_URI
+         * @see #COLUMN_APP_LINK_POSTER_ART_URI
+         */
+        public static final String COLUMN_APP_LINK_TEXT = "app_link_text";
+
+        /**
+         * The accent color of the app link template for this channel. This is primarily used for
+         * the background color of the text box in the template.
+         *
+         * <p>The app-linking allows channel input sources to provide activity links from their live
+         * channel programming to another activity. This enables content providers to increase user
+         * engagement by offering the viewer other content or actions.
+         *
+         * <p>Type: INTEGER (color value)
+         * @see #COLUMN_APP_LINK_ICON_URI
+         * @see #COLUMN_APP_LINK_INTENT_URI
+         * @see #COLUMN_APP_LINK_POSTER_ART_URI
+         * @see #COLUMN_APP_LINK_TEXT
+         */
+        public static final String COLUMN_APP_LINK_COLOR = "app_link_color";
+
+        /**
+         * The intent URI of the app link for this channel.
+         *
+         * <p>The URI is created using {@link Intent#toUri} with {@link Intent#URI_INTENT_SCHEME}
+         * and converted back to the original intent with {@link Intent#parseUri}. The intent is
+         * launched when the user clicks the corresponding app link for the current channel.
+         *
+         * <p>The app-linking allows channel input sources to provide activity links from their live
+         * channel programming to another activity. This enables content providers to increase user
+         * engagement by offering the viewer other content or actions.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_APP_LINK_COLOR
+         * @see #COLUMN_APP_LINK_ICON_URI
+         * @see #COLUMN_APP_LINK_POSTER_ART_URI
+         * @see #COLUMN_APP_LINK_TEXT
+         */
+        public static final String COLUMN_APP_LINK_INTENT_URI = "app_link_intent_uri";
+
+        /**
+         * The internal ID used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_ID = "internal_provider_id";
+
+        /**
+         * Internal data used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: BLOB
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_DATA = "internal_provider_data";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG1 = "internal_provider_flag1";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG2 = "internal_provider_flag2";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG3 = "internal_provider_flag3";
+
+        /**
+         * Internal integer flag used by individual TV input services.
+         *
+         * <p>This is internal to the provider that inserted it, and should not be decoded by other
+         * apps.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_INTERNAL_PROVIDER_FLAG4 = "internal_provider_flag4";
+
+        /**
+         * The version number of this row entry used by TV input services.
+         *
+         * <p>This is best used by sync adapters to identify the rows to update. The number can be
+         * defined by individual TV input services. One may assign the same value as
+         * {@code version_number} that appears in ETSI EN 300 468 or ATSC A/65, if the data are
+         * coming from a TV broadcast.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_VERSION_NUMBER = "version_number";
+
+        /**
+         * The flag indicating whether this TV channel is transient or not.
+         *
+         * <p>A value of 1 indicates that the channel will be automatically removed by the system on
+         * reboot, and a value of 0 indicates that the channel is persistent across reboot. If not
+         * specified, this value is set to 0 (not transient) by default.
+         *
+         * <p>Type: INTEGER (boolean)
+         * @see PreviewPrograms#COLUMN_TRANSIENT
+         * @see WatchNextPrograms#COLUMN_TRANSIENT
+         */
+        public static final String COLUMN_TRANSIENT = "transient";
+
+        /**
+         * The global content ID of this TV channel, as a URI.
+         *
+         * <p>A globally unique URI that identifies this TV channel, if applicable. Suitable URIs
+         * include
+         * <ul>
+         * <li>{@code globalServiceId} from ATSC A/331. ex {@code https://doi.org/10.5239/7E4E-B472}
+         * <li>Other broadcast ID provider. ex {@code http://example.com/tv_channel/1234}
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_GLOBAL_CONTENT_ID = "global_content_id";
+
+        /**
+         * The remote control key preset number that is assigned to this channel.
+         *
+         * <p> This can be used for one-touch-tuning, tuning to the channel with
+         * pressing the preset button.
+         *
+         * <p> Type: INTEGER (remote control key preset number)
+         */
+        public static final String COLUMN_REMOTE_CONTROL_KEY_PRESET_NUMBER =
+                "remote_control_key_preset_number";
+
+        /**
+         * The flag indicating whether this TV channel is scrambled or not.
+         *
+         * <p>Use the same coding for scrambled in the underlying broadcast standard
+         * if {@code free_ca_mode} in SDT is defined there (e.g. ETSI EN 300 468).
+         *
+         * <p>Type: INTEGER (boolean)
+         */
+        public static final String COLUMN_SCRAMBLED = "scrambled";
+
+        /**
+         * The typical video resolution.
+         *
+         * <p>This is primarily used to filter out channels based on video resolution
+         * by applications. The value is from SDT if defined there. (e.g. ETSI EN 300 468)
+         * The value should match one of the followings: {@link #VIDEO_RESOLUTION_SD},
+         * {@link #VIDEO_RESOLUTION_HD}, {@link #VIDEO_RESOLUTION_UHD}.
+         *
+         * <p>Type: TEXT
+         *
+         */
+        public static final String COLUMN_VIDEO_RESOLUTION = "video_resolution";
+
+        /**
+         * The channel list ID of this TV channel.
+         *
+         * <p>It is used to identify the channel list constructed from broadcast SI based on the
+         * underlying broadcast standard or country/operator profile, if applicable. Otherwise,
+         * leave empty.
+         *
+         * <p>The ID can be defined by individual TV input services. For example, one may assign a
+         * service operator name for the service operator channel list constructed from broadcast
+         * SI or one may assign the {@code profile_name} of the operator_info() APDU defined in CI
+         * Plus 1.3 for the dedicated CICAM operator profile channel list constructed
+         * from CICAM NIT.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_CHANNEL_LIST_ID = "channel_list_id";
+
+        /**
+         * The comma-separated genre string of this TV channel.
+         *
+         * <p>Use the same language appeared in the underlying broadcast standard, if applicable.
+         * Otherwise, leave empty. Use
+         * {@link Genres#encode Genres.encode()} to create a text that can be stored in this column.
+         * Use {@link Genres#decode Genres.decode()} to get the broadcast genre strings from the
+         * text stored in the column.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_BROADCAST_GENRE
+         */
+        public static final String COLUMN_BROADCAST_GENRE = Programs.COLUMN_BROADCAST_GENRE;
+
+        private Channels() {}
+
+        /**
+         * A sub-directory of a single TV channel that represents its primary logo.
+         *
+         * <p>To access this directory, append {@link Channels.Logo#CONTENT_DIRECTORY} to the raw
+         * channel URI.  The resulting URI represents an image file, and should be interacted
+         * using ContentResolver.openAssetFileDescriptor.
+         *
+         * <p>Note that this sub-directory also supports opening the logo as an asset file in write
+         * mode.  Callers can create or replace the primary logo associated with this channel by
+         * opening the asset file and writing the full-size photo contents into it. (Make sure there
+         * is no padding around the logo image.) When the file is closed, the image will be parsed,
+         * sized down if necessary, and stored.
+         *
+         * <p>Usage example:
+         * <pre>
+         * public void writeChannelLogo(long channelId, byte[] logo) {
+         *     Uri channelLogoUri = TvContract.buildChannelLogoUri(channelId);
+         *     try {
+         *         AssetFileDescriptor fd =
+         *             getContentResolver().openAssetFileDescriptor(channelLogoUri, "rw");
+         *         OutputStream os = fd.createOutputStream();
+         *         os.write(logo);
+         *         os.close();
+         *         fd.close();
+         *     } catch (IOException e) {
+         *         // Handle error cases.
+         *     }
+         * }
+         * </pre>
+         */
+        public static final class Logo {
+
+            /**
+             * The directory twig for this sub-table.
+             */
+            public static final String CONTENT_DIRECTORY = "logo";
+
+            private Logo() {}
+        }
+    }
+
+    /**
+     * Column definitions for the TV programs table.
+     *
+     * <p>By default, the query results will be sorted by
+     * {@link Programs#COLUMN_START_TIME_UTC_MILLIS} in ascending order.
+     */
+    public static final class Programs implements BaseTvColumns, ProgramColumns {
+
+        /**
+         * The content:// style URI for this table.
+         *
+         * <p>SQL selection is not supported for {@link ContentResolver#query},
+         * {@link ContentResolver#update} and {@link ContentResolver#delete} operations.
+         */
+        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
+                + PATH_PROGRAM);
+
+        /** The MIME type of a directory of TV programs. */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/program";
+
+        /** The MIME type of a single TV program. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/program";
+
+        /**
+         * The ID of the TV channel that provides this TV program.
+         *
+         * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_CHANNEL_ID = "channel_id";
+
+        /**
+         * The season number of this TV program for episodic TV shows.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         *
+         * @deprecated Use {@link #COLUMN_SEASON_DISPLAY_NUMBER} instead.
+         */
+        @Deprecated
+        public static final String COLUMN_SEASON_NUMBER = "season_number";
+
+        /**
+         * The episode number of this TV program for episodic TV shows.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         *
+         * @deprecated Use {@link #COLUMN_EPISODE_DISPLAY_NUMBER} instead.
+         */
+        @Deprecated
+        public static final String COLUMN_EPISODE_NUMBER = "episode_number";
+
+        /**
+         * The start time of this TV program, in milliseconds since the epoch.
+         *
+         * <p>The value should be equal to or larger than {@link #COLUMN_END_TIME_UTC_MILLIS} of the
+         * previous program in the same channel. In practice, start time will usually be the end
+         * time of the previous program.
+         *
+         * <p>Can be empty if this program belongs to a {@link Channels#TYPE_PREVIEW} channel.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+
+        /**
+         * The end time of this TV program, in milliseconds since the epoch.
+         *
+         * <p>The value should be equal to or less than {@link #COLUMN_START_TIME_UTC_MILLIS} of the
+         * next program in the same channel. In practice, end time will usually be the start time of
+         * the next program.
+         *
+         * <p>Can be empty if this program belongs to a {@link Channels#TYPE_PREVIEW} channel.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+
+        /**
+         * The comma-separated genre string of this TV program.
+         *
+         * <p>Use the same language appeared in the underlying broadcast standard, if applicable.
+         * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or
+         * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use
+         * {@link Genres#encode} to create a text that can be stored in this column. Use
+         * {@link Genres#decode} to get the broadcast genre strings from the text stored in the
+         * column.
+         *
+         * <p>Type: TEXT
+         * @see Genres#encode
+         * @see Genres#decode
+         */
+        public static final String COLUMN_BROADCAST_GENRE = "broadcast_genre";
+
+        /**
+         * The flag indicating whether recording of this program is prohibited.
+         *
+         * <p>A value of 1 indicates that recording of this program is prohibited and application
+         * will not schedule any recording for this program. A value of 0 indicates that the
+         * recording is not prohibited. If not specified, this value is set to 0 (not prohibited) by
+         * default.
+         *
+         * <p>Type: INTEGER (boolean)
+         */
+        public static final String COLUMN_RECORDING_PROHIBITED = "recording_prohibited";
+
+        /**
+         * The event ID of this TV program.
+         *
+         * <p>It is used to identify the current TV program in the same channel, if applicable.
+         * Use the same coding for {@code event_id} in the underlying broadcast standard if it
+         * is defined there (e.g. ATSC A/65, ETSI EN 300 468 and ARIB STD-B10).
+         *
+         * <p>This is a required field only if the underlying broadcast standard defines the same
+         * name field. Otherwise, leave empty.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_EVENT_ID = "event_id";
+
+        /**
+         * The global content ID of this TV program, as a URI.
+         *
+         * <p>A globally unique ID that identifies this TV program, if applicable. Suitable URIs
+         * include
+         * <ul>
+         * <li>{@code crid://<CRIDauthority>/<data>} from ETSI TS 102 323
+         * <li>{@code globalContentId} from ATSC A/332
+         * <li>Other broadcast ID provider. ex {@code http://example.com/tv_program/1234}
+         * </ul>
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_GLOBAL_CONTENT_ID = "global_content_id";
+
+        private Programs() {}
+
+        /** Canonical genres for TV programs. */
+        public static final class Genres {
+            /** @hide */
+            @StringDef({
+                    FAMILY_KIDS,
+                    SPORTS,
+                    SHOPPING,
+                    MOVIES,
+                    COMEDY,
+                    TRAVEL,
+                    DRAMA,
+                    EDUCATION,
+                    ANIMAL_WILDLIFE,
+                    NEWS,
+                    GAMING,
+                    ARTS,
+                    ENTERTAINMENT,
+                    LIFE_STYLE,
+                    MUSIC,
+                    PREMIER,
+                    TECH_SCIENCE,
+            })
+            @Retention(RetentionPolicy.SOURCE)
+            public @interface Genre {}
+
+            /** The genre for Family/Kids. */
+            public static final String FAMILY_KIDS = "FAMILY_KIDS";
+
+            /** The genre for Sports. */
+            public static final String SPORTS = "SPORTS";
+
+            /** The genre for Shopping. */
+            public static final String SHOPPING = "SHOPPING";
+
+            /** The genre for Movies. */
+            public static final String MOVIES = "MOVIES";
+
+            /** The genre for Comedy. */
+            public static final String COMEDY = "COMEDY";
+
+            /** The genre for Travel. */
+            public static final String TRAVEL = "TRAVEL";
+
+            /** The genre for Drama. */
+            public static final String DRAMA = "DRAMA";
+
+            /** The genre for Education. */
+            public static final String EDUCATION = "EDUCATION";
+
+            /** The genre for Animal/Wildlife. */
+            public static final String ANIMAL_WILDLIFE = "ANIMAL_WILDLIFE";
+
+            /** The genre for News. */
+            public static final String NEWS = "NEWS";
+
+            /** The genre for Gaming. */
+            public static final String GAMING = "GAMING";
+
+            /** The genre for Arts. */
+            public static final String ARTS = "ARTS";
+
+            /** The genre for Entertainment. */
+            public static final String ENTERTAINMENT = "ENTERTAINMENT";
+
+            /** The genre for Life Style. */
+            public static final String LIFE_STYLE = "LIFE_STYLE";
+
+            /** The genre for Music. */
+            public static final String MUSIC = "MUSIC";
+
+            /** The genre for Premier. */
+            public static final String PREMIER = "PREMIER";
+
+            /** The genre for Tech/Science. */
+            public static final String TECH_SCIENCE = "TECH_SCIENCE";
+
+            private static final ArraySet<String> CANONICAL_GENRES = new ArraySet<>();
+            static {
+                CANONICAL_GENRES.add(FAMILY_KIDS);
+                CANONICAL_GENRES.add(SPORTS);
+                CANONICAL_GENRES.add(SHOPPING);
+                CANONICAL_GENRES.add(MOVIES);
+                CANONICAL_GENRES.add(COMEDY);
+                CANONICAL_GENRES.add(TRAVEL);
+                CANONICAL_GENRES.add(DRAMA);
+                CANONICAL_GENRES.add(EDUCATION);
+                CANONICAL_GENRES.add(ANIMAL_WILDLIFE);
+                CANONICAL_GENRES.add(NEWS);
+                CANONICAL_GENRES.add(GAMING);
+                CANONICAL_GENRES.add(ARTS);
+                CANONICAL_GENRES.add(ENTERTAINMENT);
+                CANONICAL_GENRES.add(LIFE_STYLE);
+                CANONICAL_GENRES.add(MUSIC);
+                CANONICAL_GENRES.add(PREMIER);
+                CANONICAL_GENRES.add(TECH_SCIENCE);
+            }
+
+            private static final char DOUBLE_QUOTE = '"';
+            private static final char COMMA = ',';
+            private static final String DELIMITER = ",";
+
+            private static final String[] EMPTY_STRING_ARRAY = new String[0];
+
+            private Genres() {}
+
+            /**
+             * Encodes genre strings to a text that can be put into the database.
+             *
+             * @param genres Genre strings.
+             * @return an encoded genre string that can be inserted into the
+             *         {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column.
+             */
+            public static String encode(@NonNull @Genre String... genres) {
+                if (genres == null) {
+                    // MNC and before will throw a NPE.
+                    return null;
+                }
+                StringBuilder sb = new StringBuilder();
+                String separator = "";
+                for (String genre : genres) {
+                    sb.append(separator).append(encodeToCsv(genre));
+                    separator = DELIMITER;
+                }
+                return sb.toString();
+            }
+
+            private static String encodeToCsv(String genre) {
+                StringBuilder sb = new StringBuilder();
+                int length = genre.length();
+                for (int i = 0; i < length; ++i) {
+                    char c = genre.charAt(i);
+                    switch (c) {
+                        case DOUBLE_QUOTE:
+                            sb.append(DOUBLE_QUOTE);
+                            break;
+                        case COMMA:
+                            sb.append(DOUBLE_QUOTE);
+                            break;
+                    }
+                    sb.append(c);
+                }
+                return sb.toString();
+            }
+
+            /**
+             * Decodes the genre strings from the text stored in the database.
+             *
+             * @param genres The encoded genre string retrieved from the
+             *            {@link #COLUMN_BROADCAST_GENRE} or {@link #COLUMN_CANONICAL_GENRE} column.
+             * @return genre strings.
+             */
+            public static @Genre String[] decode(@NonNull String genres) {
+                if (TextUtils.isEmpty(genres)) {
+                    // MNC and before will throw a NPE for {@code null} genres.
+                    return EMPTY_STRING_ARRAY;
+                }
+                if (genres.indexOf(COMMA) == -1 && genres.indexOf(DOUBLE_QUOTE) == -1) {
+                    return new String[] {genres.trim()};
+                }
+                StringBuilder sb = new StringBuilder();
+                List<String> results = new ArrayList<>();
+                int length = genres.length();
+                boolean escape = false;
+                for (int i = 0; i < length; ++i) {
+                    char c = genres.charAt(i);
+                    switch (c) {
+                        case DOUBLE_QUOTE:
+                            if (!escape) {
+                                escape = true;
+                                continue;
+                            }
+                            break;
+                        case COMMA:
+                            if (!escape) {
+                                String string = sb.toString().trim();
+                                if (string.length() > 0) {
+                                    results.add(string);
+                                }
+                                sb = new StringBuilder();
+                                continue;
+                            }
+                            break;
+                    }
+                    sb.append(c);
+                    escape = false;
+                }
+                String string = sb.toString().trim();
+                if (string.length() > 0) {
+                    results.add(string);
+                }
+                return results.toArray(new String[results.size()]);
+            }
+
+            /**
+             * Returns whether a given text is a canonical genre defined in {@link Genres}.
+             *
+             * @param genre The name of genre to be checked.
+             * @return {@code true} if the genre is canonical, otherwise {@code false}.
+             */
+            public static boolean isCanonical(String genre) {
+                return CANONICAL_GENRES.contains(genre);
+            }
+        }
+    }
+
+    /**
+     * Column definitions for the recorded TV programs table.
+     *
+     * <p>By default, the query results will be sorted by {@link #COLUMN_START_TIME_UTC_MILLIS} in
+     * ascending order.
+     */
+    public static final class RecordedPrograms implements BaseTvColumns, ProgramColumns {
+
+        /**
+         * The content:// style URI for this table.
+         *
+         * <p>SQL selection is not supported for {@link ContentResolver#query},
+         * {@link ContentResolver#update} and {@link ContentResolver#delete} operations.
+         */
+        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
+                + PATH_RECORDED_PROGRAM);
+
+        /** The MIME type of a directory of recorded TV programs. */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/recorded_program";
+
+        /** The MIME type of a single recorded TV program. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/recorded_program";
+
+        /**
+         * The ID of the TV channel that provides this recorded program.
+         *
+         * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_CHANNEL_ID = "channel_id";
+
+        /**
+         * The ID of the TV input service that is associated with this recorded program.
+         *
+         * <p>Use {@link #buildInputId} to build the ID.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_INPUT_ID = "input_id";
+
+        /**
+         * The start time of the original TV program, in milliseconds since the epoch.
+         *
+         * <p>Type: INTEGER (long)
+         * @see Programs#COLUMN_START_TIME_UTC_MILLIS
+         */
+        public static final String COLUMN_START_TIME_UTC_MILLIS =
+                Programs.COLUMN_START_TIME_UTC_MILLIS;
+
+        /**
+         * The end time of the original TV program, in milliseconds since the epoch.
+         *
+         * <p>Type: INTEGER (long)
+         * @see Programs#COLUMN_END_TIME_UTC_MILLIS
+         */
+        public static final String COLUMN_END_TIME_UTC_MILLIS = Programs.COLUMN_END_TIME_UTC_MILLIS;
+
+        /**
+         * The comma-separated genre string of this recorded TV program.
+         *
+         * <p>Use the same language appeared in the underlying broadcast standard, if applicable.
+         * (For example, one can refer to the genre strings used in Genre Descriptor of ATSC A/65 or
+         * Content Descriptor of ETSI EN 300 468, if appropriate.) Otherwise, leave empty. Use
+         * {@link Genres#encode Genres.encode()} to create a text that can be stored in this column.
+         * Use {@link Genres#decode Genres.decode()} to get the broadcast genre strings from the
+         * text stored in the column.
+         *
+         * <p>Type: TEXT
+         * @see Programs#COLUMN_BROADCAST_GENRE
+         */
+        public static final String COLUMN_BROADCAST_GENRE = Programs.COLUMN_BROADCAST_GENRE;
+
+        /**
+         * The URI of the recording data for this recorded program.
+         *
+         * <p>Together with {@link #COLUMN_RECORDING_DATA_BYTES}, applications can use this
+         * information to manage recording storage. The URI should indicate a file or directory with
+         * the scheme {@link android.content.ContentResolver#SCHEME_FILE}.
+         *
+         * <p>Type: TEXT
+         * @see #COLUMN_RECORDING_DATA_BYTES
+         */
+        public static final String COLUMN_RECORDING_DATA_URI = "recording_data_uri";
+
+        /**
+         * The data size (in bytes) for this recorded program.
+         *
+         * <p>Together with {@link #COLUMN_RECORDING_DATA_URI}, applications can use this
+         * information to manage recording storage.
+         *
+         * <p>Type: INTEGER (long)
+         * @see #COLUMN_RECORDING_DATA_URI
+         */
+        public static final String COLUMN_RECORDING_DATA_BYTES = "recording_data_bytes";
+
+        /**
+         * The duration (in milliseconds) of this recorded program.
+         *
+         * <p>The actual duration of the recorded program can differ from the one calculated by
+         * {@link #COLUMN_END_TIME_UTC_MILLIS} - {@link #COLUMN_START_TIME_UTC_MILLIS} as program
+         * recording can be interrupted in the middle for some reason, resulting in a partially
+         * recorded program, which is still playable.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_RECORDING_DURATION_MILLIS = "recording_duration_millis";
+
+        /**
+         * The expiration time for this recorded program, in milliseconds since the epoch.
+         *
+         * <p>Recorded TV programs do not expire by default unless explicitly requested by the user
+         * or the user allows applications to delete them in order to free up disk space for future
+         * recording. However, some TV content can have expiration date set by the content provider
+         * when recorded. This field is used to indicate such a restriction.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_RECORDING_EXPIRE_TIME_UTC_MILLIS =
+                "recording_expire_time_utc_millis";
+
+        private RecordedPrograms() {}
+    }
+
+    /**
+     * Column definitions for the preview TV programs table.
+     */
+    public static final class PreviewPrograms implements BaseTvColumns, ProgramColumns,
+        PreviewProgramColumns {
+
+        /**
+         * The content:// style URI for this table.
+         *
+         * <p>SQL selection is not supported for {@link ContentResolver#query},
+         * {@link ContentResolver#update} and {@link ContentResolver#delete} operations.
+         */
+        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
+                + PATH_PREVIEW_PROGRAM);
+
+        /** The MIME type of a directory of preview TV programs. */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/preview_program";
+
+        /** The MIME type of a single preview TV program. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/preview_program";
+
+        /**
+         * The ID of the TV channel that provides this TV program.
+         *
+         * <p>This value cannot be changed once it's set. Trying to modify it will make the update
+         * fail.
+         *
+         * <p>This is a part of the channel URI and matches to {@link BaseColumns#_ID}.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_CHANNEL_ID = "channel_id";
+
+        /**
+         * The weight of the preview program within the channel.
+         *
+         * <p>The UI may choose to show this item in a different position in the channel row.
+         * A larger weight value means the program is more important than other programs having
+         * smaller weight values. The value is relevant for the preview programs in the same
+         * channel. This is only relevant to {@link Channels#TYPE_PREVIEW}.
+         *
+         * <p>Can be empty.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_WEIGHT = "weight";
+
+        private PreviewPrograms() {}
+    }
+
+    /**
+     * Column definitions for the "watch next" TV programs table.
+     */
+    public static final class WatchNextPrograms implements BaseTvColumns, ProgramColumns,
+        PreviewProgramColumns {
+
+        /**
+         * The content:// style URI for this table.
+         *
+         * <p>SQL selection is not supported for {@link ContentResolver#query},
+         * {@link ContentResolver#update} and {@link ContentResolver#delete} operations.
+         */
+        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/"
+                + PATH_WATCH_NEXT_PROGRAM);
+
+        /** The MIME type of a directory of "watch next" TV programs. */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watch_next_program";
+
+        /** The MIME type of a single preview TV program. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watch_next_program";
+
+        /** @hide */
+        @IntDef({
+                WATCH_NEXT_TYPE_CONTINUE,
+                WATCH_NEXT_TYPE_NEXT,
+                WATCH_NEXT_TYPE_NEW,
+                WATCH_NEXT_TYPE_WATCHLIST,
+        })
+        @Retention(RetentionPolicy.SOURCE)
+        public @interface WatchNextType {}
+
+        /**
+         * The watch next type for CONTINUE. Use this type when the user has already watched more
+         * than 1 minute of this content.
+         *
+         * @see #COLUMN_WATCH_NEXT_TYPE
+         */
+        public static final int WATCH_NEXT_TYPE_CONTINUE = 0;
+
+        /**
+         * The watch next type for NEXT. Use this type when the user has watched one or more
+         * complete episodes from some episodic content, but there remains more than one episode
+         * remaining or there is one last episode remaining, but it is not “new” in that it was
+         * released before the user started watching the show.
+         *
+         * @see #COLUMN_WATCH_NEXT_TYPE
+         */
+        public static final int WATCH_NEXT_TYPE_NEXT = 1;
+
+        /**
+         * The watch next type for NEW. Use this type when the user had watched all of the available
+         * episodes from some episodic content, but a new episode became available since the user
+         * started watching the first episode and now there is exactly one unwatched episode. This
+         * could also work for recorded events in a series e.g. soccer matches or football games.
+         *
+         * @see #COLUMN_WATCH_NEXT_TYPE
+         */
+        public static final int WATCH_NEXT_TYPE_NEW = 2;
+
+        /**
+         * The watch next type for WATCHLIST. Use this type when the user has elected to explicitly
+         * add a movie, event or series to a “watchlist” as a manual way of curating what they
+         * want to watch next.
+         *
+         * @see #COLUMN_WATCH_NEXT_TYPE
+         */
+        public static final int WATCH_NEXT_TYPE_WATCHLIST = 3;
+
+        /**
+         * The "watch next" type of this program content.
+         *
+         * <p>The value should match one of the followings:
+         * {@link #WATCH_NEXT_TYPE_CONTINUE},
+         * {@link #WATCH_NEXT_TYPE_NEXT},
+         * {@link #WATCH_NEXT_TYPE_NEW}, and
+         * {@link #WATCH_NEXT_TYPE_WATCHLIST}.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: INTEGER
+         */
+        public static final String COLUMN_WATCH_NEXT_TYPE = "watch_next_type";
+
+        /**
+         * The last UTC time that the user engaged in this TV program, in milliseconds since the
+         * epoch. This is a hint for the application that is used for ordering of "watch next"
+         * programs.
+         *
+         * <p>The meaning of the value varies depending on the {@link #COLUMN_WATCH_NEXT_TYPE}:
+         * <ul>
+         *     <li>{@link #WATCH_NEXT_TYPE_CONTINUE}: the date that the user was last watching the
+         *     content.</li>
+         *     <li>{@link #WATCH_NEXT_TYPE_NEXT}: the date of the last episode watched.</li>
+         *     <li>{@link #WATCH_NEXT_TYPE_NEW}: the release date of the new episode.</li>
+         *     <li>{@link #WATCH_NEXT_TYPE_WATCHLIST}: the date the item was added to the Watchlist.
+         *     </li>
+         * </ul>
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_LAST_ENGAGEMENT_TIME_UTC_MILLIS =
+                "last_engagement_time_utc_millis";
+
+        private WatchNextPrograms() {}
+    }
+
+    /**
+     * Column definitions for the TV programs that the user watched. Applications do not have access
+     * to this table.
+     *
+     * <p>By default, the query results will be sorted by
+     * {@link WatchedPrograms#COLUMN_WATCH_START_TIME_UTC_MILLIS} in descending order.
+     * @hide
+     */
+    @SystemApi
+    public static final class WatchedPrograms implements BaseTvColumns {
+
+        /** The content:// style URI for this table. */
+        public static final Uri CONTENT_URI =
+                Uri.parse("content://" + AUTHORITY + "/watched_program");
+
+        /** The MIME type of a directory of watched programs. */
+        public static final String CONTENT_TYPE = "vnd.android.cursor.dir/watched_program";
+
+        /** The MIME type of a single item in this table. */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/watched_program";
+
+        /**
+         * The UTC time that the user started watching this TV program, in milliseconds since the
+         * epoch.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_WATCH_START_TIME_UTC_MILLIS =
+                "watch_start_time_utc_millis";
+
+        /**
+         * The UTC time that the user stopped watching this TV program, in milliseconds since the
+         * epoch.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_WATCH_END_TIME_UTC_MILLIS = "watch_end_time_utc_millis";
+
+        /**
+         * The ID of the TV channel that provides this TV program.
+         *
+         * <p>This is a required field.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_CHANNEL_ID = "channel_id";
+
+        /**
+         * The title of this TV program.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_TITLE = "title";
+
+        /**
+         * The start time of this TV program, in milliseconds since the epoch.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_START_TIME_UTC_MILLIS = "start_time_utc_millis";
+
+        /**
+         * The end time of this TV program, in milliseconds since the epoch.
+         *
+         * <p>Type: INTEGER (long)
+         */
+        public static final String COLUMN_END_TIME_UTC_MILLIS = "end_time_utc_millis";
+
+        /**
+         * The description of this TV program.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_DESCRIPTION = "description";
+
+        /**
+         * Extra parameters given to {@link TvInputService.Session#tune(Uri, android.os.Bundle)
+         * TvInputService.Session.tune(Uri, android.os.Bundle)} when tuning to the channel that
+         * provides this TV program. (Used internally.)
+         *
+         * <p>This column contains an encoded string that represents comma-separated key-value pairs of
+         * the tune parameters. (Ex. "[key1]=[value1], [key2]=[value2]"). '%' is used as an escape
+         * character for '%', '=', and ','.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_INTERNAL_TUNE_PARAMS = "tune_params";
+
+        /**
+         * The session token of this TV program. (Used internally.)
+         *
+         * <p>This contains a String representation of {@link IBinder} for
+         * {@link TvInputService.Session} that provides the current TV program. It is used
+         * internally to distinguish watched programs entries from different TV input sessions.
+         *
+         * <p>Type: TEXT
+         */
+        public static final String COLUMN_INTERNAL_SESSION_TOKEN = "session_token";
+
+        private WatchedPrograms() {}
+    }
+}
diff --git a/android/media/tv/TvInputHardwareInfo.java b/android/media/tv/TvInputHardwareInfo.java
new file mode 100644
index 0000000..0bedbd3
--- /dev/null
+++ b/android/media/tv/TvInputHardwareInfo.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright (C) 2014 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.tv;
+
+import static java.lang.annotation.RetentionPolicy.SOURCE;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.input.V1_0.Constants;
+import android.media.AudioManager;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+
+/**
+ * Simple container for information about TV input hardware.
+ * Not for third-party developers.
+ *
+ * @hide
+ */
+@SystemApi
+public final class TvInputHardwareInfo implements Parcelable {
+    static final String TAG = "TvInputHardwareInfo";
+
+    // Match hardware/libhardware/include/hardware/tv_input.h
+    public static final int TV_INPUT_TYPE_OTHER_HARDWARE = Constants.TV_INPUT_TYPE_OTHER;
+    public static final int TV_INPUT_TYPE_TUNER          = Constants.TV_INPUT_TYPE_TUNER;
+    public static final int TV_INPUT_TYPE_COMPOSITE      = Constants.TV_INPUT_TYPE_COMPOSITE;
+    public static final int TV_INPUT_TYPE_SVIDEO         = Constants.TV_INPUT_TYPE_SVIDEO;
+    public static final int TV_INPUT_TYPE_SCART          = Constants.TV_INPUT_TYPE_SCART;
+    public static final int TV_INPUT_TYPE_COMPONENT      = Constants.TV_INPUT_TYPE_COMPONENT;
+    public static final int TV_INPUT_TYPE_VGA            = Constants.TV_INPUT_TYPE_VGA;
+    public static final int TV_INPUT_TYPE_DVI            = Constants.TV_INPUT_TYPE_DVI;
+    public static final int TV_INPUT_TYPE_HDMI           = Constants.TV_INPUT_TYPE_HDMI;
+    public static final int TV_INPUT_TYPE_DISPLAY_PORT   = Constants.TV_INPUT_TYPE_DISPLAY_PORT;
+
+    /** @hide */
+    @Retention(SOURCE)
+    @IntDef({CABLE_CONNECTION_STATUS_UNKNOWN, CABLE_CONNECTION_STATUS_CONNECTED,
+        CABLE_CONNECTION_STATUS_DISCONNECTED})
+    public @interface CableConnectionStatus {}
+
+    // Match hardware/interfaces/tv/input/1.0/types.hal
+    /**
+     * The hardware is unsure about the connection status or does not support cable detection.
+     */
+    public static final int CABLE_CONNECTION_STATUS_UNKNOWN =
+            Constants.CABLE_CONNECTION_STATUS_UNKNOWN;
+
+    /**
+     * Cable is connected to the hardware.
+     */
+    public static final int CABLE_CONNECTION_STATUS_CONNECTED =
+            Constants.CABLE_CONNECTION_STATUS_CONNECTED;
+
+    /**
+     * Cable is disconnected to the hardware.
+     */
+    public static final int CABLE_CONNECTION_STATUS_DISCONNECTED =
+            Constants.CABLE_CONNECTION_STATUS_DISCONNECTED;
+
+    public static final @android.annotation.NonNull Parcelable.Creator<TvInputHardwareInfo> CREATOR =
+            new Parcelable.Creator<TvInputHardwareInfo>() {
+        @Override
+        public TvInputHardwareInfo createFromParcel(Parcel source) {
+            try {
+                TvInputHardwareInfo info = new TvInputHardwareInfo();
+                info.readFromParcel(source);
+                return info;
+            } catch (Exception e) {
+                Log.e(TAG, "Exception creating TvInputHardwareInfo from parcel", e);
+                return null;
+            }
+        }
+
+        @Override
+        public TvInputHardwareInfo[] newArray(int size) {
+            return new TvInputHardwareInfo[size];
+        }
+    };
+
+    private int mDeviceId;
+    private int mType;
+    private int mAudioType;
+    private String mAudioAddress;
+    private int mHdmiPortId;
+    @CableConnectionStatus
+    private int mCableConnectionStatus;
+
+    private TvInputHardwareInfo() {
+    }
+
+    public int getDeviceId() {
+        return mDeviceId;
+    }
+
+    public int getType() {
+        return mType;
+    }
+
+    public int getAudioType() {
+        return mAudioType;
+    }
+
+    public String getAudioAddress() {
+        return mAudioAddress;
+    }
+
+    public int getHdmiPortId() {
+        if (mType != TV_INPUT_TYPE_HDMI) {
+            throw new IllegalStateException();
+        }
+        return mHdmiPortId;
+    }
+
+    /**
+     * Gets the cable connection status of the hardware.
+     *
+     * @return {@code CABLE_CONNECTION_STATUS_CONNECTED} if cable is connected.
+     *         {@code CABLE_CONNECTION_STATUS_DISCONNECTED} if cable is disconnected.
+     *         {@code CABLE_CONNECTION_STATUS_UNKNOWN} if the hardware is unsure about the
+     *         connection status or does not support cable detection.
+     */
+    @CableConnectionStatus
+    public int getCableConnectionStatus() {
+        return mCableConnectionStatus;
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        StringBuilder b = new StringBuilder(128);
+        b.append("TvInputHardwareInfo {id=").append(mDeviceId);
+        b.append(", type=").append(mType);
+        b.append(", audio_type=").append(mAudioType);
+        b.append(", audio_addr=").append(mAudioAddress);
+        if (mType == TV_INPUT_TYPE_HDMI) {
+            b.append(", hdmi_port=").append(mHdmiPortId);
+        }
+        b.append(", cable_connection_status=").append(mCableConnectionStatus);
+        b.append("}");
+        return b.toString();
+    }
+
+    // Parcelable
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mDeviceId);
+        dest.writeInt(mType);
+        dest.writeInt(mAudioType);
+        dest.writeString(mAudioAddress);
+        if (mType == TV_INPUT_TYPE_HDMI) {
+            dest.writeInt(mHdmiPortId);
+        }
+        dest.writeInt(mCableConnectionStatus);
+    }
+
+    public void readFromParcel(Parcel source) {
+        mDeviceId = source.readInt();
+        mType = source.readInt();
+        mAudioType = source.readInt();
+        mAudioAddress = source.readString();
+        if (mType == TV_INPUT_TYPE_HDMI) {
+            mHdmiPortId = source.readInt();
+        }
+        mCableConnectionStatus = source.readInt();
+    }
+
+    /** @hide */
+    public Builder toBuilder() {
+        Builder newBuilder = new Builder()
+            .deviceId(mDeviceId)
+            .type(mType)
+            .audioType(mAudioType)
+            .audioAddress(mAudioAddress)
+            .cableConnectionStatus(mCableConnectionStatus);
+        if (mType == TV_INPUT_TYPE_HDMI) {
+            newBuilder.hdmiPortId(mHdmiPortId);
+        }
+        return newBuilder;
+    }
+
+    public static final class Builder {
+        private Integer mDeviceId = null;
+        private Integer mType = null;
+        private int mAudioType = AudioManager.DEVICE_NONE;
+        private String mAudioAddress = "";
+        private Integer mHdmiPortId = null;
+        private Integer mCableConnectionStatus = CABLE_CONNECTION_STATUS_UNKNOWN;
+
+        public Builder() {
+        }
+
+        public Builder deviceId(int deviceId) {
+            mDeviceId = deviceId;
+            return this;
+        }
+
+        public Builder type(int type) {
+            mType = type;
+            return this;
+        }
+
+        public Builder audioType(int audioType) {
+            mAudioType = audioType;
+            return this;
+        }
+
+        public Builder audioAddress(String audioAddress) {
+            mAudioAddress = audioAddress;
+            return this;
+        }
+
+        public Builder hdmiPortId(int hdmiPortId) {
+            mHdmiPortId = hdmiPortId;
+            return this;
+        }
+
+        /**
+         * Sets cable connection status.
+         */
+        public Builder cableConnectionStatus(@CableConnectionStatus int cableConnectionStatus) {
+            mCableConnectionStatus = cableConnectionStatus;
+            return this;
+        }
+
+        public TvInputHardwareInfo build() {
+            if (mDeviceId == null || mType == null) {
+                throw new UnsupportedOperationException();
+            }
+            if ((mType == TV_INPUT_TYPE_HDMI && mHdmiPortId == null) ||
+                    (mType != TV_INPUT_TYPE_HDMI && mHdmiPortId != null)) {
+                throw new UnsupportedOperationException();
+            }
+
+            TvInputHardwareInfo info = new TvInputHardwareInfo();
+            info.mDeviceId = mDeviceId;
+            info.mType = mType;
+            info.mAudioType = mAudioType;
+            if (info.mAudioType != AudioManager.DEVICE_NONE) {
+                info.mAudioAddress = mAudioAddress;
+            }
+            if (mHdmiPortId != null) {
+                info.mHdmiPortId = mHdmiPortId;
+            }
+            info.mCableConnectionStatus = mCableConnectionStatus;
+            return info;
+        }
+    }
+}
diff --git a/android/media/tv/TvInputInfo.java b/android/media/tv/TvInputInfo.java
new file mode 100644
index 0000000..54cb2bf
--- /dev/null
+++ b/android/media/tv/TvInputInfo.java
@@ -0,0 +1,1189 @@
+/*
+ * Copyright (C) 2014 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.tv;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.StringRes;
+import android.annotation.SystemApi;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
+import android.content.pm.ResolveInfo;
+import android.content.pm.ServiceInfo;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.Icon;
+import android.hardware.hdmi.HdmiControlManager;
+import android.hardware.hdmi.HdmiDeviceInfo;
+import android.hardware.hdmi.HdmiUtils;
+import android.hardware.hdmi.HdmiUtils.HdmiAddressRelativePosition;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.UserHandle;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.SparseIntArray;
+import android.util.Xml;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+
+/**
+ * This class is used to specify meta information of a TV input.
+ */
+public final class TvInputInfo implements Parcelable {
+    private static final boolean DEBUG = false;
+    private static final String TAG = "TvInputInfo";
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({TYPE_TUNER, TYPE_OTHER, TYPE_COMPOSITE, TYPE_SVIDEO, TYPE_SCART, TYPE_COMPONENT,
+            TYPE_VGA, TYPE_DVI, TYPE_HDMI, TYPE_DISPLAY_PORT})
+    public @interface Type {}
+
+    // Should be in sync with frameworks/base/core/res/res/values/attrs.xml
+    /**
+     * TV input type: the TV input service is a tuner which provides channels.
+     */
+    public static final int TYPE_TUNER = 0;
+    /**
+     * TV input type: a generic hardware TV input type.
+     */
+    public static final int TYPE_OTHER = 1000;
+    /**
+     * TV input type: the TV input service represents a composite port.
+     */
+    public static final int TYPE_COMPOSITE = 1001;
+    /**
+     * TV input type: the TV input service represents a SVIDEO port.
+     */
+    public static final int TYPE_SVIDEO = 1002;
+    /**
+     * TV input type: the TV input service represents a SCART port.
+     */
+    public static final int TYPE_SCART = 1003;
+    /**
+     * TV input type: the TV input service represents a component port.
+     */
+    public static final int TYPE_COMPONENT = 1004;
+    /**
+     * TV input type: the TV input service represents a VGA port.
+     */
+    public static final int TYPE_VGA = 1005;
+    /**
+     * TV input type: the TV input service represents a DVI port.
+     */
+    public static final int TYPE_DVI = 1006;
+    /**
+     * TV input type: the TV input service is HDMI. (e.g. HDMI 1)
+     */
+    public static final int TYPE_HDMI = 1007;
+    /**
+     * TV input type: the TV input service represents a display port.
+     */
+    public static final int TYPE_DISPLAY_PORT = 1008;
+
+    /**
+     * Used as a String extra field in setup intents created by {@link #createSetupIntent()} to
+     * supply the ID of a specific TV input to set up.
+     */
+    public static final String EXTRA_INPUT_ID = "android.media.tv.extra.INPUT_ID";
+
+    private final ResolveInfo mService;
+
+    private final String mId;
+    private final int mType;
+    private final boolean mIsHardwareInput;
+
+    // TODO: Remove mIconUri when createTvInputInfo() is removed.
+    private Uri mIconUri;
+
+    private final CharSequence mLabel;
+    private final int mLabelResId;
+    private final Icon mIcon;
+    private final Icon mIconStandby;
+    private final Icon mIconDisconnected;
+
+    // Attributes from XML meta data.
+    private final String mSetupActivity;
+    private final boolean mCanRecord;
+    private final boolean mCanPauseRecording;
+    private final int mTunerCount;
+
+    // Attributes specific to HDMI
+    private final HdmiDeviceInfo mHdmiDeviceInfo;
+    private final boolean mIsConnectedToHdmiSwitch;
+    @HdmiAddressRelativePosition
+    private final int mHdmiConnectionRelativePosition;
+    private final String mParentId;
+
+    private final Bundle mExtras;
+
+    /**
+     * Create a new instance of the TvInputInfo class, instantiating it from the given Context,
+     * ResolveInfo, and HdmiDeviceInfo.
+     *
+     * @param service The ResolveInfo returned from the package manager about this TV input service.
+     * @param hdmiDeviceInfo The HdmiDeviceInfo for a HDMI CEC logical device.
+     * @param parentId The ID of this TV input's parent input. {@code null} if none exists.
+     * @param label The label of this TvInputInfo. If it is {@code null} or empty, {@code service}
+     *            label will be loaded.
+     * @param iconUri The {@link android.net.Uri} to load the icon image. See
+     *            {@link android.content.ContentResolver#openInputStream}. If it is {@code null},
+     *            the application icon of {@code service} will be loaded.
+     * @hide
+     * @deprecated Use {@link Builder} instead.
+     */
+    @Deprecated
+    @SystemApi
+    public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service,
+            HdmiDeviceInfo hdmiDeviceInfo, String parentId, String label, Uri iconUri)
+                    throws XmlPullParserException, IOException {
+        TvInputInfo info = new TvInputInfo.Builder(context, service)
+                .setHdmiDeviceInfo(hdmiDeviceInfo)
+                .setParentId(parentId)
+                .setLabel(label)
+                .build();
+        info.mIconUri = iconUri;
+        return info;
+    }
+
+    /**
+     * Create a new instance of the TvInputInfo class, instantiating it from the given Context,
+     * ResolveInfo, and HdmiDeviceInfo.
+     *
+     * @param service The ResolveInfo returned from the package manager about this TV input service.
+     * @param hdmiDeviceInfo The HdmiDeviceInfo for a HDMI CEC logical device.
+     * @param parentId The ID of this TV input's parent input. {@code null} if none exists.
+     * @param labelRes The label resource ID of this TvInputInfo. If it is {@code 0},
+     *            {@code service} label will be loaded.
+     * @param icon The {@link android.graphics.drawable.Icon} to load the icon image. If it is
+     *            {@code null}, the application icon of {@code service} will be loaded.
+     * @hide
+     * @deprecated Use {@link Builder} instead.
+     */
+    @Deprecated
+    @SystemApi
+    public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service,
+            HdmiDeviceInfo hdmiDeviceInfo, String parentId, int labelRes, Icon icon)
+            throws XmlPullParserException, IOException {
+        return new TvInputInfo.Builder(context, service)
+                .setHdmiDeviceInfo(hdmiDeviceInfo)
+                .setParentId(parentId)
+                .setLabel(labelRes)
+                .setIcon(icon)
+                .build();
+    }
+
+    /**
+     * Create a new instance of the TvInputInfo class, instantiating it from the given Context,
+     * ResolveInfo, and TvInputHardwareInfo.
+     *
+     * @param service The ResolveInfo returned from the package manager about this TV input service.
+     * @param hardwareInfo The TvInputHardwareInfo for a TV input hardware device.
+     * @param label The label of this TvInputInfo. If it is {@code null} or empty, {@code service}
+     *            label will be loaded.
+     * @param iconUri The {@link android.net.Uri} to load the icon image. See
+     *            {@link android.content.ContentResolver#openInputStream}. If it is {@code null},
+     *            the application icon of {@code service} will be loaded.
+     * @hide
+     * @deprecated Use {@link Builder} instead.
+     */
+    @Deprecated
+    @SystemApi
+    public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service,
+            TvInputHardwareInfo hardwareInfo, String label, Uri iconUri)
+                    throws XmlPullParserException, IOException {
+        TvInputInfo info = new TvInputInfo.Builder(context, service)
+                .setTvInputHardwareInfo(hardwareInfo)
+                .setLabel(label)
+                .build();
+        info.mIconUri = iconUri;
+        return info;
+    }
+
+    /**
+     * Create a new instance of the TvInputInfo class, instantiating it from the given Context,
+     * ResolveInfo, and TvInputHardwareInfo.
+     *
+     * @param service The ResolveInfo returned from the package manager about this TV input service.
+     * @param hardwareInfo The TvInputHardwareInfo for a TV input hardware device.
+     * @param labelRes The label resource ID of this TvInputInfo. If it is {@code 0},
+     *            {@code service} label will be loaded.
+     * @param icon The {@link android.graphics.drawable.Icon} to load the icon image. If it is
+     *            {@code null}, the application icon of {@code service} will be loaded.
+     * @hide
+     * @deprecated Use {@link Builder} instead.
+     */
+    @Deprecated
+    @SystemApi
+    public static TvInputInfo createTvInputInfo(Context context, ResolveInfo service,
+            TvInputHardwareInfo hardwareInfo, int labelRes, Icon icon)
+            throws XmlPullParserException, IOException {
+        return new TvInputInfo.Builder(context, service)
+                .setTvInputHardwareInfo(hardwareInfo)
+                .setLabel(labelRes)
+                .setIcon(icon)
+                .build();
+    }
+
+    private TvInputInfo(ResolveInfo service, String id, int type, boolean isHardwareInput,
+            CharSequence label, int labelResId, Icon icon, Icon iconStandby, Icon iconDisconnected,
+            String setupActivity, boolean canRecord, boolean canPauseRecording, int tunerCount,
+            HdmiDeviceInfo hdmiDeviceInfo, boolean isConnectedToHdmiSwitch,
+            @HdmiAddressRelativePosition int hdmiConnectionRelativePosition, String parentId,
+            Bundle extras) {
+        mService = service;
+        mId = id;
+        mType = type;
+        mIsHardwareInput = isHardwareInput;
+        mLabel = label;
+        mLabelResId = labelResId;
+        mIcon = icon;
+        mIconStandby = iconStandby;
+        mIconDisconnected = iconDisconnected;
+        mSetupActivity = setupActivity;
+        mCanRecord = canRecord;
+        mCanPauseRecording = canPauseRecording;
+        mTunerCount = tunerCount;
+        mHdmiDeviceInfo = hdmiDeviceInfo;
+        mIsConnectedToHdmiSwitch = isConnectedToHdmiSwitch;
+        mHdmiConnectionRelativePosition = hdmiConnectionRelativePosition;
+        mParentId = parentId;
+        mExtras = extras;
+    }
+
+    /**
+     * Returns a unique ID for this TV input. The ID is generated from the package and class name
+     * implementing the TV input service.
+     */
+    public String getId() {
+        return mId;
+    }
+
+    /**
+     * Returns the parent input ID.
+     *
+     * <p>A TV input may have a parent input if the TV input is actually a logical representation of
+     * a device behind the hardware port represented by the parent input.
+     * For example, a HDMI CEC logical device, connected to a HDMI port, appears as another TV
+     * input. In this case, the parent input of this logical device is the HDMI port.
+     *
+     * <p>Applications may group inputs by parent input ID to provide an easier access to inputs
+     * sharing the same physical port. In the example of HDMI CEC, logical HDMI CEC devices behind
+     * the same HDMI port have the same parent ID, which is the ID representing the port. Thus
+     * applications can group the hardware HDMI port and the logical HDMI CEC devices behind it
+     * together using this method.
+     *
+     * @return the ID of the parent input, if exists. Returns {@code null} if the parent input is
+     *         not specified.
+     */
+    public String getParentId() {
+        return mParentId;
+    }
+
+    /**
+     * Returns the information of the service that implements this TV input.
+     */
+    public ServiceInfo getServiceInfo() {
+        return mService.serviceInfo;
+    }
+
+    /**
+     * Returns the component of the service that implements this TV input.
+     * @hide
+     */
+    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+    public ComponentName getComponent() {
+        return new ComponentName(mService.serviceInfo.packageName, mService.serviceInfo.name);
+    }
+
+    /**
+     * Returns an intent to start the setup activity for this TV input.
+     */
+    public Intent createSetupIntent() {
+        if (!TextUtils.isEmpty(mSetupActivity)) {
+            Intent intent = new Intent(Intent.ACTION_MAIN);
+            intent.setClassName(mService.serviceInfo.packageName, mSetupActivity);
+            intent.putExtra(EXTRA_INPUT_ID, getId());
+            return intent;
+        }
+        return null;
+    }
+
+    /**
+     * Returns an intent to start the settings activity for this TV input.
+     *
+     * @deprecated Use {@link #createSetupIntent()} instead. Settings activity is deprecated.
+     *             Use setup activity instead to provide settings.
+     */
+    @Deprecated
+    public Intent createSettingsIntent() {
+        return null;
+    }
+
+    /**
+     * Returns the type of this TV input.
+     */
+    @Type
+    public int getType() {
+        return mType;
+    }
+
+    /**
+     * Returns the number of tuners this TV input has.
+     *
+     * <p>This method is valid only for inputs of type {@link #TYPE_TUNER}. For inputs of other
+     * types, it returns 0.
+     *
+     * <p>Tuners correspond to physical/logical resources that allow reception of TV signal. Having
+     * <i>N</i> tuners means that the TV input is capable of receiving <i>N</i> different channels
+     * concurrently.
+     */
+    public int getTunerCount() {
+        return mTunerCount;
+    }
+
+    /**
+     * Returns {@code true} if this TV input can record TV programs, {@code false} otherwise.
+     */
+    public boolean canRecord() {
+        return mCanRecord;
+    }
+
+    /**
+     * Returns {@code true} if this TV input can pause recording TV programs,
+     * {@code false} otherwise.
+     */
+    public boolean canPauseRecording() {
+        return mCanPauseRecording;
+    }
+
+    /**
+     * Returns domain-specific extras associated with this TV input.
+     */
+    public Bundle getExtras() {
+        return mExtras;
+    }
+
+    /**
+     * Returns the HDMI device information of this TV input.
+     * @hide
+     */
+    @SystemApi
+    public HdmiDeviceInfo getHdmiDeviceInfo() {
+        if (mType == TYPE_HDMI) {
+            return mHdmiDeviceInfo;
+        }
+        return null;
+    }
+
+    /**
+     * Returns {@code true} if this TV input is pass-though which does not have any real channels in
+     * TvProvider. {@code false} otherwise.
+     *
+     * @see TvContract#buildChannelUriForPassthroughInput(String)
+     */
+    public boolean isPassthroughInput() {
+        return mType != TYPE_TUNER;
+    }
+
+    /**
+     * Returns {@code true} if this TV input represents a hardware device. (e.g. built-in tuner,
+     * HDMI1) {@code false} otherwise.
+     * @hide
+     */
+    @SystemApi
+    public boolean isHardwareInput() {
+        return mIsHardwareInput;
+    }
+
+    /**
+     * Returns {@code true}, if a CEC device for this TV input is connected to an HDMI switch, i.e.,
+     * the device isn't directly connected to a HDMI port.
+     * TODO(b/110094868): add @Deprecated for Q
+     * @hide
+     */
+    @SystemApi
+    public boolean isConnectedToHdmiSwitch() {
+        return mIsConnectedToHdmiSwitch;
+    }
+
+    /**
+     * Returns the relative position of this HDMI input.
+     * TODO(b/110094868): unhide for Q
+     * @hide
+     */
+    @HdmiAddressRelativePosition
+    public int getHdmiConnectionRelativePosition() {
+        return mHdmiConnectionRelativePosition;
+    }
+
+    /**
+     * Checks if this TV input is marked hidden by the user in the settings.
+     *
+     * @param context Supplies a {@link Context} used to check if this TV input is hidden.
+     * @return {@code true} if the user marked this TV input hidden in settings. {@code false}
+     *         otherwise.
+     */
+    public boolean isHidden(Context context) {
+        return TvInputSettings.isHidden(context, mId, UserHandle.myUserId());
+    }
+
+    /**
+     * Loads the user-displayed label for this TV input.
+     *
+     * @param context Supplies a {@link Context} used to load the label.
+     * @return a CharSequence containing the TV input's label. If the TV input does not have
+     *         a label, its name is returned.
+     */
+    public CharSequence loadLabel(@NonNull Context context) {
+        if (mLabelResId != 0) {
+            return context.getPackageManager().getText(mService.serviceInfo.packageName,
+                    mLabelResId, null);
+        } else if (!TextUtils.isEmpty(mLabel)) {
+            return mLabel;
+        }
+        return mService.loadLabel(context.getPackageManager());
+    }
+
+    /**
+     * Loads the custom label set by user in settings.
+     *
+     * @param context Supplies a {@link Context} used to load the custom label.
+     * @return a CharSequence containing the TV input's custom label. {@code null} if there is no
+     *         custom label.
+     */
+    public CharSequence loadCustomLabel(Context context) {
+        return TvInputSettings.getCustomLabel(context, mId, UserHandle.myUserId());
+    }
+
+    /**
+     * Loads the user-displayed icon for this TV input.
+     *
+     * @param context Supplies a {@link Context} used to load the icon.
+     * @return a Drawable containing the TV input's icon. If the TV input does not have an icon,
+     *         application's icon is returned. If it's unavailable too, {@code null} is returned.
+     */
+    public Drawable loadIcon(@NonNull Context context) {
+        if (mIcon != null) {
+            return mIcon.loadDrawable(context);
+        } else if (mIconUri != null) {
+            try (InputStream is = context.getContentResolver().openInputStream(mIconUri)) {
+                Drawable drawable = Drawable.createFromStream(is, null);
+                if (drawable != null) {
+                    return drawable;
+                }
+            } catch (IOException e) {
+                Log.w(TAG, "Loading the default icon due to a failure on loading " + mIconUri, e);
+                // Falls back.
+            }
+        }
+        return loadServiceIcon(context);
+    }
+
+    /**
+     * Loads the user-displayed icon for this TV input per input state.
+     *
+     * @param context Supplies a {@link Context} used to load the icon.
+     * @param state The input state. Should be one of the followings.
+     *              {@link TvInputManager#INPUT_STATE_CONNECTED},
+     *              {@link TvInputManager#INPUT_STATE_CONNECTED_STANDBY} and
+     *              {@link TvInputManager#INPUT_STATE_DISCONNECTED}.
+     * @return a Drawable containing the TV input's icon for the given state or {@code null} if such
+     *         an icon is not defined.
+     * @hide
+     */
+    @SystemApi
+    public Drawable loadIcon(@NonNull Context context, int state) {
+        if (state == TvInputManager.INPUT_STATE_CONNECTED) {
+            return loadIcon(context);
+        } else if (state == TvInputManager.INPUT_STATE_CONNECTED_STANDBY) {
+            if (mIconStandby != null) {
+                return mIconStandby.loadDrawable(context);
+            }
+        } else if (state == TvInputManager.INPUT_STATE_DISCONNECTED) {
+            if (mIconDisconnected != null) {
+                return mIconDisconnected.loadDrawable(context);
+            }
+        } else {
+            throw new IllegalArgumentException("Unknown state: " + state);
+        }
+        return null;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public int hashCode() {
+        return mId.hashCode();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) {
+            return true;
+        }
+
+        if (!(o instanceof TvInputInfo)) {
+            return false;
+        }
+
+        TvInputInfo obj = (TvInputInfo) o;
+        return Objects.equals(mService, obj.mService)
+                && TextUtils.equals(mId, obj.mId)
+                && mType == obj.mType
+                && mIsHardwareInput == obj.mIsHardwareInput
+                && TextUtils.equals(mLabel, obj.mLabel)
+                && Objects.equals(mIconUri, obj.mIconUri)
+                && mLabelResId == obj.mLabelResId
+                && Objects.equals(mIcon, obj.mIcon)
+                && Objects.equals(mIconStandby, obj.mIconStandby)
+                && Objects.equals(mIconDisconnected, obj.mIconDisconnected)
+                && TextUtils.equals(mSetupActivity, obj.mSetupActivity)
+                && mCanRecord == obj.mCanRecord
+                && mCanPauseRecording == obj.mCanPauseRecording
+                && mTunerCount == obj.mTunerCount
+                && Objects.equals(mHdmiDeviceInfo, obj.mHdmiDeviceInfo)
+                && mIsConnectedToHdmiSwitch == obj.mIsConnectedToHdmiSwitch
+                && mHdmiConnectionRelativePosition == obj.mHdmiConnectionRelativePosition
+                && TextUtils.equals(mParentId, obj.mParentId)
+                && Objects.equals(mExtras, obj.mExtras);
+    }
+
+    @Override
+    public String toString() {
+        return "TvInputInfo{id=" + mId
+                + ", pkg=" + mService.serviceInfo.packageName
+                + ", service=" + mService.serviceInfo.name + "}";
+    }
+
+    /**
+     * Used to package this object into a {@link Parcel}.
+     *
+     * @param dest The {@link Parcel} to be written.
+     * @param flags The flags used for parceling.
+     */
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        mService.writeToParcel(dest, flags);
+        dest.writeString(mId);
+        dest.writeInt(mType);
+        dest.writeByte(mIsHardwareInput ? (byte) 1 : 0);
+        TextUtils.writeToParcel(mLabel, dest, flags);
+        dest.writeParcelable(mIconUri, flags);
+        dest.writeInt(mLabelResId);
+        dest.writeParcelable(mIcon, flags);
+        dest.writeParcelable(mIconStandby, flags);
+        dest.writeParcelable(mIconDisconnected, flags);
+        dest.writeString(mSetupActivity);
+        dest.writeByte(mCanRecord ? (byte) 1 : 0);
+        dest.writeByte(mCanPauseRecording ? (byte) 1 : 0);
+        dest.writeInt(mTunerCount);
+        dest.writeParcelable(mHdmiDeviceInfo, flags);
+        dest.writeByte(mIsConnectedToHdmiSwitch ? (byte) 1 : 0);
+        dest.writeInt(mHdmiConnectionRelativePosition);
+        dest.writeString(mParentId);
+        dest.writeBundle(mExtras);
+    }
+
+    private Drawable loadServiceIcon(Context context) {
+        if (mService.serviceInfo.icon == 0
+                && mService.serviceInfo.applicationInfo.icon == 0) {
+            return null;
+        }
+        return mService.serviceInfo.loadIcon(context.getPackageManager());
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<TvInputInfo> CREATOR =
+            new Parcelable.Creator<TvInputInfo>() {
+        @Override
+        public TvInputInfo createFromParcel(Parcel in) {
+            return new TvInputInfo(in);
+        }
+
+        @Override
+        public TvInputInfo[] newArray(int size) {
+            return new TvInputInfo[size];
+        }
+    };
+
+    private TvInputInfo(Parcel in) {
+        mService = ResolveInfo.CREATOR.createFromParcel(in);
+        mId = in.readString();
+        mType = in.readInt();
+        mIsHardwareInput = in.readByte() == 1;
+        mLabel = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(in);
+        mIconUri = in.readParcelable(null);
+        mLabelResId = in.readInt();
+        mIcon = in.readParcelable(null);
+        mIconStandby = in.readParcelable(null);
+        mIconDisconnected = in.readParcelable(null);
+        mSetupActivity = in.readString();
+        mCanRecord = in.readByte() == 1;
+        mCanPauseRecording = in.readByte() == 1;
+        mTunerCount = in.readInt();
+        mHdmiDeviceInfo = in.readParcelable(null);
+        mIsConnectedToHdmiSwitch = in.readByte() == 1;
+        mHdmiConnectionRelativePosition = in.readInt();
+        mParentId = in.readString();
+        mExtras = in.readBundle();
+    }
+
+    /**
+     * A convenience builder for creating {@link TvInputInfo} objects.
+     */
+    public static final class Builder {
+        private static final int LENGTH_HDMI_PHYSICAL_ADDRESS = 4;
+        private static final int LENGTH_HDMI_DEVICE_ID = 2;
+
+        private static final String XML_START_TAG_NAME = "tv-input";
+        private static final String DELIMITER_INFO_IN_ID = "/";
+        private static final String PREFIX_HDMI_DEVICE = "HDMI";
+        private static final String PREFIX_HARDWARE_DEVICE = "HW";
+
+        private static final SparseIntArray sHardwareTypeToTvInputType = new SparseIntArray();
+        static {
+            sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_OTHER_HARDWARE,
+                    TYPE_OTHER);
+            sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_TUNER, TYPE_TUNER);
+            sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_COMPOSITE,
+                    TYPE_COMPOSITE);
+            sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_SVIDEO, TYPE_SVIDEO);
+            sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_SCART, TYPE_SCART);
+            sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_COMPONENT,
+                    TYPE_COMPONENT);
+            sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_VGA, TYPE_VGA);
+            sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_DVI, TYPE_DVI);
+            sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_HDMI, TYPE_HDMI);
+            sHardwareTypeToTvInputType.put(TvInputHardwareInfo.TV_INPUT_TYPE_DISPLAY_PORT,
+                    TYPE_DISPLAY_PORT);
+        }
+
+        private final Context mContext;
+        private final ResolveInfo mResolveInfo;
+        private CharSequence mLabel;
+        private int mLabelResId;
+        private Icon mIcon;
+        private Icon mIconStandby;
+        private Icon mIconDisconnected;
+        private String mSetupActivity;
+        private Boolean mCanRecord;
+        private Boolean mCanPauseRecording;
+        private Integer mTunerCount;
+        private TvInputHardwareInfo mTvInputHardwareInfo;
+        private HdmiDeviceInfo mHdmiDeviceInfo;
+        private String mParentId;
+        private Bundle mExtras;
+
+        /**
+         * Constructs a new builder for {@link TvInputInfo}.
+         *
+         * @param context A Context of the application package implementing this class.
+         * @param component The name of the application component to be used for the
+         *            {@link TvInputService}.
+         */
+        public Builder(Context context, ComponentName component) {
+            if (context == null) {
+                throw new IllegalArgumentException("context cannot be null.");
+            }
+            Intent intent = new Intent(TvInputService.SERVICE_INTERFACE).setComponent(component);
+            mResolveInfo = context.getPackageManager().resolveService(intent,
+                    PackageManager.GET_SERVICES | PackageManager.GET_META_DATA);
+            if (mResolveInfo == null) {
+                throw new IllegalArgumentException("Invalid component. Can't find the service.");
+            }
+            mContext = context;
+        }
+
+        /**
+         * Constructs a new builder for {@link TvInputInfo}.
+         *
+         * @param resolveInfo The ResolveInfo returned from the package manager about this TV input
+         *            service.
+         * @hide
+         */
+        public Builder(Context context, ResolveInfo resolveInfo) {
+            if (context == null) {
+                throw new IllegalArgumentException("context cannot be null");
+            }
+            if (resolveInfo == null) {
+                throw new IllegalArgumentException("resolveInfo cannot be null");
+            }
+            mContext = context;
+            mResolveInfo = resolveInfo;
+        }
+
+        /**
+         * Sets the icon.
+         *
+         * @param icon The icon that represents this TV input.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @SystemApi
+        public Builder setIcon(Icon icon) {
+            this.mIcon = icon;
+            return this;
+        }
+
+        /**
+         * Sets the icon for a given input state.
+         *
+         * @param icon The icon that represents this TV input for the given state.
+         * @param state The input state. Should be one of the followings.
+         *              {@link TvInputManager#INPUT_STATE_CONNECTED},
+         *              {@link TvInputManager#INPUT_STATE_CONNECTED_STANDBY} and
+         *              {@link TvInputManager#INPUT_STATE_DISCONNECTED}.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @SystemApi
+        public Builder setIcon(Icon icon, int state) {
+            if (state == TvInputManager.INPUT_STATE_CONNECTED) {
+                this.mIcon = icon;
+            } else if (state == TvInputManager.INPUT_STATE_CONNECTED_STANDBY) {
+                this.mIconStandby = icon;
+            } else if (state == TvInputManager.INPUT_STATE_DISCONNECTED) {
+                this.mIconDisconnected = icon;
+            } else {
+                throw new IllegalArgumentException("Unknown state: " + state);
+            }
+            return this;
+        }
+
+        /**
+         * Sets the label.
+         *
+         * @param label The text to be used as label.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @SystemApi
+        public Builder setLabel(CharSequence label) {
+            if (mLabelResId != 0) {
+                throw new IllegalStateException("Resource ID for label is already set.");
+            }
+            this.mLabel = label;
+            return this;
+        }
+
+        /**
+         * Sets the label.
+         *
+         * @param resId The resource ID of the text to use.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @SystemApi
+        public Builder setLabel(@StringRes int resId) {
+            if (mLabel != null) {
+                throw new IllegalStateException("Label text is already set.");
+            }
+            this.mLabelResId = resId;
+            return this;
+        }
+
+        /**
+         * Sets the HdmiDeviceInfo.
+         *
+         * @param hdmiDeviceInfo The HdmiDeviceInfo for a HDMI CEC logical device.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @SystemApi
+        public Builder setHdmiDeviceInfo(HdmiDeviceInfo hdmiDeviceInfo) {
+            if (mTvInputHardwareInfo != null) {
+                Log.w(TAG, "TvInputHardwareInfo will not be used to build this TvInputInfo");
+                mTvInputHardwareInfo = null;
+            }
+            this.mHdmiDeviceInfo = hdmiDeviceInfo;
+            return this;
+        }
+
+        /**
+         * Sets the parent ID.
+         *
+         * @param parentId The parent ID.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @SystemApi
+        public Builder setParentId(String parentId) {
+            this.mParentId = parentId;
+            return this;
+        }
+
+        /**
+         * Sets the TvInputHardwareInfo.
+         *
+         * @param tvInputHardwareInfo
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         * @hide
+         */
+        @SystemApi
+        public Builder setTvInputHardwareInfo(TvInputHardwareInfo tvInputHardwareInfo) {
+            if (mHdmiDeviceInfo != null) {
+                Log.w(TAG, "mHdmiDeviceInfo will not be used to build this TvInputInfo");
+                mHdmiDeviceInfo = null;
+            }
+            this.mTvInputHardwareInfo = tvInputHardwareInfo;
+            return this;
+        }
+
+        /**
+         * Sets the tuner count. Valid only for {@link #TYPE_TUNER}.
+         *
+         * @param tunerCount The number of tuners this TV input has.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setTunerCount(int tunerCount) {
+            this.mTunerCount = tunerCount;
+            return this;
+        }
+
+        /**
+         * Sets whether this TV input can record TV programs or not.
+         *
+         * @param canRecord Whether this TV input can record TV programs.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setCanRecord(boolean canRecord) {
+            this.mCanRecord = canRecord;
+            return this;
+        }
+
+        /**
+         * Sets whether this TV input can pause recording TV programs or not.
+         *
+         * @param canPauseRecording Whether this TV input can pause recording TV programs.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        @NonNull
+        public Builder setCanPauseRecording(boolean canPauseRecording) {
+            this.mCanPauseRecording = canPauseRecording;
+            return this;
+        }
+
+        /**
+         * Sets domain-specific extras associated with this TV input.
+         *
+         * @param extras Domain-specific extras associated with this TV input. Keys <em>must</em> be
+         *            a scoped name, i.e. prefixed with a package name you own, so that different
+         *            developers will not create conflicting keys.
+         * @return This Builder object to allow for chaining of calls to builder methods.
+         */
+        public Builder setExtras(Bundle extras) {
+            this.mExtras = extras;
+            return this;
+        }
+
+        /**
+         * Creates a {@link TvInputInfo} instance with the specified fields. Most of the information
+         * is obtained by parsing the AndroidManifest and {@link TvInputService#SERVICE_META_DATA}
+         * for the {@link TvInputService} this TV input implements.
+         *
+         * @return TvInputInfo containing information about this TV input.
+         */
+        public TvInputInfo build() {
+            ComponentName componentName = new ComponentName(mResolveInfo.serviceInfo.packageName,
+                    mResolveInfo.serviceInfo.name);
+            String id;
+            int type;
+            boolean isHardwareInput = false;
+            boolean isConnectedToHdmiSwitch = false;
+            @HdmiAddressRelativePosition
+            int hdmiConnectionRelativePosition = HdmiUtils.HDMI_RELATIVE_POSITION_UNKNOWN;
+
+            if (mHdmiDeviceInfo != null) {
+                id = generateInputId(componentName, mHdmiDeviceInfo);
+                type = TYPE_HDMI;
+                isHardwareInput = true;
+                hdmiConnectionRelativePosition = getRelativePosition(mContext, mHdmiDeviceInfo);
+                isConnectedToHdmiSwitch =
+                        hdmiConnectionRelativePosition
+                                != HdmiUtils.HDMI_RELATIVE_POSITION_DIRECTLY_BELOW;
+            } else if (mTvInputHardwareInfo != null) {
+                id = generateInputId(componentName, mTvInputHardwareInfo);
+                type = sHardwareTypeToTvInputType.get(mTvInputHardwareInfo.getType(), TYPE_TUNER);
+                isHardwareInput = true;
+            } else {
+                id = generateInputId(componentName);
+                type = TYPE_TUNER;
+            }
+            parseServiceMetadata(type);
+            return new TvInputInfo(mResolveInfo, id, type, isHardwareInput, mLabel, mLabelResId,
+                    mIcon, mIconStandby, mIconDisconnected, mSetupActivity,
+                    mCanRecord == null ? false : mCanRecord,
+                    mCanPauseRecording == null ? false : mCanPauseRecording,
+                    mTunerCount == null ? 0 : mTunerCount,
+                    mHdmiDeviceInfo, isConnectedToHdmiSwitch, hdmiConnectionRelativePosition,
+                    mParentId, mExtras);
+        }
+
+        private static String generateInputId(ComponentName name) {
+            return name.flattenToShortString();
+        }
+
+        private static String generateInputId(ComponentName name, HdmiDeviceInfo hdmiDeviceInfo) {
+            // Example of the format : "/HDMI%04X%02X"
+            String format = DELIMITER_INFO_IN_ID + PREFIX_HDMI_DEVICE
+                    + "%0" + LENGTH_HDMI_PHYSICAL_ADDRESS + "X"
+                    + "%0" + LENGTH_HDMI_DEVICE_ID + "X";
+            return name.flattenToShortString() + String.format(Locale.ENGLISH, format,
+                    hdmiDeviceInfo.getPhysicalAddress(), hdmiDeviceInfo.getId());
+        }
+
+        private static String generateInputId(ComponentName name,
+                TvInputHardwareInfo tvInputHardwareInfo) {
+            return name.flattenToShortString() + DELIMITER_INFO_IN_ID + PREFIX_HARDWARE_DEVICE
+                    + tvInputHardwareInfo.getDeviceId();
+        }
+
+        private static int getRelativePosition(Context context, HdmiDeviceInfo info) {
+            HdmiControlManager hcm =
+                    (HdmiControlManager) context.getSystemService(Context.HDMI_CONTROL_SERVICE);
+            if (hcm == null) {
+                return HdmiUtils.HDMI_RELATIVE_POSITION_UNKNOWN;
+            }
+            return HdmiUtils.getHdmiAddressRelativePosition(
+                    info.getPhysicalAddress(), hcm.getPhysicalAddress());
+        }
+
+        private void parseServiceMetadata(int inputType) {
+            ServiceInfo si = mResolveInfo.serviceInfo;
+            PackageManager pm = mContext.getPackageManager();
+            try (XmlResourceParser parser =
+                         si.loadXmlMetaData(pm, TvInputService.SERVICE_META_DATA)) {
+                if (parser == null) {
+                    throw new IllegalStateException("No " + TvInputService.SERVICE_META_DATA
+                            + " meta-data found for " + si.name);
+                }
+
+                Resources res = pm.getResourcesForApplication(si.applicationInfo);
+                AttributeSet attrs = Xml.asAttributeSet(parser);
+
+                int type;
+                while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+                        && type != XmlPullParser.START_TAG) {
+                }
+
+                String nodeName = parser.getName();
+                if (!XML_START_TAG_NAME.equals(nodeName)) {
+                    throw new IllegalStateException("Meta-data does not start with "
+                            + XML_START_TAG_NAME + " tag for " + si.name);
+                }
+
+                TypedArray sa = res.obtainAttributes(attrs,
+                        com.android.internal.R.styleable.TvInputService);
+                mSetupActivity = sa.getString(
+                        com.android.internal.R.styleable.TvInputService_setupActivity);
+                if (mCanRecord == null) {
+                    mCanRecord = sa.getBoolean(
+                            com.android.internal.R.styleable.TvInputService_canRecord, false);
+                }
+                if (mTunerCount == null && inputType == TYPE_TUNER) {
+                    mTunerCount = sa.getInt(
+                            com.android.internal.R.styleable.TvInputService_tunerCount, 1);
+                }
+                if (mCanPauseRecording == null) {
+                    mCanPauseRecording = sa.getBoolean(
+                            com.android.internal.R.styleable.TvInputService_canPauseRecording,
+                            false);
+                }
+
+                sa.recycle();
+            } catch (IOException | XmlPullParserException e) {
+                throw new IllegalStateException("Failed reading meta-data for " + si.packageName, e);
+            } catch (NameNotFoundException e) {
+                throw new IllegalStateException("No resources found for " + si.packageName, e);
+            }
+        }
+    }
+
+    /**
+     * Utility class for putting and getting settings for TV input.
+     *
+     * @hide
+     */
+    @SystemApi
+    public static final class TvInputSettings {
+        private static final String TV_INPUT_SEPARATOR = ":";
+        private static final String CUSTOM_NAME_SEPARATOR = ",";
+
+        private TvInputSettings() { }
+
+        private static boolean isHidden(Context context, String inputId, int userId) {
+            return getHiddenTvInputIds(context, userId).contains(inputId);
+        }
+
+        private static String getCustomLabel(Context context, String inputId, int userId) {
+            return getCustomLabels(context, userId).get(inputId);
+        }
+
+        /**
+         * Returns a set of TV input IDs which are marked as hidden by user in the settings.
+         *
+         * @param context The application context
+         * @param userId The user ID for the stored hidden input set
+         * @hide
+         */
+        @SystemApi
+        public static Set<String> getHiddenTvInputIds(Context context, int userId) {
+            String hiddenIdsString = Settings.Secure.getStringForUser(
+                    context.getContentResolver(), Settings.Secure.TV_INPUT_HIDDEN_INPUTS, userId);
+            Set<String> set = new HashSet<>();
+            if (TextUtils.isEmpty(hiddenIdsString)) {
+                return set;
+            }
+            String[] ids = hiddenIdsString.split(TV_INPUT_SEPARATOR);
+            for (String id : ids) {
+                set.add(Uri.decode(id));
+            }
+            return set;
+        }
+
+        /**
+         * Returns a map of TV input ID/custom label pairs set by the user in the settings.
+         *
+         * @param context The application context
+         * @param userId The user ID for the stored hidden input map
+         * @hide
+         */
+        @SystemApi
+        public static Map<String, String> getCustomLabels(Context context, int userId) {
+            String labelsString = Settings.Secure.getStringForUser(
+                    context.getContentResolver(), Settings.Secure.TV_INPUT_CUSTOM_LABELS, userId);
+            Map<String, String> map = new HashMap<>();
+            if (TextUtils.isEmpty(labelsString)) {
+                return map;
+            }
+            String[] pairs = labelsString.split(TV_INPUT_SEPARATOR);
+            for (String pairString : pairs) {
+                String[] pair = pairString.split(CUSTOM_NAME_SEPARATOR);
+                map.put(Uri.decode(pair[0]), Uri.decode(pair[1]));
+            }
+            return map;
+        }
+
+        /**
+         * Stores a set of TV input IDs which are marked as hidden by user. This is expected to
+         * be called from the settings app.
+         *
+         * @param context The application context
+         * @param hiddenInputIds A set including all the hidden TV input IDs
+         * @param userId The user ID for the stored hidden input set
+         * @hide
+         */
+        @SystemApi
+        public static void putHiddenTvInputs(Context context, Set<String> hiddenInputIds,
+                int userId) {
+            StringBuilder builder = new StringBuilder();
+            boolean firstItem = true;
+            for (String inputId : hiddenInputIds) {
+                ensureValidField(inputId);
+                if (firstItem) {
+                    firstItem = false;
+                } else {
+                    builder.append(TV_INPUT_SEPARATOR);
+                }
+                builder.append(Uri.encode(inputId));
+            }
+            Settings.Secure.putStringForUser(context.getContentResolver(),
+                    Settings.Secure.TV_INPUT_HIDDEN_INPUTS, builder.toString(), userId);
+
+            // Notify of the TvInputInfo changes.
+            TvInputManager tm = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
+            for (String inputId : hiddenInputIds) {
+                TvInputInfo info = tm.getTvInputInfo(inputId);
+                if (info != null) {
+                    tm.updateTvInputInfo(info);
+                }
+            }
+        }
+
+        /**
+         * Stores a map of TV input ID/custom label set by user. This is expected to be
+         * called from the settings app.
+         *
+         * @param context The application context.
+         * @param customLabels A map of TV input ID/custom label pairs
+         * @param userId The user ID for the stored hidden input map
+         * @hide
+         */
+        @SystemApi
+        public static void putCustomLabels(Context context,
+                Map<String, String> customLabels, int userId) {
+            StringBuilder builder = new StringBuilder();
+            boolean firstItem = true;
+            for (Map.Entry<String, String> entry: customLabels.entrySet()) {
+                ensureValidField(entry.getKey());
+                ensureValidField(entry.getValue());
+                if (firstItem) {
+                    firstItem = false;
+                } else {
+                    builder.append(TV_INPUT_SEPARATOR);
+                }
+                builder.append(Uri.encode(entry.getKey()));
+                builder.append(CUSTOM_NAME_SEPARATOR);
+                builder.append(Uri.encode(entry.getValue()));
+            }
+            Settings.Secure.putStringForUser(context.getContentResolver(),
+                    Settings.Secure.TV_INPUT_CUSTOM_LABELS, builder.toString(), userId);
+
+            // Notify of the TvInputInfo changes.
+            TvInputManager tm = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
+            for (String inputId : customLabels.keySet()) {
+                TvInputInfo info = tm.getTvInputInfo(inputId);
+                if (info != null) {
+                    tm.updateTvInputInfo(info);
+                }
+            }
+        }
+
+        private static void ensureValidField(String value) {
+            if (TextUtils.isEmpty(value)) {
+                throw new IllegalArgumentException(value + " should not empty ");
+            }
+        }
+    }
+}
diff --git a/android/media/tv/TvInputManager.java b/android/media/tv/TvInputManager.java
new file mode 100644
index 0000000..34e4609
--- /dev/null
+++ b/android/media/tv/TvInputManager.java
@@ -0,0 +1,2960 @@
+/*
+ * Copyright (C) 2014 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.tv;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.annotation.SystemService;
+import android.annotation.TestApi;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.media.PlaybackParams;
+import android.net.Uri;
+import android.os.Binder;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Looper;
+import android.os.Message;
+import android.os.ParcelFileDescriptor;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.Log;
+import android.util.Pools.Pool;
+import android.util.Pools.SimplePool;
+import android.util.SparseArray;
+import android.view.InputChannel;
+import android.view.InputEvent;
+import android.view.InputEventSender;
+import android.view.KeyEvent;
+import android.view.Surface;
+import android.view.View;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Executor;
+
+/**
+ * Central system API to the overall TV input framework (TIF) architecture, which arbitrates
+ * interaction between applications and the selected TV inputs.
+ *
+ * <p>There are three primary parties involved in the TV input framework (TIF) architecture:
+ *
+ * <ul>
+ * <li>The <strong>TV input manager</strong> as expressed by this class is the central point of the
+ * system that manages interaction between all other parts. It is expressed as the client-side API
+ * here which exists in each application context and communicates with a global system service that
+ * manages the interaction across all processes.
+ * <li>A <strong>TV input</strong> implemented by {@link TvInputService} represents an input source
+ * of TV, which can be a pass-through input such as HDMI, or a tuner input which provides broadcast
+ * TV programs. The system binds to the TV input per application’s request.
+ * on implementing TV inputs.
+ * <li><strong>Applications</strong> talk to the TV input manager to list TV inputs and check their
+ * status. Once an application find the input to use, it uses {@link TvView} or
+ * {@link TvRecordingClient} for further interaction such as watching and recording broadcast TV
+ * programs.
+ * </ul>
+ */
+@SystemService(Context.TV_INPUT_SERVICE)
+public final class TvInputManager {
+    private static final String TAG = "TvInputManager";
+
+    static final int DVB_DEVICE_START = 0;
+    static final int DVB_DEVICE_END = 2;
+
+    /**
+     * A demux device of DVB API for controlling the filters of DVB hardware/software.
+     * @hide
+     */
+    public static final int DVB_DEVICE_DEMUX = DVB_DEVICE_START;
+     /**
+     * A DVR device of DVB API for reading transport streams.
+     * @hide
+     */
+    public static final int DVB_DEVICE_DVR = 1;
+    /**
+     * A frontend device of DVB API for controlling the tuner and DVB demodulator hardware.
+     * @hide
+     */
+    public static final int DVB_DEVICE_FRONTEND = DVB_DEVICE_END;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({DVB_DEVICE_DEMUX, DVB_DEVICE_DVR, DVB_DEVICE_FRONTEND})
+    public @interface DvbDeviceType {}
+
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({VIDEO_UNAVAILABLE_REASON_UNKNOWN, VIDEO_UNAVAILABLE_REASON_TUNING,
+        VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL, VIDEO_UNAVAILABLE_REASON_BUFFERING,
+        VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY, VIDEO_UNAVAILABLE_REASON_INSUFFICIENT_RESOURCE,
+        VIDEO_UNAVAILABLE_REASON_CAS_INSUFFICIENT_OUTPUT_PROTECTION,
+        VIDEO_UNAVAILABLE_REASON_CAS_PVR_RECORDING_NOT_ALLOWED,
+        VIDEO_UNAVAILABLE_REASON_CAS_PVR_RECORDING_NOT_ALLOWED,
+        VIDEO_UNAVAILABLE_REASON_CAS_NO_LICENSE, VIDEO_UNAVAILABLE_REASON_CAS_LICENSE_EXPIRED,
+        VIDEO_UNAVAILABLE_REASON_CAS_NEED_ACTIVATION, VIDEO_UNAVAILABLE_REASON_CAS_NEED_PAIRING,
+        VIDEO_UNAVAILABLE_REASON_CAS_NO_CARD, VIDEO_UNAVAILABLE_REASON_CAS_CARD_MUTE,
+        VIDEO_UNAVAILABLE_REASON_CAS_CARD_INVALID, VIDEO_UNAVAILABLE_REASON_CAS_BLACKOUT,
+        VIDEO_UNAVAILABLE_REASON_CAS_REBOOTING, VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN})
+    public @interface VideoUnavailableReason {}
+
+    static final int VIDEO_UNAVAILABLE_REASON_START = 0;
+    static final int VIDEO_UNAVAILABLE_REASON_END = 18;
+
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable due to
+     * an unspecified error.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_UNKNOWN = VIDEO_UNAVAILABLE_REASON_START;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the corresponding TV input is in the middle of tuning to a new channel.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_TUNING = 1;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable due to
+     * weak TV signal.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL = 2;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the corresponding TV input has stopped playback temporarily to buffer more data.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_BUFFERING = 3;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the current TV program is audio-only.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY = 4;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the source is not physically connected, for example the HDMI cable is not connected.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_NOT_CONNECTED = 5;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the resource is not enough to meet requirement.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_INSUFFICIENT_RESOURCE = 6;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the output protection level enabled on the device is not sufficient to meet the requirements
+     * in the license policy.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_INSUFFICIENT_OUTPUT_PROTECTION = 7;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the PVR record is not allowed by the license policy.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_PVR_RECORDING_NOT_ALLOWED = 8;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * no license keys have been provided.
+     * @hide
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_NO_LICENSE = 9;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * Using a license in whhich the keys have expired.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_LICENSE_EXPIRED = 10;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the device need be activated.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_NEED_ACTIVATION = 11;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * the device need be paired.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_NEED_PAIRING = 12;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * smart card is missed.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_NO_CARD = 13;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * smart card is muted.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_CARD_MUTE = 14;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * smart card is invalid.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_CARD_INVALID = 15;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * of a geographical blackout.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_BLACKOUT = 16;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * CAS system is rebooting.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_REBOOTING = 17;
+    /**
+     * Reason for {@link TvInputService.Session#notifyVideoUnavailable(int)} and
+     * {@link TvView.TvInputCallback#onVideoUnavailable(String, int)}: Video is unavailable because
+     * of unknown CAS error.
+     */
+    public static final int VIDEO_UNAVAILABLE_REASON_CAS_UNKNOWN = VIDEO_UNAVAILABLE_REASON_END;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({TIME_SHIFT_STATUS_UNKNOWN, TIME_SHIFT_STATUS_UNSUPPORTED,
+            TIME_SHIFT_STATUS_UNAVAILABLE, TIME_SHIFT_STATUS_AVAILABLE})
+    public @interface TimeShiftStatus {}
+
+    /**
+     * Status for {@link TvInputService.Session#notifyTimeShiftStatusChanged(int)} and
+     * {@link TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)}: Unknown status. Also
+     * the status prior to calling {@code notifyTimeShiftStatusChanged}.
+     */
+    public static final int TIME_SHIFT_STATUS_UNKNOWN = 0;
+
+    /**
+     * Status for {@link TvInputService.Session#notifyTimeShiftStatusChanged(int)} and
+     * {@link TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)}: The current TV input
+     * does not support time shifting.
+     */
+    public static final int TIME_SHIFT_STATUS_UNSUPPORTED = 1;
+
+    /**
+     * Status for {@link TvInputService.Session#notifyTimeShiftStatusChanged(int)} and
+     * {@link TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)}: Time shifting is
+     * currently unavailable but might work again later.
+     */
+    public static final int TIME_SHIFT_STATUS_UNAVAILABLE = 2;
+
+    /**
+     * Status for {@link TvInputService.Session#notifyTimeShiftStatusChanged(int)} and
+     * {@link TvView.TvInputCallback#onTimeShiftStatusChanged(String, int)}: Time shifting is
+     * currently available. In this status, the application assumes it can pause/resume playback,
+     * seek to a specified time position and set playback rate and audio mode.
+     */
+    public static final int TIME_SHIFT_STATUS_AVAILABLE = 3;
+
+    /**
+     * Value returned by {@link TvInputService.Session#onTimeShiftGetCurrentPosition()} and
+     * {@link TvInputService.Session#onTimeShiftGetStartPosition()} when time shifting has not
+     * yet started.
+     */
+    public static final long TIME_SHIFT_INVALID_TIME = Long.MIN_VALUE;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({RECORDING_ERROR_UNKNOWN, RECORDING_ERROR_INSUFFICIENT_SPACE,
+            RECORDING_ERROR_RESOURCE_BUSY})
+    public @interface RecordingError {}
+
+    static final int RECORDING_ERROR_START = 0;
+    static final int RECORDING_ERROR_END = 2;
+
+    /**
+     * Error for {@link TvInputService.RecordingSession#notifyError(int)} and
+     * {@link TvRecordingClient.RecordingCallback#onError(int)}: The requested operation cannot be
+     * completed due to a problem that does not fit under any other error codes, or the error code
+     * for the problem is defined on the higher version than application's
+     * <code>android:targetSdkVersion</code>.
+     */
+    public static final int RECORDING_ERROR_UNKNOWN = RECORDING_ERROR_START;
+
+    /**
+     * Error for {@link TvInputService.RecordingSession#notifyError(int)} and
+     * {@link TvRecordingClient.RecordingCallback#onError(int)}: Recording cannot proceed due to
+     * insufficient storage space.
+     */
+    public static final int RECORDING_ERROR_INSUFFICIENT_SPACE = 1;
+
+    /**
+     * Error for {@link TvInputService.RecordingSession#notifyError(int)} and
+     * {@link TvRecordingClient.RecordingCallback#onError(int)}: Recording cannot proceed because
+     * a required recording resource was not able to be allocated.
+     */
+    public static final int RECORDING_ERROR_RESOURCE_BUSY = RECORDING_ERROR_END;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({INPUT_STATE_CONNECTED, INPUT_STATE_CONNECTED_STANDBY, INPUT_STATE_DISCONNECTED})
+    public @interface InputState {}
+
+    /**
+     * State for {@link #getInputState(String)} and
+     * {@link TvInputCallback#onInputStateChanged(String, int)}: The input source is connected.
+     *
+     * <p>This state indicates that a source device is connected to the input port and is in the
+     * normal operation mode. It is mostly relevant to hardware inputs such as HDMI input.
+     * Non-hardware inputs are considered connected all the time.
+     */
+    public static final int INPUT_STATE_CONNECTED = 0;
+
+    /**
+     * State for {@link #getInputState(String)} and
+     * {@link TvInputCallback#onInputStateChanged(String, int)}: The input source is connected but
+     * in standby mode.
+     *
+     * <p>This state indicates that a source device is connected to the input port but is in standby
+     * or low power mode. It is mostly relevant to hardware inputs such as HDMI input and Component
+     * inputs.
+     */
+    public static final int INPUT_STATE_CONNECTED_STANDBY = 1;
+
+    /**
+     * State for {@link #getInputState(String)} and
+     * {@link TvInputCallback#onInputStateChanged(String, int)}: The input source is disconnected.
+     *
+     * <p>This state indicates that a source device is disconnected from the input port. It is
+     * mostly relevant to hardware inputs such as HDMI input.
+     *
+     */
+    public static final int INPUT_STATE_DISCONNECTED = 2;
+
+    /**
+     * An unknown state of the client pid gets from the TvInputManager. Client gets this value when
+     * query through {@link getClientPid(String sessionId)} fails.
+     *
+     * @hide
+     */
+    public static final int UNKNOWN_CLIENT_PID = -1;
+
+    /**
+     * Broadcast intent action when the user blocked content ratings change. For use with the
+     * {@link #isRatingBlocked}.
+     */
+    public static final String ACTION_BLOCKED_RATINGS_CHANGED =
+            "android.media.tv.action.BLOCKED_RATINGS_CHANGED";
+
+    /**
+     * Broadcast intent action when the parental controls enabled state changes. For use with the
+     * {@link #isParentalControlsEnabled}.
+     */
+    public static final String ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED =
+            "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED";
+
+    /**
+     * Broadcast intent action used to query available content rating systems.
+     *
+     * <p>The TV input manager service locates available content rating systems by querying
+     * broadcast receivers that are registered for this action. An application can offer additional
+     * content rating systems to the user by declaring a suitable broadcast receiver in its
+     * manifest.
+     *
+     * <p>Here is an example broadcast receiver declaration that an application might include in its
+     * AndroidManifest.xml to advertise custom content rating systems. The meta-data specifies a
+     * resource that contains a description of each content rating system that is provided by the
+     * application.
+     *
+     * <p><pre class="prettyprint">
+     * {@literal
+     * <receiver android:name=".TvInputReceiver">
+     *     <intent-filter>
+     *         <action android:name=
+     *                 "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS" />
+     *     </intent-filter>
+     *     <meta-data
+     *             android:name="android.media.tv.metadata.CONTENT_RATING_SYSTEMS"
+     *             android:resource="@xml/tv_content_rating_systems" />
+     * </receiver>}</pre>
+     *
+     * <p>In the above example, the <code>@xml/tv_content_rating_systems</code> resource refers to an
+     * XML resource whose root element is <code>&lt;rating-system-definitions&gt;</code> that
+     * contains zero or more <code>&lt;rating-system-definition&gt;</code> elements. Each <code>
+     * &lt;rating-system-definition&gt;</code> element specifies the ratings, sub-ratings and rating
+     * orders of a particular content rating system.
+     *
+     * @see TvContentRating
+     */
+    public static final String ACTION_QUERY_CONTENT_RATING_SYSTEMS =
+            "android.media.tv.action.QUERY_CONTENT_RATING_SYSTEMS";
+
+    /**
+     * Content rating systems metadata associated with {@link #ACTION_QUERY_CONTENT_RATING_SYSTEMS}.
+     *
+     * <p>Specifies the resource ID of an XML resource that describes the content rating systems
+     * that are provided by the application.
+     */
+    public static final String META_DATA_CONTENT_RATING_SYSTEMS =
+            "android.media.tv.metadata.CONTENT_RATING_SYSTEMS";
+
+    /**
+     * Activity action to set up channel sources i.e.&nbsp;TV inputs of type
+     * {@link TvInputInfo#TYPE_TUNER}. When invoked, the system will display an appropriate UI for
+     * the user to initiate the individual setup flow provided by
+     * {@link android.R.attr#setupActivity} of each TV input service.
+     */
+    public static final String ACTION_SETUP_INPUTS = "android.media.tv.action.SETUP_INPUTS";
+
+    /**
+     * Activity action to display the recording schedules. When invoked, the system will display an
+     * appropriate UI to browse the schedules.
+     */
+    public static final String ACTION_VIEW_RECORDING_SCHEDULES =
+            "android.media.tv.action.VIEW_RECORDING_SCHEDULES";
+
+    private final ITvInputManager mService;
+
+    private final Object mLock = new Object();
+
+    // @GuardedBy("mLock")
+    private final List<TvInputCallbackRecord> mCallbackRecords = new LinkedList<>();
+
+    // A mapping from TV input ID to the state of corresponding input.
+    // @GuardedBy("mLock")
+    private final Map<String, Integer> mStateMap = new ArrayMap<>();
+
+    // A mapping from the sequence number of a session to its SessionCallbackRecord.
+    private final SparseArray<SessionCallbackRecord> mSessionCallbackRecordMap =
+            new SparseArray<>();
+
+    // A sequence number for the next session to be created. Should be protected by a lock
+    // {@code mSessionCallbackRecordMap}.
+    private int mNextSeq;
+
+    private final ITvInputClient mClient;
+
+    private final int mUserId;
+
+    /**
+     * Interface used to receive the created session.
+     * @hide
+     */
+    public abstract static class SessionCallback {
+        /**
+         * This is called after {@link TvInputManager#createSession} has been processed.
+         *
+         * @param session A {@link TvInputManager.Session} instance created. This can be
+         *            {@code null} if the creation request failed.
+         */
+        public void onSessionCreated(@Nullable Session session) {
+        }
+
+        /**
+         * This is called when {@link TvInputManager.Session} is released.
+         * This typically happens when the process hosting the session has crashed or been killed.
+         *
+         * @param session A {@link TvInputManager.Session} instance released.
+         */
+        public void onSessionReleased(Session session) {
+        }
+
+        /**
+         * This is called when the channel of this session is changed by the underlying TV input
+         * without any {@link TvInputManager.Session#tune(Uri)} request.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback.
+         * @param channelUri The URI of a channel.
+         */
+        public void onChannelRetuned(Session session, Uri channelUri) {
+        }
+
+        /**
+         * This is called when the track information of the session has been changed.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback.
+         * @param tracks A list which includes track information.
+         */
+        public void onTracksChanged(Session session, List<TvTrackInfo> tracks) {
+        }
+
+        /**
+         * This is called when a track for a given type is selected.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback.
+         * @param type The type of the selected track. The type can be
+         *            {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+         *            {@link TvTrackInfo#TYPE_SUBTITLE}.
+         * @param trackId The ID of the selected track. When {@code null} the currently selected
+         *            track for a given type should be unselected.
+         */
+        public void onTrackSelected(Session session, int type, @Nullable String trackId) {
+        }
+
+        /**
+         * This is invoked when the video size has been changed. It is also called when the first
+         * time video size information becomes available after the session is tuned to a specific
+         * channel.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback.
+         * @param width The width of the video.
+         * @param height The height of the video.
+         */
+        public void onVideoSizeChanged(Session session, int width, int height) {
+        }
+
+        /**
+         * This is called when the video is available, so the TV input starts the playback.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback.
+         */
+        public void onVideoAvailable(Session session) {
+        }
+
+        /**
+         * This is called when the video is not available, so the TV input stops the playback.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback.
+         * @param reason The reason why the TV input stopped the playback:
+         * <ul>
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_UNKNOWN}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_TUNING}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_BUFFERING}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY}
+         * </ul>
+         */
+        public void onVideoUnavailable(Session session, int reason) {
+        }
+
+        /**
+         * This is called when the current program content turns out to be allowed to watch since
+         * its content rating is not blocked by parental controls.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback.
+         */
+        public void onContentAllowed(Session session) {
+        }
+
+        /**
+         * This is called when the current program content turns out to be not allowed to watch
+         * since its content rating is blocked by parental controls.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback.
+         * @param rating The content ration of the blocked program.
+         */
+        public void onContentBlocked(Session session, TvContentRating rating) {
+        }
+
+        /**
+         * This is called when {@link TvInputService.Session#layoutSurface} is called to change the
+         * layout of surface.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback.
+         * @param left Left position.
+         * @param top Top position.
+         * @param right Right position.
+         * @param bottom Bottom position.
+         */
+        public void onLayoutSurface(Session session, int left, int top, int right, int bottom) {
+        }
+
+        /**
+         * This is called when a custom event has been sent from this session.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback
+         * @param eventType The type of the event.
+         * @param eventArgs Optional arguments of the event.
+         */
+        public void onSessionEvent(Session session, String eventType, Bundle eventArgs) {
+        }
+
+        /**
+         * This is called when the time shift status is changed.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback.
+         * @param status The current time shift status. Should be one of the followings.
+         * <ul>
+         * <li>{@link TvInputManager#TIME_SHIFT_STATUS_UNSUPPORTED}
+         * <li>{@link TvInputManager#TIME_SHIFT_STATUS_UNAVAILABLE}
+         * <li>{@link TvInputManager#TIME_SHIFT_STATUS_AVAILABLE}
+         * </ul>
+         */
+        public void onTimeShiftStatusChanged(Session session, int status) {
+        }
+
+        /**
+         * This is called when the start position for time shifting has changed.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback.
+         * @param timeMs The start position for time shifting, in milliseconds since the epoch.
+         */
+        public void onTimeShiftStartPositionChanged(Session session, long timeMs) {
+        }
+
+        /**
+         * This is called when the current position for time shifting is changed.
+         *
+         * @param session A {@link TvInputManager.Session} associated with this callback.
+         * @param timeMs The current position for time shifting, in milliseconds since the epoch.
+         */
+        public void onTimeShiftCurrentPositionChanged(Session session, long timeMs) {
+        }
+
+        // For the recording session only
+        /**
+         * This is called when the recording session has been tuned to the given channel and is
+         * ready to start recording.
+         *
+         * @param channelUri The URI of a channel.
+         */
+        void onTuned(Session session, Uri channelUri) {
+        }
+
+        // For the recording session only
+        /**
+         * This is called when the current recording session has stopped recording and created a
+         * new data entry in the {@link TvContract.RecordedPrograms} table that describes the newly
+         * recorded program.
+         *
+         * @param recordedProgramUri The URI for the newly recorded program.
+         **/
+        void onRecordingStopped(Session session, Uri recordedProgramUri) {
+        }
+
+        // For the recording session only
+        /**
+         * This is called when an issue has occurred. It may be called at any time after the current
+         * recording session is created until it is released.
+         *
+         * @param error The error code.
+         */
+        void onError(Session session, @TvInputManager.RecordingError int error) {
+        }
+    }
+
+    private static final class SessionCallbackRecord {
+        private final SessionCallback mSessionCallback;
+        private final Handler mHandler;
+        private Session mSession;
+
+        SessionCallbackRecord(SessionCallback sessionCallback,
+                Handler handler) {
+            mSessionCallback = sessionCallback;
+            mHandler = handler;
+        }
+
+        void postSessionCreated(final Session session) {
+            mSession = session;
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onSessionCreated(session);
+                }
+            });
+        }
+
+        void postSessionReleased() {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onSessionReleased(mSession);
+                }
+            });
+        }
+
+        void postChannelRetuned(final Uri channelUri) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onChannelRetuned(mSession, channelUri);
+                }
+            });
+        }
+
+        void postTracksChanged(final List<TvTrackInfo> tracks) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onTracksChanged(mSession, tracks);
+                }
+            });
+        }
+
+        void postTrackSelected(final int type, final String trackId) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onTrackSelected(mSession, type, trackId);
+                }
+            });
+        }
+
+        void postVideoSizeChanged(final int width, final int height) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onVideoSizeChanged(mSession, width, height);
+                }
+            });
+        }
+
+        void postVideoAvailable() {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onVideoAvailable(mSession);
+                }
+            });
+        }
+
+        void postVideoUnavailable(final int reason) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onVideoUnavailable(mSession, reason);
+                }
+            });
+        }
+
+        void postContentAllowed() {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onContentAllowed(mSession);
+                }
+            });
+        }
+
+        void postContentBlocked(final TvContentRating rating) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onContentBlocked(mSession, rating);
+                }
+            });
+        }
+
+        void postLayoutSurface(final int left, final int top, final int right,
+                final int bottom) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onLayoutSurface(mSession, left, top, right, bottom);
+                }
+            });
+        }
+
+        void postSessionEvent(final String eventType, final Bundle eventArgs) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onSessionEvent(mSession, eventType, eventArgs);
+                }
+            });
+        }
+
+        void postTimeShiftStatusChanged(final int status) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onTimeShiftStatusChanged(mSession, status);
+                }
+            });
+        }
+
+        void postTimeShiftStartPositionChanged(final long timeMs) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onTimeShiftStartPositionChanged(mSession, timeMs);
+                }
+            });
+        }
+
+        void postTimeShiftCurrentPositionChanged(final long timeMs) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onTimeShiftCurrentPositionChanged(mSession, timeMs);
+                }
+            });
+        }
+
+        // For the recording session only
+        void postTuned(final Uri channelUri) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onTuned(mSession, channelUri);
+                }
+            });
+        }
+
+        // For the recording session only
+        void postRecordingStopped(final Uri recordedProgramUri) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onRecordingStopped(mSession, recordedProgramUri);
+                }
+            });
+        }
+
+        // For the recording session only
+        void postError(final int error) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mSessionCallback.onError(mSession, error);
+                }
+            });
+        }
+    }
+
+    /**
+     * Callback used to monitor status of the TV inputs.
+     */
+    public abstract static class TvInputCallback {
+        /**
+         * This is called when the state of a given TV input is changed.
+         *
+         * @param inputId The ID of the TV input.
+         * @param state State of the TV input. The value is one of the following:
+         * <ul>
+         * <li>{@link TvInputManager#INPUT_STATE_CONNECTED}
+         * <li>{@link TvInputManager#INPUT_STATE_CONNECTED_STANDBY}
+         * <li>{@link TvInputManager#INPUT_STATE_DISCONNECTED}
+         * </ul>
+         */
+        public void onInputStateChanged(String inputId, @InputState int state) {
+        }
+
+        /**
+         * This is called when a TV input is added to the system.
+         *
+         * <p>Normally it happens when the user installs a new TV input package that implements
+         * {@link TvInputService} interface.
+         *
+         * @param inputId The ID of the TV input.
+         */
+        public void onInputAdded(String inputId) {
+        }
+
+        /**
+         * This is called when a TV input is removed from the system.
+         *
+         * <p>Normally it happens when the user uninstalls the previously installed TV input
+         * package.
+         *
+         * @param inputId The ID of the TV input.
+         */
+        public void onInputRemoved(String inputId) {
+        }
+
+        /**
+         * This is called when a TV input is updated on the system.
+         *
+         * <p>Normally it happens when a previously installed TV input package is re-installed or
+         * the media on which a newer version of the package exists becomes available/unavailable.
+         *
+         * @param inputId The ID of the TV input.
+         */
+        public void onInputUpdated(String inputId) {
+        }
+
+        /**
+         * This is called when the information about an existing TV input has been updated.
+         *
+         * <p>Because the system automatically creates a <code>TvInputInfo</code> object for each TV
+         * input based on the information collected from the <code>AndroidManifest.xml</code>, this
+         * method is only called back when such information has changed dynamically.
+         *
+         * @param inputInfo The <code>TvInputInfo</code> object that contains new information.
+         */
+        public void onTvInputInfoUpdated(TvInputInfo inputInfo) {
+        }
+
+        /**
+         * This is called when the information about current tuned information has been updated.
+         *
+         * @param tunedInfos a list of {@link TunedInfo} objects of new tuned information.
+         * @hide
+         */
+        @SystemApi
+        @RequiresPermission(android.Manifest.permission.ACCESS_TUNED_INFO)
+        public void onCurrentTunedInfosUpdated(@NonNull List<TunedInfo> tunedInfos) {
+        }
+    }
+
+    private static final class TvInputCallbackRecord {
+        private final TvInputCallback mCallback;
+        private final Handler mHandler;
+
+        public TvInputCallbackRecord(TvInputCallback callback, Handler handler) {
+            mCallback = callback;
+            mHandler = handler;
+        }
+
+        public TvInputCallback getCallback() {
+            return mCallback;
+        }
+
+        public void postInputAdded(final String inputId) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onInputAdded(inputId);
+                }
+            });
+        }
+
+        public void postInputRemoved(final String inputId) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onInputRemoved(inputId);
+                }
+            });
+        }
+
+        public void postInputUpdated(final String inputId) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onInputUpdated(inputId);
+                }
+            });
+        }
+
+        public void postInputStateChanged(final String inputId, final int state) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onInputStateChanged(inputId, state);
+                }
+            });
+        }
+
+        public void postTvInputInfoUpdated(final TvInputInfo inputInfo) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onTvInputInfoUpdated(inputInfo);
+                }
+            });
+        }
+
+        public void postCurrentTunedInfosUpdated(final List<TunedInfo> currentTunedInfos) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    mCallback.onCurrentTunedInfosUpdated(currentTunedInfos);
+                }
+            });
+        }
+    }
+
+    /**
+     * Interface used to receive events from Hardware objects.
+     *
+     * @hide
+     */
+    @SystemApi
+    public abstract static class HardwareCallback {
+        /**
+         * This is called when {@link Hardware} is no longer available for the client.
+         */
+        public abstract void onReleased();
+
+        /**
+         * This is called when the underlying {@link TvStreamConfig} has been changed.
+         *
+         * @param configs The new {@link TvStreamConfig}s.
+         */
+        public abstract void onStreamConfigChanged(TvStreamConfig[] configs);
+    }
+
+    /**
+     * @hide
+     */
+    public TvInputManager(ITvInputManager service, int userId) {
+        mService = service;
+        mUserId = userId;
+        mClient = new ITvInputClient.Stub() {
+            @Override
+            public void onSessionCreated(String inputId, IBinder token, InputChannel channel,
+                    int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for " + token);
+                        return;
+                    }
+                    Session session = null;
+                    if (token != null) {
+                        session = new Session(token, channel, mService, mUserId, seq,
+                                mSessionCallbackRecordMap);
+                    } else {
+                        mSessionCallbackRecordMap.delete(seq);
+                    }
+                    record.postSessionCreated(session);
+                }
+            }
+
+            @Override
+            public void onSessionReleased(int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    mSessionCallbackRecordMap.delete(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq:" + seq);
+                        return;
+                    }
+                    record.mSession.releaseInternal();
+                    record.postSessionReleased();
+                }
+            }
+
+            @Override
+            public void onChannelRetuned(Uri channelUri, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postChannelRetuned(channelUri);
+                }
+            }
+
+            @Override
+            public void onTracksChanged(List<TvTrackInfo> tracks, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    if (record.mSession.updateTracks(tracks)) {
+                        record.postTracksChanged(tracks);
+                        postVideoSizeChangedIfNeededLocked(record);
+                    }
+                }
+            }
+
+            @Override
+            public void onTrackSelected(int type, String trackId, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    if (record.mSession.updateTrackSelection(type, trackId)) {
+                        record.postTrackSelected(type, trackId);
+                        postVideoSizeChangedIfNeededLocked(record);
+                    }
+                }
+            }
+
+            private void postVideoSizeChangedIfNeededLocked(SessionCallbackRecord record) {
+                TvTrackInfo track = record.mSession.getVideoTrackToNotify();
+                if (track != null) {
+                    record.postVideoSizeChanged(track.getVideoWidth(), track.getVideoHeight());
+                }
+            }
+
+            @Override
+            public void onVideoAvailable(int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postVideoAvailable();
+                }
+            }
+
+            @Override
+            public void onVideoUnavailable(int reason, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postVideoUnavailable(reason);
+                }
+            }
+
+            @Override
+            public void onContentAllowed(int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postContentAllowed();
+                }
+            }
+
+            @Override
+            public void onContentBlocked(String rating, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postContentBlocked(TvContentRating.unflattenFromString(rating));
+                }
+            }
+
+            @Override
+            public void onLayoutSurface(int left, int top, int right, int bottom, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postLayoutSurface(left, top, right, bottom);
+                }
+            }
+
+            @Override
+            public void onSessionEvent(String eventType, Bundle eventArgs, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postSessionEvent(eventType, eventArgs);
+                }
+            }
+
+            @Override
+            public void onTimeShiftStatusChanged(int status, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postTimeShiftStatusChanged(status);
+                }
+            }
+
+            @Override
+            public void onTimeShiftStartPositionChanged(long timeMs, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postTimeShiftStartPositionChanged(timeMs);
+                }
+            }
+
+            @Override
+            public void onTimeShiftCurrentPositionChanged(long timeMs, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postTimeShiftCurrentPositionChanged(timeMs);
+                }
+            }
+
+            @Override
+            public void onTuned(int seq, Uri channelUri) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postTuned(channelUri);
+                }
+            }
+
+            @Override
+            public void onRecordingStopped(Uri recordedProgramUri, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postRecordingStopped(recordedProgramUri);
+                }
+            }
+
+            @Override
+            public void onError(int error, int seq) {
+                synchronized (mSessionCallbackRecordMap) {
+                    SessionCallbackRecord record = mSessionCallbackRecordMap.get(seq);
+                    if (record == null) {
+                        Log.e(TAG, "Callback not found for seq " + seq);
+                        return;
+                    }
+                    record.postError(error);
+                }
+            }
+        };
+        ITvInputManagerCallback managerCallback = new ITvInputManagerCallback.Stub() {
+            @Override
+            public void onInputAdded(String inputId) {
+                synchronized (mLock) {
+                    mStateMap.put(inputId, INPUT_STATE_CONNECTED);
+                    for (TvInputCallbackRecord record : mCallbackRecords) {
+                        record.postInputAdded(inputId);
+                    }
+                }
+            }
+
+            @Override
+            public void onInputRemoved(String inputId) {
+                synchronized (mLock) {
+                    mStateMap.remove(inputId);
+                    for (TvInputCallbackRecord record : mCallbackRecords) {
+                        record.postInputRemoved(inputId);
+                    }
+                }
+            }
+
+            @Override
+            public void onInputUpdated(String inputId) {
+                synchronized (mLock) {
+                    for (TvInputCallbackRecord record : mCallbackRecords) {
+                        record.postInputUpdated(inputId);
+                    }
+                }
+            }
+
+            @Override
+            public void onInputStateChanged(String inputId, int state) {
+                synchronized (mLock) {
+                    mStateMap.put(inputId, state);
+                    for (TvInputCallbackRecord record : mCallbackRecords) {
+                        record.postInputStateChanged(inputId, state);
+                    }
+                }
+            }
+
+            @Override
+            public void onTvInputInfoUpdated(TvInputInfo inputInfo) {
+                synchronized (mLock) {
+                    for (TvInputCallbackRecord record : mCallbackRecords) {
+                        record.postTvInputInfoUpdated(inputInfo);
+                    }
+                }
+            }
+
+            @Override
+            public void onCurrentTunedInfosUpdated(List<TunedInfo> currentTunedInfos) {
+                synchronized (mLock) {
+                    for (TvInputCallbackRecord record : mCallbackRecords) {
+                        record.postCurrentTunedInfosUpdated(currentTunedInfos);
+                    }
+                }
+            }
+        };
+        try {
+            if (mService != null) {
+                mService.registerCallback(managerCallback, mUserId);
+                List<TvInputInfo> infos = mService.getTvInputList(mUserId);
+                synchronized (mLock) {
+                    for (TvInputInfo info : infos) {
+                        String inputId = info.getId();
+                        mStateMap.put(inputId, mService.getTvInputState(inputId, mUserId));
+                    }
+                }
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the complete list of TV inputs on the system.
+     *
+     * @return List of {@link TvInputInfo} for each TV input that describes its meta information.
+     */
+    public List<TvInputInfo> getTvInputList() {
+        try {
+            return mService.getTvInputList(mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the {@link TvInputInfo} for a given TV input.
+     *
+     * @param inputId The ID of the TV input.
+     * @return the {@link TvInputInfo} for a given TV input. {@code null} if not found.
+     */
+    @Nullable
+    public TvInputInfo getTvInputInfo(@NonNull String inputId) {
+        Preconditions.checkNotNull(inputId);
+        try {
+            return mService.getTvInputInfo(inputId, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Updates the <code>TvInputInfo</code> for an existing TV input. A TV input service
+     * implementation may call this method to pass the application and system an up-to-date
+     * <code>TvInputInfo</code> object that describes itself.
+     *
+     * <p>The system automatically creates a <code>TvInputInfo</code> object for each TV input,
+     * based on the information collected from the <code>AndroidManifest.xml</code>, thus it is not
+     * necessary to call this method unless such information has changed dynamically.
+     * Use {@link TvInputInfo.Builder} to build a new <code>TvInputInfo</code> object.
+     *
+     * <p>Attempting to change information about a TV input that the calling package does not own
+     * does nothing.
+     *
+     * @param inputInfo The <code>TvInputInfo</code> object that contains new information.
+     * @throws IllegalArgumentException if the argument is {@code null}.
+     * @see TvInputCallback#onTvInputInfoUpdated(TvInputInfo)
+     */
+    public void updateTvInputInfo(@NonNull TvInputInfo inputInfo) {
+        Preconditions.checkNotNull(inputInfo);
+        try {
+            mService.updateTvInputInfo(inputInfo, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the state of a given TV input.
+     *
+     * <p>The state is one of the following:
+     * <ul>
+     * <li>{@link #INPUT_STATE_CONNECTED}
+     * <li>{@link #INPUT_STATE_CONNECTED_STANDBY}
+     * <li>{@link #INPUT_STATE_DISCONNECTED}
+     * </ul>
+     *
+     * @param inputId The ID of the TV input.
+     * @throws IllegalArgumentException if the argument is {@code null}.
+     */
+    @InputState
+    public int getInputState(@NonNull String inputId) {
+        Preconditions.checkNotNull(inputId);
+        synchronized (mLock) {
+            Integer state = mStateMap.get(inputId);
+            if (state == null) {
+                Log.w(TAG, "Unrecognized input ID: " + inputId);
+                return INPUT_STATE_DISCONNECTED;
+            }
+            return state;
+        }
+    }
+
+    /**
+     * Registers a {@link TvInputCallback}.
+     *
+     * @param callback A callback used to monitor status of the TV inputs.
+     * @param handler A {@link Handler} that the status change will be delivered to.
+     */
+    public void registerCallback(@NonNull TvInputCallback callback, @NonNull Handler handler) {
+        Preconditions.checkNotNull(callback);
+        Preconditions.checkNotNull(handler);
+        synchronized (mLock) {
+            mCallbackRecords.add(new TvInputCallbackRecord(callback, handler));
+        }
+    }
+
+    /**
+     * Unregisters the existing {@link TvInputCallback}.
+     *
+     * @param callback The existing callback to remove.
+     */
+    public void unregisterCallback(@NonNull final TvInputCallback callback) {
+        Preconditions.checkNotNull(callback);
+        synchronized (mLock) {
+            for (Iterator<TvInputCallbackRecord> it = mCallbackRecords.iterator();
+                    it.hasNext(); ) {
+                TvInputCallbackRecord record = it.next();
+                if (record.getCallback() == callback) {
+                    it.remove();
+                    break;
+                }
+            }
+        }
+    }
+
+    /**
+     * Returns the user's parental controls enabled state.
+     *
+     * @return {@code true} if the user enabled the parental controls, {@code false} otherwise.
+     */
+    public boolean isParentalControlsEnabled() {
+        try {
+            return mService.isParentalControlsEnabled(mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Sets the user's parental controls enabled state.
+     *
+     * @param enabled The user's parental controls enabled state. {@code true} if the user enabled
+     *            the parental controls, {@code false} otherwise.
+     * @see #isParentalControlsEnabled
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PARENTAL_CONTROLS)
+    public void setParentalControlsEnabled(boolean enabled) {
+        try {
+            mService.setParentalControlsEnabled(enabled, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Checks whether a given TV content rating is blocked by the user.
+     *
+     * @param rating The TV content rating to check. Can be {@link TvContentRating#UNRATED}.
+     * @return {@code true} if the given TV content rating is blocked, {@code false} otherwise.
+     */
+    public boolean isRatingBlocked(@NonNull TvContentRating rating) {
+        Preconditions.checkNotNull(rating);
+        try {
+            return mService.isRatingBlocked(rating.flattenToString(), mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the list of blocked content ratings.
+     *
+     * @return the list of content ratings blocked by the user.
+     */
+    public List<TvContentRating> getBlockedRatings() {
+        try {
+            List<TvContentRating> ratings = new ArrayList<>();
+            for (String rating : mService.getBlockedRatings(mUserId)) {
+                ratings.add(TvContentRating.unflattenFromString(rating));
+            }
+            return ratings;
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Adds a user blocked content rating.
+     *
+     * @param rating The content rating to block.
+     * @see #isRatingBlocked
+     * @see #removeBlockedRating
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PARENTAL_CONTROLS)
+    public void addBlockedRating(@NonNull TvContentRating rating) {
+        Preconditions.checkNotNull(rating);
+        try {
+            mService.addBlockedRating(rating.flattenToString(), mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Removes a user blocked content rating.
+     *
+     * @param rating The content rating to unblock.
+     * @see #isRatingBlocked
+     * @see #addBlockedRating
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PARENTAL_CONTROLS)
+    public void removeBlockedRating(@NonNull TvContentRating rating) {
+        Preconditions.checkNotNull(rating);
+        try {
+            mService.removeBlockedRating(rating.flattenToString(), mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the list of all TV content rating systems defined.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.READ_CONTENT_RATING_SYSTEMS)
+    public List<TvContentRatingSystemInfo> getTvContentRatingSystemList() {
+        try {
+            return mService.getTvContentRatingSystemList(mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Notifies the TV input of the given preview program that the program's browsable state is
+     * disabled.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NOTIFY_TV_INPUTS)
+    public void notifyPreviewProgramBrowsableDisabled(String packageName, long programId) {
+        Intent intent = new Intent();
+        intent.setAction(TvContract.ACTION_PREVIEW_PROGRAM_BROWSABLE_DISABLED);
+        intent.putExtra(TvContract.EXTRA_PREVIEW_PROGRAM_ID, programId);
+        intent.setPackage(packageName);
+        try {
+            mService.sendTvInputNotifyIntent(intent, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Notifies the TV input of the given watch next program that the program's browsable state is
+     * disabled.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NOTIFY_TV_INPUTS)
+    public void notifyWatchNextProgramBrowsableDisabled(String packageName, long programId) {
+        Intent intent = new Intent();
+        intent.setAction(TvContract.ACTION_WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED);
+        intent.putExtra(TvContract.EXTRA_WATCH_NEXT_PROGRAM_ID, programId);
+        intent.setPackage(packageName);
+        try {
+            mService.sendTvInputNotifyIntent(intent, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Notifies the TV input of the given preview program that the program is added to watch next.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.NOTIFY_TV_INPUTS)
+    public void notifyPreviewProgramAddedToWatchNext(String packageName, long previewProgramId,
+            long watchNextProgramId) {
+        Intent intent = new Intent();
+        intent.setAction(TvContract.ACTION_PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT);
+        intent.putExtra(TvContract.EXTRA_PREVIEW_PROGRAM_ID, previewProgramId);
+        intent.putExtra(TvContract.EXTRA_WATCH_NEXT_PROGRAM_ID, watchNextProgramId);
+        intent.setPackage(packageName);
+        try {
+            mService.sendTvInputNotifyIntent(intent, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Creates a {@link Session} for a given TV input.
+     *
+     * <p>The number of sessions that can be created at the same time is limited by the capability
+     * of the given TV input.
+     *
+     * @param inputId The ID of the TV input.
+     * @param callback A callback used to receive the created session.
+     * @param handler A {@link Handler} that the session creation will be delivered to.
+     * @hide
+     */
+    public void createSession(@NonNull String inputId, @NonNull final SessionCallback callback,
+            @NonNull Handler handler) {
+        createSessionInternal(inputId, false, callback, handler);
+    }
+
+    /**
+     * Get a the client pid when creating the session with the session id provided.
+     *
+     * @param sessionId a String of session id that is used to query the client pid.
+     * @return the client pid when created the session. Returns {@link #UNKNOWN_CLIENT_PID}
+     *         if the call fails.
+     *
+     * @hide
+     */
+    @RequiresPermission(android.Manifest.permission.TUNER_RESOURCE_ACCESS)
+    public int getClientPid(@NonNull String sessionId) {
+        return getClientPidInternal(sessionId);
+    };
+
+    /**
+     * Creates a recording {@link Session} for a given TV input.
+     *
+     * <p>The number of sessions that can be created at the same time is limited by the capability
+     * of the given TV input.
+     *
+     * @param inputId The ID of the TV input.
+     * @param callback A callback used to receive the created session.
+     * @param handler A {@link Handler} that the session creation will be delivered to.
+     * @hide
+     */
+    public void createRecordingSession(@NonNull String inputId,
+            @NonNull final SessionCallback callback, @NonNull Handler handler) {
+        createSessionInternal(inputId, true, callback, handler);
+    }
+
+    private void createSessionInternal(String inputId, boolean isRecordingSession,
+            SessionCallback callback, Handler handler) {
+        Preconditions.checkNotNull(inputId);
+        Preconditions.checkNotNull(callback);
+        Preconditions.checkNotNull(handler);
+        SessionCallbackRecord record = new SessionCallbackRecord(callback, handler);
+        synchronized (mSessionCallbackRecordMap) {
+            int seq = mNextSeq++;
+            mSessionCallbackRecordMap.put(seq, record);
+            try {
+                mService.createSession(mClient, inputId, isRecordingSession, seq, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+    }
+
+    private int getClientPidInternal(String sessionId) {
+        Preconditions.checkNotNull(sessionId);
+        int clientPid = UNKNOWN_CLIENT_PID;
+        try {
+            clientPid = mService.getClientPid(sessionId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return clientPid;
+    }
+
+    /**
+     * Returns the TvStreamConfig list of the given TV input.
+     *
+     * If you are using {@link Hardware} object from {@link
+     * #acquireTvInputHardware}, you should get the list of available streams
+     * from {@link HardwareCallback#onStreamConfigChanged} method, not from
+     * here. This method is designed to be used with {@link #captureFrame} in
+     * capture scenarios specifically and not suitable for any other use.
+     *
+     * @param inputId The ID of the TV input.
+     * @return List of {@link TvStreamConfig} which is available for capturing
+     *   of the given TV input.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.CAPTURE_TV_INPUT)
+    public List<TvStreamConfig> getAvailableTvStreamConfigList(String inputId) {
+        try {
+            return mService.getAvailableTvStreamConfigList(inputId, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Take a snapshot of the given TV input into the provided Surface.
+     *
+     * @param inputId The ID of the TV input.
+     * @param surface the {@link Surface} to which the snapshot is captured.
+     * @param config the {@link TvStreamConfig} which is used for capturing.
+     * @return true when the {@link Surface} is ready to be captured.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.CAPTURE_TV_INPUT)
+    public boolean captureFrame(String inputId, Surface surface, TvStreamConfig config) {
+        try {
+            return mService.captureFrame(inputId, surface, config, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns true if there is only a single TV input session.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.CAPTURE_TV_INPUT)
+    public boolean isSingleSessionActive() {
+        try {
+            return mService.isSingleSessionActive(mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns a list of TvInputHardwareInfo objects representing available hardware.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
+    public List<TvInputHardwareInfo> getHardwareList() {
+        try {
+            return mService.getHardwareList();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Acquires {@link Hardware} object for the given device ID.
+     *
+     * <p>A subsequent call to this method on the same {@code deviceId} will release the currently
+     * acquired Hardware.
+     *
+     * @param deviceId The device ID to acquire Hardware for.
+     * @param callback A callback to receive updates on Hardware.
+     * @param info The TV input which will use the acquired Hardware.
+     * @return Hardware on success, {@code null} otherwise.
+     *
+     * @hide
+     * @removed
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
+    public Hardware acquireTvInputHardware(int deviceId, final HardwareCallback callback,
+            TvInputInfo info) {
+        return acquireTvInputHardware(deviceId, info, callback);
+    }
+
+    /**
+     * Acquires {@link Hardware} object for the given device ID.
+     *
+     * <p>A subsequent call to this method on the same {@code deviceId} could release the currently
+     * acquired Hardware if TunerResourceManager(TRM) detects higher priority from the current
+     * request.
+     *
+     * <p>If the client would like to provide information for the TRM to compare, use
+     * {@link #acquireTvInputHardware(int, TvInputInfo, HardwareCallback, String, int)} instead.
+     *
+     * <p>Otherwise default priority will be applied.
+     *
+     * @param deviceId The device ID to acquire Hardware for.
+     * @param info The TV input which will use the acquired Hardware.
+     * @param callback A callback to receive updates on Hardware.
+     * @return Hardware on success, {@code null} otherwise.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
+    public Hardware acquireTvInputHardware(int deviceId, @NonNull TvInputInfo info,
+            @NonNull final HardwareCallback callback) {
+        Preconditions.checkNotNull(info);
+        Preconditions.checkNotNull(callback);
+        return acquireTvInputHardwareInternal(deviceId, info, null,
+                TvInputService.PRIORITY_HINT_USE_CASE_TYPE_LIVE, new Executor() {
+                    public void execute(Runnable r) {
+                        r.run();
+                    }
+                }, callback);
+    }
+
+    /**
+     * Acquires {@link Hardware} object for the given device ID.
+     *
+     * <p>A subsequent call to this method on the same {@code deviceId} could release the currently
+     * acquired Hardware if TunerResourceManager(TRM) detects higher priority from the current
+     * request.
+     *
+     * @param deviceId The device ID to acquire Hardware for.
+     * @param info The TV input which will use the acquired Hardware.
+     * @param tvInputSessionId a String returned to TIS when the session was created.
+     *        {@see TvInputService#onCreateSession(String, String)}. If null, the client will be
+     *        treated as a background app.
+     * @param priorityHint The use case of the client. {@see TvInputService#PriorityHintUseCaseType}
+     * @param executor the executor on which the listener would be invoked.
+     * @param callback A callback to receive updates on Hardware.
+     * @return Hardware on success, {@code null} otherwise. When the TRM decides to not grant
+     *         resource, null is returned and the {@link IllegalStateException} is thrown with
+     *         "No enough resources".
+     *
+     * @hide
+     */
+    @SystemApi
+    @Nullable
+    @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
+    public Hardware acquireTvInputHardware(int deviceId, @NonNull TvInputInfo info,
+            @Nullable String tvInputSessionId,
+            @TvInputService.PriorityHintUseCaseType int priorityHint,
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull final HardwareCallback callback) {
+        Preconditions.checkNotNull(info);
+        Preconditions.checkNotNull(callback);
+        return acquireTvInputHardwareInternal(deviceId, info, tvInputSessionId, priorityHint,
+                executor, callback);
+    }
+
+    /**
+     * API to add a hardware device in the TvInputHardwareManager for CTS testing
+     * purpose.
+     *
+     * @param deviceId Id of the adding hardware device.
+     *
+     * @hide
+     */
+    @TestApi
+    public void addHardwareDevice(int deviceId) {
+        try {
+            mService.addHardwareDevice(deviceId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * API to remove a hardware device in the TvInputHardwareManager for CTS testing
+     * purpose.
+     *
+     * @param deviceId Id of the removing hardware device.
+     *
+     * @hide
+     */
+    @TestApi
+    public void removeHardwareDevice(int deviceId) {
+        try {
+            mService.removeHardwareDevice(deviceId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    private Hardware acquireTvInputHardwareInternal(int deviceId, TvInputInfo info,
+            String tvInputSessionId, int priorityHint,
+            Executor executor, final HardwareCallback callback) {
+        try {
+            ITvInputHardware hardware =
+                    mService.acquireTvInputHardware(deviceId, new ITvInputHardwareCallback.Stub() {
+                @Override
+                public void onReleased() {
+                            final long identity = Binder.clearCallingIdentity();
+                            try {
+                                executor.execute(() -> callback.onReleased());
+                            } finally {
+                                Binder.restoreCallingIdentity(identity);
+                            }
+                }
+
+                @Override
+                public void onStreamConfigChanged(TvStreamConfig[] configs) {
+                            final long identity = Binder.clearCallingIdentity();
+                            try {
+                                executor.execute(() -> callback.onStreamConfigChanged(configs));
+                            } finally {
+                                Binder.restoreCallingIdentity(identity);
+                            }
+                }
+                    }, info, mUserId, tvInputSessionId, priorityHint);
+            if (hardware == null) {
+                return null;
+            }
+            return new Hardware(hardware);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Releases previously acquired hardware object.
+     *
+     * @param deviceId The device ID this Hardware was acquired for
+     * @param hardware Hardware to release.
+     *
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.TV_INPUT_HARDWARE)
+    public void releaseTvInputHardware(int deviceId, Hardware hardware) {
+        try {
+            mService.releaseTvInputHardware(deviceId, hardware.getInterface(), mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the list of currently available DVB frontend devices on the system.
+     *
+     * @return the list of {@link DvbDeviceInfo} objects representing available DVB devices.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.DVB_DEVICE)
+    @NonNull
+    public List<DvbDeviceInfo> getDvbDeviceList() {
+        try {
+            return mService.getDvbDeviceList();
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns a {@link ParcelFileDescriptor} of a specified DVB device of a given type for a given
+     * {@link DvbDeviceInfo}.
+     *
+     * @param info A {@link DvbDeviceInfo} to open a DVB device.
+     * @param deviceType A DVB device type.
+     * @return a {@link ParcelFileDescriptor} of a specified DVB device for a given
+     * {@link DvbDeviceInfo}, or {@code null} if the given {@link DvbDeviceInfo}
+     * failed to open.
+     * @throws IllegalArgumentException if {@code deviceType} is invalid or the device is not found.
+
+     * @see <a href="https://www.linuxtv.org/docs/dvbapi/dvbapi.html">Linux DVB API v3</a>
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.DVB_DEVICE)
+    @Nullable
+    public ParcelFileDescriptor openDvbDevice(@NonNull DvbDeviceInfo info,
+            @DvbDeviceType int deviceType) {
+        try {
+            if (DVB_DEVICE_START > deviceType || DVB_DEVICE_END < deviceType) {
+                throw new IllegalArgumentException("Invalid DVB device: " + deviceType);
+            }
+            return mService.openDvbDevice(info, deviceType);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Requests to make a channel browsable.
+     *
+     * <p>Once called, the system will review the request and make the channel browsable based on
+     * its policy. The first request from a package is guaranteed to be approved.
+     *
+     * @param channelUri The URI for the channel to be browsable.
+     * @hide
+     */
+    public void requestChannelBrowsable(Uri channelUri) {
+        try {
+            mService.requestChannelBrowsable(channelUri, mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Returns the list of session information for {@link TvInputService.Session} that are
+     * currently in use.
+     * <p> Permission com.android.providers.tv.permission.ACCESS_WATCHED_PROGRAMS is required to get
+     * the channel URIs. If the permission is not granted,
+     * {@link TunedInfo#getChannelUri()} returns {@code null}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.ACCESS_TUNED_INFO)
+    @NonNull
+    public List<TunedInfo> getCurrentTunedInfos() {
+        try {
+            return mService.getCurrentTunedInfos(mUserId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * The Session provides the per-session functionality of TV inputs.
+     * @hide
+     */
+    public static final class Session {
+        static final int DISPATCH_IN_PROGRESS = -1;
+        static final int DISPATCH_NOT_HANDLED = 0;
+        static final int DISPATCH_HANDLED = 1;
+
+        private static final long INPUT_SESSION_NOT_RESPONDING_TIMEOUT = 2500;
+
+        private final ITvInputManager mService;
+        private final int mUserId;
+        private final int mSeq;
+
+        // For scheduling input event handling on the main thread. This also serves as a lock to
+        // protect pending input events and the input channel.
+        private final InputEventHandler mHandler = new InputEventHandler(Looper.getMainLooper());
+
+        private final Pool<PendingEvent> mPendingEventPool = new SimplePool<>(20);
+        private final SparseArray<PendingEvent> mPendingEvents = new SparseArray<>(20);
+        private final SparseArray<SessionCallbackRecord> mSessionCallbackRecordMap;
+
+        private IBinder mToken;
+        private TvInputEventSender mSender;
+        private InputChannel mChannel;
+
+        private final Object mMetadataLock = new Object();
+        // @GuardedBy("mMetadataLock")
+        private final List<TvTrackInfo> mAudioTracks = new ArrayList<>();
+        // @GuardedBy("mMetadataLock")
+        private final List<TvTrackInfo> mVideoTracks = new ArrayList<>();
+        // @GuardedBy("mMetadataLock")
+        private final List<TvTrackInfo> mSubtitleTracks = new ArrayList<>();
+        // @GuardedBy("mMetadataLock")
+        private String mSelectedAudioTrackId;
+        // @GuardedBy("mMetadataLock")
+        private String mSelectedVideoTrackId;
+        // @GuardedBy("mMetadataLock")
+        private String mSelectedSubtitleTrackId;
+        // @GuardedBy("mMetadataLock")
+        private int mVideoWidth;
+        // @GuardedBy("mMetadataLock")
+        private int mVideoHeight;
+
+        private Session(IBinder token, InputChannel channel, ITvInputManager service, int userId,
+                int seq, SparseArray<SessionCallbackRecord> sessionCallbackRecordMap) {
+            mToken = token;
+            mChannel = channel;
+            mService = service;
+            mUserId = userId;
+            mSeq = seq;
+            mSessionCallbackRecordMap = sessionCallbackRecordMap;
+        }
+
+        /**
+         * Releases this session.
+         */
+        public void release() {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.releaseSession(mToken, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+
+            releaseInternal();
+        }
+
+        /**
+         * Sets this as the main session. The main session is a session whose corresponding TV
+         * input determines the HDMI-CEC active source device.
+         *
+         * @see TvView#setMain
+         */
+        void setMain() {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.setMainSession(mToken, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Sets the {@link android.view.Surface} for this session.
+         *
+         * @param surface A {@link android.view.Surface} used to render video.
+         */
+        public void setSurface(Surface surface) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            // surface can be null.
+            try {
+                mService.setSurface(mToken, surface, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Notifies of any structural changes (format or size) of the surface passed in
+         * {@link #setSurface}.
+         *
+         * @param format The new PixelFormat of the surface.
+         * @param width The new width of the surface.
+         * @param height The new height of the surface.
+         */
+        public void dispatchSurfaceChanged(int format, int width, int height) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.dispatchSurfaceChanged(mToken, format, width, height, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Sets the relative stream volume of this session to handle a change of audio focus.
+         *
+         * @param volume A volume value between 0.0f to 1.0f.
+         * @throws IllegalArgumentException if the volume value is out of range.
+         */
+        public void setStreamVolume(float volume) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                if (volume < 0.0f || volume > 1.0f) {
+                    throw new IllegalArgumentException("volume should be between 0.0f and 1.0f");
+                }
+                mService.setVolume(mToken, volume, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Tunes to a given channel.
+         *
+         * @param channelUri The URI of a channel.
+         */
+        public void tune(Uri channelUri) {
+            tune(channelUri, null);
+        }
+
+        /**
+         * Tunes to a given channel.
+         *
+         * @param channelUri The URI of a channel.
+         * @param params A set of extra parameters which might be handled with this tune event.
+         */
+        public void tune(@NonNull Uri channelUri, Bundle params) {
+            Preconditions.checkNotNull(channelUri);
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            synchronized (mMetadataLock) {
+                mAudioTracks.clear();
+                mVideoTracks.clear();
+                mSubtitleTracks.clear();
+                mSelectedAudioTrackId = null;
+                mSelectedVideoTrackId = null;
+                mSelectedSubtitleTrackId = null;
+                mVideoWidth = 0;
+                mVideoHeight = 0;
+            }
+            try {
+                mService.tune(mToken, channelUri, params, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Enables or disables the caption for this session.
+         *
+         * @param enabled {@code true} to enable, {@code false} to disable.
+         */
+        public void setCaptionEnabled(boolean enabled) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.setCaptionEnabled(mToken, enabled, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Selects a track.
+         *
+         * @param type The type of the track to select. The type can be
+         *            {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+         *            {@link TvTrackInfo#TYPE_SUBTITLE}.
+         * @param trackId The ID of the track to select. When {@code null}, the currently selected
+         *            track of the given type will be unselected.
+         * @see #getTracks
+         */
+        public void selectTrack(int type, @Nullable String trackId) {
+            synchronized (mMetadataLock) {
+                if (type == TvTrackInfo.TYPE_AUDIO) {
+                    if (trackId != null && !containsTrack(mAudioTracks, trackId)) {
+                        Log.w(TAG, "Invalid audio trackId: " + trackId);
+                        return;
+                    }
+                } else if (type == TvTrackInfo.TYPE_VIDEO) {
+                    if (trackId != null && !containsTrack(mVideoTracks, trackId)) {
+                        Log.w(TAG, "Invalid video trackId: " + trackId);
+                        return;
+                    }
+                } else if (type == TvTrackInfo.TYPE_SUBTITLE) {
+                    if (trackId != null && !containsTrack(mSubtitleTracks, trackId)) {
+                        Log.w(TAG, "Invalid subtitle trackId: " + trackId);
+                        return;
+                    }
+                } else {
+                    throw new IllegalArgumentException("invalid type: " + type);
+                }
+            }
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.selectTrack(mToken, type, trackId, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        private boolean containsTrack(List<TvTrackInfo> tracks, String trackId) {
+            for (TvTrackInfo track : tracks) {
+                if (track.getId().equals(trackId)) {
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Returns the list of tracks for a given type. Returns {@code null} if the information is
+         * not available.
+         *
+         * @param type The type of the tracks. The type can be {@link TvTrackInfo#TYPE_AUDIO},
+         *            {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}.
+         * @return the list of tracks for the given type.
+         */
+        @Nullable
+        public List<TvTrackInfo> getTracks(int type) {
+            synchronized (mMetadataLock) {
+                if (type == TvTrackInfo.TYPE_AUDIO) {
+                    if (mAudioTracks == null) {
+                        return null;
+                    }
+                    return new ArrayList<>(mAudioTracks);
+                } else if (type == TvTrackInfo.TYPE_VIDEO) {
+                    if (mVideoTracks == null) {
+                        return null;
+                    }
+                    return new ArrayList<>(mVideoTracks);
+                } else if (type == TvTrackInfo.TYPE_SUBTITLE) {
+                    if (mSubtitleTracks == null) {
+                        return null;
+                    }
+                    return new ArrayList<>(mSubtitleTracks);
+                }
+            }
+            throw new IllegalArgumentException("invalid type: " + type);
+        }
+
+        /**
+         * Returns the selected track for a given type. Returns {@code null} if the information is
+         * not available or any of the tracks for the given type is not selected.
+         *
+         * @return The ID of the selected track.
+         * @see #selectTrack
+         */
+        @Nullable
+        public String getSelectedTrack(int type) {
+            synchronized (mMetadataLock) {
+                if (type == TvTrackInfo.TYPE_AUDIO) {
+                    return mSelectedAudioTrackId;
+                } else if (type == TvTrackInfo.TYPE_VIDEO) {
+                    return mSelectedVideoTrackId;
+                } else if (type == TvTrackInfo.TYPE_SUBTITLE) {
+                    return mSelectedSubtitleTrackId;
+                }
+            }
+            throw new IllegalArgumentException("invalid type: " + type);
+        }
+
+        /**
+         * Responds to onTracksChanged() and updates the internal track information. Returns true if
+         * there is an update.
+         */
+        boolean updateTracks(List<TvTrackInfo> tracks) {
+            synchronized (mMetadataLock) {
+                mAudioTracks.clear();
+                mVideoTracks.clear();
+                mSubtitleTracks.clear();
+                for (TvTrackInfo track : tracks) {
+                    if (track.getType() == TvTrackInfo.TYPE_AUDIO) {
+                        mAudioTracks.add(track);
+                    } else if (track.getType() == TvTrackInfo.TYPE_VIDEO) {
+                        mVideoTracks.add(track);
+                    } else if (track.getType() == TvTrackInfo.TYPE_SUBTITLE) {
+                        mSubtitleTracks.add(track);
+                    }
+                }
+                return !mAudioTracks.isEmpty() || !mVideoTracks.isEmpty()
+                        || !mSubtitleTracks.isEmpty();
+            }
+        }
+
+        /**
+         * Responds to onTrackSelected() and updates the internal track selection information.
+         * Returns true if there is an update.
+         */
+        boolean updateTrackSelection(int type, String trackId) {
+            synchronized (mMetadataLock) {
+                if (type == TvTrackInfo.TYPE_AUDIO
+                        && !TextUtils.equals(trackId, mSelectedAudioTrackId)) {
+                    mSelectedAudioTrackId = trackId;
+                    return true;
+                } else if (type == TvTrackInfo.TYPE_VIDEO
+                        && !TextUtils.equals(trackId, mSelectedVideoTrackId)) {
+                    mSelectedVideoTrackId = trackId;
+                    return true;
+                } else if (type == TvTrackInfo.TYPE_SUBTITLE
+                        && !TextUtils.equals(trackId, mSelectedSubtitleTrackId)) {
+                    mSelectedSubtitleTrackId = trackId;
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        /**
+         * Returns the new/updated video track that contains new video size information. Returns
+         * null if there is no video track to notify. Subsequent calls of this method results in a
+         * non-null video track returned only by the first call and null returned by following
+         * calls. The caller should immediately notify of the video size change upon receiving the
+         * track.
+         */
+        TvTrackInfo getVideoTrackToNotify() {
+            synchronized (mMetadataLock) {
+                if (!mVideoTracks.isEmpty() && mSelectedVideoTrackId != null) {
+                    for (TvTrackInfo track : mVideoTracks) {
+                        if (track.getId().equals(mSelectedVideoTrackId)) {
+                            int videoWidth = track.getVideoWidth();
+                            int videoHeight = track.getVideoHeight();
+                            if (mVideoWidth != videoWidth || mVideoHeight != videoHeight) {
+                                mVideoWidth = videoWidth;
+                                mVideoHeight = videoHeight;
+                                return track;
+                            }
+                        }
+                    }
+                }
+            }
+            return null;
+        }
+
+        /**
+         * Plays a given recorded TV program.
+         */
+        void timeShiftPlay(Uri recordedProgramUri) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.timeShiftPlay(mToken, recordedProgramUri, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Pauses the playback. Call {@link #timeShiftResume()} to restart the playback.
+         */
+        void timeShiftPause() {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.timeShiftPause(mToken, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Resumes the playback. No-op if it is already playing the channel.
+         */
+        void timeShiftResume() {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.timeShiftResume(mToken, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Seeks to a specified time position.
+         *
+         * <p>Normally, the position is given within range between the start and the current time,
+         * inclusively.
+         *
+         * @param timeMs The time position to seek to, in milliseconds since the epoch.
+         * @see TvView.TimeShiftPositionCallback#onTimeShiftStartPositionChanged
+         */
+        void timeShiftSeekTo(long timeMs) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.timeShiftSeekTo(mToken, timeMs, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Sets playback rate using {@link android.media.PlaybackParams}.
+         *
+         * @param params The playback params.
+         */
+        void timeShiftSetPlaybackParams(PlaybackParams params) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.timeShiftSetPlaybackParams(mToken, params, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Enable/disable position tracking.
+         *
+         * @param enable {@code true} to enable tracking, {@code false} otherwise.
+         */
+        void timeShiftEnablePositionTracking(boolean enable) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.timeShiftEnablePositionTracking(mToken, enable, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Starts TV program recording in the current recording session.
+         *
+         * @param programUri The URI for the TV program to record as a hint, built by
+         *            {@link TvContract#buildProgramUri(long)}. Can be {@code null}.
+         */
+        void startRecording(@Nullable Uri programUri) {
+            startRecording(programUri, null);
+        }
+
+        /**
+         * Starts TV program recording in the current recording session.
+         *
+         * @param programUri The URI for the TV program to record as a hint, built by
+         *            {@link TvContract#buildProgramUri(long)}. Can be {@code null}.
+         * @param params A set of extra parameters which might be handled with this event.
+         */
+        void startRecording(@Nullable Uri programUri, @Nullable Bundle params) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.startRecording(mToken, programUri, params, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Stops TV program recording in the current recording session.
+         */
+        void stopRecording() {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.stopRecording(mToken, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Pauses TV program recording in the current recording session.
+         *
+         * @param params Domain-specific data for this request. Keys <em>must</em> be a scoped
+         *            name, i.e. prefixed with a package name you own, so that different developers
+         *            will not create conflicting keys.
+         *        {@link TvRecordingClient#pauseRecording(Bundle)}.
+         */
+        void pauseRecording(@NonNull Bundle params) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.pauseRecording(mToken, params, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Resumes TV program recording in the current recording session.
+         *
+         * @param params Domain-specific data for this request. Keys <em>must</em> be a scoped
+         *            name, i.e. prefixed with a package name you own, so that different developers
+         *            will not create conflicting keys.
+         *        {@link TvRecordingClient#resumeRecording(Bundle)}.
+         */
+        void resumeRecording(@NonNull Bundle params) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.resumeRecording(mToken, params, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Calls {@link TvInputService.Session#appPrivateCommand(String, Bundle)
+         * TvInputService.Session.appPrivateCommand()} on the current TvView.
+         *
+         * @param action Name of the command to be performed. This <em>must</em> be a scoped name,
+         *            i.e. prefixed with a package name you own, so that different developers will
+         *            not create conflicting commands.
+         * @param data Any data to include with the command.
+         */
+        public void sendAppPrivateCommand(String action, Bundle data) {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.sendAppPrivateCommand(mToken, action, data, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Creates an overlay view. Once the overlay view is created, {@link #relayoutOverlayView}
+         * should be called whenever the layout of its containing view is changed.
+         * {@link #removeOverlayView()} should be called to remove the overlay view.
+         * Since a session can have only one overlay view, this method should be called only once
+         * or it can be called again after calling {@link #removeOverlayView()}.
+         *
+         * @param view A view playing TV.
+         * @param frame A position of the overlay view.
+         * @throws IllegalStateException if {@code view} is not attached to a window.
+         */
+        void createOverlayView(@NonNull View view, @NonNull Rect frame) {
+            Preconditions.checkNotNull(view);
+            Preconditions.checkNotNull(frame);
+            if (view.getWindowToken() == null) {
+                throw new IllegalStateException("view must be attached to a window");
+            }
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.createOverlayView(mToken, view.getWindowToken(), frame, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Relayouts the current overlay view.
+         *
+         * @param frame A new position of the overlay view.
+         */
+        void relayoutOverlayView(@NonNull Rect frame) {
+            Preconditions.checkNotNull(frame);
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.relayoutOverlayView(mToken, frame, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Removes the current overlay view.
+         */
+        void removeOverlayView() {
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.removeOverlayView(mToken, mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Requests to unblock content blocked by parental controls.
+         */
+        void unblockContent(@NonNull TvContentRating unblockedRating) {
+            Preconditions.checkNotNull(unblockedRating);
+            if (mToken == null) {
+                Log.w(TAG, "The session has been already released");
+                return;
+            }
+            try {
+                mService.unblockContent(mToken, unblockedRating.flattenToString(), mUserId);
+            } catch (RemoteException e) {
+                throw e.rethrowFromSystemServer();
+            }
+        }
+
+        /**
+         * Dispatches an input event to this session.
+         *
+         * @param event An {@link InputEvent} to dispatch. Cannot be {@code null}.
+         * @param token A token used to identify the input event later in the callback.
+         * @param callback A callback used to receive the dispatch result. Cannot be {@code null}.
+         * @param handler A {@link Handler} that the dispatch result will be delivered to. Cannot be
+         *            {@code null}.
+         * @return Returns {@link #DISPATCH_HANDLED} if the event was handled. Returns
+         *         {@link #DISPATCH_NOT_HANDLED} if the event was not handled. Returns
+         *         {@link #DISPATCH_IN_PROGRESS} if the event is in progress and the callback will
+         *         be invoked later.
+         * @hide
+         */
+        public int dispatchInputEvent(@NonNull InputEvent event, Object token,
+                @NonNull FinishedInputEventCallback callback, @NonNull Handler handler) {
+            Preconditions.checkNotNull(event);
+            Preconditions.checkNotNull(callback);
+            Preconditions.checkNotNull(handler);
+            synchronized (mHandler) {
+                if (mChannel == null) {
+                    return DISPATCH_NOT_HANDLED;
+                }
+                PendingEvent p = obtainPendingEventLocked(event, token, callback, handler);
+                if (Looper.myLooper() == Looper.getMainLooper()) {
+                    // Already running on the main thread so we can send the event immediately.
+                    return sendInputEventOnMainLooperLocked(p);
+                }
+
+                // Post the event to the main thread.
+                Message msg = mHandler.obtainMessage(InputEventHandler.MSG_SEND_INPUT_EVENT, p);
+                msg.setAsynchronous(true);
+                mHandler.sendMessage(msg);
+                return DISPATCH_IN_PROGRESS;
+            }
+        }
+
+        /**
+         * Callback that is invoked when an input event that was dispatched to this session has been
+         * finished.
+         *
+         * @hide
+         */
+        public interface FinishedInputEventCallback {
+            /**
+             * Called when the dispatched input event is finished.
+             *
+             * @param token A token passed to {@link #dispatchInputEvent}.
+             * @param handled {@code true} if the dispatched input event was handled properly.
+             *            {@code false} otherwise.
+             */
+            void onFinishedInputEvent(Object token, boolean handled);
+        }
+
+        // Must be called on the main looper
+        private void sendInputEventAndReportResultOnMainLooper(PendingEvent p) {
+            synchronized (mHandler) {
+                int result = sendInputEventOnMainLooperLocked(p);
+                if (result == DISPATCH_IN_PROGRESS) {
+                    return;
+                }
+            }
+
+            invokeFinishedInputEventCallback(p, false);
+        }
+
+        private int sendInputEventOnMainLooperLocked(PendingEvent p) {
+            if (mChannel != null) {
+                if (mSender == null) {
+                    mSender = new TvInputEventSender(mChannel, mHandler.getLooper());
+                }
+
+                final InputEvent event = p.mEvent;
+                final int seq = event.getSequenceNumber();
+                if (mSender.sendInputEvent(seq, event)) {
+                    mPendingEvents.put(seq, p);
+                    Message msg = mHandler.obtainMessage(InputEventHandler.MSG_TIMEOUT_INPUT_EVENT, p);
+                    msg.setAsynchronous(true);
+                    mHandler.sendMessageDelayed(msg, INPUT_SESSION_NOT_RESPONDING_TIMEOUT);
+                    return DISPATCH_IN_PROGRESS;
+                }
+
+                Log.w(TAG, "Unable to send input event to session: " + mToken + " dropping:"
+                        + event);
+            }
+            return DISPATCH_NOT_HANDLED;
+        }
+
+        void finishedInputEvent(int seq, boolean handled, boolean timeout) {
+            final PendingEvent p;
+            synchronized (mHandler) {
+                int index = mPendingEvents.indexOfKey(seq);
+                if (index < 0) {
+                    return; // spurious, event already finished or timed out
+                }
+
+                p = mPendingEvents.valueAt(index);
+                mPendingEvents.removeAt(index);
+
+                if (timeout) {
+                    Log.w(TAG, "Timeout waiting for session to handle input event after "
+                            + INPUT_SESSION_NOT_RESPONDING_TIMEOUT + " ms: " + mToken);
+                } else {
+                    mHandler.removeMessages(InputEventHandler.MSG_TIMEOUT_INPUT_EVENT, p);
+                }
+            }
+
+            invokeFinishedInputEventCallback(p, handled);
+        }
+
+        // Assumes the event has already been removed from the queue.
+        void invokeFinishedInputEventCallback(PendingEvent p, boolean handled) {
+            p.mHandled = handled;
+            if (p.mEventHandler.getLooper().isCurrentThread()) {
+                // Already running on the callback handler thread so we can send the callback
+                // immediately.
+                p.run();
+            } else {
+                // Post the event to the callback handler thread.
+                // In this case, the callback will be responsible for recycling the event.
+                Message msg = Message.obtain(p.mEventHandler, p);
+                msg.setAsynchronous(true);
+                msg.sendToTarget();
+            }
+        }
+
+        private void flushPendingEventsLocked() {
+            mHandler.removeMessages(InputEventHandler.MSG_FLUSH_INPUT_EVENT);
+
+            final int count = mPendingEvents.size();
+            for (int i = 0; i < count; i++) {
+                int seq = mPendingEvents.keyAt(i);
+                Message msg = mHandler.obtainMessage(InputEventHandler.MSG_FLUSH_INPUT_EVENT, seq, 0);
+                msg.setAsynchronous(true);
+                msg.sendToTarget();
+            }
+        }
+
+        private PendingEvent obtainPendingEventLocked(InputEvent event, Object token,
+                FinishedInputEventCallback callback, Handler handler) {
+            PendingEvent p = mPendingEventPool.acquire();
+            if (p == null) {
+                p = new PendingEvent();
+            }
+            p.mEvent = event;
+            p.mEventToken = token;
+            p.mCallback = callback;
+            p.mEventHandler = handler;
+            return p;
+        }
+
+        private void recyclePendingEventLocked(PendingEvent p) {
+            p.recycle();
+            mPendingEventPool.release(p);
+        }
+
+        IBinder getToken() {
+            return mToken;
+        }
+
+        private void releaseInternal() {
+            mToken = null;
+            synchronized (mHandler) {
+                if (mChannel != null) {
+                    if (mSender != null) {
+                        flushPendingEventsLocked();
+                        mSender.dispose();
+                        mSender = null;
+                    }
+                    mChannel.dispose();
+                    mChannel = null;
+                }
+            }
+            synchronized (mSessionCallbackRecordMap) {
+                mSessionCallbackRecordMap.delete(mSeq);
+            }
+        }
+
+        private final class InputEventHandler extends Handler {
+            public static final int MSG_SEND_INPUT_EVENT = 1;
+            public static final int MSG_TIMEOUT_INPUT_EVENT = 2;
+            public static final int MSG_FLUSH_INPUT_EVENT = 3;
+
+            InputEventHandler(Looper looper) {
+                super(looper, null, true);
+            }
+
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case MSG_SEND_INPUT_EVENT: {
+                        sendInputEventAndReportResultOnMainLooper((PendingEvent) msg.obj);
+                        return;
+                    }
+                    case MSG_TIMEOUT_INPUT_EVENT: {
+                        finishedInputEvent(msg.arg1, false, true);
+                        return;
+                    }
+                    case MSG_FLUSH_INPUT_EVENT: {
+                        finishedInputEvent(msg.arg1, false, false);
+                        return;
+                    }
+                }
+            }
+        }
+
+        private final class TvInputEventSender extends InputEventSender {
+            public TvInputEventSender(InputChannel inputChannel, Looper looper) {
+                super(inputChannel, looper);
+            }
+
+            @Override
+            public void onInputEventFinished(int seq, boolean handled) {
+                finishedInputEvent(seq, handled, false);
+            }
+        }
+
+        private final class PendingEvent implements Runnable {
+            public InputEvent mEvent;
+            public Object mEventToken;
+            public FinishedInputEventCallback mCallback;
+            public Handler mEventHandler;
+            public boolean mHandled;
+
+            public void recycle() {
+                mEvent = null;
+                mEventToken = null;
+                mCallback = null;
+                mEventHandler = null;
+                mHandled = false;
+            }
+
+            @Override
+            public void run() {
+                mCallback.onFinishedInputEvent(mEventToken, mHandled);
+
+                synchronized (mEventHandler) {
+                    recyclePendingEventLocked(this);
+                }
+            }
+        }
+    }
+
+    /**
+     * The Hardware provides the per-hardware functionality of TV hardware.
+     *
+     * <p>TV hardware is physical hardware attached to the Android device; for example, HDMI ports,
+     * Component/Composite ports, etc. Specifically, logical devices such as HDMI CEC logical
+     * devices don't fall into this category.
+     *
+     * @hide
+     */
+    @SystemApi
+    public final static class Hardware {
+        private final ITvInputHardware mInterface;
+
+        private Hardware(ITvInputHardware hardwareInterface) {
+            mInterface = hardwareInterface;
+        }
+
+        private ITvInputHardware getInterface() {
+            return mInterface;
+        }
+
+        public boolean setSurface(Surface surface, TvStreamConfig config) {
+            try {
+                return mInterface.setSurface(surface, config);
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        public void setStreamVolume(float volume) {
+            try {
+                mInterface.setStreamVolume(volume);
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        /** @removed */
+        @SystemApi
+        public boolean dispatchKeyEventToHdmi(KeyEvent event) {
+            return false;
+        }
+
+        public void overrideAudioSink(int audioType, String audioAddress, int samplingRate,
+                int channelMask, int format) {
+            try {
+                mInterface.overrideAudioSink(audioType, audioAddress, samplingRate, channelMask,
+                        format);
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+}
diff --git a/android/media/tv/TvInputService.java b/android/media/tv/TvInputService.java
new file mode 100644
index 0000000..77fb2b2
--- /dev/null
+++ b/android/media/tv/TvInputService.java
@@ -0,0 +1,2337 @@
+/*
+ * Copyright (C) 2014 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.tv;
+
+import android.annotation.FloatRange;
+import android.annotation.IntDef;
+import android.annotation.MainThread;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.app.ActivityManager;
+import android.app.Service;
+import android.compat.annotation.UnsupportedAppUsage;
+import android.content.Context;
+import android.content.Intent;
+import android.graphics.PixelFormat;
+import android.graphics.Rect;
+import android.hardware.hdmi.HdmiDeviceInfo;
+import android.media.PlaybackParams;
+import android.net.Uri;
+import android.os.AsyncTask;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.Process;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.InputChannel;
+import android.view.InputDevice;
+import android.view.InputEvent;
+import android.view.InputEventReceiver;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.View;
+import android.view.WindowManager;
+import android.view.accessibility.CaptioningManager;
+import android.widget.FrameLayout;
+
+import com.android.internal.os.SomeArgs;
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * The TvInputService class represents a TV input or source such as HDMI or built-in tuner which
+ * provides pass-through video or broadcast TV programs.
+ *
+ * <p>Applications will not normally use this service themselves, instead relying on the standard
+ * interaction provided by {@link TvView}. Those implementing TV input services should normally do
+ * so by deriving from this class and providing their own session implementation based on
+ * {@link TvInputService.Session}. All TV input services must require that clients hold the
+ * {@link android.Manifest.permission#BIND_TV_INPUT} in order to interact with the service; if this
+ * permission is not specified in the manifest, the system will refuse to bind to that TV input
+ * service.
+ */
+public abstract class TvInputService extends Service {
+    private static final boolean DEBUG = false;
+    private static final String TAG = "TvInputService";
+
+    private static final int DETACH_OVERLAY_VIEW_TIMEOUT_MS = 5000;
+
+    /**
+     * This is the interface name that a service implementing a TV input should say that it support
+     * -- that is, this is the action it uses for its intent filter. To be supported, the service
+     * must also require the {@link android.Manifest.permission#BIND_TV_INPUT} permission so that
+     * other applications cannot abuse it.
+     */
+    public static final String SERVICE_INTERFACE = "android.media.tv.TvInputService";
+
+    /**
+     * Name under which a TvInputService component publishes information about itself.
+     * This meta-data must reference an XML resource containing an
+     * <code>&lt;{@link android.R.styleable#TvInputService tv-input}&gt;</code>
+     * tag.
+     */
+    public static final String SERVICE_META_DATA = "android.media.tv.input";
+
+    /**
+     * Prioirity hint from use case types.
+     *
+     * @hide
+     */
+    @IntDef(prefix = "PRIORITY_HINT_USE_CASE_TYPE_",
+        value = {PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND, PRIORITY_HINT_USE_CASE_TYPE_SCAN,
+            PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK, PRIORITY_HINT_USE_CASE_TYPE_LIVE,
+            PRIORITY_HINT_USE_CASE_TYPE_RECORD})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PriorityHintUseCaseType {}
+
+    /**
+     * Use case of priority hint for {@link android.media.MediaCas#MediaCas(Context, int, String,
+     * int)}: Background. TODO Link: Tuner#Tuner(Context, string, int).
+     */
+    public static final int PRIORITY_HINT_USE_CASE_TYPE_BACKGROUND = 100;
+
+    /**
+     * Use case of priority hint for {@link android.media.MediaCas#MediaCas(Context, int, String,
+     * int)}: Scan. TODO Link: Tuner#Tuner(Context, string, int).
+     */
+    public static final int PRIORITY_HINT_USE_CASE_TYPE_SCAN = 200;
+
+    /**
+     * Use case of priority hint for {@link android.media.MediaCas#MediaCas(Context, int, String,
+     * int)}: Playback. TODO Link: Tuner#Tuner(Context, string, int).
+     */
+    public static final int PRIORITY_HINT_USE_CASE_TYPE_PLAYBACK = 300;
+
+    /**
+     * Use case of priority hint for {@link android.media.MediaCas#MediaCas(Context, int, String,
+     * int)}: Live. TODO Link: Tuner#Tuner(Context, string, int).
+     */
+    public static final int PRIORITY_HINT_USE_CASE_TYPE_LIVE = 400;
+
+    /**
+     * Use case of priority hint for {@link android.media.MediaCas#MediaCas(Context, int, String,
+     * int)}: Record. TODO Link: Tuner#Tuner(Context, string, int).
+     */
+    public static final int PRIORITY_HINT_USE_CASE_TYPE_RECORD = 500;
+
+    /**
+     * Handler instance to handle request from TV Input Manager Service. Should be run in the main
+     * looper to be synchronously run with {@code Session.mHandler}.
+     */
+    private final Handler mServiceHandler = new ServiceHandler();
+    private final RemoteCallbackList<ITvInputServiceCallback> mCallbacks =
+            new RemoteCallbackList<>();
+
+    private TvInputManager mTvInputManager;
+
+    @Override
+    public final IBinder onBind(Intent intent) {
+        ITvInputService.Stub tvInputServiceBinder = new ITvInputService.Stub() {
+            @Override
+            public void registerCallback(ITvInputServiceCallback cb) {
+                if (cb != null) {
+                    mCallbacks.register(cb);
+                }
+            }
+
+            @Override
+            public void unregisterCallback(ITvInputServiceCallback cb) {
+                if (cb != null) {
+                    mCallbacks.unregister(cb);
+                }
+            }
+
+            @Override
+            public void createSession(InputChannel channel, ITvInputSessionCallback cb,
+                    String inputId, String sessionId) {
+                if (channel == null) {
+                    Log.w(TAG, "Creating session without input channel");
+                }
+                if (cb == null) {
+                    return;
+                }
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = channel;
+                args.arg2 = cb;
+                args.arg3 = inputId;
+                args.arg4 = sessionId;
+                mServiceHandler.obtainMessage(ServiceHandler.DO_CREATE_SESSION,
+                        args).sendToTarget();
+            }
+
+            @Override
+            public void createRecordingSession(ITvInputSessionCallback cb, String inputId,
+                    String sessionId) {
+                if (cb == null) {
+                    return;
+                }
+                SomeArgs args = SomeArgs.obtain();
+                args.arg1 = cb;
+                args.arg2 = inputId;
+                args.arg3 = sessionId;
+                mServiceHandler.obtainMessage(ServiceHandler.DO_CREATE_RECORDING_SESSION, args)
+                        .sendToTarget();
+            }
+
+            @Override
+            public void notifyHardwareAdded(TvInputHardwareInfo hardwareInfo) {
+                mServiceHandler.obtainMessage(ServiceHandler.DO_ADD_HARDWARE_INPUT,
+                        hardwareInfo).sendToTarget();
+            }
+
+            @Override
+            public void notifyHardwareRemoved(TvInputHardwareInfo hardwareInfo) {
+                mServiceHandler.obtainMessage(ServiceHandler.DO_REMOVE_HARDWARE_INPUT,
+                        hardwareInfo).sendToTarget();
+            }
+
+            @Override
+            public void notifyHdmiDeviceAdded(HdmiDeviceInfo deviceInfo) {
+                mServiceHandler.obtainMessage(ServiceHandler.DO_ADD_HDMI_INPUT,
+                        deviceInfo).sendToTarget();
+            }
+
+            @Override
+            public void notifyHdmiDeviceRemoved(HdmiDeviceInfo deviceInfo) {
+                mServiceHandler.obtainMessage(ServiceHandler.DO_REMOVE_HDMI_INPUT,
+                        deviceInfo).sendToTarget();
+            }
+
+            @Override
+            public void notifyHdmiDeviceUpdated(HdmiDeviceInfo deviceInfo) {
+                mServiceHandler.obtainMessage(ServiceHandler.DO_UPDATE_HDMI_INPUT,
+                        deviceInfo).sendToTarget();
+            }
+        };
+        IBinder ext = createExtension();
+        if (ext != null) {
+            tvInputServiceBinder.setExtension(ext);
+        }
+        return tvInputServiceBinder;
+    }
+
+    /**
+     * Returns a new {@link android.os.Binder}
+     *
+     * <p> if an extension is provided on top of existing {@link TvInputService}; otherwise,
+     * return {@code null}. Override to provide extended interface.
+     *
+     * @see android.os.Binder#setExtension(IBinder)
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    public IBinder createExtension() {
+        return null;
+    }
+
+    /**
+     * Returns a concrete implementation of {@link Session}.
+     *
+     * <p>May return {@code null} if this TV input service fails to create a session for some
+     * reason. If TV input represents an external device connected to a hardware TV input,
+     * {@link HardwareSession} should be returned.
+     *
+     * @param inputId The ID of the TV input associated with the session.
+     */
+    @Nullable
+    public abstract Session onCreateSession(@NonNull String inputId);
+
+    /**
+     * Returns a concrete implementation of {@link RecordingSession}.
+     *
+     * <p>May return {@code null} if this TV input service fails to create a recording session for
+     * some reason.
+     *
+     * @param inputId The ID of the TV input associated with the recording session.
+     */
+    @Nullable
+    public RecordingSession onCreateRecordingSession(@NonNull String inputId) {
+        return null;
+    }
+
+    /**
+     * Returns a concrete implementation of {@link Session}.
+     *
+     * <p>For any apps that needs sessionId to request tuner resources from TunerResourceManager,
+     * it needs to override this method to get the sessionId passed. When no overriding, this method
+     * calls {@link #onCreateSession(String)} defaultly.
+     *
+     * @param inputId The ID of the TV input associated with the session.
+     * @param sessionId the unique sessionId created by TIF when session is created.
+     */
+    @Nullable
+    public Session onCreateSession(@NonNull String inputId, @NonNull String sessionId) {
+        return onCreateSession(inputId);
+    }
+
+    /**
+     * Returns a concrete implementation of {@link RecordingSession}.
+     *
+     * <p>For any apps that needs sessionId to request tuner resources from TunerResourceManager,
+     * it needs to override this method to get the sessionId passed. When no overriding, this method
+     * calls {@link #onCreateRecordingSession(String)} defaultly.
+     *
+     * @param inputId The ID of the TV input associated with the recording session.
+     * @param sessionId the unique sessionId created by TIF when session is created.
+     */
+    @Nullable
+    public RecordingSession onCreateRecordingSession(
+            @NonNull String inputId, @NonNull String sessionId) {
+        return onCreateRecordingSession(inputId);
+    }
+
+    /**
+     * Returns a new {@link TvInputInfo} object if this service is responsible for
+     * {@code hardwareInfo}; otherwise, return {@code null}. Override to modify default behavior of
+     * ignoring all hardware input.
+     *
+     * @param hardwareInfo {@link TvInputHardwareInfo} object just added.
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    public TvInputInfo onHardwareAdded(TvInputHardwareInfo hardwareInfo) {
+        return null;
+    }
+
+    /**
+     * Returns the input ID for {@code deviceId} if it is handled by this service;
+     * otherwise, return {@code null}. Override to modify default behavior of ignoring all hardware
+     * input.
+     *
+     * @param hardwareInfo {@link TvInputHardwareInfo} object just removed.
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    public String onHardwareRemoved(TvInputHardwareInfo hardwareInfo) {
+        return null;
+    }
+
+    /**
+     * Returns a new {@link TvInputInfo} object if this service is responsible for
+     * {@code deviceInfo}; otherwise, return {@code null}. Override to modify default behavior of
+     * ignoring all HDMI logical input device.
+     *
+     * @param deviceInfo {@link HdmiDeviceInfo} object just added.
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    public TvInputInfo onHdmiDeviceAdded(HdmiDeviceInfo deviceInfo) {
+        return null;
+    }
+
+    /**
+     * Returns the input ID for {@code deviceInfo} if it is handled by this service; otherwise,
+     * return {@code null}. Override to modify default behavior of ignoring all HDMI logical input
+     * device.
+     *
+     * @param deviceInfo {@link HdmiDeviceInfo} object just removed.
+     * @hide
+     */
+    @Nullable
+    @SystemApi
+    public String onHdmiDeviceRemoved(HdmiDeviceInfo deviceInfo) {
+        return null;
+    }
+
+    /**
+     * Called when {@code deviceInfo} is updated.
+     *
+     * <p>The changes are usually cuased by the corresponding HDMI-CEC logical device.
+     *
+     * <p>The default behavior ignores all changes.
+     *
+     * <p>The TV input service responsible for {@code deviceInfo} can update the {@link TvInputInfo}
+     * object based on the updated {@code deviceInfo} (e.g. update the label based on the preferred
+     * device OSD name).
+     *
+     * @param deviceInfo the updated {@link HdmiDeviceInfo} object.
+     * @hide
+     */
+    @SystemApi
+    public void onHdmiDeviceUpdated(@NonNull HdmiDeviceInfo deviceInfo) {
+    }
+
+    private boolean isPassthroughInput(String inputId) {
+        if (mTvInputManager == null) {
+            mTvInputManager = (TvInputManager) getSystemService(Context.TV_INPUT_SERVICE);
+        }
+        TvInputInfo info = mTvInputManager.getTvInputInfo(inputId);
+        return info != null && info.isPassthroughInput();
+    }
+
+    /**
+     * Base class for derived classes to implement to provide a TV input session.
+     */
+    public abstract static class Session implements KeyEvent.Callback {
+        private static final int POSITION_UPDATE_INTERVAL_MS = 1000;
+
+        private final KeyEvent.DispatcherState mDispatcherState = new KeyEvent.DispatcherState();
+        private final WindowManager mWindowManager;
+        final Handler mHandler;
+        private WindowManager.LayoutParams mWindowParams;
+        private Surface mSurface;
+        private final Context mContext;
+        private FrameLayout mOverlayViewContainer;
+        private View mOverlayView;
+        private OverlayViewCleanUpTask mOverlayViewCleanUpTask;
+        private boolean mOverlayViewEnabled;
+        private IBinder mWindowToken;
+        @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
+        private Rect mOverlayFrame;
+        private long mStartPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
+        private long mCurrentPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
+        private final TimeShiftPositionTrackingRunnable
+                mTimeShiftPositionTrackingRunnable = new TimeShiftPositionTrackingRunnable();
+
+        private final Object mLock = new Object();
+        // @GuardedBy("mLock")
+        private ITvInputSessionCallback mSessionCallback;
+        // @GuardedBy("mLock")
+        private final List<Runnable> mPendingActions = new ArrayList<>();
+
+        /**
+         * Creates a new Session.
+         *
+         * @param context The context of the application
+         */
+        public Session(Context context) {
+            mContext = context;
+            mWindowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+            mHandler = new Handler(context.getMainLooper());
+        }
+
+        /**
+         * Enables or disables the overlay view.
+         *
+         * <p>By default, the overlay view is disabled. Must be called explicitly after the
+         * session is created to enable the overlay view.
+         *
+         * <p>The TV input service can disable its overlay view when the size of the overlay view is
+         * insufficient to display the whole information, such as when used in Picture-in-picture.
+         * Override {@link #onOverlayViewSizeChanged} to get the size of the overlay view, which
+         * then can be used to determine whether to enable/disable the overlay view.
+         *
+         * @param enable {@code true} if you want to enable the overlay view. {@code false}
+         *            otherwise.
+         */
+        public void setOverlayViewEnabled(final boolean enable) {
+            mHandler.post(new Runnable() {
+                @Override
+                public void run() {
+                    if (enable == mOverlayViewEnabled) {
+                        return;
+                    }
+                    mOverlayViewEnabled = enable;
+                    if (enable) {
+                        if (mWindowToken != null) {
+                            createOverlayView(mWindowToken, mOverlayFrame);
+                        }
+                    } else {
+                        removeOverlayView(false);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Dispatches an event to the application using this session.
+         *
+         * @param eventType The type of the event.
+         * @param eventArgs Optional arguments of the event.
+         * @hide
+         */
+        @SystemApi
+        public void notifySessionEvent(@NonNull final String eventType, final Bundle eventArgs) {
+            Preconditions.checkNotNull(eventType);
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifySessionEvent(" + eventType + ")");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onSessionEvent(eventType, eventArgs);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in sending event (event=" + eventType + ")", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Informs the application that the current channel is re-tuned for some reason and the
+         * session now displays the content from a new channel. This is used to handle special cases
+         * such as when the current channel becomes unavailable, it is necessary to send the user to
+         * a certain channel or the user changes channel in some other way (e.g. by using a
+         * dedicated remote).
+         *
+         * @param channelUri The URI of the new channel.
+         */
+        public void notifyChannelRetuned(final Uri channelUri) {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyChannelRetuned");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onChannelRetuned(channelUri);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyChannelRetuned", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Sends the list of all audio/video/subtitle tracks. The is used by the framework to
+         * maintain the track information for a given session, which in turn is used by
+         * {@link TvView#getTracks} for the application to retrieve metadata for a given track type.
+         * The TV input service must call this method as soon as the track information becomes
+         * available or is updated. Note that in a case where a part of the information for a
+         * certain track is updated, it is not necessary to create a new {@link TvTrackInfo} object
+         * with a different track ID.
+         *
+         * @param tracks A list which includes track information.
+         */
+        public void notifyTracksChanged(final List<TvTrackInfo> tracks) {
+            final List<TvTrackInfo> tracksCopy = new ArrayList<>(tracks);
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyTracksChanged");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onTracksChanged(tracksCopy);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyTracksChanged", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Sends the type and ID of a selected track. This is used to inform the application that a
+         * specific track is selected. The TV input service must call this method as soon as a track
+         * is selected either by default or in response to a call to {@link #onSelectTrack}. The
+         * selected track ID for a given type is maintained in the framework until the next call to
+         * this method even after the entire track list is updated (but is reset when the session is
+         * tuned to a new channel), so care must be taken not to result in an obsolete track ID.
+         *
+         * @param type The type of the selected track. The type can be
+         *            {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+         *            {@link TvTrackInfo#TYPE_SUBTITLE}.
+         * @param trackId The ID of the selected track.
+         * @see #onSelectTrack
+         */
+        public void notifyTrackSelected(final int type, final String trackId) {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyTrackSelected");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onTrackSelected(type, trackId);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyTrackSelected", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Informs the application that the video is now available for watching. Video is blocked
+         * until this method is called.
+         *
+         * <p>The TV input service must call this method as soon as the content rendered onto its
+         * surface is ready for viewing. This method must be called each time {@link #onTune}
+         * is called.
+         *
+         * @see #notifyVideoUnavailable
+         */
+        public void notifyVideoAvailable() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyVideoAvailable");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onVideoAvailable();
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyVideoAvailable", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Informs the application that the video became unavailable for some reason. This is
+         * primarily used to signal the application to block the screen not to show any intermittent
+         * video artifacts.
+         *
+         * @param reason The reason why the video became unavailable:
+         *            <ul>
+         *            <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_UNKNOWN}
+         *            <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_TUNING}
+         *            <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL}
+         *            <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_BUFFERING}
+         *            <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY}
+         *            </ul>
+         * @see #notifyVideoAvailable
+         */
+        public void notifyVideoUnavailable(
+                @TvInputManager.VideoUnavailableReason final int reason) {
+            if (reason < TvInputManager.VIDEO_UNAVAILABLE_REASON_START
+                    || reason > TvInputManager.VIDEO_UNAVAILABLE_REASON_END) {
+                Log.e(TAG, "notifyVideoUnavailable - unknown reason: " + reason);
+            }
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyVideoUnavailable");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onVideoUnavailable(reason);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyVideoUnavailable", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Informs the application that the user is allowed to watch the current program content.
+         *
+         * <p>Each TV input service is required to query the system whether the user is allowed to
+         * watch the current program before showing it to the user if the parental controls is
+         * enabled (i.e. {@link TvInputManager#isParentalControlsEnabled
+         * TvInputManager.isParentalControlsEnabled()} returns {@code true}). Whether the TV input
+         * service should block the content or not is determined by invoking
+         * {@link TvInputManager#isRatingBlocked TvInputManager.isRatingBlocked(TvContentRating)}
+         * with the content rating for the current program. Then the {@link TvInputManager} makes a
+         * judgment based on the user blocked ratings stored in the secure settings and returns the
+         * result. If the rating in question turns out to be allowed by the user, the TV input
+         * service must call this method to notify the application that is permitted to show the
+         * content.
+         *
+         * <p>Each TV input service also needs to continuously listen to any changes made to the
+         * parental controls settings by registering a broadcast receiver to receive
+         * {@link TvInputManager#ACTION_BLOCKED_RATINGS_CHANGED} and
+         * {@link TvInputManager#ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED} and immediately
+         * reevaluate the current program with the new parental controls settings.
+         *
+         * @see #notifyContentBlocked
+         * @see TvInputManager
+         */
+        public void notifyContentAllowed() {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyContentAllowed");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onContentAllowed();
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyContentAllowed", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Informs the application that the current program content is blocked by parent controls.
+         *
+         * <p>Each TV input service is required to query the system whether the user is allowed to
+         * watch the current program before showing it to the user if the parental controls is
+         * enabled (i.e. {@link TvInputManager#isParentalControlsEnabled
+         * TvInputManager.isParentalControlsEnabled()} returns {@code true}). Whether the TV input
+         * service should block the content or not is determined by invoking
+         * {@link TvInputManager#isRatingBlocked TvInputManager.isRatingBlocked(TvContentRating)}
+         * with the content rating for the current program or {@link TvContentRating#UNRATED} in
+         * case the rating information is missing. Then the {@link TvInputManager} makes a judgment
+         * based on the user blocked ratings stored in the secure settings and returns the result.
+         * If the rating in question turns out to be blocked, the TV input service must immediately
+         * block the content and call this method with the content rating of the current program to
+         * prompt the PIN verification screen.
+         *
+         * <p>Each TV input service also needs to continuously listen to any changes made to the
+         * parental controls settings by registering a broadcast receiver to receive
+         * {@link TvInputManager#ACTION_BLOCKED_RATINGS_CHANGED} and
+         * {@link TvInputManager#ACTION_PARENTAL_CONTROLS_ENABLED_CHANGED} and immediately
+         * reevaluate the current program with the new parental controls settings.
+         *
+         * @param rating The content rating for the current TV program. Can be
+         *            {@link TvContentRating#UNRATED}.
+         * @see #notifyContentAllowed
+         * @see TvInputManager
+         */
+        public void notifyContentBlocked(@NonNull final TvContentRating rating) {
+            Preconditions.checkNotNull(rating);
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyContentBlocked");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onContentBlocked(rating.flattenToString());
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyContentBlocked", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Informs the application that the time shift status is changed.
+         *
+         * <p>Prior to calling this method, the application assumes the status
+         * {@link TvInputManager#TIME_SHIFT_STATUS_UNKNOWN}. Right after the session is created, it
+         * is important to invoke the method with the status
+         * {@link TvInputManager#TIME_SHIFT_STATUS_AVAILABLE} if the implementation does support
+         * time shifting, or {@link TvInputManager#TIME_SHIFT_STATUS_UNSUPPORTED} otherwise. Failure
+         * to notifying the current status change immediately might result in an undesirable
+         * behavior in the application such as hiding the play controls.
+         *
+         * <p>If the status {@link TvInputManager#TIME_SHIFT_STATUS_AVAILABLE} is reported, the
+         * application assumes it can pause/resume playback, seek to a specified time position and
+         * set playback rate and audio mode. The implementation should override
+         * {@link #onTimeShiftPause}, {@link #onTimeShiftResume}, {@link #onTimeShiftSeekTo},
+         * {@link #onTimeShiftGetStartPosition}, {@link #onTimeShiftGetCurrentPosition} and
+         * {@link #onTimeShiftSetPlaybackParams}.
+         *
+         * @param status The current time shift status. Should be one of the followings.
+         * <ul>
+         * <li>{@link TvInputManager#TIME_SHIFT_STATUS_UNSUPPORTED}
+         * <li>{@link TvInputManager#TIME_SHIFT_STATUS_UNAVAILABLE}
+         * <li>{@link TvInputManager#TIME_SHIFT_STATUS_AVAILABLE}
+         * </ul>
+         */
+        public void notifyTimeShiftStatusChanged(@TvInputManager.TimeShiftStatus final int status) {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    timeShiftEnablePositionTracking(
+                            status == TvInputManager.TIME_SHIFT_STATUS_AVAILABLE);
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyTimeShiftStatusChanged");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onTimeShiftStatusChanged(status);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyTimeShiftStatusChanged", e);
+                    }
+                }
+            });
+        }
+
+        private void notifyTimeShiftStartPositionChanged(final long timeMs) {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyTimeShiftStartPositionChanged");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onTimeShiftStartPositionChanged(timeMs);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyTimeShiftStartPositionChanged", e);
+                    }
+                }
+            });
+        }
+
+        private void notifyTimeShiftCurrentPositionChanged(final long timeMs) {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyTimeShiftCurrentPositionChanged");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onTimeShiftCurrentPositionChanged(timeMs);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyTimeShiftCurrentPositionChanged", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Assigns a size and position to the surface passed in {@link #onSetSurface}. The position
+         * is relative to the overlay view that sits on top of this surface.
+         *
+         * @param left Left position in pixels, relative to the overlay view.
+         * @param top Top position in pixels, relative to the overlay view.
+         * @param right Right position in pixels, relative to the overlay view.
+         * @param bottom Bottom position in pixels, relative to the overlay view.
+         * @see #onOverlayViewSizeChanged
+         */
+        public void layoutSurface(final int left, final int top, final int right,
+                final int bottom) {
+            if (left > right || top > bottom) {
+                throw new IllegalArgumentException("Invalid parameter");
+            }
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "layoutSurface (l=" + left + ", t=" + top + ", r="
+                                + right + ", b=" + bottom + ",)");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onLayoutSurface(left, top, right, bottom);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in layoutSurface", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Called when the session is released.
+         */
+        public abstract void onRelease();
+
+        /**
+         * Sets the current session as the main session. The main session is a session whose
+         * corresponding TV input determines the HDMI-CEC active source device.
+         *
+         * <p>TV input service that manages HDMI-CEC logical device should implement {@link
+         * #onSetMain} to (1) select the corresponding HDMI logical device as the source device
+         * when {@code isMain} is {@code true}, and to (2) select the internal device (= TV itself)
+         * as the source device when {@code isMain} is {@code false} and the session is still main.
+         * Also, if a surface is passed to a non-main session and active source is changed to
+         * initiate the surface, the active source should be returned to the main session.
+         *
+         * <p>{@link TvView} guarantees that, when tuning involves a session transition, {@code
+         * onSetMain(true)} for new session is called first, {@code onSetMain(false)} for old
+         * session is called afterwards. This allows {@code onSetMain(false)} to be no-op when TV
+         * input service knows that the next main session corresponds to another HDMI logical
+         * device. Practically, this implies that one TV input service should handle all HDMI port
+         * and HDMI-CEC logical devices for smooth active source transition.
+         *
+         * @param isMain If true, session should become main.
+         * @see TvView#setMain
+         * @hide
+         */
+        @SystemApi
+        public void onSetMain(boolean isMain) {
+        }
+
+        /**
+         * Called when the application sets the surface.
+         *
+         * <p>The TV input service should render video onto the given surface. When called with
+         * {@code null}, the input service should immediately free any references to the
+         * currently set surface and stop using it.
+         *
+         * @param surface The surface to be used for video rendering. Can be {@code null}.
+         * @return {@code true} if the surface was set successfully, {@code false} otherwise.
+         */
+        public abstract boolean onSetSurface(@Nullable Surface surface);
+
+        /**
+         * Called after any structural changes (format or size) have been made to the surface passed
+         * in {@link #onSetSurface}. This method is always called at least once, after
+         * {@link #onSetSurface} is called with non-null surface.
+         *
+         * @param format The new PixelFormat of the surface.
+         * @param width The new width of the surface.
+         * @param height The new height of the surface.
+         */
+        public void onSurfaceChanged(int format, int width, int height) {
+        }
+
+        /**
+         * Called when the size of the overlay view is changed by the application.
+         *
+         * <p>This is always called at least once when the session is created regardless of whether
+         * the overlay view is enabled or not. The overlay view size is the same as the containing
+         * {@link TvView}. Note that the size of the underlying surface can be different if the
+         * surface was changed by calling {@link #layoutSurface}.
+         *
+         * @param width The width of the overlay view.
+         * @param height The height of the overlay view.
+         */
+        public void onOverlayViewSizeChanged(int width, int height) {
+        }
+
+        /**
+         * Sets the relative stream volume of the current TV input session.
+         *
+         * <p>The implementation should honor this request in order to handle audio focus changes or
+         * mute the current session when multiple sessions, possibly from different inputs are
+         * active. If the method has not yet been called, the implementation should assume the
+         * default value of {@code 1.0f}.
+         *
+         * @param volume A volume value between {@code 0.0f} to {@code 1.0f}.
+         */
+        public abstract void onSetStreamVolume(@FloatRange(from = 0.0, to = 1.0) float volume);
+
+        /**
+         * Tunes to a given channel.
+         *
+         * <p>No video will be displayed until {@link #notifyVideoAvailable()} is called.
+         * Also, {@link #notifyVideoUnavailable(int)} should be called when the TV input cannot
+         * continue playing the given channel.
+         *
+         * @param channelUri The URI of the channel.
+         * @return {@code true} if the tuning was successful, {@code false} otherwise.
+         */
+        public abstract boolean onTune(Uri channelUri);
+
+        /**
+         * Tunes to a given channel. Override this method in order to handle domain-specific
+         * features that are only known between certain TV inputs and their clients.
+         *
+         * <p>The default implementation calls {@link #onTune(Uri)}.
+         *
+         * @param channelUri The URI of the channel.
+         * @param params Domain-specific data for this tune request. Keys <em>must</em> be a scoped
+         *            name, i.e. prefixed with a package name you own, so that different developers
+         *            will not create conflicting keys.
+         * @return {@code true} if the tuning was successful, {@code false} otherwise.
+         */
+        public boolean onTune(Uri channelUri, Bundle params) {
+            return onTune(channelUri);
+        }
+
+        /**
+         * Enables or disables the caption.
+         *
+         * <p>The locale for the user's preferred captioning language can be obtained by calling
+         * {@link CaptioningManager#getLocale CaptioningManager.getLocale()}.
+         *
+         * @param enabled {@code true} to enable, {@code false} to disable.
+         * @see CaptioningManager
+         */
+        public abstract void onSetCaptionEnabled(boolean enabled);
+
+        /**
+         * Requests to unblock the content according to the given rating.
+         *
+         * <p>The implementation should unblock the content.
+         * TV input service has responsibility to decide when/how the unblock expires
+         * while it can keep previously unblocked ratings in order not to ask a user
+         * to unblock whenever a content rating is changed.
+         * Therefore an unblocked rating can be valid for a channel, a program,
+         * or certain amount of time depending on the implementation.
+         *
+         * @param unblockedRating An unblocked content rating
+         */
+        public void onUnblockContent(TvContentRating unblockedRating) {
+        }
+
+        /**
+         * Selects a given track.
+         *
+         * <p>If this is done successfully, the implementation should call
+         * {@link #notifyTrackSelected} to help applications maintain the up-to-date list of the
+         * selected tracks.
+         *
+         * @param trackId The ID of the track to select. {@code null} means to unselect the current
+         *            track for a given type.
+         * @param type The type of the track to select. The type can be
+         *            {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+         *            {@link TvTrackInfo#TYPE_SUBTITLE}.
+         * @return {@code true} if the track selection was successful, {@code false} otherwise.
+         * @see #notifyTrackSelected
+         */
+        public boolean onSelectTrack(int type, @Nullable String trackId) {
+            return false;
+        }
+
+        /**
+         * Processes a private command sent from the application to the TV input. This can be used
+         * to provide domain-specific features that are only known between certain TV inputs and
+         * their clients.
+         *
+         * @param action Name of the command to be performed. This <em>must</em> be a scoped name,
+         *            i.e. prefixed with a package name you own, so that different developers will
+         *            not create conflicting commands.
+         * @param data Any data to include with the command.
+         */
+        public void onAppPrivateCommand(@NonNull String action, Bundle data) {
+        }
+
+        /**
+         * Called when the application requests to create an overlay view. Each session
+         * implementation can override this method and return its own view.
+         *
+         * @return a view attached to the overlay window
+         */
+        public View onCreateOverlayView() {
+            return null;
+        }
+
+        /**
+         * Called when the application requests to play a given recorded TV program.
+         *
+         * @param recordedProgramUri The URI of a recorded TV program.
+         * @see #onTimeShiftResume()
+         * @see #onTimeShiftPause()
+         * @see #onTimeShiftSeekTo(long)
+         * @see #onTimeShiftSetPlaybackParams(PlaybackParams)
+         * @see #onTimeShiftGetStartPosition()
+         * @see #onTimeShiftGetCurrentPosition()
+         */
+        public void onTimeShiftPlay(Uri recordedProgramUri) {
+        }
+
+        /**
+         * Called when the application requests to pause playback.
+         *
+         * @see #onTimeShiftPlay(Uri)
+         * @see #onTimeShiftResume()
+         * @see #onTimeShiftSeekTo(long)
+         * @see #onTimeShiftSetPlaybackParams(PlaybackParams)
+         * @see #onTimeShiftGetStartPosition()
+         * @see #onTimeShiftGetCurrentPosition()
+         */
+        public void onTimeShiftPause() {
+        }
+
+        /**
+         * Called when the application requests to resume playback.
+         *
+         * @see #onTimeShiftPlay(Uri)
+         * @see #onTimeShiftPause()
+         * @see #onTimeShiftSeekTo(long)
+         * @see #onTimeShiftSetPlaybackParams(PlaybackParams)
+         * @see #onTimeShiftGetStartPosition()
+         * @see #onTimeShiftGetCurrentPosition()
+         */
+        public void onTimeShiftResume() {
+        }
+
+        /**
+         * Called when the application requests to seek to a specified time position. Normally, the
+         * position is given within range between the start and the current time, inclusively. The
+         * implementation is expected to seek to the nearest time position if the given position is
+         * not in the range.
+         *
+         * @param timeMs The time position to seek to, in milliseconds since the epoch.
+         * @see #onTimeShiftPlay(Uri)
+         * @see #onTimeShiftResume()
+         * @see #onTimeShiftPause()
+         * @see #onTimeShiftSetPlaybackParams(PlaybackParams)
+         * @see #onTimeShiftGetStartPosition()
+         * @see #onTimeShiftGetCurrentPosition()
+         */
+        public void onTimeShiftSeekTo(long timeMs) {
+        }
+
+        /**
+         * Called when the application sets playback parameters containing the speed and audio mode.
+         *
+         * <p>Once the playback parameters are set, the implementation should honor the current
+         * settings until the next tune request. Pause/resume/seek request does not reset the
+         * parameters previously set.
+         *
+         * @param params The playback params.
+         * @see #onTimeShiftPlay(Uri)
+         * @see #onTimeShiftResume()
+         * @see #onTimeShiftPause()
+         * @see #onTimeShiftSeekTo(long)
+         * @see #onTimeShiftGetStartPosition()
+         * @see #onTimeShiftGetCurrentPosition()
+         */
+        public void onTimeShiftSetPlaybackParams(PlaybackParams params) {
+        }
+
+        /**
+         * Returns the start position for time shifting, in milliseconds since the epoch.
+         * Returns {@link TvInputManager#TIME_SHIFT_INVALID_TIME} if the position is unknown at the
+         * moment.
+         *
+         * <p>The start position for time shifting indicates the earliest possible time the user can
+         * seek to. Initially this is equivalent to the time when the implementation starts
+         * recording. Later it may be adjusted because there is insufficient space or the duration
+         * of recording is limited by the implementation. The application does not allow the user to
+         * seek to a position earlier than the start position.
+         *
+         * <p>For playback of a recorded program initiated by {@link #onTimeShiftPlay(Uri)}, the
+         * start position should be 0 and does not change.
+         *
+         * @see #onTimeShiftPlay(Uri)
+         * @see #onTimeShiftResume()
+         * @see #onTimeShiftPause()
+         * @see #onTimeShiftSeekTo(long)
+         * @see #onTimeShiftSetPlaybackParams(PlaybackParams)
+         * @see #onTimeShiftGetCurrentPosition()
+         */
+        public long onTimeShiftGetStartPosition() {
+            return TvInputManager.TIME_SHIFT_INVALID_TIME;
+        }
+
+        /**
+         * Returns the current position for time shifting, in milliseconds since the epoch.
+         * Returns {@link TvInputManager#TIME_SHIFT_INVALID_TIME} if the position is unknown at the
+         * moment.
+         *
+         * <p>The current position for time shifting is the same as the current position of
+         * playback. It should be equal to or greater than the start position reported by
+         * {@link #onTimeShiftGetStartPosition()}. When playback is completed, the current position
+         * should stay where the playback ends, in other words, the returned value of this mehtod
+         * should be equal to the start position plus the duration of the program.
+         *
+         * @see #onTimeShiftPlay(Uri)
+         * @see #onTimeShiftResume()
+         * @see #onTimeShiftPause()
+         * @see #onTimeShiftSeekTo(long)
+         * @see #onTimeShiftSetPlaybackParams(PlaybackParams)
+         * @see #onTimeShiftGetStartPosition()
+         */
+        public long onTimeShiftGetCurrentPosition() {
+            return TvInputManager.TIME_SHIFT_INVALID_TIME;
+        }
+
+        /**
+         * Default implementation of {@link android.view.KeyEvent.Callback#onKeyDown(int, KeyEvent)
+         * KeyEvent.Callback.onKeyDown()}: always returns false (doesn't handle the event).
+         *
+         * <p>Override this to intercept key down events before they are processed by the
+         * application. If you return true, the application will not process the event itself. If
+         * you return false, the normal application processing will occur as if the TV input had not
+         * seen the event at all.
+         *
+         * @param keyCode The value in event.getKeyCode().
+         * @param event Description of the key event.
+         * @return If you handled the event, return {@code true}. If you want to allow the event to
+         *         be handled by the next receiver, return {@code false}.
+         */
+        @Override
+        public boolean onKeyDown(int keyCode, KeyEvent event) {
+            return false;
+        }
+
+        /**
+         * Default implementation of
+         * {@link android.view.KeyEvent.Callback#onKeyLongPress(int, KeyEvent)
+         * KeyEvent.Callback.onKeyLongPress()}: always returns false (doesn't handle the event).
+         *
+         * <p>Override this to intercept key long press events before they are processed by the
+         * application. If you return true, the application will not process the event itself. If
+         * you return false, the normal application processing will occur as if the TV input had not
+         * seen the event at all.
+         *
+         * @param keyCode The value in event.getKeyCode().
+         * @param event Description of the key event.
+         * @return If you handled the event, return {@code true}. If you want to allow the event to
+         *         be handled by the next receiver, return {@code false}.
+         */
+        @Override
+        public boolean onKeyLongPress(int keyCode, KeyEvent event) {
+            return false;
+        }
+
+        /**
+         * Default implementation of
+         * {@link android.view.KeyEvent.Callback#onKeyMultiple(int, int, KeyEvent)
+         * KeyEvent.Callback.onKeyMultiple()}: always returns false (doesn't handle the event).
+         *
+         * <p>Override this to intercept special key multiple events before they are processed by
+         * the application. If you return true, the application will not itself process the event.
+         * If you return false, the normal application processing will occur as if the TV input had
+         * not seen the event at all.
+         *
+         * @param keyCode The value in event.getKeyCode().
+         * @param count The number of times the action was made.
+         * @param event Description of the key event.
+         * @return If you handled the event, return {@code true}. If you want to allow the event to
+         *         be handled by the next receiver, return {@code false}.
+         */
+        @Override
+        public boolean onKeyMultiple(int keyCode, int count, KeyEvent event) {
+            return false;
+        }
+
+        /**
+         * Default implementation of {@link android.view.KeyEvent.Callback#onKeyUp(int, KeyEvent)
+         * KeyEvent.Callback.onKeyUp()}: always returns false (doesn't handle the event).
+         *
+         * <p>Override this to intercept key up events before they are processed by the application.
+         * If you return true, the application will not itself process the event. If you return false,
+         * the normal application processing will occur as if the TV input had not seen the event at
+         * all.
+         *
+         * @param keyCode The value in event.getKeyCode().
+         * @param event Description of the key event.
+         * @return If you handled the event, return {@code true}. If you want to allow the event to
+         *         be handled by the next receiver, return {@code false}.
+         */
+        @Override
+        public boolean onKeyUp(int keyCode, KeyEvent event) {
+            return false;
+        }
+
+        /**
+         * Implement this method to handle touch screen motion events on the current input session.
+         *
+         * @param event The motion event being received.
+         * @return If you handled the event, return {@code true}. If you want to allow the event to
+         *         be handled by the next receiver, return {@code false}.
+         * @see View#onTouchEvent
+         */
+        public boolean onTouchEvent(MotionEvent event) {
+            return false;
+        }
+
+        /**
+         * Implement this method to handle trackball events on the current input session.
+         *
+         * @param event The motion event being received.
+         * @return If you handled the event, return {@code true}. If you want to allow the event to
+         *         be handled by the next receiver, return {@code false}.
+         * @see View#onTrackballEvent
+         */
+        public boolean onTrackballEvent(MotionEvent event) {
+            return false;
+        }
+
+        /**
+         * Implement this method to handle generic motion events on the current input session.
+         *
+         * @param event The motion event being received.
+         * @return If you handled the event, return {@code true}. If you want to allow the event to
+         *         be handled by the next receiver, return {@code false}.
+         * @see View#onGenericMotionEvent
+         */
+        public boolean onGenericMotionEvent(MotionEvent event) {
+            return false;
+        }
+
+        /**
+         * This method is called when the application would like to stop using the current input
+         * session.
+         */
+        void release() {
+            onRelease();
+            if (mSurface != null) {
+                mSurface.release();
+                mSurface = null;
+            }
+            synchronized(mLock) {
+                mSessionCallback = null;
+                mPendingActions.clear();
+            }
+            // Removes the overlay view lastly so that any hanging on the main thread can be handled
+            // in {@link #scheduleOverlayViewCleanup}.
+            removeOverlayView(true);
+            mHandler.removeCallbacks(mTimeShiftPositionTrackingRunnable);
+        }
+
+        /**
+         * Calls {@link #onSetMain}.
+         */
+        void setMain(boolean isMain) {
+            onSetMain(isMain);
+        }
+
+        /**
+         * Calls {@link #onSetSurface}.
+         */
+        void setSurface(Surface surface) {
+            onSetSurface(surface);
+            if (mSurface != null) {
+                mSurface.release();
+            }
+            mSurface = surface;
+            // TODO: Handle failure.
+        }
+
+        /**
+         * Calls {@link #onSurfaceChanged}.
+         */
+        void dispatchSurfaceChanged(int format, int width, int height) {
+            if (DEBUG) {
+                Log.d(TAG, "dispatchSurfaceChanged(format=" + format + ", width=" + width
+                        + ", height=" + height + ")");
+            }
+            onSurfaceChanged(format, width, height);
+        }
+
+        /**
+         * Calls {@link #onSetStreamVolume}.
+         */
+        void setStreamVolume(float volume) {
+            onSetStreamVolume(volume);
+        }
+
+        /**
+         * Calls {@link #onTune(Uri, Bundle)}.
+         */
+        void tune(Uri channelUri, Bundle params) {
+            mCurrentPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
+            onTune(channelUri, params);
+            // TODO: Handle failure.
+        }
+
+        /**
+         * Calls {@link #onSetCaptionEnabled}.
+         */
+        void setCaptionEnabled(boolean enabled) {
+            onSetCaptionEnabled(enabled);
+        }
+
+        /**
+         * Calls {@link #onSelectTrack}.
+         */
+        void selectTrack(int type, String trackId) {
+            onSelectTrack(type, trackId);
+        }
+
+        /**
+         * Calls {@link #onUnblockContent}.
+         */
+        void unblockContent(String unblockedRating) {
+            onUnblockContent(TvContentRating.unflattenFromString(unblockedRating));
+            // TODO: Handle failure.
+        }
+
+        /**
+         * Calls {@link #onAppPrivateCommand}.
+         */
+        void appPrivateCommand(String action, Bundle data) {
+            onAppPrivateCommand(action, data);
+        }
+
+        /**
+         * Creates an overlay view. This calls {@link #onCreateOverlayView} to get a view to attach
+         * to the overlay window.
+         *
+         * @param windowToken A window token of the application.
+         * @param frame A position of the overlay view.
+         */
+        void createOverlayView(IBinder windowToken, Rect frame) {
+            if (mOverlayViewContainer != null) {
+                removeOverlayView(false);
+            }
+            if (DEBUG) Log.d(TAG, "create overlay view(" + frame + ")");
+            mWindowToken = windowToken;
+            mOverlayFrame = frame;
+            onOverlayViewSizeChanged(frame.right - frame.left, frame.bottom - frame.top);
+            if (!mOverlayViewEnabled) {
+                return;
+            }
+            mOverlayView = onCreateOverlayView();
+            if (mOverlayView == null) {
+                return;
+            }
+            if (mOverlayViewCleanUpTask != null) {
+                mOverlayViewCleanUpTask.cancel(true);
+                mOverlayViewCleanUpTask = null;
+            }
+            // Creates a container view to check hanging on the overlay view detaching.
+            // Adding/removing the overlay view to/from the container make the view attach/detach
+            // logic run on the main thread.
+            mOverlayViewContainer = new FrameLayout(mContext.getApplicationContext());
+            mOverlayViewContainer.addView(mOverlayView);
+            // TvView's window type is TYPE_APPLICATION_MEDIA and we want to create
+            // an overlay window above the media window but below the application window.
+            int type = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
+            // We make the overlay view non-focusable and non-touchable so that
+            // the application that owns the window token can decide whether to consume or
+            // dispatch the input events.
+            int flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+                    | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+                    | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS;
+            if (ActivityManager.isHighEndGfx()) {
+                flags |= WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED;
+            }
+            mWindowParams = new WindowManager.LayoutParams(
+                    frame.right - frame.left, frame.bottom - frame.top,
+                    frame.left, frame.top, type, flags, PixelFormat.TRANSPARENT);
+            mWindowParams.privateFlags |=
+                    WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
+            mWindowParams.gravity = Gravity.START | Gravity.TOP;
+            mWindowParams.token = windowToken;
+            mWindowManager.addView(mOverlayViewContainer, mWindowParams);
+        }
+
+        /**
+         * Relayouts the current overlay view.
+         *
+         * @param frame A new position of the overlay view.
+         */
+        void relayoutOverlayView(Rect frame) {
+            if (DEBUG) Log.d(TAG, "relayoutOverlayView(" + frame + ")");
+            if (mOverlayFrame == null || mOverlayFrame.width() != frame.width()
+                    || mOverlayFrame.height() != frame.height()) {
+                // Note: relayoutOverlayView is called whenever TvView's layout is changed
+                // regardless of setOverlayViewEnabled.
+                onOverlayViewSizeChanged(frame.right - frame.left, frame.bottom - frame.top);
+            }
+            mOverlayFrame = frame;
+            if (!mOverlayViewEnabled || mOverlayViewContainer == null) {
+                return;
+            }
+            mWindowParams.x = frame.left;
+            mWindowParams.y = frame.top;
+            mWindowParams.width = frame.right - frame.left;
+            mWindowParams.height = frame.bottom - frame.top;
+            mWindowManager.updateViewLayout(mOverlayViewContainer, mWindowParams);
+        }
+
+        /**
+         * Removes the current overlay view.
+         */
+        void removeOverlayView(boolean clearWindowToken) {
+            if (DEBUG) Log.d(TAG, "removeOverlayView(" + mOverlayViewContainer + ")");
+            if (clearWindowToken) {
+                mWindowToken = null;
+                mOverlayFrame = null;
+            }
+            if (mOverlayViewContainer != null) {
+                // Removes the overlay view from the view hierarchy in advance so that it can be
+                // cleaned up in the {@link OverlayViewCleanUpTask} if the remove process is
+                // hanging.
+                mOverlayViewContainer.removeView(mOverlayView);
+                mOverlayView = null;
+                mWindowManager.removeView(mOverlayViewContainer);
+                mOverlayViewContainer = null;
+                mWindowParams = null;
+            }
+        }
+
+        /**
+         * Calls {@link #onTimeShiftPlay(Uri)}.
+         */
+        void timeShiftPlay(Uri recordedProgramUri) {
+            mCurrentPositionMs = 0;
+            onTimeShiftPlay(recordedProgramUri);
+        }
+
+        /**
+         * Calls {@link #onTimeShiftPause}.
+         */
+        void timeShiftPause() {
+            onTimeShiftPause();
+        }
+
+        /**
+         * Calls {@link #onTimeShiftResume}.
+         */
+        void timeShiftResume() {
+            onTimeShiftResume();
+        }
+
+        /**
+         * Calls {@link #onTimeShiftSeekTo}.
+         */
+        void timeShiftSeekTo(long timeMs) {
+            onTimeShiftSeekTo(timeMs);
+        }
+
+        /**
+         * Calls {@link #onTimeShiftSetPlaybackParams}.
+         */
+        void timeShiftSetPlaybackParams(PlaybackParams params) {
+            onTimeShiftSetPlaybackParams(params);
+        }
+
+        /**
+         * Enable/disable position tracking.
+         *
+         * @param enable {@code true} to enable tracking, {@code false} otherwise.
+         */
+        void timeShiftEnablePositionTracking(boolean enable) {
+            if (enable) {
+                mHandler.post(mTimeShiftPositionTrackingRunnable);
+            } else {
+                mHandler.removeCallbacks(mTimeShiftPositionTrackingRunnable);
+                mStartPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
+                mCurrentPositionMs = TvInputManager.TIME_SHIFT_INVALID_TIME;
+            }
+        }
+
+        /**
+         * Schedules a task which checks whether the overlay view is detached and kills the process
+         * if it is not. Note that this method is expected to be called in a non-main thread.
+         */
+        void scheduleOverlayViewCleanup() {
+            View overlayViewParent = mOverlayViewContainer;
+            if (overlayViewParent != null) {
+                mOverlayViewCleanUpTask = new OverlayViewCleanUpTask();
+                mOverlayViewCleanUpTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,
+                        overlayViewParent);
+            }
+        }
+
+        /**
+         * Takes care of dispatching incoming input events and tells whether the event was handled.
+         */
+        int dispatchInputEvent(InputEvent event, InputEventReceiver receiver) {
+            if (DEBUG) Log.d(TAG, "dispatchInputEvent(" + event + ")");
+            boolean isNavigationKey = false;
+            boolean skipDispatchToOverlayView = false;
+            if (event instanceof KeyEvent) {
+                KeyEvent keyEvent = (KeyEvent) event;
+                if (keyEvent.dispatch(this, mDispatcherState, this)) {
+                    return TvInputManager.Session.DISPATCH_HANDLED;
+                }
+                isNavigationKey = isNavigationKey(keyEvent.getKeyCode());
+                // When media keys and KEYCODE_MEDIA_AUDIO_TRACK are dispatched to ViewRootImpl,
+                // ViewRootImpl always consumes the keys. In this case, the application loses
+                // a chance to handle media keys. Therefore, media keys are not dispatched to
+                // ViewRootImpl.
+                skipDispatchToOverlayView = KeyEvent.isMediaSessionKey(keyEvent.getKeyCode())
+                        || keyEvent.getKeyCode() == KeyEvent.KEYCODE_MEDIA_AUDIO_TRACK;
+            } else if (event instanceof MotionEvent) {
+                MotionEvent motionEvent = (MotionEvent) event;
+                final int source = motionEvent.getSource();
+                if (motionEvent.isTouchEvent()) {
+                    if (onTouchEvent(motionEvent)) {
+                        return TvInputManager.Session.DISPATCH_HANDLED;
+                    }
+                } else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {
+                    if (onTrackballEvent(motionEvent)) {
+                        return TvInputManager.Session.DISPATCH_HANDLED;
+                    }
+                } else {
+                    if (onGenericMotionEvent(motionEvent)) {
+                        return TvInputManager.Session.DISPATCH_HANDLED;
+                    }
+                }
+            }
+            if (mOverlayViewContainer == null || !mOverlayViewContainer.isAttachedToWindow()
+                    || skipDispatchToOverlayView) {
+                return TvInputManager.Session.DISPATCH_NOT_HANDLED;
+            }
+            if (!mOverlayViewContainer.hasWindowFocus()) {
+                mOverlayViewContainer.getViewRootImpl().windowFocusChanged(true, true);
+            }
+            if (isNavigationKey && mOverlayViewContainer.hasFocusable()) {
+                // If mOverlayView has focusable views, navigation key events should be always
+                // handled. If not, it can make the application UI navigation messed up.
+                // For example, in the case that the left-most view is focused, a left key event
+                // will not be handled in ViewRootImpl. Then, the left key event will be handled in
+                // the application during the UI navigation of the TV input.
+                mOverlayViewContainer.getViewRootImpl().dispatchInputEvent(event);
+                return TvInputManager.Session.DISPATCH_HANDLED;
+            } else {
+                mOverlayViewContainer.getViewRootImpl().dispatchInputEvent(event, receiver);
+                return TvInputManager.Session.DISPATCH_IN_PROGRESS;
+            }
+        }
+
+        private void initialize(ITvInputSessionCallback callback) {
+            synchronized(mLock) {
+                mSessionCallback = callback;
+                for (Runnable runnable : mPendingActions) {
+                    runnable.run();
+                }
+                mPendingActions.clear();
+            }
+        }
+
+        private void executeOrPostRunnableOnMainThread(Runnable action) {
+            synchronized(mLock) {
+                if (mSessionCallback == null) {
+                    // The session is not initialized yet.
+                    mPendingActions.add(action);
+                } else {
+                    if (mHandler.getLooper().isCurrentThread()) {
+                        action.run();
+                    } else {
+                        // Posts the runnable if this is not called from the main thread
+                        mHandler.post(action);
+                    }
+                }
+            }
+        }
+
+        private final class TimeShiftPositionTrackingRunnable implements Runnable {
+            @Override
+            public void run() {
+                long startPositionMs = onTimeShiftGetStartPosition();
+                if (mStartPositionMs == TvInputManager.TIME_SHIFT_INVALID_TIME
+                        || mStartPositionMs != startPositionMs) {
+                    mStartPositionMs = startPositionMs;
+                    notifyTimeShiftStartPositionChanged(startPositionMs);
+                }
+                long currentPositionMs = onTimeShiftGetCurrentPosition();
+                if (currentPositionMs < mStartPositionMs) {
+                    Log.w(TAG, "Current position (" + currentPositionMs + ") cannot be earlier than"
+                            + " start position (" + mStartPositionMs + "). Reset to the start "
+                            + "position.");
+                    currentPositionMs = mStartPositionMs;
+                }
+                if (mCurrentPositionMs == TvInputManager.TIME_SHIFT_INVALID_TIME
+                        || mCurrentPositionMs != currentPositionMs) {
+                    mCurrentPositionMs = currentPositionMs;
+                    notifyTimeShiftCurrentPositionChanged(currentPositionMs);
+                }
+                mHandler.removeCallbacks(mTimeShiftPositionTrackingRunnable);
+                mHandler.postDelayed(mTimeShiftPositionTrackingRunnable,
+                        POSITION_UPDATE_INTERVAL_MS);
+            }
+        }
+    }
+
+    private static final class OverlayViewCleanUpTask extends AsyncTask<View, Void, Void> {
+        @Override
+        protected Void doInBackground(View... views) {
+            View overlayViewParent = views[0];
+            try {
+                Thread.sleep(DETACH_OVERLAY_VIEW_TIMEOUT_MS);
+            } catch (InterruptedException e) {
+                return null;
+            }
+            if (isCancelled()) {
+                return null;
+            }
+            if (overlayViewParent.isAttachedToWindow()) {
+                Log.e(TAG, "Time out on releasing overlay view. Killing "
+                        + overlayViewParent.getContext().getPackageName());
+                Process.killProcess(Process.myPid());
+            }
+            return null;
+        }
+    }
+
+    /**
+     * Base class for derived classes to implement to provide a TV input recording session.
+     */
+    public abstract static class RecordingSession {
+        final Handler mHandler;
+
+        private final Object mLock = new Object();
+        // @GuardedBy("mLock")
+        private ITvInputSessionCallback mSessionCallback;
+        // @GuardedBy("mLock")
+        private final List<Runnable> mPendingActions = new ArrayList<>();
+
+        /**
+         * Creates a new RecordingSession.
+         *
+         * @param context The context of the application
+         */
+        public RecordingSession(Context context) {
+            mHandler = new Handler(context.getMainLooper());
+        }
+
+        /**
+         * Informs the application that this recording session has been tuned to the given channel
+         * and is ready to start recording.
+         *
+         * <p>Upon receiving a call to {@link #onTune(Uri)}, the session is expected to tune to the
+         * passed channel and call this method to indicate that it is now available for immediate
+         * recording. When {@link #onStartRecording(Uri)} is called, recording must start with
+         * minimal delay.
+         *
+         * @param channelUri The URI of a channel.
+         */
+        public void notifyTuned(Uri channelUri) {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyTuned");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onTuned(channelUri);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyTuned", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Informs the application that this recording session has stopped recording and created a
+         * new data entry in the {@link TvContract.RecordedPrograms} table that describes the newly
+         * recorded program.
+         *
+         * <p>The recording session must call this method in response to {@link #onStopRecording()}.
+         * The session may call it even before receiving a call to {@link #onStopRecording()} if a
+         * partially recorded program is available when there is an error.
+         *
+         * @param recordedProgramUri The URI of the newly recorded program.
+         */
+        public void notifyRecordingStopped(final Uri recordedProgramUri) {
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyRecordingStopped");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onRecordingStopped(recordedProgramUri);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyRecordingStopped", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Informs the application that there is an error and this recording session is no longer
+         * able to start or continue recording. It may be called at any time after the recording
+         * session is created until {@link #onRelease()} is called.
+         *
+         * <p>The application may release the current session upon receiving the error code through
+         * {@link TvRecordingClient.RecordingCallback#onError(int)}. The session may call
+         * {@link #notifyRecordingStopped(Uri)} if a partially recorded but still playable program
+         * is available, before calling this method.
+         *
+         * @param error The error code. Should be one of the followings.
+         * <ul>
+         * <li>{@link TvInputManager#RECORDING_ERROR_UNKNOWN}
+         * <li>{@link TvInputManager#RECORDING_ERROR_INSUFFICIENT_SPACE}
+         * <li>{@link TvInputManager#RECORDING_ERROR_RESOURCE_BUSY}
+         * </ul>
+         */
+        public void notifyError(@TvInputManager.RecordingError int error) {
+            if (error < TvInputManager.RECORDING_ERROR_START
+                    || error > TvInputManager.RECORDING_ERROR_END) {
+                Log.w(TAG, "notifyError - invalid error code (" + error
+                        + ") is changed to RECORDING_ERROR_UNKNOWN.");
+                error = TvInputManager.RECORDING_ERROR_UNKNOWN;
+            }
+            final int validError = error;
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifyError");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onError(validError);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in notifyError", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Dispatches an event to the application using this recording session.
+         *
+         * @param eventType The type of the event.
+         * @param eventArgs Optional arguments of the event.
+         * @hide
+         */
+        @SystemApi
+        public void notifySessionEvent(@NonNull final String eventType, final Bundle eventArgs) {
+            Preconditions.checkNotNull(eventType);
+            executeOrPostRunnableOnMainThread(new Runnable() {
+                @MainThread
+                @Override
+                public void run() {
+                    try {
+                        if (DEBUG) Log.d(TAG, "notifySessionEvent(" + eventType + ")");
+                        if (mSessionCallback != null) {
+                            mSessionCallback.onSessionEvent(eventType, eventArgs);
+                        }
+                    } catch (RemoteException e) {
+                        Log.w(TAG, "error in sending event (event=" + eventType + ")", e);
+                    }
+                }
+            });
+        }
+
+        /**
+         * Called when the application requests to tune to a given channel for TV program recording.
+         *
+         * <p>The application may call this method before starting or after stopping recording, but
+         * not during recording.
+         *
+         * <p>The session must call {@link #notifyTuned(Uri)} if the tune request was fulfilled, or
+         * {@link #notifyError(int)} otherwise.
+         *
+         * @param channelUri The URI of a channel.
+         */
+        public abstract void onTune(Uri channelUri);
+
+        /**
+         * Called when the application requests to tune to a given channel for TV program recording.
+         * Override this method in order to handle domain-specific features that are only known
+         * between certain TV inputs and their clients.
+         *
+         * <p>The application may call this method before starting or after stopping recording, but
+         * not during recording. The default implementation calls {@link #onTune(Uri)}.
+         *
+         * <p>The session must call {@link #notifyTuned(Uri)} if the tune request was fulfilled, or
+         * {@link #notifyError(int)} otherwise.
+         *
+         * @param channelUri The URI of a channel.
+         * @param params Domain-specific data for this tune request. Keys <em>must</em> be a scoped
+         *            name, i.e. prefixed with a package name you own, so that different developers
+         *            will not create conflicting keys.
+         */
+        public void onTune(Uri channelUri, Bundle params) {
+            onTune(channelUri);
+        }
+
+        /**
+         * Called when the application requests to start TV program recording. Recording must start
+         * immediately when this method is called.
+         *
+         * <p>The application may supply the URI for a TV program for filling in program specific
+         * data fields in the {@link android.media.tv.TvContract.RecordedPrograms} table.
+         * A non-null {@code programUri} implies the started recording should be of that specific
+         * program, whereas null {@code programUri} does not impose such a requirement and the
+         * recording can span across multiple TV programs. In either case, the application must call
+         * {@link TvRecordingClient#stopRecording()} to stop the recording.
+         *
+         * <p>The session must call {@link #notifyError(int)} if the start request cannot be
+         * fulfilled.
+         *
+         * @param programUri The URI for the TV program to record, built by
+         *            {@link TvContract#buildProgramUri(long)}. Can be {@code null}.
+         */
+        public abstract void onStartRecording(@Nullable Uri programUri);
+
+        /**
+         * Called when the application requests to start TV program recording. Recording must start
+         * immediately when this method is called.
+         *
+         * <p>The application may supply the URI for a TV program for filling in program specific
+         * data fields in the {@link android.media.tv.TvContract.RecordedPrograms} table.
+         * A non-null {@code programUri} implies the started recording should be of that specific
+         * program, whereas null {@code programUri} does not impose such a requirement and the
+         * recording can span across multiple TV programs. In either case, the application must call
+         * {@link TvRecordingClient#stopRecording()} to stop the recording.
+         *
+         * <p>The session must call {@link #notifyError(int)} if the start request cannot be
+         * fulfilled.
+         *
+         * @param programUri The URI for the TV program to record, built by
+         *            {@link TvContract#buildProgramUri(long)}. Can be {@code null}.
+         * @param params Domain-specific data for this tune request. Keys <em>must</em> be a scoped
+         *            name, i.e. prefixed with a package name you own, so that different developers
+         *            will not create conflicting keys.
+         */
+        public void onStartRecording(@Nullable Uri programUri, @NonNull Bundle params) {
+            onStartRecording(programUri);
+        }
+
+        /**
+         * Called when the application requests to stop TV program recording. Recording must stop
+         * immediately when this method is called.
+         *
+         * <p>The session must create a new data entry in the
+         * {@link android.media.tv.TvContract.RecordedPrograms} table that describes the newly
+         * recorded program and call {@link #notifyRecordingStopped(Uri)} with the URI to that
+         * entry.
+         * If the stop request cannot be fulfilled, the session must call {@link #notifyError(int)}.
+         *
+         */
+        public abstract void onStopRecording();
+
+
+        /**
+         * Called when the application requests to pause TV program recording. Recording must pause
+         * immediately when this method is called.
+         *
+         * If the pause request cannot be fulfilled, the session must call
+         * {@link #notifyError(int)}.
+         *
+         * @param params Domain-specific data for recording request.
+         */
+        public void onPauseRecording(@NonNull Bundle params) { }
+
+        /**
+         * Called when the application requests to resume TV program recording. Recording must
+         * resume immediately when this method is called.
+         *
+         * If the resume request cannot be fulfilled, the session must call
+         * {@link #notifyError(int)}.
+         *
+         * @param params Domain-specific data for recording request.
+         */
+        public void onResumeRecording(@NonNull Bundle params) { }
+
+        /**
+         * Called when the application requests to release all the resources held by this recording
+         * session.
+         */
+        public abstract void onRelease();
+
+        /**
+         * Processes a private command sent from the application to the TV input. This can be used
+         * to provide domain-specific features that are only known between certain TV inputs and
+         * their clients.
+         *
+         * @param action Name of the command to be performed. This <em>must</em> be a scoped name,
+         *            i.e. prefixed with a package name you own, so that different developers will
+         *            not create conflicting commands.
+         * @param data Any data to include with the command.
+         */
+        public void onAppPrivateCommand(@NonNull String action, Bundle data) {
+        }
+
+        /**
+         * Calls {@link #onTune(Uri, Bundle)}.
+         *
+         */
+        void tune(Uri channelUri, Bundle params) {
+            onTune(channelUri, params);
+        }
+
+        /**
+         * Calls {@link #onRelease()}.
+         *
+         */
+        void release() {
+            onRelease();
+        }
+
+        /**
+         * Calls {@link #onStartRecording(Uri, Bundle)}.
+         *
+         */
+        void startRecording(@Nullable  Uri programUri, @NonNull Bundle params) {
+            onStartRecording(programUri, params);
+        }
+
+        /**
+         * Calls {@link #onStopRecording()}.
+         *
+         */
+        void stopRecording() {
+            onStopRecording();
+        }
+
+        /**
+         * Calls {@link #onPauseRecording(Bundle)}.
+         *
+         */
+        void pauseRecording(@NonNull Bundle params) {
+            onPauseRecording(params);
+        }
+
+        /**
+         * Calls {@link #onResumeRecording(Bundle)}.
+         *
+         */
+        void resumeRecording(@NonNull Bundle params) {
+            onResumeRecording(params);
+        }
+
+        /**
+         * Calls {@link #onAppPrivateCommand(String, Bundle)}.
+         */
+        void appPrivateCommand(String action, Bundle data) {
+            onAppPrivateCommand(action, data);
+        }
+
+        private void initialize(ITvInputSessionCallback callback) {
+            synchronized(mLock) {
+                mSessionCallback = callback;
+                for (Runnable runnable : mPendingActions) {
+                    runnable.run();
+                }
+                mPendingActions.clear();
+            }
+        }
+
+        private void executeOrPostRunnableOnMainThread(Runnable action) {
+            synchronized(mLock) {
+                if (mSessionCallback == null) {
+                    // The session is not initialized yet.
+                    mPendingActions.add(action);
+                } else {
+                    if (mHandler.getLooper().isCurrentThread()) {
+                        action.run();
+                    } else {
+                        // Posts the runnable if this is not called from the main thread
+                        mHandler.post(action);
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * Base class for a TV input session which represents an external device connected to a
+     * hardware TV input.
+     *
+     * <p>This class is for an input which provides channels for the external set-top box to the
+     * application. Once a TV input returns an implementation of this class on
+     * {@link #onCreateSession(String)}, the framework will create a separate session for
+     * a hardware TV Input (e.g. HDMI 1) and forward the application's surface to the session so
+     * that the user can see the screen of the hardware TV Input when she tunes to a channel from
+     * this TV input. The implementation of this class is expected to change the channel of the
+     * external set-top box via a proprietary protocol when {@link HardwareSession#onTune} is
+     * requested by the application.
+     *
+     * <p>Note that this class is not for inputs for internal hardware like built-in tuner and HDMI
+     * 1.
+     *
+     * @see #onCreateSession(String)
+     */
+    public abstract static class HardwareSession extends Session {
+
+        /**
+         * Creates a new HardwareSession.
+         *
+         * @param context The context of the application
+         */
+        public HardwareSession(Context context) {
+            super(context);
+        }
+
+        private TvInputManager.Session mHardwareSession;
+        private ITvInputSession mProxySession;
+        private ITvInputSessionCallback mProxySessionCallback;
+        private Handler mServiceHandler;
+
+        /**
+         * Returns the hardware TV input ID the external device is connected to.
+         *
+         * <p>TV input is expected to provide {@link android.R.attr#setupActivity} so that
+         * the application can launch it before using this TV input. The setup activity may let
+         * the user select the hardware TV input to which the external device is connected. The ID
+         * of the selected one should be stored in the TV input so that it can be returned here.
+         */
+        public abstract String getHardwareInputId();
+
+        private final TvInputManager.SessionCallback mHardwareSessionCallback =
+                new TvInputManager.SessionCallback() {
+            @Override
+            public void onSessionCreated(TvInputManager.Session session) {
+                mHardwareSession = session;
+                SomeArgs args = SomeArgs.obtain();
+                if (session != null) {
+                    args.arg1 = HardwareSession.this;
+                    args.arg2 = mProxySession;
+                    args.arg3 = mProxySessionCallback;
+                    args.arg4 = session.getToken();
+                    session.tune(TvContract.buildChannelUriForPassthroughInput(
+                            getHardwareInputId()));
+                } else {
+                    args.arg1 = null;
+                    args.arg2 = null;
+                    args.arg3 = mProxySessionCallback;
+                    args.arg4 = null;
+                    onRelease();
+                }
+                mServiceHandler.obtainMessage(ServiceHandler.DO_NOTIFY_SESSION_CREATED, args)
+                        .sendToTarget();
+            }
+
+            @Override
+            public void onVideoAvailable(final TvInputManager.Session session) {
+                if (mHardwareSession == session) {
+                    onHardwareVideoAvailable();
+                }
+            }
+
+            @Override
+            public void onVideoUnavailable(final TvInputManager.Session session,
+                    final int reason) {
+                if (mHardwareSession == session) {
+                    onHardwareVideoUnavailable(reason);
+                }
+            }
+        };
+
+        /**
+         * This method will not be called in {@link HardwareSession}. Framework will
+         * forward the application's surface to the hardware TV input.
+         */
+        @Override
+        public final boolean onSetSurface(Surface surface) {
+            Log.e(TAG, "onSetSurface() should not be called in HardwareProxySession.");
+            return false;
+        }
+
+        /**
+         * Called when the underlying hardware TV input session calls
+         * {@link TvInputService.Session#notifyVideoAvailable()}.
+         */
+        public void onHardwareVideoAvailable() { }
+
+        /**
+         * Called when the underlying hardware TV input session calls
+         * {@link TvInputService.Session#notifyVideoUnavailable(int)}.
+         *
+         * @param reason The reason that the hardware TV input stopped the playback:
+         * <ul>
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_UNKNOWN}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_TUNING}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_BUFFERING}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY}
+         * </ul>
+         */
+        public void onHardwareVideoUnavailable(int reason) { }
+
+        @Override
+        void release() {
+            if (mHardwareSession != null) {
+                mHardwareSession.release();
+                mHardwareSession = null;
+            }
+            super.release();
+        }
+    }
+
+    /** @hide */
+    public static boolean isNavigationKey(int keyCode) {
+        switch (keyCode) {
+            case KeyEvent.KEYCODE_DPAD_LEFT:
+            case KeyEvent.KEYCODE_DPAD_RIGHT:
+            case KeyEvent.KEYCODE_DPAD_UP:
+            case KeyEvent.KEYCODE_DPAD_DOWN:
+            case KeyEvent.KEYCODE_DPAD_CENTER:
+            case KeyEvent.KEYCODE_PAGE_UP:
+            case KeyEvent.KEYCODE_PAGE_DOWN:
+            case KeyEvent.KEYCODE_MOVE_HOME:
+            case KeyEvent.KEYCODE_MOVE_END:
+            case KeyEvent.KEYCODE_TAB:
+            case KeyEvent.KEYCODE_SPACE:
+            case KeyEvent.KEYCODE_ENTER:
+                return true;
+        }
+        return false;
+    }
+
+    @SuppressLint("HandlerLeak")
+    private final class ServiceHandler extends Handler {
+        private static final int DO_CREATE_SESSION = 1;
+        private static final int DO_NOTIFY_SESSION_CREATED = 2;
+        private static final int DO_CREATE_RECORDING_SESSION = 3;
+        private static final int DO_ADD_HARDWARE_INPUT = 4;
+        private static final int DO_REMOVE_HARDWARE_INPUT = 5;
+        private static final int DO_ADD_HDMI_INPUT = 6;
+        private static final int DO_REMOVE_HDMI_INPUT = 7;
+        private static final int DO_UPDATE_HDMI_INPUT = 8;
+
+        private void broadcastAddHardwareInput(int deviceId, TvInputInfo inputInfo) {
+            int n = mCallbacks.beginBroadcast();
+            for (int i = 0; i < n; ++i) {
+                try {
+                    mCallbacks.getBroadcastItem(i).addHardwareInput(deviceId, inputInfo);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "error in broadcastAddHardwareInput", e);
+                }
+            }
+            mCallbacks.finishBroadcast();
+        }
+
+        private void broadcastAddHdmiInput(int id, TvInputInfo inputInfo) {
+            int n = mCallbacks.beginBroadcast();
+            for (int i = 0; i < n; ++i) {
+                try {
+                    mCallbacks.getBroadcastItem(i).addHdmiInput(id, inputInfo);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "error in broadcastAddHdmiInput", e);
+                }
+            }
+            mCallbacks.finishBroadcast();
+        }
+
+        private void broadcastRemoveHardwareInput(String inputId) {
+            int n = mCallbacks.beginBroadcast();
+            for (int i = 0; i < n; ++i) {
+                try {
+                    mCallbacks.getBroadcastItem(i).removeHardwareInput(inputId);
+                } catch (RemoteException e) {
+                    Log.e(TAG, "error in broadcastRemoveHardwareInput", e);
+                }
+            }
+            mCallbacks.finishBroadcast();
+        }
+
+        @Override
+        public final void handleMessage(Message msg) {
+            switch (msg.what) {
+                case DO_CREATE_SESSION: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    InputChannel channel = (InputChannel) args.arg1;
+                    ITvInputSessionCallback cb = (ITvInputSessionCallback) args.arg2;
+                    String inputId = (String) args.arg3;
+                    String sessionId = (String) args.arg4;
+                    args.recycle();
+                    Session sessionImpl = onCreateSession(inputId, sessionId);
+                    if (sessionImpl == null) {
+                        try {
+                            // Failed to create a session.
+                            cb.onSessionCreated(null, null);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "error in onSessionCreated", e);
+                        }
+                        return;
+                    }
+                    ITvInputSession stub = new ITvInputSessionWrapper(TvInputService.this,
+                            sessionImpl, channel);
+                    if (sessionImpl instanceof HardwareSession) {
+                        HardwareSession proxySession =
+                                ((HardwareSession) sessionImpl);
+                        String hardwareInputId = proxySession.getHardwareInputId();
+                        if (TextUtils.isEmpty(hardwareInputId) ||
+                                !isPassthroughInput(hardwareInputId)) {
+                            if (TextUtils.isEmpty(hardwareInputId)) {
+                                Log.w(TAG, "Hardware input id is not setup yet.");
+                            } else {
+                                Log.w(TAG, "Invalid hardware input id : " + hardwareInputId);
+                            }
+                            sessionImpl.onRelease();
+                            try {
+                                cb.onSessionCreated(null, null);
+                            } catch (RemoteException e) {
+                                Log.e(TAG, "error in onSessionCreated", e);
+                            }
+                            return;
+                        }
+                        proxySession.mProxySession = stub;
+                        proxySession.mProxySessionCallback = cb;
+                        proxySession.mServiceHandler = mServiceHandler;
+                        TvInputManager manager = (TvInputManager) getSystemService(
+                                Context.TV_INPUT_SERVICE);
+                        manager.createSession(hardwareInputId,
+                                proxySession.mHardwareSessionCallback, mServiceHandler);
+                    } else {
+                        SomeArgs someArgs = SomeArgs.obtain();
+                        someArgs.arg1 = sessionImpl;
+                        someArgs.arg2 = stub;
+                        someArgs.arg3 = cb;
+                        someArgs.arg4 = null;
+                        mServiceHandler.obtainMessage(ServiceHandler.DO_NOTIFY_SESSION_CREATED,
+                                someArgs).sendToTarget();
+                    }
+                    return;
+                }
+                case DO_NOTIFY_SESSION_CREATED: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    Session sessionImpl = (Session) args.arg1;
+                    ITvInputSession stub = (ITvInputSession) args.arg2;
+                    ITvInputSessionCallback cb = (ITvInputSessionCallback) args.arg3;
+                    IBinder hardwareSessionToken = (IBinder) args.arg4;
+                    try {
+                        cb.onSessionCreated(stub, hardwareSessionToken);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "error in onSessionCreated", e);
+                    }
+                    if (sessionImpl != null) {
+                        sessionImpl.initialize(cb);
+                    }
+                    args.recycle();
+                    return;
+                }
+                case DO_CREATE_RECORDING_SESSION: {
+                    SomeArgs args = (SomeArgs) msg.obj;
+                    ITvInputSessionCallback cb = (ITvInputSessionCallback) args.arg1;
+                    String inputId = (String) args.arg2;
+                    String sessionId = (String) args.arg3;
+                    args.recycle();
+                    RecordingSession recordingSessionImpl =
+                            onCreateRecordingSession(inputId, sessionId);
+                    if (recordingSessionImpl == null) {
+                        try {
+                            // Failed to create a recording session.
+                            cb.onSessionCreated(null, null);
+                        } catch (RemoteException e) {
+                            Log.e(TAG, "error in onSessionCreated", e);
+                        }
+                        return;
+                    }
+                    ITvInputSession stub = new ITvInputSessionWrapper(TvInputService.this,
+                            recordingSessionImpl);
+                    try {
+                        cb.onSessionCreated(stub, null);
+                    } catch (RemoteException e) {
+                        Log.e(TAG, "error in onSessionCreated", e);
+                    }
+                    recordingSessionImpl.initialize(cb);
+                    return;
+                }
+                case DO_ADD_HARDWARE_INPUT: {
+                    TvInputHardwareInfo hardwareInfo = (TvInputHardwareInfo) msg.obj;
+                    TvInputInfo inputInfo = onHardwareAdded(hardwareInfo);
+                    if (inputInfo != null) {
+                        broadcastAddHardwareInput(hardwareInfo.getDeviceId(), inputInfo);
+                    }
+                    return;
+                }
+                case DO_REMOVE_HARDWARE_INPUT: {
+                    TvInputHardwareInfo hardwareInfo = (TvInputHardwareInfo) msg.obj;
+                    String inputId = onHardwareRemoved(hardwareInfo);
+                    if (inputId != null) {
+                        broadcastRemoveHardwareInput(inputId);
+                    }
+                    return;
+                }
+                case DO_ADD_HDMI_INPUT: {
+                    HdmiDeviceInfo deviceInfo = (HdmiDeviceInfo) msg.obj;
+                    TvInputInfo inputInfo = onHdmiDeviceAdded(deviceInfo);
+                    if (inputInfo != null) {
+                        broadcastAddHdmiInput(deviceInfo.getId(), inputInfo);
+                    }
+                    return;
+                }
+                case DO_REMOVE_HDMI_INPUT: {
+                    HdmiDeviceInfo deviceInfo = (HdmiDeviceInfo) msg.obj;
+                    String inputId = onHdmiDeviceRemoved(deviceInfo);
+                    if (inputId != null) {
+                        broadcastRemoveHardwareInput(inputId);
+                    }
+                    return;
+                }
+                case DO_UPDATE_HDMI_INPUT: {
+                    HdmiDeviceInfo deviceInfo = (HdmiDeviceInfo) msg.obj;
+                    onHdmiDeviceUpdated(deviceInfo);
+                    return;
+                }
+                default: {
+                    Log.w(TAG, "Unhandled message code: " + msg.what);
+                    return;
+                }
+            }
+        }
+    }
+}
diff --git a/android/media/tv/TvRecordingClient.java b/android/media/tv/TvRecordingClient.java
new file mode 100644
index 0000000..180e2bd
--- /dev/null
+++ b/android/media/tv/TvRecordingClient.java
@@ -0,0 +1,558 @@
+/*
+ * Copyright (C) 2016 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.tv;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.media.tv.TvInputManager;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
+
+import java.util.ArrayDeque;
+import java.util.Objects;
+import java.util.Queue;
+
+/**
+ * The public interface object used to interact with a specific TV input service for TV program
+ * recording.
+ */
+public class TvRecordingClient {
+    private static final String TAG = "TvRecordingClient";
+    private static final boolean DEBUG = false;
+
+    private final RecordingCallback mCallback;
+    private final Handler mHandler;
+
+    private final TvInputManager mTvInputManager;
+    private TvInputManager.Session mSession;
+    private MySessionCallback mSessionCallback;
+
+    private boolean mIsRecordingStarted;
+    private boolean mIsTuned;
+    private boolean mIsPaused;
+    private boolean mIsRecordingStopping;
+    private final Queue<Pair<String, Bundle>> mPendingAppPrivateCommands = new ArrayDeque<>();
+
+    /**
+     * Creates a new TvRecordingClient object.
+     *
+     * @param context The application context to create a TvRecordingClient with.
+     * @param tag A short name for debugging purposes.
+     * @param callback The callback to receive recording status changes.
+     * @param handler The handler to invoke the callback on.
+     */
+    public TvRecordingClient(Context context, String tag, @NonNull RecordingCallback callback,
+            Handler handler) {
+        mCallback = callback;
+        mHandler = handler == null ? new Handler(Looper.getMainLooper()) : handler;
+        mTvInputManager = (TvInputManager) context.getSystemService(Context.TV_INPUT_SERVICE);
+    }
+
+    /**
+     * Tunes to a given channel for TV program recording. The first tune request will create a new
+     * recording session for the corresponding TV input and establish a connection between the
+     * application and the session. If recording has already started in the current recording
+     * session, this method throws an exception.
+     *
+     * <p>The application may call this method before starting or after stopping recording, but not
+     * during recording.
+     *
+     * <p>The recording session will respond by calling
+     * {@link RecordingCallback#onTuned(Uri)} if the tune request was fulfilled, or
+     * {@link RecordingCallback#onError(int)} otherwise.
+     *
+     * @param inputId The ID of the TV input for the given channel.
+     * @param channelUri The URI of a channel.
+     * @throws IllegalStateException If recording is already started.
+     */
+    public void tune(String inputId, Uri channelUri) {
+        tune(inputId, channelUri, null);
+    }
+
+    /**
+     * Tunes to a given channel for TV program recording. The first tune request will create a new
+     * recording session for the corresponding TV input and establish a connection between the
+     * application and the session. If recording has already started in the current recording
+     * session, this method throws an exception. This can be used to provide domain-specific
+     * features that are only known between certain client and their TV inputs.
+     *
+     * <p>The application may call this method before starting or after stopping recording, but not
+     * during recording.
+     *
+     * <p>The recording session will respond by calling
+     * {@link RecordingCallback#onTuned(Uri)} if the tune request was fulfilled, or
+     * {@link RecordingCallback#onError(int)} otherwise.
+     *
+     * @param inputId The ID of the TV input for the given channel.
+     * @param channelUri The URI of a channel.
+     * @param params Domain-specific data for this tune request. Keys <em>must</em> be a scoped
+     *            name, i.e. prefixed with a package name you own, so that different developers will
+     *            not create conflicting keys.
+     * @throws IllegalStateException If recording is already started.
+     */
+    public void tune(String inputId, Uri channelUri, Bundle params) {
+        if (DEBUG) Log.d(TAG, "tune(" + channelUri + ")");
+        if (TextUtils.isEmpty(inputId)) {
+            throw new IllegalArgumentException("inputId cannot be null or an empty string");
+        }
+        if (mIsRecordingStarted && !mIsPaused) {
+            throw new IllegalStateException("tune failed - recording already started");
+        }
+        if (mSessionCallback != null && TextUtils.equals(mSessionCallback.mInputId, inputId)) {
+            if (mSession != null) {
+                mSessionCallback.mChannelUri = channelUri;
+                mSession.tune(channelUri, params);
+            } else {
+                mSessionCallback.mChannelUri = channelUri;
+                mSessionCallback.mConnectionParams = params;
+            }
+            mIsTuned = false;
+        } else {
+            if (mIsPaused) {
+                throw new IllegalStateException("tune failed - inputId is changed during pause");
+            }
+            resetInternal();
+            mSessionCallback = new MySessionCallback(inputId, channelUri, params);
+            if (mTvInputManager != null) {
+                mTvInputManager.createRecordingSession(inputId, mSessionCallback, mHandler);
+            }
+        }
+    }
+
+    /**
+     * Releases the resources in the current recording session immediately. This may be called at
+     * any time, however if the session is already released, it does nothing.
+     */
+    public void release() {
+        if (DEBUG) Log.d(TAG, "release()");
+        resetInternal();
+    }
+
+    private void resetInternal() {
+        mSessionCallback = null;
+        mPendingAppPrivateCommands.clear();
+        if (mSession != null) {
+            mSession.release();
+            mIsTuned = false;
+            mIsRecordingStarted = false;
+            mIsPaused = false;
+            mIsRecordingStopping = false;
+            mSession = null;
+        }
+    }
+
+    /**
+     * Starts TV program recording in the current recording session. Recording is expected to start
+     * immediately when this method is called. If the current recording session has not yet tuned to
+     * any channel, this method throws an exception.
+     *
+     * <p>The application may supply the URI for a TV program for filling in program specific data
+     * fields in the {@link android.media.tv.TvContract.RecordedPrograms} table.
+     * A non-null {@code programUri} implies the started recording should be of that specific
+     * program, whereas null {@code programUri} does not impose such a requirement and the
+     * recording can span across multiple TV programs. In either case, the application must call
+     * {@link TvRecordingClient#stopRecording()} to stop the recording.
+     *
+     * <p>The recording session will respond by calling {@link RecordingCallback#onError(int)} if
+     * the start request cannot be fulfilled.
+     *
+     * @param programUri The URI for the TV program to record, built by
+     *            {@link TvContract#buildProgramUri(long)}. Can be {@code null}.
+     * @throws IllegalStateException If {@link #tune} request hasn't been handled yet or during
+     *            pause.
+     */
+    public void startRecording(@Nullable Uri programUri) {
+        startRecording(programUri, Bundle.EMPTY);
+    }
+
+    /**
+     * Starts TV program recording in the current recording session. Recording is expected to start
+     * immediately when this method is called. If the current recording session has not yet tuned to
+     * any channel, this method throws an exception.
+     *
+     * <p>The application may supply the URI for a TV program for filling in program specific data
+     * fields in the {@link android.media.tv.TvContract.RecordedPrograms} table.
+     * A non-null {@code programUri} implies the started recording should be of that specific
+     * program, whereas null {@code programUri} does not impose such a requirement and the
+     * recording can span across multiple TV programs. In either case, the application must call
+     * {@link TvRecordingClient#stopRecording()} to stop the recording.
+     *
+     * <p>The recording session will respond by calling {@link RecordingCallback#onError(int)} if
+     * the start request cannot be fulfilled.
+     *
+     * @param programUri The URI for the TV program to record, built by
+     *            {@link TvContract#buildProgramUri(long)}. Can be {@code null}.
+     * @param params Domain-specific data for this request. Keys <em>must</em> be a scoped
+     *            name, i.e. prefixed with a package name you own, so that different developers will
+     *            not create conflicting keys.
+     * @throws IllegalStateException If {@link #tune} request hasn't been handled yet or during
+     *            pause.
+     */
+    public void startRecording(@Nullable Uri programUri, @NonNull Bundle params) {
+        if (mIsRecordingStopping || !mIsTuned || mIsPaused) {
+            throw new IllegalStateException("startRecording failed -"
+                    + "recording not yet stopped or not yet tuned or paused");
+        }
+        if (mIsRecordingStarted) {
+            Log.w(TAG, "startRecording failed - recording already started");
+        }
+        if (mSession != null) {
+            mSession.startRecording(programUri, params);
+            mIsRecordingStarted = true;
+        }
+    }
+
+    /**
+     * Stops TV program recording in the current recording session. Recording is expected to stop
+     * immediately when this method is called. If recording has not yet started in the current
+     * recording session, this method does nothing.
+     *
+     * <p>The recording session is expected to create a new data entry in the
+     * {@link android.media.tv.TvContract.RecordedPrograms} table that describes the newly
+     * recorded program and pass the URI to that entry through to
+     * {@link RecordingCallback#onRecordingStopped(Uri)}.
+     * If the stop request cannot be fulfilled, the recording session will respond by calling
+     * {@link RecordingCallback#onError(int)}.
+     */
+    public void stopRecording() {
+        if (!mIsRecordingStarted) {
+            Log.w(TAG, "stopRecording failed - recording not yet started");
+        }
+        if (mSession != null) {
+            mSession.stopRecording();
+            if (mIsRecordingStarted) {
+                mIsRecordingStopping = true;
+            }
+        }
+    }
+
+    /**
+     * Pause TV program recording in the current recording session. Recording is expected to pause
+     * immediately when this method is called. If recording has not yet started in the current
+     * recording session, this method does nothing.
+     *
+     * <p>In pause status, the application can tune during recording. To continue recording,
+     * please call {@link TvRecordingClient#resumeRecording()} to resume instead of
+     * {@link TvRecordingClient#startRecording(Uri)}. Application can stop
+     * the recording with {@link TvRecordingClient#stopRecording()} in recording pause status.
+     *
+     * <p>If the pause request cannot be fulfilled, the recording session will respond by calling
+     * {@link RecordingCallback#onError(int)}.
+     */
+    public void pauseRecording() {
+        pauseRecording(Bundle.EMPTY);
+    }
+
+    /**
+     * Pause TV program recording in the current recording session. Recording is expected to pause
+     * immediately when this method is called. If recording has not yet started in the current
+     * recording session, this method does nothing.
+     *
+     * <p>In pause status, the application can tune during recording. To continue recording,
+     * please call {@link TvRecordingClient#resumeRecording()} to resume instead of
+     * {@link TvRecordingClient#startRecording(Uri)}. Application can stop
+     * the recording with {@link TvRecordingClient#stopRecording()} in recording pause status.
+     *
+     * <p>If the pause request cannot be fulfilled, the recording session will respond by calling
+     * {@link RecordingCallback#onError(int)}.
+     *
+     * @param params Domain-specific data for this request.
+     */
+    public void pauseRecording(@NonNull Bundle params) {
+        if (!mIsRecordingStarted || mIsRecordingStopping) {
+            throw new IllegalStateException(
+                    "pauseRecording failed - recording not yet started or stopping");
+        }
+        TvInputInfo info = mTvInputManager.getTvInputInfo(mSessionCallback.mInputId);
+        if (info == null || !info.canPauseRecording()) {
+            throw new UnsupportedOperationException(
+                    "pauseRecording failed - operation not supported");
+        }
+        if (mIsPaused) {
+            Log.w(TAG, "pauseRecording failed - recording already paused");
+        }
+        if (mSession != null) {
+            mSession.pauseRecording(params);
+            mIsPaused  = true;
+        }
+    }
+
+    /**
+     * Resume TV program recording only in recording pause status in the current recording session.
+     * Recording is expected to resume immediately when this method is called. If recording has not
+     * yet paused in the current recording session, this method does nothing.
+     *
+     * <p>When record is resumed, the recording is continue and can not re-tune. Application can
+     * stop the recording with {@link TvRecordingClient#stopRecording()} after record resumed.
+     *
+     * <p>If the pause request cannot be fulfilled, the recording session will respond by calling
+     * {@link RecordingCallback#onError(int)}.
+     */
+    public void resumeRecording() {
+        resumeRecording(Bundle.EMPTY);
+    }
+
+    /**
+     * Resume TV program recording only in recording pause status in the current recording session.
+     * Recording is expected to resume immediately when this method is called. If recording has not
+     * yet paused in the current recording session, this method does nothing.
+     *
+     * <p>When record is resumed, the recording is continues and can not re-tune. Application can
+     * stop the recording with {@link TvRecordingClient#stopRecording()} after record resumed.
+     *
+     * <p>If the resume request cannot be fulfilled, the recording session will respond by calling
+     * {@link RecordingCallback#onError(int)}.
+     *
+     * @param params Domain-specific data for this request.
+     */
+    public void resumeRecording(@NonNull Bundle params) {
+        if (!mIsRecordingStarted || mIsRecordingStopping || !mIsTuned) {
+            throw new IllegalStateException(
+                    "resumeRecording failed - recording not yet started or stopping or "
+                            + "not yet tuned");
+        }
+        if (!mIsPaused) {
+            Log.w(TAG, "resumeRecording failed - recording not yet paused");
+        }
+        if (mSession != null) {
+            mSession.resumeRecording(params);
+            mIsPaused  = false;
+        }
+    }
+
+    /**
+     * Sends a private command to the underlying TV input. This can be used to provide
+     * domain-specific features that are only known between certain clients and their TV inputs.
+     *
+     * @param action The name of the private command to send. This <em>must</em> be a scoped name,
+     *            i.e. prefixed with a package name you own, so that different developers will not
+     *            create conflicting commands.
+     * @param data An optional bundle to send with the command.
+     */
+    public void sendAppPrivateCommand(@NonNull String action, Bundle data) {
+        if (TextUtils.isEmpty(action)) {
+            throw new IllegalArgumentException("action cannot be null or an empty string");
+        }
+        if (mSession != null) {
+            mSession.sendAppPrivateCommand(action, data);
+        } else {
+            Log.w(TAG, "sendAppPrivateCommand - session not yet created (action \"" + action
+                    + "\" pending)");
+            mPendingAppPrivateCommands.add(Pair.create(action, data));
+        }
+    }
+
+    /**
+     * Callback used to receive various status updates on the
+     * {@link android.media.tv.TvInputService.RecordingSession}
+     */
+    public abstract static class RecordingCallback {
+        /**
+         * This is called when an error occurred while establishing a connection to the recording
+         * session for the corresponding TV input.
+         *
+         * @param inputId The ID of the TV input bound to the current TvRecordingClient.
+         */
+        public void onConnectionFailed(String inputId) {
+        }
+
+        /**
+         * This is called when the connection to the current recording session is lost.
+         *
+         * @param inputId The ID of the TV input bound to the current TvRecordingClient.
+         */
+        public void onDisconnected(String inputId) {
+        }
+
+        /**
+         * This is called when the recording session has been tuned to the given channel and is
+         * ready to start recording.
+         *
+         * @param channelUri The URI of a channel.
+         */
+        public void onTuned(Uri channelUri) {
+        }
+
+        /**
+         * This is called when the current recording session has stopped recording and created a
+         * new data entry in the {@link TvContract.RecordedPrograms} table that describes the newly
+         * recorded program.
+         *
+         * @param recordedProgramUri The URI for the newly recorded program.
+         */
+        public void onRecordingStopped(Uri recordedProgramUri) {
+        }
+
+        /**
+         * This is called when an issue has occurred. It may be called at any time after the current
+         * recording session is created until it is released.
+         *
+         * @param error The error code. Should be one of the followings.
+         * <ul>
+         * <li>{@link TvInputManager#RECORDING_ERROR_UNKNOWN}
+         * <li>{@link TvInputManager#RECORDING_ERROR_INSUFFICIENT_SPACE}
+         * <li>{@link TvInputManager#RECORDING_ERROR_RESOURCE_BUSY}
+         * </ul>
+         */
+        public void onError(@TvInputManager.RecordingError int error) {
+        }
+
+        /**
+         * This is invoked when a custom event from the bound TV input is sent to this client.
+         *
+         * @param inputId The ID of the TV input bound to this client.
+         * @param eventType The type of the event.
+         * @param eventArgs Optional arguments of the event.
+         * @hide
+         */
+        @SystemApi
+        public void onEvent(String inputId, String eventType, Bundle eventArgs) {
+        }
+    }
+
+    private class MySessionCallback extends TvInputManager.SessionCallback {
+        final String mInputId;
+        Uri mChannelUri;
+        Bundle mConnectionParams;
+
+        MySessionCallback(String inputId, Uri channelUri, Bundle connectionParams) {
+            mInputId = inputId;
+            mChannelUri = channelUri;
+            mConnectionParams = connectionParams;
+        }
+
+        @Override
+        public void onSessionCreated(TvInputManager.Session session) {
+            if (DEBUG) {
+                Log.d(TAG, "onSessionCreated()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onSessionCreated - session already created");
+                // This callback is obsolete.
+                if (session != null) {
+                    session.release();
+                }
+                return;
+            }
+            mSession = session;
+            if (session != null) {
+                // Sends the pending app private commands.
+                for (Pair<String, Bundle> command : mPendingAppPrivateCommands) {
+                    mSession.sendAppPrivateCommand(command.first, command.second);
+                }
+                mPendingAppPrivateCommands.clear();
+                mSession.tune(mChannelUri, mConnectionParams);
+            } else {
+                mSessionCallback = null;
+                if (mCallback != null) {
+                    mCallback.onConnectionFailed(mInputId);
+                }
+            }
+        }
+
+        @Override
+        void onTuned(TvInputManager.Session session, Uri channelUri) {
+            if (DEBUG) {
+                Log.d(TAG, "onTuned()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onTuned - session not created");
+                return;
+            }
+            if (mIsTuned || !Objects.equals(mChannelUri, channelUri)) {
+                Log.w(TAG, "onTuned - already tuned or not yet tuned to last channel");
+                return;
+            }
+            mIsTuned = true;
+            mCallback.onTuned(channelUri);
+        }
+
+        @Override
+        public void onSessionReleased(TvInputManager.Session session) {
+            if (DEBUG) {
+                Log.d(TAG, "onSessionReleased()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onSessionReleased - session not created");
+                return;
+            }
+            mIsTuned = false;
+            mIsRecordingStarted = false;
+            mIsPaused = false;
+            mIsRecordingStopping = false;
+            mSessionCallback = null;
+            mSession = null;
+            if (mCallback != null) {
+                mCallback.onDisconnected(mInputId);
+            }
+        }
+
+        @Override
+        public void onRecordingStopped(TvInputManager.Session session, Uri recordedProgramUri) {
+            if (DEBUG) {
+                Log.d(TAG, "onRecordingStopped(recordedProgramUri= " + recordedProgramUri + ")");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onRecordingStopped - session not created");
+                return;
+            }
+            if (!mIsRecordingStarted) {
+                Log.w(TAG, "onRecordingStopped - recording not yet started");
+                return;
+            }
+            mIsRecordingStarted = false;
+            mIsPaused = false;
+            mIsRecordingStopping = false;
+            mCallback.onRecordingStopped(recordedProgramUri);
+        }
+
+        @Override
+        public void onError(TvInputManager.Session session, int error) {
+            if (DEBUG) {
+                Log.d(TAG, "onError(error=" + error + ")");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onError - session not created");
+                return;
+            }
+            mCallback.onError(error);
+        }
+
+        @Override
+        public void onSessionEvent(TvInputManager.Session session, String eventType,
+                Bundle eventArgs) {
+            if (DEBUG) {
+                Log.d(TAG, "onSessionEvent(eventType=" + eventType + ", eventArgs=" + eventArgs
+                        + ")");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onSessionEvent - session not created");
+                return;
+            }
+            if (mCallback != null) {
+                mCallback.onEvent(mInputId, eventType, eventArgs);
+            }
+        }
+    }
+}
diff --git a/android/media/tv/TvStreamConfig.java b/android/media/tv/TvStreamConfig.java
new file mode 100644
index 0000000..7ea93b4
--- /dev/null
+++ b/android/media/tv/TvStreamConfig.java
@@ -0,0 +1,180 @@
+/*
+ * Copyright (C) 2014 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.tv;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/**
+ * @hide
+ */
+@SystemApi
+public class TvStreamConfig implements Parcelable {
+    static final String TAG = TvStreamConfig.class.getSimpleName();
+
+    public final static int STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE = 1;
+    public final static int STREAM_TYPE_BUFFER_PRODUCER = 2;
+
+    private int mStreamId;
+    private int mType;
+    private int mMaxWidth;
+    private int mMaxHeight;
+    /**
+     * Generations are incremented once framework receives STREAM_CONFIGURATION_CHANGED event from
+     * HAL module. Framework should throw away outdated configurations and get new configurations
+     * via tv_input_device::get_stream_configurations().
+     */
+    private int mGeneration;
+
+    public static final @android.annotation.NonNull Parcelable.Creator<TvStreamConfig> CREATOR =
+            new Parcelable.Creator<TvStreamConfig>() {
+        @Override
+        public TvStreamConfig createFromParcel(Parcel source) {
+            try {
+                return new Builder().
+                        streamId(source.readInt()).
+                        type(source.readInt()).
+                        maxWidth(source.readInt()).
+                        maxHeight(source.readInt()).
+                        generation(source.readInt()).build();
+            } catch (Exception e) {
+                Log.e(TAG, "Exception creating TvStreamConfig from parcel", e);
+                return null;
+            }
+        }
+
+        @Override
+        public TvStreamConfig[] newArray(int size) {
+            return new TvStreamConfig[size];
+        }
+    };
+
+    private TvStreamConfig() {}
+
+    public int getStreamId() {
+        return mStreamId;
+    }
+
+    public int getType() {
+        return mType;
+    }
+
+    public int getMaxWidth() {
+        return mMaxWidth;
+    }
+
+    public int getMaxHeight() {
+        return mMaxHeight;
+    }
+
+    public int getGeneration() {
+        return mGeneration;
+    }
+
+    @NonNull
+    @Override
+    public String toString() {
+        return "TvStreamConfig {mStreamId=" + mStreamId + ";" + "mType=" + mType + ";mGeneration="
+                + mGeneration + "}";
+    }
+
+    // Parcelable
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(Parcel dest, int flags) {
+        dest.writeInt(mStreamId);
+        dest.writeInt(mType);
+        dest.writeInt(mMaxWidth);
+        dest.writeInt(mMaxHeight);
+        dest.writeInt(mGeneration);
+    }
+
+    /**
+     * A helper class for creating a TvStreamConfig object.
+     */
+    public static final class Builder {
+        private Integer mStreamId;
+        private Integer mType;
+        private Integer mMaxWidth;
+        private Integer mMaxHeight;
+        private Integer mGeneration;
+
+        public Builder() {
+        }
+
+        public Builder streamId(int streamId) {
+            mStreamId = streamId;
+            return this;
+        }
+
+        public Builder type(int type) {
+            mType = type;
+            return this;
+        }
+
+        public Builder maxWidth(int maxWidth) {
+            mMaxWidth = maxWidth;
+            return this;
+        }
+
+        public Builder maxHeight(int maxHeight) {
+            mMaxHeight = maxHeight;
+            return this;
+        }
+
+        public Builder generation(int generation) {
+            mGeneration = generation;
+            return this;
+        }
+
+        public TvStreamConfig build() {
+            if (mStreamId == null || mType == null || mMaxWidth == null || mMaxHeight == null
+                    || mGeneration == null) {
+                throw new UnsupportedOperationException();
+            }
+
+            TvStreamConfig config = new TvStreamConfig();
+            config.mStreamId = mStreamId;
+            config.mType = mType;
+            config.mMaxWidth = mMaxWidth;
+            config.mMaxHeight = mMaxHeight;
+            config.mGeneration = mGeneration;
+            return config;
+        }
+    }
+
+    @Override
+    public boolean equals(@Nullable Object obj) {
+        if (obj == null) return false;
+        if (!(obj instanceof TvStreamConfig)) return false;
+
+        TvStreamConfig config = (TvStreamConfig) obj;
+        return config.mGeneration == mGeneration
+            && config.mStreamId == mStreamId
+            && config.mType == mType
+            && config.mMaxWidth == mMaxWidth
+            && config.mMaxHeight == mMaxHeight;
+    }
+}
diff --git a/android/media/tv/TvTrackInfo.java b/android/media/tv/TvTrackInfo.java
new file mode 100644
index 0000000..78d7d76
--- /dev/null
+++ b/android/media/tv/TvTrackInfo.java
@@ -0,0 +1,735 @@
+/*
+ * Copyright (C) 2014 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.tv;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.text.TextUtils;
+
+import com.android.internal.util.Preconditions;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * Encapsulates the format of tracks played in {@link TvInputService}.
+ */
+public final class TvTrackInfo implements Parcelable {
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef({TYPE_AUDIO, TYPE_VIDEO, TYPE_SUBTITLE})
+    public @interface Type {}
+
+    /**
+     * The type value for audio tracks.
+     */
+    public static final int TYPE_AUDIO = 0;
+
+    /**
+     * The type value for video tracks.
+     */
+    public static final int TYPE_VIDEO = 1;
+
+    /**
+     * The type value for subtitle tracks.
+     */
+    public static final int TYPE_SUBTITLE = 2;
+
+    private final int mType;
+    private final String mId;
+    private final String mLanguage;
+    private final CharSequence mDescription;
+    @Nullable
+    private final String mEncoding;
+    private final boolean mEncrypted;
+    private final int mAudioChannelCount;
+    private final int mAudioSampleRate;
+    private final boolean mAudioDescription;
+    private final boolean mHardOfHearing;
+    private final boolean mSpokenSubtitle;
+    private final int mVideoWidth;
+    private final int mVideoHeight;
+    private final float mVideoFrameRate;
+    private final float mVideoPixelAspectRatio;
+    private final byte mVideoActiveFormatDescription;
+
+    private final Bundle mExtra;
+
+    private TvTrackInfo(int type, String id, String language, CharSequence description,
+            String encoding, boolean encrypted, int audioChannelCount, int audioSampleRate,
+            boolean audioDescription, boolean hardOfHearing, boolean spokenSubtitle, int videoWidth,
+            int videoHeight, float videoFrameRate, float videoPixelAspectRatio,
+            byte videoActiveFormatDescription, Bundle extra) {
+        mType = type;
+        mId = id;
+        mLanguage = language;
+        mDescription = description;
+        mEncoding = encoding;
+        mEncrypted = encrypted;
+        mAudioChannelCount = audioChannelCount;
+        mAudioSampleRate = audioSampleRate;
+        mAudioDescription = audioDescription;
+        mHardOfHearing = hardOfHearing;
+        mSpokenSubtitle = spokenSubtitle;
+        mVideoWidth = videoWidth;
+        mVideoHeight = videoHeight;
+        mVideoFrameRate = videoFrameRate;
+        mVideoPixelAspectRatio = videoPixelAspectRatio;
+        mVideoActiveFormatDescription = videoActiveFormatDescription;
+        mExtra = extra;
+    }
+
+    private TvTrackInfo(Parcel in) {
+        mType = in.readInt();
+        mId = in.readString();
+        mLanguage = in.readString();
+        mDescription = in.readString();
+        mEncoding = in.readString();
+        mEncrypted = in.readInt() != 0;
+        mAudioChannelCount = in.readInt();
+        mAudioSampleRate = in.readInt();
+        mAudioDescription = in.readInt() != 0;
+        mHardOfHearing = in.readInt() != 0;
+        mSpokenSubtitle = in.readInt() != 0;
+        mVideoWidth = in.readInt();
+        mVideoHeight = in.readInt();
+        mVideoFrameRate = in.readFloat();
+        mVideoPixelAspectRatio = in.readFloat();
+        mVideoActiveFormatDescription = in.readByte();
+        mExtra = in.readBundle();
+    }
+
+    /**
+     * Returns the type of the track. The type should be one of the followings:
+     * {@link #TYPE_AUDIO}, {@link #TYPE_VIDEO} and {@link #TYPE_SUBTITLE}.
+     */
+    @Type
+    public final int getType() {
+        return mType;
+    }
+
+    /**
+     * Returns the ID of the track.
+     */
+    public final String getId() {
+        return mId;
+    }
+
+    /**
+     * Returns the language information encoded by either ISO 639-1 or ISO 639-2/T. If the language
+     * is unknown or could not be determined, the corresponding value will be {@code null}.
+     */
+    public final String getLanguage() {
+        return mLanguage;
+    }
+
+    /**
+     * Returns a user readable description for the current track.
+     */
+    public final CharSequence getDescription() {
+        return mDescription;
+    }
+
+    /**
+     * Returns the codec in the form of mime type. If the encoding is unknown or could not be
+     * determined, the corresponding value will be {@code null}.
+     *
+     * <p>For example of broadcast, codec information may be referred to broadcast standard (e.g.
+     * Component Descriptor of ETSI EN 300 468). In the case that track type is subtitle, mime type
+     * could be defined in broadcast standard (e.g. "text/dvb.subtitle" or "text/dvb.teletext" in
+     * ETSI TS 102 812 V1.3.1 section 7.6).
+     */
+    @Nullable
+    public String getEncoding() {
+        return mEncoding;
+    }
+
+    /**
+     * Returns {@code true} if the track is encrypted, {@code false} otherwise. If the encryption
+     * status is unknown or could not be determined, the corresponding value will be {@code false}.
+     *
+     * <p>For example: ISO/IEC 13818-1 defines a CA descriptor that can be used to determine the
+     * encryption status of some broadcast streams.
+     */
+    public boolean isEncrypted() {
+        return mEncrypted;
+    }
+
+    /**
+     * Returns the audio channel count. Valid only for {@link #TYPE_AUDIO} tracks.
+     *
+     * @throws IllegalStateException if not called on an audio track
+     */
+    public final int getAudioChannelCount() {
+        if (mType != TYPE_AUDIO) {
+            throw new IllegalStateException("Not an audio track");
+        }
+        return mAudioChannelCount;
+    }
+
+    /**
+     * Returns the audio sample rate, in the unit of Hz. Valid only for {@link #TYPE_AUDIO} tracks.
+     *
+     * @throws IllegalStateException if not called on an audio track
+     */
+    public final int getAudioSampleRate() {
+        if (mType != TYPE_AUDIO) {
+            throw new IllegalStateException("Not an audio track");
+        }
+        return mAudioSampleRate;
+    }
+
+    /**
+     * Returns {@code true} if the track is an audio description intended for people with visual
+     * impairment, {@code false} otherwise. Valid only for {@link #TYPE_AUDIO} tracks.
+     *
+     * <p>For example of broadcast, audio description information may be referred to broadcast
+     * standard (e.g. ISO 639 Language Descriptor of ISO/IEC 13818-1, Supplementary Audio Language
+     * Descriptor, AC-3 Descriptor, Enhanced AC-3 Descriptor, AAC Descriptor of ETSI EN 300 468).
+     *
+     * @throws IllegalStateException if not called on an audio track
+     */
+    public boolean isAudioDescription() {
+        if (mType != TYPE_AUDIO) {
+            throw new IllegalStateException("Not an audio track");
+        }
+        return mAudioDescription;
+    }
+
+    /**
+     * Returns {@code true} if the track is intended for people with hearing impairment, {@code
+     * false} otherwise. Valid only for {@link #TYPE_AUDIO} and {@link #TYPE_SUBTITLE} tracks.
+     *
+     * <p>For example of broadcast, hard of hearing information may be referred to broadcast
+     * standard (e.g. ISO 639 Language Descriptor of ISO/IEC 13818-1, Supplementary Audio Language
+     * Descriptor, AC-3 Descriptor, Enhanced AC-3 Descriptor, AAC Descriptor of ETSI EN 300 468).
+     *
+     * @throws IllegalStateException if not called on an audio track or a subtitle track
+     */
+    public boolean isHardOfHearing() {
+        if (mType != TYPE_AUDIO && mType != TYPE_SUBTITLE) {
+            throw new IllegalStateException("Not an audio or a subtitle track");
+        }
+        return mHardOfHearing;
+    }
+
+    /**
+     * Returns {@code true} if the track is a spoken subtitle for people with visual impairment,
+     * {@code false} otherwise. Valid only for {@link #TYPE_AUDIO} tracks.
+     *
+     * <p>For example of broadcast, spoken subtitle information may be referred to broadcast
+     * standard (e.g. Supplementary Audio Language Descriptor of ETSI EN 300 468).
+     *
+     * @throws IllegalStateException if not called on an audio track
+     */
+    public boolean isSpokenSubtitle() {
+        if (mType != TYPE_AUDIO) {
+            throw new IllegalStateException("Not an audio track");
+        }
+        return mSpokenSubtitle;
+    }
+
+    /**
+     * Returns the width of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
+     * tracks.
+     *
+     * @throws IllegalStateException if not called on a video track
+     */
+    public final int getVideoWidth() {
+        if (mType != TYPE_VIDEO) {
+            throw new IllegalStateException("Not a video track");
+        }
+        return mVideoWidth;
+    }
+
+    /**
+     * Returns the height of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
+     * tracks.
+     *
+     * @throws IllegalStateException if not called on a video track
+     */
+    public final int getVideoHeight() {
+        if (mType != TYPE_VIDEO) {
+            throw new IllegalStateException("Not a video track");
+        }
+        return mVideoHeight;
+    }
+
+    /**
+     * Returns the frame rate of the video, in the unit of fps (frames per second). Valid only for
+     * {@link #TYPE_VIDEO} tracks.
+     *
+     * @throws IllegalStateException if not called on a video track
+     */
+    public final float getVideoFrameRate() {
+        if (mType != TYPE_VIDEO) {
+            throw new IllegalStateException("Not a video track");
+        }
+        return mVideoFrameRate;
+    }
+
+    /**
+     * Returns the pixel aspect ratio (the ratio of a pixel's width to its height) of the video.
+     * Valid only for {@link #TYPE_VIDEO} tracks.
+     *
+     * @throws IllegalStateException if not called on a video track
+     */
+    public final float getVideoPixelAspectRatio() {
+        if (mType != TYPE_VIDEO) {
+            throw new IllegalStateException("Not a video track");
+        }
+        return mVideoPixelAspectRatio;
+    }
+
+    /**
+     * Returns the Active Format Description (AFD) code of the video.
+     * Valid only for {@link #TYPE_VIDEO} tracks.
+     *
+     * <p>The complete list of values are defined in ETSI TS 101 154 V1.7.1 Annex B, ATSC A/53 Part
+     * 4 and SMPTE 2016-1-2007.
+     *
+     * @throws IllegalStateException if not called on a video track
+     */
+    public final byte getVideoActiveFormatDescription() {
+        if (mType != TYPE_VIDEO) {
+            throw new IllegalStateException("Not a video track");
+        }
+        return mVideoActiveFormatDescription;
+    }
+
+    /**
+     * Returns the extra information about the current track.
+     */
+    public final Bundle getExtra() {
+        return mExtra;
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    /**
+     * Used to package this object into a {@link Parcel}.
+     *
+     * @param dest The {@link Parcel} to be written.
+     * @param flags The flags used for parceling.
+     */
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        Preconditions.checkNotNull(dest);
+        dest.writeInt(mType);
+        dest.writeString(mId);
+        dest.writeString(mLanguage);
+        dest.writeString(mDescription != null ? mDescription.toString() : null);
+        dest.writeString(mEncoding);
+        dest.writeInt(mEncrypted ? 1 : 0);
+        dest.writeInt(mAudioChannelCount);
+        dest.writeInt(mAudioSampleRate);
+        dest.writeInt(mAudioDescription ? 1 : 0);
+        dest.writeInt(mHardOfHearing ? 1 : 0);
+        dest.writeInt(mSpokenSubtitle ? 1 : 0);
+        dest.writeInt(mVideoWidth);
+        dest.writeInt(mVideoHeight);
+        dest.writeFloat(mVideoFrameRate);
+        dest.writeFloat(mVideoPixelAspectRatio);
+        dest.writeByte(mVideoActiveFormatDescription);
+        dest.writeBundle(mExtra);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+
+        if (!(o instanceof TvTrackInfo)) {
+            return false;
+        }
+
+        TvTrackInfo obj = (TvTrackInfo) o;
+
+        if (!TextUtils.equals(mId, obj.mId) || mType != obj.mType
+                || !TextUtils.equals(mLanguage, obj.mLanguage)
+                || !TextUtils.equals(mDescription, obj.mDescription)
+                || !TextUtils.equals(mEncoding, obj.mEncoding)
+                || mEncrypted != obj.mEncrypted) {
+            return false;
+        }
+
+        switch (mType) {
+            case TYPE_AUDIO:
+                return mAudioChannelCount == obj.mAudioChannelCount
+                        && mAudioSampleRate == obj.mAudioSampleRate
+                        && mAudioDescription == obj.mAudioDescription
+                        && mHardOfHearing == obj.mHardOfHearing
+                        && mSpokenSubtitle == obj.mSpokenSubtitle;
+
+            case TYPE_VIDEO:
+                return mVideoWidth == obj.mVideoWidth
+                        && mVideoHeight == obj.mVideoHeight
+                        && mVideoFrameRate == obj.mVideoFrameRate
+                        && mVideoPixelAspectRatio == obj.mVideoPixelAspectRatio
+                        && mVideoActiveFormatDescription == obj.mVideoActiveFormatDescription;
+
+            case TYPE_SUBTITLE:
+                return mHardOfHearing == obj.mHardOfHearing;
+        }
+
+        return true;
+    }
+
+    @Override
+    public int hashCode() {
+        int result = Objects.hash(mId, mType, mLanguage, mDescription);
+
+        if (mType == TYPE_AUDIO) {
+            result = Objects.hash(result, mAudioChannelCount, mAudioSampleRate);
+        } else if (mType == TYPE_VIDEO) {
+            result = Objects.hash(result, mVideoWidth, mVideoHeight, mVideoFrameRate,
+                    mVideoPixelAspectRatio);
+        }
+
+        return result;
+    }
+
+    public static final @android.annotation.NonNull Parcelable.Creator<TvTrackInfo> CREATOR =
+            new Parcelable.Creator<TvTrackInfo>() {
+                @Override
+                @NonNull
+                public TvTrackInfo createFromParcel(Parcel in) {
+                    return new TvTrackInfo(in);
+                }
+
+                @Override
+                @NonNull
+                public TvTrackInfo[] newArray(int size) {
+                    return new TvTrackInfo[size];
+                }
+            };
+
+    /**
+     * A builder class for creating {@link TvTrackInfo} objects.
+     */
+    public static final class Builder {
+        private final String mId;
+        private final int mType;
+        private String mLanguage;
+        private CharSequence mDescription;
+        private String mEncoding;
+        private boolean mEncrypted;
+        private int mAudioChannelCount;
+        private int mAudioSampleRate;
+        private boolean mAudioDescription;
+        private boolean mHardOfHearing;
+        private boolean mSpokenSubtitle;
+        private int mVideoWidth;
+        private int mVideoHeight;
+        private float mVideoFrameRate;
+        private float mVideoPixelAspectRatio = 1.0f;
+        private byte mVideoActiveFormatDescription;
+        private Bundle mExtra;
+
+        /**
+         * Create a {@link Builder}. Any field that should be included in the {@link TvTrackInfo}
+         * must be added.
+         *
+         * @param type The type of the track.
+         * @param id The ID of the track that uniquely identifies the current track among all the
+         *            other tracks in the same TV program.
+         * @throws IllegalArgumentException if the type is not any of {@link #TYPE_AUDIO},
+         *                                  {@link #TYPE_VIDEO} and {@link #TYPE_SUBTITLE}
+         */
+        public Builder(@Type int type, @NonNull String id) {
+            if (type != TYPE_AUDIO
+                    && type != TYPE_VIDEO
+                    && type != TYPE_SUBTITLE) {
+                throw new IllegalArgumentException("Unknown type: " + type);
+            }
+            Preconditions.checkNotNull(id);
+            mType = type;
+            mId = id;
+        }
+
+        /**
+         * Sets the language information of the current track.
+         *
+         * @param language The language string encoded by either ISO 639-1 or ISO 639-2/T.
+         */
+        @NonNull
+        public  Builder setLanguage(@NonNull String language) {
+            Preconditions.checkNotNull(language);
+            mLanguage = language;
+            return this;
+        }
+
+        /**
+         * Sets a user readable description for the current track.
+         *
+         * @param description The user readable description.
+         */
+        @NonNull
+        public  Builder setDescription(@NonNull CharSequence description) {
+            Preconditions.checkNotNull(description);
+            mDescription = description;
+            return this;
+        }
+
+        /**
+         * Sets the encoding of the track.
+         *
+         * <p>For example of broadcast, codec information may be referred to broadcast standard
+         * (e.g. Component Descriptor of ETSI EN 300 468). In the case that track type is subtitle,
+         * mime type could be defined in broadcast standard (e.g. "text/dvb.subtitle" or
+         * "text/dvb.teletext" in ETSI TS 102 812 V1.3.1 section 7.6).
+         *
+         * @param encoding The encoding of the track in the form of mime type.
+         */
+        @NonNull
+        public Builder setEncoding(@Nullable String encoding) {
+            mEncoding = encoding;
+            return this;
+        }
+
+        /**
+         * Sets the encryption status of the track.
+         *
+         * <p>For example: ISO/IEC 13818-1 defines a CA descriptor that can be used to determine the
+         * encryption status of some broadcast streams.
+         *
+         * @param encrypted The encryption status of the track.
+         */
+        @NonNull
+        public Builder setEncrypted(boolean encrypted) {
+            mEncrypted = encrypted;
+            return this;
+        }
+
+        /**
+         * Sets the audio channel count. Valid only for {@link #TYPE_AUDIO} tracks.
+         *
+         * @param audioChannelCount The audio channel count.
+         * @throws IllegalStateException if not called on an audio track
+         */
+        @NonNull
+        public Builder setAudioChannelCount(int audioChannelCount) {
+            if (mType != TYPE_AUDIO) {
+                throw new IllegalStateException("Not an audio track");
+            }
+            mAudioChannelCount = audioChannelCount;
+            return this;
+        }
+
+        /**
+         * Sets the audio sample rate, in the unit of Hz. Valid only for {@link #TYPE_AUDIO}
+         * tracks.
+         *
+         * @param audioSampleRate The audio sample rate.
+         * @throws IllegalStateException if not called on an audio track
+         */
+        @NonNull
+        public Builder setAudioSampleRate(int audioSampleRate) {
+            if (mType != TYPE_AUDIO) {
+                throw new IllegalStateException("Not an audio track");
+            }
+            mAudioSampleRate = audioSampleRate;
+            return this;
+        }
+
+        /**
+         * Sets the audio description attribute of the audio. Valid only for {@link #TYPE_AUDIO}
+         * tracks.
+         *
+         * <p>For example of broadcast, audio description information may be referred to broadcast
+         * standard (e.g. ISO 639 Language Descriptor of ISO/IEC 13818-1, Supplementary Audio
+         * Language Descriptor, AC-3 Descriptor, Enhanced AC-3 Descriptor, AAC Descriptor of ETSI EN
+         * 300 468).
+         *
+         * @param audioDescription The audio description attribute of the audio.
+         * @throws IllegalStateException if not called on an audio track
+         */
+        @NonNull
+        public Builder setAudioDescription(boolean audioDescription) {
+            if (mType != TYPE_AUDIO) {
+                throw new IllegalStateException("Not an audio track");
+            }
+            mAudioDescription = audioDescription;
+            return this;
+        }
+
+        /**
+         * Sets the hard of hearing attribute of the track. Valid only for {@link #TYPE_AUDIO} and
+         * {@link #TYPE_SUBTITLE} tracks.
+         *
+         * <p>For example of broadcast, hard of hearing information may be referred to broadcast
+         * standard (e.g. ISO 639 Language Descriptor of ISO/IEC 13818-1, Supplementary Audio
+         * Language Descriptor, AC-3 Descriptor, Enhanced AC-3 Descriptor, AAC Descriptor of ETSI EN
+         * 300 468).
+         *
+         * @param hardOfHearing The hard of hearing attribute of the track.
+         * @throws IllegalStateException if not called on an audio track or a subtitle track
+         */
+        @NonNull
+        public Builder setHardOfHearing(boolean hardOfHearing) {
+            if (mType != TYPE_AUDIO && mType != TYPE_SUBTITLE) {
+                throw new IllegalStateException("Not an audio track or a subtitle track");
+            }
+            mHardOfHearing = hardOfHearing;
+            return this;
+        }
+
+        /**
+         * Sets the spoken subtitle attribute of the audio. Valid only for {@link #TYPE_AUDIO}
+         * tracks.
+         *
+         * <p>For example of broadcast, spoken subtitle information may be referred to broadcast
+         * standard (e.g. Supplementary Audio Language Descriptor of ETSI EN 300 468).
+         *
+         * @param spokenSubtitle The spoken subtitle attribute of the audio.
+         * @throws IllegalStateException if not called on an audio track
+         */
+        @NonNull
+        public Builder setSpokenSubtitle(boolean spokenSubtitle) {
+            if (mType != TYPE_AUDIO) {
+                throw new IllegalStateException("Not an audio track");
+            }
+            mSpokenSubtitle = spokenSubtitle;
+            return this;
+        }
+
+        /**
+         * Sets the width of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
+         * tracks.
+         *
+         * @param videoWidth The width of the video.
+         * @throws IllegalStateException if not called on a video track
+         */
+        @NonNull
+        public Builder setVideoWidth(int videoWidth) {
+            if (mType != TYPE_VIDEO) {
+                throw new IllegalStateException("Not a video track");
+            }
+            mVideoWidth = videoWidth;
+            return this;
+        }
+
+        /**
+         * Sets the height of the video, in the unit of pixels. Valid only for {@link #TYPE_VIDEO}
+         * tracks.
+         *
+         * @param videoHeight The height of the video.
+         * @throws IllegalStateException if not called on a video track
+         */
+        @NonNull
+        public Builder setVideoHeight(int videoHeight) {
+            if (mType != TYPE_VIDEO) {
+                throw new IllegalStateException("Not a video track");
+            }
+            mVideoHeight = videoHeight;
+            return this;
+        }
+
+        /**
+         * Sets the frame rate of the video, in the unit fps (frames per rate). Valid only for
+         * {@link #TYPE_VIDEO} tracks.
+         *
+         * @param videoFrameRate The frame rate of the video.
+         * @throws IllegalStateException if not called on a video track
+         */
+        @NonNull
+        public Builder setVideoFrameRate(float videoFrameRate) {
+            if (mType != TYPE_VIDEO) {
+                throw new IllegalStateException("Not a video track");
+            }
+            mVideoFrameRate = videoFrameRate;
+            return this;
+        }
+
+        /**
+         * Sets the pixel aspect ratio (the ratio of a pixel's width to its height) of the video.
+         * Valid only for {@link #TYPE_VIDEO} tracks.
+         *
+         * <p>This is needed for applications to be able to scale the video properly for some video
+         * formats such as 720x576 4:3 and 720x576 16:9 where pixels are not square. By default,
+         * applications assume the value of 1.0 (square pixels), so it is not necessary to set the
+         * pixel aspect ratio for most video formats.
+         *
+         * @param videoPixelAspectRatio The pixel aspect ratio of the video.
+         * @throws IllegalStateException if not called on a video track
+         */
+        @NonNull
+        public Builder setVideoPixelAspectRatio(float videoPixelAspectRatio) {
+            if (mType != TYPE_VIDEO) {
+                throw new IllegalStateException("Not a video track");
+            }
+            mVideoPixelAspectRatio = videoPixelAspectRatio;
+            return this;
+        }
+
+        /**
+         * Sets the Active Format Description (AFD) code of the video.
+         * Valid only for {@link #TYPE_VIDEO} tracks.
+         *
+         * <p>This is needed for applications to be able to scale the video properly based on the
+         * information about where in the coded picture the active video is.
+         * The complete list of values are defined in ETSI TS 101 154 V1.7.1 Annex B, ATSC A/53 Part
+         * 4 and SMPTE 2016-1-2007.
+         *
+         * @param videoActiveFormatDescription The AFD code of the video.
+         * @throws IllegalStateException if not called on a video track
+         */
+        @NonNull
+        public Builder setVideoActiveFormatDescription(byte videoActiveFormatDescription) {
+            if (mType != TYPE_VIDEO) {
+                throw new IllegalStateException("Not a video track");
+            }
+            mVideoActiveFormatDescription = videoActiveFormatDescription;
+            return this;
+        }
+
+        /**
+         * Sets the extra information about the current track.
+         *
+         * @param extra The extra information.
+         */
+        @NonNull
+        public Builder setExtra(@NonNull Bundle extra) {
+            Preconditions.checkNotNull(extra);
+            mExtra = new Bundle(extra);
+            return this;
+        }
+
+        /**
+         * Creates a {@link TvTrackInfo} instance with the specified fields.
+         *
+         * @return The new {@link TvTrackInfo} instance
+         */
+        @NonNull
+        public TvTrackInfo build() {
+            return new TvTrackInfo(mType, mId, mLanguage, mDescription, mEncoding, mEncrypted,
+                    mAudioChannelCount, mAudioSampleRate, mAudioDescription, mHardOfHearing,
+                    mSpokenSubtitle, mVideoWidth, mVideoHeight, mVideoFrameRate,
+                    mVideoPixelAspectRatio, mVideoActiveFormatDescription, mExtra);
+        }
+    }
+}
diff --git a/android/media/tv/TvView.java b/android/media/tv/TvView.java
new file mode 100644
index 0000000..6b329f8
--- /dev/null
+++ b/android/media/tv/TvView.java
@@ -0,0 +1,1330 @@
+/*
+ * Copyright (C) 2014 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.tv;
+
+import android.annotation.FloatRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.graphics.Canvas;
+import android.graphics.PorterDuff;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.graphics.Region;
+import android.media.PlaybackParams;
+import android.media.tv.TvInputManager.Session;
+import android.media.tv.TvInputManager.Session.FinishedInputEventCallback;
+import android.media.tv.TvInputManager.SessionCallback;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Pair;
+import android.view.InputEvent;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.Surface;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewRootImpl;
+
+import java.lang.ref.WeakReference;
+import java.util.ArrayDeque;
+import java.util.List;
+import java.util.Queue;
+
+/**
+ * Displays TV contents. The TvView class provides a high level interface for applications to show
+ * TV programs from various TV sources that implement {@link TvInputService}. (Note that the list of
+ * TV inputs available on the system can be obtained by calling
+ * {@link TvInputManager#getTvInputList() TvInputManager.getTvInputList()}.)
+ *
+ * <p>Once the application supplies the URI for a specific TV channel to {@link #tune}
+ * method, it takes care of underlying service binding (and unbinding if the current TvView is
+ * already bound to a service) and automatically allocates/deallocates resources needed. In addition
+ * to a few essential methods to control how the contents are presented, it also provides a way to
+ * dispatch input events to the connected TvInputService in order to enable custom key actions for
+ * the TV input.
+ */
+public class TvView extends ViewGroup {
+    private static final String TAG = "TvView";
+    private static final boolean DEBUG = false;
+
+    private static final int ZORDER_MEDIA = 0;
+    private static final int ZORDER_MEDIA_OVERLAY = 1;
+    private static final int ZORDER_ON_TOP = 2;
+
+    private static final WeakReference<TvView> NULL_TV_VIEW = new WeakReference<>(null);
+
+    private static final Object sMainTvViewLock = new Object();
+    private static WeakReference<TvView> sMainTvView = NULL_TV_VIEW;
+
+    private final Handler mHandler = new Handler();
+    private Session mSession;
+    private SurfaceView mSurfaceView;
+    private Surface mSurface;
+    private boolean mOverlayViewCreated;
+    private Rect mOverlayViewFrame;
+    private final TvInputManager mTvInputManager;
+    private MySessionCallback mSessionCallback;
+    private TvInputCallback mCallback;
+    private OnUnhandledInputEventListener mOnUnhandledInputEventListener;
+    private Float mStreamVolume;
+    private Boolean mCaptionEnabled;
+    private final Queue<Pair<String, Bundle>> mPendingAppPrivateCommands = new ArrayDeque<>();
+
+    private boolean mSurfaceChanged;
+    private int mSurfaceFormat;
+    private int mSurfaceWidth;
+    private int mSurfaceHeight;
+    private final AttributeSet mAttrs;
+    private final int mDefStyleAttr;
+    private int mWindowZOrder;
+    private boolean mUseRequestedSurfaceLayout;
+    private int mSurfaceViewLeft;
+    private int mSurfaceViewRight;
+    private int mSurfaceViewTop;
+    private int mSurfaceViewBottom;
+    private TimeShiftPositionCallback mTimeShiftPositionCallback;
+
+    private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() {
+        @Override
+        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+            if (DEBUG) {
+                Log.d(TAG, "surfaceChanged(holder=" + holder + ", format=" + format + ", width="
+                    + width + ", height=" + height + ")");
+            }
+            mSurfaceFormat = format;
+            mSurfaceWidth = width;
+            mSurfaceHeight = height;
+            mSurfaceChanged = true;
+            dispatchSurfaceChanged(mSurfaceFormat, mSurfaceWidth, mSurfaceHeight);
+        }
+
+        @Override
+        public void surfaceCreated(SurfaceHolder holder) {
+            mSurface = holder.getSurface();
+            setSessionSurface(mSurface);
+        }
+
+        @Override
+        public void surfaceDestroyed(SurfaceHolder holder) {
+            mSurface = null;
+            mSurfaceChanged = false;
+            setSessionSurface(null);
+        }
+    };
+
+    private final FinishedInputEventCallback mFinishedInputEventCallback =
+            new FinishedInputEventCallback() {
+        @Override
+        public void onFinishedInputEvent(Object token, boolean handled) {
+            if (DEBUG) {
+                Log.d(TAG, "onFinishedInputEvent(token=" + token + ", handled=" + handled + ")");
+            }
+            if (handled) {
+                return;
+            }
+            // TODO: Re-order unhandled events.
+            InputEvent event = (InputEvent) token;
+            if (dispatchUnhandledInputEvent(event)) {
+                return;
+            }
+            ViewRootImpl viewRootImpl = getViewRootImpl();
+            if (viewRootImpl != null) {
+                viewRootImpl.dispatchUnhandledInputEvent(event);
+            }
+        }
+    };
+
+    public TvView(Context context) {
+        this(context, null, 0);
+    }
+
+    public TvView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public TvView(Context context, AttributeSet attrs, int defStyleAttr) {
+        super(context, attrs, defStyleAttr);
+        mAttrs = attrs;
+        mDefStyleAttr = defStyleAttr;
+        resetSurfaceView();
+        mTvInputManager = (TvInputManager) getContext().getSystemService(Context.TV_INPUT_SERVICE);
+    }
+
+    /**
+     * Sets the callback to be invoked when an event is dispatched to this TvView.
+     *
+     * @param callback The callback to receive events. A value of {@code null} removes the existing
+     *            callback.
+     */
+    public void setCallback(@Nullable TvInputCallback callback) {
+        mCallback = callback;
+    }
+
+    /**
+     * Sets this as the main {@link TvView}.
+     *
+     * <p>The main {@link TvView} is a {@link TvView} whose corresponding TV input determines the
+     * HDMI-CEC active source device. For an HDMI port input, one of source devices that is
+     * connected to that HDMI port becomes the active source. For an HDMI-CEC logical device input,
+     * the corresponding HDMI-CEC logical device becomes the active source. For any non-HDMI input
+     * (including the tuner, composite, S-Video, etc.), the internal device (= TV itself) becomes
+     * the active source.
+     *
+     * <p>First tuned {@link TvView} becomes main automatically, and keeps to be main until either
+     * {@link #reset} is called for the main {@link TvView} or {@code setMain()} is called for other
+     * {@link TvView}.
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.CHANGE_HDMI_CEC_ACTIVE_SOURCE)
+    public void setMain() {
+        synchronized (sMainTvViewLock) {
+            sMainTvView = new WeakReference<>(this);
+            if (hasWindowFocus() && mSession != null) {
+                mSession.setMain();
+            }
+        }
+    }
+
+    /**
+     * Controls whether the TvView's surface is placed on top of another regular surface view in the
+     * window (but still behind the window itself).
+     * This is typically used to place overlays on top of an underlying TvView.
+     *
+     * <p>Note that this must be set before the TvView's containing window is attached to the
+     * window manager.
+     *
+     * <p>Calling this overrides any previous call to {@link #setZOrderOnTop}.
+     *
+     * @param isMediaOverlay {@code true} to be on top of another regular surface, {@code false}
+     *            otherwise.
+     */
+    public void setZOrderMediaOverlay(boolean isMediaOverlay) {
+        if (isMediaOverlay) {
+            mWindowZOrder = ZORDER_MEDIA_OVERLAY;
+            removeSessionOverlayView();
+        } else {
+            mWindowZOrder = ZORDER_MEDIA;
+            createSessionOverlayView();
+        }
+        if (mSurfaceView != null) {
+            // ZOrderOnTop(false) removes WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM
+            // from WindowLayoutParam as well as changes window type.
+            mSurfaceView.setZOrderOnTop(false);
+            mSurfaceView.setZOrderMediaOverlay(isMediaOverlay);
+        }
+    }
+
+    /**
+     * Controls whether the TvView's surface is placed on top of its window. Normally it is placed
+     * behind the window, to allow it to (for the most part) appear to composite with the views in
+     * the hierarchy.  By setting this, you cause it to be placed above the window. This means that
+     * none of the contents of the window this TvView is in will be visible on top of its surface.
+     *
+     * <p>Note that this must be set before the TvView's containing window is attached to the window
+     * manager.
+     *
+     * <p>Calling this overrides any previous call to {@link #setZOrderMediaOverlay}.
+     *
+     * @param onTop {@code true} to be on top of its window, {@code false} otherwise.
+     */
+    public void setZOrderOnTop(boolean onTop) {
+        if (onTop) {
+            mWindowZOrder = ZORDER_ON_TOP;
+            removeSessionOverlayView();
+        } else {
+            mWindowZOrder = ZORDER_MEDIA;
+            createSessionOverlayView();
+        }
+        if (mSurfaceView != null) {
+            mSurfaceView.setZOrderMediaOverlay(false);
+            mSurfaceView.setZOrderOnTop(onTop);
+        }
+     }
+
+    /**
+     * Sets the relative stream volume of this TvView.
+     *
+     * <p>This method is primarily used to handle audio focus changes or mute a specific TvView when
+     * multiple views are displayed. If the method has not yet been called, the TvView assumes the
+     * default value of {@code 1.0f}.
+     *
+     * @param volume A volume value between {@code 0.0f} to {@code 1.0f}.
+     */
+    public void setStreamVolume(@FloatRange(from = 0.0, to = 1.0) float volume) {
+        if (DEBUG) Log.d(TAG, "setStreamVolume(" + volume + ")");
+        mStreamVolume = volume;
+        if (mSession == null) {
+            // Volume will be set once the connection has been made.
+            return;
+        }
+        mSession.setStreamVolume(volume);
+    }
+
+    /**
+     * Tunes to a given channel.
+     *
+     * @param inputId The ID of the TV input for the given channel.
+     * @param channelUri The URI of a channel.
+     */
+    public void tune(@NonNull String inputId, Uri channelUri) {
+        tune(inputId, channelUri, null);
+    }
+
+    /**
+     * Tunes to a given channel. This can be used to provide domain-specific features that are only
+     * known between certain clients and their TV inputs.
+     *
+     * @param inputId The ID of TV input for the given channel.
+     * @param channelUri The URI of a channel.
+     * @param params Domain-specific data for this tune request. Keys <em>must</em> be a scoped
+     *            name, i.e. prefixed with a package name you own, so that different developers will
+     *            not create conflicting keys.
+     */
+    public void tune(String inputId, Uri channelUri, Bundle params) {
+        if (DEBUG) Log.d(TAG, "tune(" + channelUri + ")");
+        if (TextUtils.isEmpty(inputId)) {
+            throw new IllegalArgumentException("inputId cannot be null or an empty string");
+        }
+        synchronized (sMainTvViewLock) {
+            if (sMainTvView.get() == null) {
+                sMainTvView = new WeakReference<>(this);
+            }
+        }
+        if (mSessionCallback != null && TextUtils.equals(mSessionCallback.mInputId, inputId)) {
+            if (mSession != null) {
+                mSession.tune(channelUri, params);
+            } else {
+                // createSession() was called but the actual session for the given inputId has not
+                // yet been created. Just replace the existing tuning params in the callback with
+                // the new ones and tune later in onSessionCreated(). It is not necessary to create
+                // a new callback because this tuning request was made on the same inputId.
+                mSessionCallback.mChannelUri = channelUri;
+                mSessionCallback.mTuneParams = params;
+            }
+        } else {
+            resetInternal();
+            // In case createSession() is called multiple times across different inputId's before
+            // any session is created (e.g. when quickly tuning to a channel from input A and then
+            // to another channel from input B), only the callback for the last createSession()
+            // should be invoked. (The previous callbacks are simply ignored.) To do that, we create
+            // a new callback each time and keep mSessionCallback pointing to the last one. If
+            // MySessionCallback.this is different from mSessionCallback, we know that this callback
+            // is obsolete and should ignore it.
+            mSessionCallback = new MySessionCallback(inputId, channelUri, params);
+            if (mTvInputManager != null) {
+                mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
+            }
+        }
+    }
+
+    /**
+     * Resets this TvView.
+     *
+     * <p>This method is primarily used to un-tune the current TvView.
+     */
+    public void reset() {
+        if (DEBUG) Log.d(TAG, "reset()");
+        synchronized (sMainTvViewLock) {
+            if (this == sMainTvView.get()) {
+                sMainTvView = NULL_TV_VIEW;
+            }
+        }
+        resetInternal();
+    }
+
+    private void resetInternal() {
+        mSessionCallback = null;
+        mPendingAppPrivateCommands.clear();
+        if (mSession != null) {
+            setSessionSurface(null);
+            removeSessionOverlayView();
+            mUseRequestedSurfaceLayout = false;
+            mSession.release();
+            mSession = null;
+            resetSurfaceView();
+        }
+    }
+
+    /**
+     * Requests to unblock TV content according to the given rating.
+     *
+     * <p>This notifies TV input that blocked content is now OK to play.
+     *
+     * @param unblockedRating A TvContentRating to unblock.
+     * @see TvInputService.Session#notifyContentBlocked(TvContentRating)
+     * @removed
+     */
+    public void requestUnblockContent(TvContentRating unblockedRating) {
+        unblockContent(unblockedRating);
+    }
+
+    /**
+     * Requests to unblock TV content according to the given rating.
+     *
+     * <p>This notifies TV input that blocked content is now OK to play.
+     *
+     * @param unblockedRating A TvContentRating to unblock.
+     * @see TvInputService.Session#notifyContentBlocked(TvContentRating)
+     * @hide
+     */
+    @SystemApi
+    @RequiresPermission(android.Manifest.permission.MODIFY_PARENTAL_CONTROLS)
+    public void unblockContent(TvContentRating unblockedRating) {
+        if (mSession != null) {
+            mSession.unblockContent(unblockedRating);
+        }
+    }
+
+    /**
+     * Enables or disables the caption in this TvView.
+     *
+     * <p>Note that this method does not take any effect unless the current TvView is tuned.
+     *
+     * @param enabled {@code true} to enable, {@code false} to disable.
+     */
+    public void setCaptionEnabled(boolean enabled) {
+        if (DEBUG) Log.d(TAG, "setCaptionEnabled(" + enabled + ")");
+        mCaptionEnabled = enabled;
+        if (mSession != null) {
+            mSession.setCaptionEnabled(enabled);
+        }
+    }
+
+    /**
+     * Selects a track.
+     *
+     * @param type The type of the track to select. The type can be {@link TvTrackInfo#TYPE_AUDIO},
+     *            {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}.
+     * @param trackId The ID of the track to select. {@code null} means to unselect the current
+     *            track for a given type.
+     * @see #getTracks
+     * @see #getSelectedTrack
+     */
+    public void selectTrack(int type, String trackId) {
+        if (mSession != null) {
+            mSession.selectTrack(type, trackId);
+        }
+    }
+
+    /**
+     * Returns the list of tracks. Returns {@code null} if the information is not available.
+     *
+     * @param type The type of the tracks. The type can be {@link TvTrackInfo#TYPE_AUDIO},
+     *            {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}.
+     * @see #selectTrack
+     * @see #getSelectedTrack
+     */
+    public List<TvTrackInfo> getTracks(int type) {
+        if (mSession == null) {
+            return null;
+        }
+        return mSession.getTracks(type);
+    }
+
+    /**
+     * Returns the ID of the selected track for a given type. Returns {@code null} if the
+     * information is not available or the track is not selected.
+     *
+     * @param type The type of the selected tracks. The type can be {@link TvTrackInfo#TYPE_AUDIO},
+     *            {@link TvTrackInfo#TYPE_VIDEO} or {@link TvTrackInfo#TYPE_SUBTITLE}.
+     * @see #selectTrack
+     * @see #getTracks
+     */
+    public String getSelectedTrack(int type) {
+        if (mSession == null) {
+            return null;
+        }
+        return mSession.getSelectedTrack(type);
+    }
+
+    /**
+     * Plays a given recorded TV program.
+     *
+     * @param inputId The ID of the TV input that created the given recorded program.
+     * @param recordedProgramUri The URI of a recorded program.
+     */
+    public void timeShiftPlay(String inputId, Uri recordedProgramUri) {
+        if (DEBUG) Log.d(TAG, "timeShiftPlay(" + recordedProgramUri + ")");
+        if (TextUtils.isEmpty(inputId)) {
+            throw new IllegalArgumentException("inputId cannot be null or an empty string");
+        }
+        synchronized (sMainTvViewLock) {
+            if (sMainTvView.get() == null) {
+                sMainTvView = new WeakReference<>(this);
+            }
+        }
+        if (mSessionCallback != null && TextUtils.equals(mSessionCallback.mInputId, inputId)) {
+            if (mSession != null) {
+                mSession.timeShiftPlay(recordedProgramUri);
+            } else {
+                mSessionCallback.mRecordedProgramUri = recordedProgramUri;
+            }
+        } else {
+            resetInternal();
+            mSessionCallback = new MySessionCallback(inputId, recordedProgramUri);
+            if (mTvInputManager != null) {
+                mTvInputManager.createSession(inputId, mSessionCallback, mHandler);
+            }
+        }
+    }
+
+    /**
+     * Pauses playback. No-op if it is already paused. Call {@link #timeShiftResume} to resume.
+     */
+    public void timeShiftPause() {
+        if (mSession != null) {
+            mSession.timeShiftPause();
+        }
+    }
+
+    /**
+     * Resumes playback. No-op if it is already resumed. Call {@link #timeShiftPause} to pause.
+     */
+    public void timeShiftResume() {
+        if (mSession != null) {
+            mSession.timeShiftResume();
+        }
+    }
+
+    /**
+     * Seeks to a specified time position. {@code timeMs} must be equal to or greater than the start
+     * position returned by {@link TimeShiftPositionCallback#onTimeShiftStartPositionChanged} and
+     * equal to or less than the current time.
+     *
+     * @param timeMs The time position to seek to, in milliseconds since the epoch.
+     */
+    public void timeShiftSeekTo(long timeMs) {
+        if (mSession != null) {
+            mSession.timeShiftSeekTo(timeMs);
+        }
+    }
+
+    /**
+     * Sets playback rate using {@link android.media.PlaybackParams}.
+     *
+     * @param params The playback params.
+     */
+    public void timeShiftSetPlaybackParams(@NonNull PlaybackParams params) {
+        if (mSession != null) {
+            mSession.timeShiftSetPlaybackParams(params);
+        }
+    }
+
+    /**
+     * Sets the callback to be invoked when the time shift position is changed.
+     *
+     * @param callback The callback to receive time shift position changes. A value of {@code null}
+     *            removes the existing callback.
+     */
+    public void setTimeShiftPositionCallback(@Nullable TimeShiftPositionCallback callback) {
+        mTimeShiftPositionCallback = callback;
+        ensurePositionTracking();
+    }
+
+    private void ensurePositionTracking() {
+        if (mSession == null) {
+            return;
+        }
+        mSession.timeShiftEnablePositionTracking(mTimeShiftPositionCallback != null);
+    }
+
+    /**
+     * Sends a private command to the underlying TV input. This can be used to provide
+     * domain-specific features that are only known between certain clients and their TV inputs.
+     *
+     * @param action The name of the private command to send. This <em>must</em> be a scoped name,
+     *            i.e. prefixed with a package name you own, so that different developers will not
+     *            create conflicting commands.
+     * @param data An optional bundle to send with the command.
+     */
+    public void sendAppPrivateCommand(@NonNull String action, Bundle data) {
+        if (TextUtils.isEmpty(action)) {
+            throw new IllegalArgumentException("action cannot be null or an empty string");
+        }
+        if (mSession != null) {
+            mSession.sendAppPrivateCommand(action, data);
+        } else {
+            Log.w(TAG, "sendAppPrivateCommand - session not yet created (action \"" + action
+                    + "\" pending)");
+            mPendingAppPrivateCommands.add(Pair.create(action, data));
+        }
+    }
+
+    /**
+     * Dispatches an unhandled input event to the next receiver.
+     *
+     * <p>Except system keys, TvView always consumes input events in the normal flow. This is called
+     * asynchronously from where the event is dispatched. It gives the host application a chance to
+     * dispatch the unhandled input events.
+     *
+     * @param event The input event.
+     * @return {@code true} if the event was handled by the view, {@code false} otherwise.
+     */
+    public boolean dispatchUnhandledInputEvent(InputEvent event) {
+        if (mOnUnhandledInputEventListener != null) {
+            if (mOnUnhandledInputEventListener.onUnhandledInputEvent(event)) {
+                return true;
+            }
+        }
+        return onUnhandledInputEvent(event);
+    }
+
+    /**
+     * Called when an unhandled input event also has not been handled by the user provided
+     * callback. This is the last chance to handle the unhandled input event in the TvView.
+     *
+     * @param event The input event.
+     * @return If you handled the event, return {@code true}. If you want to allow the event to be
+     *         handled by the next receiver, return {@code false}.
+     */
+    public boolean onUnhandledInputEvent(InputEvent event) {
+        return false;
+    }
+
+    /**
+     * Registers a callback to be invoked when an input event is not handled by the bound TV input.
+     *
+     * @param listener The callback to be invoked when the unhandled input event is received.
+     */
+    public void setOnUnhandledInputEventListener(OnUnhandledInputEventListener listener) {
+        mOnUnhandledInputEventListener = listener;
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        if (super.dispatchKeyEvent(event)) {
+            return true;
+        }
+        if (DEBUG) Log.d(TAG, "dispatchKeyEvent(" + event + ")");
+        if (mSession == null) {
+            return false;
+        }
+        InputEvent copiedEvent = event.copy();
+        int ret = mSession.dispatchInputEvent(copiedEvent, copiedEvent, mFinishedInputEventCallback,
+                mHandler);
+        return ret != Session.DISPATCH_NOT_HANDLED;
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent event) {
+        if (super.dispatchTouchEvent(event)) {
+            return true;
+        }
+        if (DEBUG) Log.d(TAG, "dispatchTouchEvent(" + event + ")");
+        if (mSession == null) {
+            return false;
+        }
+        InputEvent copiedEvent = event.copy();
+        int ret = mSession.dispatchInputEvent(copiedEvent, copiedEvent, mFinishedInputEventCallback,
+                mHandler);
+        return ret != Session.DISPATCH_NOT_HANDLED;
+    }
+
+    @Override
+    public boolean dispatchTrackballEvent(MotionEvent event) {
+        if (super.dispatchTrackballEvent(event)) {
+            return true;
+        }
+        if (DEBUG) Log.d(TAG, "dispatchTrackballEvent(" + event + ")");
+        if (mSession == null) {
+            return false;
+        }
+        InputEvent copiedEvent = event.copy();
+        int ret = mSession.dispatchInputEvent(copiedEvent, copiedEvent, mFinishedInputEventCallback,
+                mHandler);
+        return ret != Session.DISPATCH_NOT_HANDLED;
+    }
+
+    @Override
+    public boolean dispatchGenericMotionEvent(MotionEvent event) {
+        if (super.dispatchGenericMotionEvent(event)) {
+            return true;
+        }
+        if (DEBUG) Log.d(TAG, "dispatchGenericMotionEvent(" + event + ")");
+        if (mSession == null) {
+            return false;
+        }
+        InputEvent copiedEvent = event.copy();
+        int ret = mSession.dispatchInputEvent(copiedEvent, copiedEvent, mFinishedInputEventCallback,
+                mHandler);
+        return ret != Session.DISPATCH_NOT_HANDLED;
+    }
+
+    @Override
+    public void dispatchWindowFocusChanged(boolean hasFocus) {
+        super.dispatchWindowFocusChanged(hasFocus);
+        // Other app may have shown its own main TvView.
+        // Set main again to regain main session.
+        synchronized (sMainTvViewLock) {
+            if (hasFocus && this == sMainTvView.get() && mSession != null
+                    && checkChangeHdmiCecActiveSourcePermission()) {
+                mSession.setMain();
+            }
+        }
+    }
+
+    @Override
+    protected void onAttachedToWindow() {
+        super.onAttachedToWindow();
+        createSessionOverlayView();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        removeSessionOverlayView();
+        super.onDetachedFromWindow();
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+        if (DEBUG) {
+            Log.d(TAG, "onLayout (left=" + left + ", top=" + top + ", right=" + right
+                    + ", bottom=" + bottom + ",)");
+        }
+        if (mUseRequestedSurfaceLayout) {
+            mSurfaceView.layout(mSurfaceViewLeft, mSurfaceViewTop, mSurfaceViewRight,
+                    mSurfaceViewBottom);
+        } else {
+            mSurfaceView.layout(0, 0, right - left, bottom - top);
+        }
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        mSurfaceView.measure(widthMeasureSpec, heightMeasureSpec);
+        int width = mSurfaceView.getMeasuredWidth();
+        int height = mSurfaceView.getMeasuredHeight();
+        int childState = mSurfaceView.getMeasuredState();
+        setMeasuredDimension(resolveSizeAndState(width, widthMeasureSpec, childState),
+                resolveSizeAndState(height, heightMeasureSpec,
+                        childState << MEASURED_HEIGHT_STATE_SHIFT));
+    }
+
+    @Override
+    public boolean gatherTransparentRegion(Region region) {
+        if (mWindowZOrder != ZORDER_ON_TOP) {
+            if (region != null) {
+                int width = getWidth();
+                int height = getHeight();
+                if (width > 0 && height > 0) {
+                    int location[] = new int[2];
+                    getLocationInWindow(location);
+                    int left = location[0];
+                    int top = location[1];
+                    region.op(left, top, left + width, top + height, Region.Op.UNION);
+                }
+            }
+        }
+        return super.gatherTransparentRegion(region);
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        if (mWindowZOrder != ZORDER_ON_TOP) {
+            // Punch a hole so that the underlying overlay view and surface can be shown.
+            canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+        }
+        super.draw(canvas);
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        if (mWindowZOrder != ZORDER_ON_TOP) {
+            // Punch a hole so that the underlying overlay view and surface can be shown.
+            canvas.drawColor(0, PorterDuff.Mode.CLEAR);
+        }
+        super.dispatchDraw(canvas);
+    }
+
+    @Override
+    protected void onVisibilityChanged(View changedView, int visibility) {
+        super.onVisibilityChanged(changedView, visibility);
+        mSurfaceView.setVisibility(visibility);
+        if (visibility == View.VISIBLE) {
+            createSessionOverlayView();
+        } else {
+            removeSessionOverlayView();
+        }
+    }
+
+    private void resetSurfaceView() {
+        if (mSurfaceView != null) {
+            mSurfaceView.getHolder().removeCallback(mSurfaceHolderCallback);
+            removeView(mSurfaceView);
+        }
+        mSurface = null;
+        mSurfaceView = new SurfaceView(getContext(), mAttrs, mDefStyleAttr) {
+            @Override
+            protected void updateSurface() {
+                super.updateSurface();
+                relayoutSessionOverlayView();
+            }};
+        // The surface view's content should be treated as secure all the time.
+        mSurfaceView.setSecure(true);
+        mSurfaceView.getHolder().addCallback(mSurfaceHolderCallback);
+        if (mWindowZOrder == ZORDER_MEDIA_OVERLAY) {
+            mSurfaceView.setZOrderMediaOverlay(true);
+        } else if (mWindowZOrder == ZORDER_ON_TOP) {
+            mSurfaceView.setZOrderOnTop(true);
+        }
+        addView(mSurfaceView);
+    }
+
+    private void setSessionSurface(Surface surface) {
+        if (mSession == null) {
+            return;
+        }
+        mSession.setSurface(surface);
+    }
+
+    private void dispatchSurfaceChanged(int format, int width, int height) {
+        if (mSession == null) {
+            return;
+        }
+        mSession.dispatchSurfaceChanged(format, width, height);
+    }
+
+    private void createSessionOverlayView() {
+        if (mSession == null || !isAttachedToWindow()
+                || mOverlayViewCreated || mWindowZOrder != ZORDER_MEDIA) {
+            return;
+        }
+        mOverlayViewFrame = getViewFrameOnScreen();
+        mSession.createOverlayView(this, mOverlayViewFrame);
+        mOverlayViewCreated = true;
+    }
+
+    private void removeSessionOverlayView() {
+        if (mSession == null || !mOverlayViewCreated) {
+            return;
+        }
+        mSession.removeOverlayView();
+        mOverlayViewCreated = false;
+        mOverlayViewFrame = null;
+    }
+
+    private void relayoutSessionOverlayView() {
+        if (mSession == null || !isAttachedToWindow() || !mOverlayViewCreated
+                || mWindowZOrder != ZORDER_MEDIA) {
+            return;
+        }
+        Rect viewFrame = getViewFrameOnScreen();
+        if (viewFrame.equals(mOverlayViewFrame)) {
+            return;
+        }
+        mSession.relayoutOverlayView(viewFrame);
+        mOverlayViewFrame = viewFrame;
+    }
+
+    private Rect getViewFrameOnScreen() {
+        Rect frame = new Rect();
+        getGlobalVisibleRect(frame);
+        RectF frameF = new RectF(frame);
+        getMatrix().mapRect(frameF);
+        frameF.round(frame);
+        return frame;
+    }
+
+    private boolean checkChangeHdmiCecActiveSourcePermission() {
+        return getContext().checkSelfPermission(
+                android.Manifest.permission.CHANGE_HDMI_CEC_ACTIVE_SOURCE)
+                        == PackageManager.PERMISSION_GRANTED;
+    }
+
+    /**
+     * Callback used to receive time shift position changes.
+     */
+    public abstract static class TimeShiftPositionCallback {
+
+        /**
+         * This is called when the start position for time shifting has changed.
+         *
+         * <p>The start position for time shifting indicates the earliest possible time the user can
+         * seek to. Initially this is equivalent to the time when the underlying TV input starts
+         * recording. Later it may be adjusted because there is insufficient space or the duration
+         * of recording is limited. The application must not allow the user to seek to a position
+         * earlier than the start position.
+         *
+         * <p>For playback of a recorded program initiated by {@link #timeShiftPlay(String, Uri)},
+         * the start position is the time when playback starts. It does not change.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param timeMs The start position for time shifting, in milliseconds since the epoch.
+         */
+        public void onTimeShiftStartPositionChanged(String inputId, long timeMs) {
+        }
+
+        /**
+         * This is called when the current position for time shifting has changed.
+         *
+         * <p>The current position for time shifting is the same as the current position of
+         * playback. During playback, the current position changes continuously. When paused, it
+         * does not change.
+         *
+         * <p>Note that {@code timeMs} is wall-clock time.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param timeMs The current position for time shifting, in milliseconds since the epoch.
+         */
+        public void onTimeShiftCurrentPositionChanged(String inputId, long timeMs) {
+        }
+    }
+
+    /**
+     * Callback used to receive various status updates on the {@link TvView}.
+     */
+    public abstract static class TvInputCallback {
+
+        /**
+         * This is invoked when an error occurred while establishing a connection to the underlying
+         * TV input.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         */
+        public void onConnectionFailed(String inputId) {
+        }
+
+        /**
+         * This is invoked when the existing connection to the underlying TV input is lost.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         */
+        public void onDisconnected(String inputId) {
+        }
+
+        /**
+         * This is invoked when the channel of this TvView is changed by the underlying TV input
+         * without any {@link TvView#tune} request.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param channelUri The URI of a channel.
+         */
+        public void onChannelRetuned(String inputId, Uri channelUri) {
+        }
+
+        /**
+         * This is called when the track information has been changed.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param tracks A list which includes track information.
+         */
+        public void onTracksChanged(String inputId, List<TvTrackInfo> tracks) {
+        }
+
+        /**
+         * This is called when there is a change on the selected tracks.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param type The type of the track selected. The type can be
+         *            {@link TvTrackInfo#TYPE_AUDIO}, {@link TvTrackInfo#TYPE_VIDEO} or
+         *            {@link TvTrackInfo#TYPE_SUBTITLE}.
+         * @param trackId The ID of the track selected.
+         */
+        public void onTrackSelected(String inputId, int type, String trackId) {
+        }
+
+        /**
+         * This is invoked when the video size has been changed. It is also called when the first
+         * time video size information becomes available after this view is tuned to a specific
+         * channel.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param width The width of the video.
+         * @param height The height of the video.
+         */
+        public void onVideoSizeChanged(String inputId, int width, int height) {
+        }
+
+        /**
+         * This is called when the video is available, so the TV input starts the playback.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         */
+        public void onVideoAvailable(String inputId) {
+        }
+
+        /**
+         * This is called when the video is not available, so the TV input stops the playback.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param reason The reason why the TV input stopped the playback:
+         * <ul>
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_UNKNOWN}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_TUNING}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_WEAK_SIGNAL}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_BUFFERING}
+         * <li>{@link TvInputManager#VIDEO_UNAVAILABLE_REASON_AUDIO_ONLY}
+         * </ul>
+         */
+        public void onVideoUnavailable(
+                String inputId, @TvInputManager.VideoUnavailableReason int reason) {
+        }
+
+        /**
+         * This is called when the current program content turns out to be allowed to watch since
+         * its content rating is not blocked by parental controls.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         */
+        public void onContentAllowed(String inputId) {
+        }
+
+        /**
+         * This is called when the current program content turns out to be not allowed to watch
+         * since its content rating is blocked by parental controls.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param rating The content rating of the blocked program.
+         */
+        public void onContentBlocked(String inputId, TvContentRating rating) {
+        }
+
+        /**
+         * This is invoked when a custom event from the bound TV input is sent to this view.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param eventType The type of the event.
+         * @param eventArgs Optional arguments of the event.
+         * @hide
+         */
+        @SystemApi
+        public void onEvent(String inputId, String eventType, Bundle eventArgs) {
+        }
+
+        /**
+         * This is called when the time shift status is changed.
+         *
+         * @param inputId The ID of the TV input bound to this view.
+         * @param status The current time shift status. Should be one of the followings.
+         * <ul>
+         * <li>{@link TvInputManager#TIME_SHIFT_STATUS_UNSUPPORTED}
+         * <li>{@link TvInputManager#TIME_SHIFT_STATUS_UNAVAILABLE}
+         * <li>{@link TvInputManager#TIME_SHIFT_STATUS_AVAILABLE}
+         * </ul>
+         */
+        public void onTimeShiftStatusChanged(
+                String inputId, @TvInputManager.TimeShiftStatus int status) {
+        }
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when the unhandled input event is received.
+     */
+    public interface OnUnhandledInputEventListener {
+        /**
+         * Called when an input event was not handled by the bound TV input.
+         *
+         * <p>This is called asynchronously from where the event is dispatched. It gives the host
+         * application a chance to handle the unhandled input events.
+         *
+         * @param event The input event.
+         * @return If you handled the event, return {@code true}. If you want to allow the event to
+         *         be handled by the next receiver, return {@code false}.
+         */
+        boolean onUnhandledInputEvent(InputEvent event);
+    }
+
+    private class MySessionCallback extends SessionCallback {
+        final String mInputId;
+        Uri mChannelUri;
+        Bundle mTuneParams;
+        Uri mRecordedProgramUri;
+
+        MySessionCallback(String inputId, Uri channelUri, Bundle tuneParams) {
+            mInputId = inputId;
+            mChannelUri = channelUri;
+            mTuneParams = tuneParams;
+        }
+
+        MySessionCallback(String inputId, Uri recordedProgramUri) {
+            mInputId = inputId;
+            mRecordedProgramUri = recordedProgramUri;
+        }
+
+        @Override
+        public void onSessionCreated(Session session) {
+            if (DEBUG) {
+                Log.d(TAG, "onSessionCreated()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onSessionCreated - session already created");
+                // This callback is obsolete.
+                if (session != null) {
+                    session.release();
+                }
+                return;
+            }
+            mSession = session;
+            if (session != null) {
+                // Sends the pending app private commands first.
+                for (Pair<String, Bundle> command : mPendingAppPrivateCommands) {
+                    mSession.sendAppPrivateCommand(command.first, command.second);
+                }
+                mPendingAppPrivateCommands.clear();
+
+                synchronized (sMainTvViewLock) {
+                    if (hasWindowFocus() && TvView.this == sMainTvView.get()
+                            && checkChangeHdmiCecActiveSourcePermission()) {
+                        mSession.setMain();
+                    }
+                }
+                // mSurface may not be ready yet as soon as starting an application.
+                // In the case, we don't send Session.setSurface(null) unnecessarily.
+                // setSessionSurface will be called in surfaceCreated.
+                if (mSurface != null) {
+                    setSessionSurface(mSurface);
+                    if (mSurfaceChanged) {
+                        dispatchSurfaceChanged(mSurfaceFormat, mSurfaceWidth, mSurfaceHeight);
+                    }
+                }
+                createSessionOverlayView();
+                if (mStreamVolume != null) {
+                    mSession.setStreamVolume(mStreamVolume);
+                }
+                if (mCaptionEnabled != null) {
+                    mSession.setCaptionEnabled(mCaptionEnabled);
+                }
+                if (mChannelUri != null) {
+                    mSession.tune(mChannelUri, mTuneParams);
+                } else {
+                    mSession.timeShiftPlay(mRecordedProgramUri);
+                }
+                ensurePositionTracking();
+            } else {
+                mSessionCallback = null;
+                if (mCallback != null) {
+                    mCallback.onConnectionFailed(mInputId);
+                }
+            }
+        }
+
+        @Override
+        public void onSessionReleased(Session session) {
+            if (DEBUG) {
+                Log.d(TAG, "onSessionReleased()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onSessionReleased - session not created");
+                return;
+            }
+            mOverlayViewCreated = false;
+            mOverlayViewFrame = null;
+            mSessionCallback = null;
+            mSession = null;
+            if (mCallback != null) {
+                mCallback.onDisconnected(mInputId);
+            }
+        }
+
+        @Override
+        public void onChannelRetuned(Session session, Uri channelUri) {
+            if (DEBUG) {
+                Log.d(TAG, "onChannelChangedByTvInput(" + channelUri + ")");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onChannelRetuned - session not created");
+                return;
+            }
+            if (mCallback != null) {
+                mCallback.onChannelRetuned(mInputId, channelUri);
+            }
+        }
+
+        @Override
+        public void onTracksChanged(Session session, List<TvTrackInfo> tracks) {
+            if (DEBUG) {
+                Log.d(TAG, "onTracksChanged(" + tracks + ")");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onTracksChanged - session not created");
+                return;
+            }
+            if (mCallback != null) {
+                mCallback.onTracksChanged(mInputId, tracks);
+            }
+        }
+
+        @Override
+        public void onTrackSelected(Session session, int type, String trackId) {
+            if (DEBUG) {
+                Log.d(TAG, "onTrackSelected(type=" + type + ", trackId=" + trackId + ")");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onTrackSelected - session not created");
+                return;
+            }
+            if (mCallback != null) {
+                mCallback.onTrackSelected(mInputId, type, trackId);
+            }
+        }
+
+        @Override
+        public void onVideoSizeChanged(Session session, int width, int height) {
+            if (DEBUG) {
+                Log.d(TAG, "onVideoSizeChanged()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onVideoSizeChanged - session not created");
+                return;
+            }
+            if (mCallback != null) {
+                mCallback.onVideoSizeChanged(mInputId, width, height);
+            }
+        }
+
+        @Override
+        public void onVideoAvailable(Session session) {
+            if (DEBUG) {
+                Log.d(TAG, "onVideoAvailable()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onVideoAvailable - session not created");
+                return;
+            }
+            if (mCallback != null) {
+                mCallback.onVideoAvailable(mInputId);
+            }
+        }
+
+        @Override
+        public void onVideoUnavailable(Session session, int reason) {
+            if (DEBUG) {
+                Log.d(TAG, "onVideoUnavailable(reason=" + reason + ")");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onVideoUnavailable - session not created");
+                return;
+            }
+            if (mCallback != null) {
+                mCallback.onVideoUnavailable(mInputId, reason);
+            }
+        }
+
+        @Override
+        public void onContentAllowed(Session session) {
+            if (DEBUG) {
+                Log.d(TAG, "onContentAllowed()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onContentAllowed - session not created");
+                return;
+            }
+            if (mCallback != null) {
+                mCallback.onContentAllowed(mInputId);
+            }
+        }
+
+        @Override
+        public void onContentBlocked(Session session, TvContentRating rating) {
+            if (DEBUG) {
+                Log.d(TAG, "onContentBlocked(rating=" + rating + ")");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onContentBlocked - session not created");
+                return;
+            }
+            if (mCallback != null) {
+                mCallback.onContentBlocked(mInputId, rating);
+            }
+        }
+
+        @Override
+        public void onLayoutSurface(Session session, int left, int top, int right, int bottom) {
+            if (DEBUG) {
+                Log.d(TAG, "onLayoutSurface (left=" + left + ", top=" + top + ", right="
+                        + right + ", bottom=" + bottom + ",)");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onLayoutSurface - session not created");
+                return;
+            }
+            mSurfaceViewLeft = left;
+            mSurfaceViewTop = top;
+            mSurfaceViewRight = right;
+            mSurfaceViewBottom = bottom;
+            mUseRequestedSurfaceLayout = true;
+            requestLayout();
+        }
+
+        @Override
+        public void onSessionEvent(Session session, String eventType, Bundle eventArgs) {
+            if (DEBUG) {
+                Log.d(TAG, "onSessionEvent(" + eventType + ")");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onSessionEvent - session not created");
+                return;
+            }
+            if (mCallback != null) {
+                mCallback.onEvent(mInputId, eventType, eventArgs);
+            }
+        }
+
+        @Override
+        public void onTimeShiftStatusChanged(Session session, int status) {
+            if (DEBUG) {
+                Log.d(TAG, "onTimeShiftStatusChanged()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onTimeShiftStatusChanged - session not created");
+                return;
+            }
+            if (mCallback != null) {
+                mCallback.onTimeShiftStatusChanged(mInputId, status);
+            }
+        }
+
+        @Override
+        public void onTimeShiftStartPositionChanged(Session session, long timeMs) {
+            if (DEBUG) {
+                Log.d(TAG, "onTimeShiftStartPositionChanged()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onTimeShiftStartPositionChanged - session not created");
+                return;
+            }
+            if (mTimeShiftPositionCallback != null) {
+                mTimeShiftPositionCallback.onTimeShiftStartPositionChanged(mInputId, timeMs);
+            }
+        }
+
+        @Override
+        public void onTimeShiftCurrentPositionChanged(Session session, long timeMs) {
+            if (DEBUG) {
+                Log.d(TAG, "onTimeShiftCurrentPositionChanged()");
+            }
+            if (this != mSessionCallback) {
+                Log.w(TAG, "onTimeShiftCurrentPositionChanged - session not created");
+                return;
+            }
+            if (mTimeShiftPositionCallback != null) {
+                mTimeShiftPositionCallback.onTimeShiftCurrentPositionChanged(mInputId, timeMs);
+            }
+        }
+    }
+}
diff --git a/android/media/tv/tuner/DemuxCapabilities.java b/android/media/tv/tuner/DemuxCapabilities.java
new file mode 100644
index 0000000..0f5bf08
--- /dev/null
+++ b/android/media/tv/tuner/DemuxCapabilities.java
@@ -0,0 +1,173 @@
+/*
+ * Copyright 2019 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.tv.tuner;
+
+import android.annotation.BytesLong;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Size;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.filter.Filter;
+import android.media.tv.tuner.filter.FilterConfiguration;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Capabilities info for Demux.
+ *
+ * @hide
+ */
+@SystemApi
+public class DemuxCapabilities {
+
+    /** @hide */
+    @IntDef(flag = true, value = {
+            Filter.TYPE_TS,
+            Filter.TYPE_MMTP,
+            Filter.TYPE_IP,
+            Filter.TYPE_TLV,
+            Filter.TYPE_ALP
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FilterCapabilities {}
+
+    private final int mDemuxCount;
+    private final int mRecordCount;
+    private final int mPlaybackCount;
+    private final int mTsFilterCount;
+    private final int mSectionFilterCount;
+    private final int mAudioFilterCount;
+    private final int mVideoFilterCount;
+    private final int mPesFilterCount;
+    private final int mPcrFilterCount;
+    private final long mSectionFilterLength;
+    private final int mFilterCaps;
+    private final int[] mLinkCaps;
+    private final boolean mSupportTimeFilter;
+
+    // Used by JNI
+    private DemuxCapabilities(int demuxCount, int recordCount, int playbackCount, int tsFilterCount,
+            int sectionFilterCount, int audioFilterCount, int videoFilterCount, int pesFilterCount,
+            int pcrFilterCount, long sectionFilterLength, int filterCaps, int[] linkCaps,
+            boolean timeFilter) {
+        mDemuxCount = demuxCount;
+        mRecordCount = recordCount;
+        mPlaybackCount = playbackCount;
+        mTsFilterCount = tsFilterCount;
+        mSectionFilterCount = sectionFilterCount;
+        mAudioFilterCount = audioFilterCount;
+        mVideoFilterCount = videoFilterCount;
+        mPesFilterCount = pesFilterCount;
+        mPcrFilterCount = pcrFilterCount;
+        mSectionFilterLength = sectionFilterLength;
+        mFilterCaps = filterCaps;
+        mLinkCaps = linkCaps;
+        mSupportTimeFilter = timeFilter;
+    }
+
+    /**
+     * Gets total number of demuxes.
+     */
+    public int getDemuxCount() {
+        return mDemuxCount;
+    }
+    /**
+     * Gets max number of recordings at a time.
+     */
+    public int getRecordCount() {
+        return mRecordCount;
+    }
+    /**
+     * Gets max number of playbacks at a time.
+     */
+    public int getPlaybackCount() {
+        return mPlaybackCount;
+    }
+    /**
+     * Gets number of TS filters.
+     */
+    public int getTsFilterCount() {
+        return mTsFilterCount;
+    }
+    /**
+     * Gets number of section filters.
+     */
+    public int getSectionFilterCount() {
+        return mSectionFilterCount;
+    }
+    /**
+     * Gets number of audio filters.
+     */
+    public int getAudioFilterCount() {
+        return mAudioFilterCount;
+    }
+    /**
+     * Gets number of video filters.
+     */
+    public int getVideoFilterCount() {
+        return mVideoFilterCount;
+    }
+    /**
+     * Gets number of PES filters.
+     */
+    public int getPesFilterCount() {
+        return mPesFilterCount;
+    }
+    /**
+     * Gets number of PCR filters.
+     */
+    public int getPcrFilterCount() {
+        return mPcrFilterCount;
+    }
+    /**
+     * Gets number of bytes in the mask of a section filter.
+     */
+    @BytesLong
+    public long getSectionFilterLength() {
+        return mSectionFilterLength;
+    }
+    /**
+     * Gets filter capabilities in bit field.
+     *
+     * <p>The bits of the returned value is corresponding to the types in
+     * {@link FilterConfiguration}.
+     */
+    @FilterCapabilities
+    public int getFilterCapabilities() {
+        return mFilterCaps;
+    }
+
+    /**
+     * Gets link capabilities.
+     *
+     * <p>The returned array contains the same elements as the number of types in
+     * {@link FilterConfiguration}.
+     * <p>The ith element represents the filter's capability as the source for the ith type.
+     */
+    @NonNull
+    @Size(5)
+    public int[] getLinkCapabilities() {
+        return mLinkCaps;
+    }
+    /**
+     * Is {@link android.media.tv.tuner.filter.TimeFilter} supported.
+     */
+    public boolean isTimeFilterSupported() {
+        return mSupportTimeFilter;
+    }
+}
diff --git a/android/media/tv/tuner/Descrambler.java b/android/media/tv/tuner/Descrambler.java
new file mode 100644
index 0000000..b64ba88
--- /dev/null
+++ b/android/media/tv/tuner/Descrambler.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright 2019 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.tv.tuner;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.Tuner.Result;
+import android.media.tv.tuner.filter.Filter;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Objects;
+
+/**
+ * This class is used to interact with descramblers.
+ *
+ * <p> Descrambler is a hardware component used to descramble data.
+ *
+ * <p> This class controls the TIS interaction with Tuner HAL.
+ *
+ * @hide
+ */
+@SystemApi
+public class Descrambler implements AutoCloseable {
+    /** @hide */
+    @IntDef(prefix = "PID_TYPE_", value = {PID_TYPE_T, PID_TYPE_MMTP})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PidType {}
+
+    /**
+     * Packet ID is used to specify packets in transport stream.
+     */
+    public static final int PID_TYPE_T = 1;
+    /**
+     * Packet ID is used to specify packets in MMTP.
+     */
+    public static final int PID_TYPE_MMTP = 2;
+
+    private static final String TAG = "Descrambler";
+
+
+    private long mNativeContext;
+    private boolean mIsClosed = false;
+    private final Object mLock = new Object();
+
+    private native int nativeAddPid(int pidType, int pid, Filter filter);
+    private native int nativeRemovePid(int pidType, int pid, Filter filter);
+    private native int nativeSetKeyToken(byte[] keyToken);
+    private native int nativeClose();
+
+    // Called by JNI code
+    private Descrambler() {}
+
+    /**
+     * Add packets' PID to the descrambler for descrambling.
+     *
+     * The descrambler will start descrambling packets with this PID. Multiple PIDs can be added
+     * into one descrambler instance because descambling can happen simultaneously on packets
+     * from different PIDs.
+     *
+     * If the Descrambler previously contained a filter for the PID, the old filter is replaced
+     * by the specified filter.
+     *
+     * @param pidType the type of the PID.
+     * @param pid the PID of packets to start to be descrambled.
+     * @param filter an optional filter instance to identify upper stream.
+     * @return result status of the operation.
+     */
+    @Result
+    public int addPid(@PidType int pidType, int pid, @Nullable Filter filter) {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            return nativeAddPid(pidType, pid, filter);
+        }
+    }
+
+    /**
+     * Remove packets' PID from the descrambler
+     *
+     * The descrambler will stop descrambling packets with this PID.
+     *
+     * @param pidType the type of the PID.
+     * @param pid the PID of packets to stop to be descrambled.
+     * @param filter an optional filter instance to identify upper stream.
+     * @return result status of the operation.
+     */
+    @Result
+    public int removePid(@PidType int pidType, int pid, @Nullable Filter filter) {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            return nativeRemovePid(pidType, pid, filter);
+        }
+    }
+
+    /**
+     * Set a key token to link descrambler to a key slot. Use {@link isValidKeyToken(byte[])} to
+     * validate the key token format. Invalid key token would cause no-op and return
+     * {@link Tuner.RESULT_INVALID_ARGUMENT}.
+     *
+     * <p>A descrambler instance can have only one key slot to link, but a key slot can hold a few
+     * keys for different purposes. {@link Tuner.VOID_KEYTOKEN} is considered valid.
+     *
+     * @param keyToken the token to be used to link the key slot. Use {@link Tuner#VOID_KEYTOKEN}
+     *        to remove the current key from descrambler. If the current keyToken comes from a
+     *        MediaCas session, use {@link Tuner#VOID_KEYTOKEN} to remove current key before
+     *        closing the MediaCas session.
+     * @return result status of the operation.
+     */
+    @Result
+    public int setKeyToken(@NonNull byte[] keyToken) {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            Objects.requireNonNull(keyToken, "key token must not be null");
+            if (!isValidKeyToken(keyToken)) {
+                return Tuner.RESULT_INVALID_ARGUMENT;
+            }
+            return nativeSetKeyToken(keyToken);
+        }
+    }
+
+    /**
+     * Validate the key token format as the parameter of {@link setKeyToken(byte[])}.
+     *
+     * <p>The key token is expected to be less than 128 bits.
+     *
+     * @param keyToken the token to be validated.
+     * @return true if the given key token is a valid one.
+     */
+    public static boolean isValidKeyToken(@NonNull byte[] keyToken) {
+        if (keyToken.length == 0 || keyToken.length > 16) {
+            Log.d(TAG, "Invalid key token size: " + (keyToken.length * 8) + " bit.");
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Release the descrambler instance.
+     */
+    @Override
+    public void close() {
+        synchronized (mLock) {
+            if (mIsClosed) {
+                return;
+            }
+            int res = nativeClose();
+            if (res != Tuner.RESULT_SUCCESS) {
+                TunerUtils.throwExceptionForResult(res, "Failed to close descrambler");
+            } else {
+                mIsClosed = true;
+            }
+        }
+    }
+}
diff --git a/android/media/tv/tuner/Lnb.java b/android/media/tv/tuner/Lnb.java
new file mode 100644
index 0000000..8b69d33
--- /dev/null
+++ b/android/media/tv/tuner/Lnb.java
@@ -0,0 +1,274 @@
+/*
+ * Copyright 2019 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.tv.tuner;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.Tuner.Result;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
+
+/**
+ * LNB (low-noise block downconverter) for satellite tuner.
+ *
+ * A Tuner LNB (low-noise block downconverter) is used by satellite frontend to receive the
+ * microwave signal from the satellite, amplify it, and downconvert the frequency to a lower
+ * frequency.
+ *
+ * @hide
+ */
+@SystemApi
+public class Lnb implements AutoCloseable {
+    /** @hide */
+    @IntDef(prefix = "VOLTAGE_",
+            value = {VOLTAGE_NONE, VOLTAGE_5V, VOLTAGE_11V, VOLTAGE_12V, VOLTAGE_13V, VOLTAGE_14V,
+            VOLTAGE_15V, VOLTAGE_18V, VOLTAGE_19V})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Voltage {}
+
+    /**
+     * LNB power voltage not set.
+     */
+    public static final int VOLTAGE_NONE = Constants.LnbVoltage.NONE;
+    /**
+     * LNB power voltage 5V.
+     */
+    public static final int VOLTAGE_5V = Constants.LnbVoltage.VOLTAGE_5V;
+    /**
+     * LNB power voltage 11V.
+     */
+    public static final int VOLTAGE_11V = Constants.LnbVoltage.VOLTAGE_11V;
+    /**
+     * LNB power voltage 12V.
+     */
+    public static final int VOLTAGE_12V = Constants.LnbVoltage.VOLTAGE_12V;
+    /**
+     * LNB power voltage 13V.
+     */
+    public static final int VOLTAGE_13V = Constants.LnbVoltage.VOLTAGE_13V;
+    /**
+     * LNB power voltage 14V.
+     */
+    public static final int VOLTAGE_14V = Constants.LnbVoltage.VOLTAGE_14V;
+    /**
+     * LNB power voltage 15V.
+     */
+    public static final int VOLTAGE_15V = Constants.LnbVoltage.VOLTAGE_15V;
+    /**
+     * LNB power voltage 18V.
+     */
+    public static final int VOLTAGE_18V = Constants.LnbVoltage.VOLTAGE_18V;
+    /**
+     * LNB power voltage 19V.
+     */
+    public static final int VOLTAGE_19V = Constants.LnbVoltage.VOLTAGE_19V;
+
+    /** @hide */
+    @IntDef(prefix = "TONE_",
+            value = {TONE_NONE, TONE_CONTINUOUS})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Tone {}
+
+    /**
+     * LNB tone mode not set.
+     */
+    public static final int TONE_NONE = Constants.LnbTone.NONE;
+    /**
+     * LNB continuous tone mode.
+     */
+    public static final int TONE_CONTINUOUS = Constants.LnbTone.CONTINUOUS;
+
+    /** @hide */
+    @IntDef(prefix = "POSITION_",
+            value = {POSITION_UNDEFINED, POSITION_A, POSITION_B})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Position {}
+
+    /**
+     * LNB position is not defined.
+     */
+    public static final int POSITION_UNDEFINED = Constants.LnbPosition.UNDEFINED;
+    /**
+     * Position A of two-band LNBs
+     */
+    public static final int POSITION_A = Constants.LnbPosition.POSITION_A;
+    /**
+     * Position B of two-band LNBs
+     */
+    public static final int POSITION_B = Constants.LnbPosition.POSITION_B;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "EVENT_TYPE_",
+            value = {EVENT_TYPE_DISEQC_RX_OVERFLOW, EVENT_TYPE_DISEQC_RX_TIMEOUT,
+            EVENT_TYPE_DISEQC_RX_PARITY_ERROR, EVENT_TYPE_LNB_OVERLOAD})
+    public @interface EventType {}
+
+    /**
+     * Outgoing Diseqc message overflow.
+     */
+    public static final int EVENT_TYPE_DISEQC_RX_OVERFLOW =
+            Constants.LnbEventType.DISEQC_RX_OVERFLOW;
+    /**
+     * Outgoing Diseqc message isn't delivered on time.
+     */
+    public static final int EVENT_TYPE_DISEQC_RX_TIMEOUT =
+            Constants.LnbEventType.DISEQC_RX_TIMEOUT;
+    /**
+     * Incoming Diseqc message has parity error.
+     */
+    public static final int EVENT_TYPE_DISEQC_RX_PARITY_ERROR =
+            Constants.LnbEventType.DISEQC_RX_PARITY_ERROR;
+    /**
+     * LNB is overload.
+     */
+    public static final int EVENT_TYPE_LNB_OVERLOAD = Constants.LnbEventType.LNB_OVERLOAD;
+
+    private static final String TAG = "Lnb";
+
+    LnbCallback mCallback;
+    Executor mExecutor;
+    Tuner mTuner;
+    private final Object mCallbackLock = new Object();
+
+
+    private native int nativeSetVoltage(int voltage);
+    private native int nativeSetTone(int tone);
+    private native int nativeSetSatellitePosition(int position);
+    private native int nativeSendDiseqcMessage(byte[] message);
+    private native int nativeClose();
+
+    private long mNativeContext;
+
+    private Boolean mIsClosed = false;
+    private final Object mLock = new Object();
+
+    private Lnb() {}
+
+    void setCallback(Executor executor, @Nullable LnbCallback callback, Tuner tuner) {
+        synchronized (mCallbackLock) {
+            mCallback = callback;
+            mExecutor = executor;
+            mTuner = tuner;
+        }
+    }
+
+    private void onEvent(int eventType) {
+        synchronized (mCallbackLock) {
+            if (mExecutor != null && mCallback != null) {
+                mExecutor.execute(() -> mCallback.onEvent(eventType));
+            }
+        }
+    }
+
+    private void onDiseqcMessage(byte[] diseqcMessage) {
+        synchronized (mCallbackLock) {
+            if (mExecutor != null && mCallback != null) {
+                mExecutor.execute(() -> mCallback.onDiseqcMessage(diseqcMessage));
+            }
+        }
+    }
+
+    /* package */ boolean isClosed() {
+        synchronized (mLock) {
+            return mIsClosed;
+        }
+    }
+
+    /**
+     * Sets the LNB's power voltage.
+     *
+     * @param voltage the power voltage constant the Lnb to use.
+     * @return result status of the operation.
+     */
+    @Result
+    public int setVoltage(@Voltage int voltage) {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            return nativeSetVoltage(voltage);
+        }
+    }
+
+    /**
+     * Sets the LNB's tone mode.
+     *
+     * @param tone the tone mode the Lnb to use.
+     * @return result status of the operation.
+     */
+    @Result
+    public int setTone(@Tone int tone) {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            return nativeSetTone(tone);
+        }
+    }
+
+    /**
+     * Selects the LNB's position.
+     *
+     * @param position the position the Lnb to use.
+     * @return result status of the operation.
+     */
+    @Result
+    public int setSatellitePosition(@Position int position) {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            return nativeSetSatellitePosition(position);
+        }
+    }
+
+    /**
+     * Sends DiSEqC (Digital Satellite Equipment Control) message.
+     *
+     * The response message from the device comes back through callback onDiseqcMessage.
+     *
+     * @param message a byte array of data for DiSEqC message which is specified by EUTELSAT Bus
+     *         Functional Specification Version 4.2.
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int sendDiseqcMessage(@NonNull byte[] message) {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            return nativeSendDiseqcMessage(message);
+        }
+    }
+
+    /**
+     * Releases the LNB instance.
+     */
+    public void close() {
+        synchronized (mLock) {
+            if (mIsClosed) {
+                return;
+            }
+            int res = nativeClose();
+            if (res != Tuner.RESULT_SUCCESS) {
+                TunerUtils.throwExceptionForResult(res, "Failed to close LNB");
+            } else {
+                mIsClosed = true;
+                mTuner.releaseLnb();
+            }
+        }
+    }
+}
diff --git a/android/media/tv/tuner/LnbCallback.java b/android/media/tv/tuner/LnbCallback.java
new file mode 100644
index 0000000..7862470
--- /dev/null
+++ b/android/media/tv/tuner/LnbCallback.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2019 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.tv.tuner;
+
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.Lnb.EventType;
+
+/**
+ * Callback interface for receiving information from LNBs.
+ *
+ * @hide
+ */
+@SystemApi
+public interface LnbCallback {
+    /**
+     * Invoked when there is a LNB event.
+     */
+    void onEvent(@EventType int lnbEventType);
+
+    /**
+     * Invoked when there is a new DiSEqC message.
+     *
+     * @param diseqcMessage a byte array of data for DiSEqC (Digital Satellite
+     * Equipment Control) message which is specified by EUTELSAT Bus Functional
+     * Specification Version 4.2.
+     */
+    void onDiseqcMessage(@NonNull byte[] diseqcMessage);
+}
diff --git a/android/media/tv/tuner/Tuner.java b/android/media/tv/tuner/Tuner.java
new file mode 100644
index 0000000..3254366
--- /dev/null
+++ b/android/media/tv/tuner/Tuner.java
@@ -0,0 +1,1513 @@
+/*
+ * Copyright 2019 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.tv.tuner;
+
+import android.annotation.BytesLong;
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+import android.content.Context;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.TvInputService;
+import android.media.tv.tuner.dvr.DvrPlayback;
+import android.media.tv.tuner.dvr.DvrRecorder;
+import android.media.tv.tuner.dvr.OnPlaybackStatusChangedListener;
+import android.media.tv.tuner.dvr.OnRecordStatusChangedListener;
+import android.media.tv.tuner.filter.Filter;
+import android.media.tv.tuner.filter.Filter.Subtype;
+import android.media.tv.tuner.filter.Filter.Type;
+import android.media.tv.tuner.filter.FilterCallback;
+import android.media.tv.tuner.filter.TimeFilter;
+import android.media.tv.tuner.frontend.Atsc3PlpInfo;
+import android.media.tv.tuner.frontend.FrontendInfo;
+import android.media.tv.tuner.frontend.FrontendSettings;
+import android.media.tv.tuner.frontend.FrontendStatus;
+import android.media.tv.tuner.frontend.FrontendStatus.FrontendStatusType;
+import android.media.tv.tuner.frontend.OnTuneEventListener;
+import android.media.tv.tuner.frontend.ScanCallback;
+import android.media.tv.tunerresourcemanager.ResourceClientProfile;
+import android.media.tv.tunerresourcemanager.TunerCiCamRequest;
+import android.media.tv.tunerresourcemanager.TunerDemuxRequest;
+import android.media.tv.tunerresourcemanager.TunerDescramblerRequest;
+import android.media.tv.tunerresourcemanager.TunerFrontendRequest;
+import android.media.tv.tunerresourcemanager.TunerLnbRequest;
+import android.media.tv.tunerresourcemanager.TunerResourceManager;
+import android.os.Handler;
+import android.os.HandlerExecutor;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Process;
+import android.util.Log;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.ref.WeakReference;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.concurrent.Executor;
+
+/**
+ * This class is used to interact with hardware tuners devices.
+ *
+ * <p> Each TvInputService Session should create one instance of this class.
+ *
+ * <p> This class controls the TIS interaction with Tuner HAL.
+ *
+ * @hide
+ */
+@SystemApi
+public class Tuner implements AutoCloseable  {
+    /**
+     * Invalid TS packet ID.
+     */
+    public static final int INVALID_TS_PID = Constants.Constant.INVALID_TS_PID;
+    /**
+     * Invalid stream ID.
+     */
+    public static final int INVALID_STREAM_ID = Constants.Constant.INVALID_STREAM_ID;
+    /**
+     * Invalid filter ID.
+     */
+    public static final int INVALID_FILTER_ID = Constants.Constant.INVALID_FILTER_ID;
+    /**
+     * Invalid AV Sync ID.
+     */
+    public static final int INVALID_AV_SYNC_ID = Constants.Constant.INVALID_AV_SYNC_ID;
+    /**
+     * Invalid timestamp.
+     *
+     * <p>Returned by {@link android.media.tv.tuner.filter.TimeFilter#getSourceTime()},
+     * {@link android.media.tv.tuner.filter.TimeFilter#getTimeStamp()},
+     * {@link Tuner#getAvSyncTime(int)} or {@link TsRecordEvent#getPts()} and
+     * {@link MmtpRecordEvent#getPts()} when the requested timestamp is not available.
+     *
+     * @see android.media.tv.tuner.filter.TimeFilter#getSourceTime()
+     * @see android.media.tv.tuner.filter.TimeFilter#getTimeStamp()
+     * @see Tuner#getAvSyncTime(int)
+     * @see android.media.tv.tuner.filter.TsRecordEvent#getPts()
+     * @see android.media.tv.tuner.filter.MmtpRecordEvent#getPts()
+     */
+    public static final long INVALID_TIMESTAMP =
+            android.hardware.tv.tuner.V1_1.Constants.Constant64Bit.INVALID_PRESENTATION_TIME_STAMP;
+    /**
+     * Invalid mpu sequence number in MmtpRecordEvent.
+     *
+     * <p>Returned by {@link MmtpRecordEvent#getMpuSequenceNumber()} when the requested sequence
+     * number is not available.
+     *
+     * @see android.media.tv.tuner.filter.MmtpRecordEvent#getMpuSequenceNumber()
+     */
+    public static final int INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM =
+            android.hardware.tv.tuner.V1_1.Constants.Constant
+                    .INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM;
+    /**
+     * Invalid first macroblock address in MmtpRecordEvent and TsRecordEvent.
+     *
+     * <p>Returned by {@link MmtpRecordEvent#getMbInSlice()} and
+     * {@link TsRecordEvent#getMbInSlice()} when the requested sequence number is not available.
+     *
+     * @see android.media.tv.tuner.filter.MmtpRecordEvent#getMbInSlice()
+     * @see android.media.tv.tuner.filter.TsRecordEvent#getMbInSlice()
+     */
+    public static final int INVALID_FIRST_MACROBLOCK_IN_SLICE =
+            android.hardware.tv.tuner.V1_1.Constants.Constant.INVALID_FIRST_MACROBLOCK_IN_SLICE;
+    /**
+     * Invalid local transport stream id.
+     *
+     * <p>Returned by {@link #linkFrontendToCiCam(int)} when the requested failed
+     * or the hal implementation does not support the operation.
+     *
+     * @see #linkFrontendToCiCam(int)
+     */
+    public static final int INVALID_LTS_ID =
+            android.hardware.tv.tuner.V1_1.Constants.Constant.INVALID_LTS_ID;
+    /**
+     * Invalid 64-bit filter ID.
+     */
+    public static final long INVALID_FILTER_ID_LONG =
+            android.hardware.tv.tuner.V1_1.Constants.Constant64Bit.INVALID_FILTER_ID_64BIT;
+    /**
+     * Invalid frequency that is used as the default frontend frequency setting.
+     */
+    public static final int INVALID_FRONTEND_SETTING_FREQUENCY =
+            android.hardware.tv.tuner.V1_1.Constants.Constant.INVALID_FRONTEND_SETTING_FREQUENCY;
+    /**
+     * Invalid frontend id.
+     */
+    public static final int INVALID_FRONTEND_ID =
+            android.hardware.tv.tuner.V1_1.Constants.Constant.INVALID_FRONTEND_ID;
+    /**
+     * Invalid LNB id.
+     *
+     * @hide
+     */
+    public static final int INVALID_LNB_ID =
+            android.hardware.tv.tuner.V1_1.Constants.Constant.INVALID_LNB_ID;
+    /**
+     * A void key token. It is used to remove the current key from descrambler.
+     *
+     * <p>If the current keyToken comes from a MediaCas session, App is recommended to
+     * to use this constant to remove current key before closing MediaCas session.
+     */
+    @NonNull
+    public static final byte[] VOID_KEYTOKEN =
+            {android.hardware.tv.tuner.V1_1.Constants.Constant.INVALID_KEYTOKEN};
+
+    /** @hide */
+    @IntDef(prefix = "SCAN_TYPE_", value = {SCAN_TYPE_UNDEFINED, SCAN_TYPE_AUTO, SCAN_TYPE_BLIND})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScanType {}
+    /**
+     * Scan type undefined.
+     */
+    public static final int SCAN_TYPE_UNDEFINED = Constants.FrontendScanType.SCAN_UNDEFINED;
+    /**
+     * Scan type auto.
+     *
+     * <p> Tuner will send {@link android.media.tv.tuner.frontend.ScanCallback#onLocked}
+     */
+    public static final int SCAN_TYPE_AUTO = Constants.FrontendScanType.SCAN_AUTO;
+    /**
+     * Blind scan.
+     *
+     * <p>Frequency range is not specified. The {@link android.media.tv.tuner.Tuner} will scan an
+     * implementation specific range.
+     */
+    public static final int SCAN_TYPE_BLIND = Constants.FrontendScanType.SCAN_BLIND;
+
+
+    /** @hide */
+    @IntDef({RESULT_SUCCESS, RESULT_UNAVAILABLE, RESULT_NOT_INITIALIZED, RESULT_INVALID_STATE,
+            RESULT_INVALID_ARGUMENT, RESULT_OUT_OF_MEMORY, RESULT_UNKNOWN_ERROR})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Result {}
+
+    /**
+     * Operation succeeded.
+     */
+    public static final int RESULT_SUCCESS = Constants.Result.SUCCESS;
+    /**
+     * Operation failed because the corresponding resources are not available.
+     */
+    public static final int RESULT_UNAVAILABLE = Constants.Result.UNAVAILABLE;
+    /**
+     * Operation failed because the corresponding resources are not initialized.
+     */
+    public static final int RESULT_NOT_INITIALIZED = Constants.Result.NOT_INITIALIZED;
+    /**
+     * Operation failed because it's not in a valid state.
+     */
+    public static final int RESULT_INVALID_STATE = Constants.Result.INVALID_STATE;
+    /**
+     * Operation failed because there are invalid arguments.
+     */
+    public static final int RESULT_INVALID_ARGUMENT = Constants.Result.INVALID_ARGUMENT;
+    /**
+     * Memory allocation failed.
+     */
+    public static final int RESULT_OUT_OF_MEMORY = Constants.Result.OUT_OF_MEMORY;
+    /**
+     * Operation failed due to unknown errors.
+     */
+    public static final int RESULT_UNKNOWN_ERROR = Constants.Result.UNKNOWN_ERROR;
+
+
+
+    private static final String TAG = "MediaTvTuner";
+    private static final boolean DEBUG = false;
+
+    private static final int MSG_RESOURCE_LOST = 1;
+    private static final int MSG_ON_FILTER_EVENT = 2;
+    private static final int MSG_ON_FILTER_STATUS = 3;
+    private static final int MSG_ON_LNB_EVENT = 4;
+
+    private static final int FILTER_CLEANUP_THRESHOLD = 256;
+
+    /** @hide */
+    @IntDef(prefix = "DVR_TYPE_", value = {DVR_TYPE_RECORD, DVR_TYPE_PLAYBACK})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DvrType {}
+
+    /**
+     * DVR for recording.
+     * @hide
+     */
+    public static final int DVR_TYPE_RECORD = Constants.DvrType.RECORD;
+    /**
+     * DVR for playback of recorded programs.
+     * @hide
+     */
+    public static final int DVR_TYPE_PLAYBACK = Constants.DvrType.PLAYBACK;
+
+    static {
+        try {
+            System.loadLibrary("media_tv_tuner");
+            nativeInit();
+        } catch (UnsatisfiedLinkError e) {
+            Log.d(TAG, "tuner JNI library not found!");
+        }
+    }
+
+    private final Context mContext;
+    private final TunerResourceManager mTunerResourceManager;
+    private final int mClientId;
+    private static int sTunerVersion = TunerVersionChecker.TUNER_VERSION_UNKNOWN;
+
+    private Frontend mFrontend;
+    private EventHandler mHandler;
+    @Nullable
+    private FrontendInfo mFrontendInfo;
+    private Integer mFrontendHandle;
+    private Boolean mIsSharedFrontend = false;
+    private int mFrontendType = FrontendSettings.TYPE_UNDEFINED;
+    private int mUserId;
+    private Lnb mLnb;
+    private Integer mLnbHandle;
+    @Nullable
+    private OnTuneEventListener mOnTuneEventListener;
+    @Nullable
+    private Executor mOnTuneEventExecutor;
+    @Nullable
+    private ScanCallback mScanCallback;
+    @Nullable
+    private Executor mScanCallbackExecutor;
+    @Nullable
+    private OnResourceLostListener mOnResourceLostListener;
+    @Nullable
+    private Executor mOnResourceLostListenerExecutor;
+
+    private final Object mOnTuneEventLock = new Object();
+    private final Object mScanCallbackLock = new Object();
+    private final Object mOnResourceLostListenerLock = new Object();
+
+    private Integer mDemuxHandle;
+    private Integer mFrontendCiCamHandle;
+    private Integer mFrontendCiCamId;
+    private Map<Integer, WeakReference<Descrambler>> mDescramblers = new HashMap<>();
+    private List<WeakReference<Filter>> mFilters = new ArrayList<WeakReference<Filter>>();
+
+    private final TunerResourceManager.ResourcesReclaimListener mResourceListener =
+            new TunerResourceManager.ResourcesReclaimListener() {
+                @Override
+                public void onReclaimResources() {
+                    if (mFrontend != null) {
+                        FrameworkStatsLog
+                                .write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
+                                    FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__UNKNOWN);
+                    }
+                    releaseAll();
+                    mHandler.sendMessage(mHandler.obtainMessage(MSG_RESOURCE_LOST));
+                }
+            };
+
+    /**
+     * Constructs a Tuner instance.
+     *
+     * @param context the context of the caller.
+     * @param tvInputSessionId the session ID of the TV input.
+     * @param useCase the use case of this Tuner instance.
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_TV_TUNER)
+    public Tuner(@NonNull Context context, @Nullable String tvInputSessionId,
+            @TvInputService.PriorityHintUseCaseType int useCase) {
+        nativeSetup();
+        sTunerVersion = nativeGetTunerVersion();
+        if (sTunerVersion == TunerVersionChecker.TUNER_VERSION_UNKNOWN) {
+            Log.e(TAG, "Unknown Tuner version!");
+        } else {
+            Log.d(TAG, "Current Tuner version is "
+                    + TunerVersionChecker.getMajorVersion(sTunerVersion) + "."
+                    + TunerVersionChecker.getMinorVersion(sTunerVersion) + ".");
+        }
+        mContext = context;
+        mTunerResourceManager = (TunerResourceManager)
+                context.getSystemService(Context.TV_TUNER_RESOURCE_MGR_SERVICE);
+        if (mHandler == null) {
+            mHandler = createEventHandler();
+        }
+
+        int[] clientId = new int[1];
+        ResourceClientProfile profile = new ResourceClientProfile();
+        profile.tvInputSessionId = tvInputSessionId;
+        profile.useCase = useCase;
+        mTunerResourceManager.registerClientProfile(
+                profile, new HandlerExecutor(mHandler), mResourceListener, clientId);
+        mClientId = clientId[0];
+
+        mUserId = Process.myUid();
+    }
+
+    /**
+     * Get frontend info list from native and build them into a {@link FrontendInfo} list. Any
+     * {@code null} FrontendInfo element would be removed.
+     */
+    private FrontendInfo[] getFrontendInfoListInternal() {
+        List<Integer> ids = getFrontendIds();
+        if (ids == null) {
+            return null;
+        }
+        FrontendInfo[] infos = new FrontendInfo[ids.size()];
+        for (int i = 0; i < ids.size(); i++) {
+            int id = ids.get(i);
+            FrontendInfo frontendInfo = getFrontendInfoById(id);
+            if (frontendInfo == null) {
+                Log.e(TAG, "Failed to get a FrontendInfo on frontend id:" + id + "!");
+                continue;
+            }
+            infos[i] = frontendInfo;
+        }
+        return Arrays.stream(infos).filter(Objects::nonNull).toArray(FrontendInfo[]::new);
+    }
+
+    /** @hide */
+    public static int getTunerVersion() {
+        return sTunerVersion;
+    }
+
+    /** @hide */
+    public List<Integer> getFrontendIds() {
+        return nativeGetFrontendIds();
+    }
+
+    /**
+     * Sets the listener for resource lost.
+     *
+     * @param executor the executor on which the listener should be invoked.
+     * @param listener the listener that will be run.
+     */
+    public void setResourceLostListener(@NonNull @CallbackExecutor Executor executor,
+            @NonNull OnResourceLostListener listener) {
+        synchronized (mOnResourceLostListenerLock) {
+            Objects.requireNonNull(executor, "OnResourceLostListener must not be null");
+            Objects.requireNonNull(listener, "executor must not be null");
+            mOnResourceLostListener = listener;
+            mOnResourceLostListenerExecutor = executor;
+        }
+    }
+
+    /**
+     * Removes the listener for resource lost.
+     */
+    public void clearResourceLostListener() {
+        synchronized (mOnResourceLostListenerLock) {
+            mOnResourceLostListener = null;
+            mOnResourceLostListenerExecutor = null;
+        }
+    }
+
+    /**
+     * Shares the frontend resource with another Tuner instance
+     *
+     * @param tuner the Tuner instance to share frontend resource with.
+     */
+    public void shareFrontendFromTuner(@NonNull Tuner tuner) {
+        mTunerResourceManager.shareFrontend(mClientId, tuner.mClientId);
+        synchronized (mIsSharedFrontend) {
+            mFrontendHandle = tuner.mFrontendHandle;
+            mFrontend = tuner.mFrontend;
+            mIsSharedFrontend = true;
+        }
+    }
+
+    /**
+     * Updates client priority with an arbitrary value along with a nice value.
+     *
+     * <p>Tuner resource manager (TRM) uses the client priority value to decide whether it is able
+     * to reclaim insufficient resources from another client.
+     *
+     * <p>The nice value represents how much the client intends to give up the resource when an
+     * insufficient resource situation happens.
+     *
+     * @param priority the new priority. Any negative value would cause no-op on priority setting
+     *                 and the API would only process nice value setting in that case.
+     * @param niceValue the nice value.
+     */
+    public void updateResourcePriority(int priority, int niceValue) {
+        mTunerResourceManager.updateClientPriority(mClientId, priority, niceValue);
+    }
+
+    private long mNativeContext; // used by native jMediaTuner
+
+    /**
+     * Releases the Tuner instance.
+     */
+    @Override
+    public void close() {
+        releaseAll();
+        TunerUtils.throwExceptionForResult(nativeClose(), "failed to close tuner");
+    }
+
+    private void releaseAll() {
+        if (mFrontendHandle != null) {
+            synchronized (mIsSharedFrontend) {
+                if (!mIsSharedFrontend) {
+                    int res = nativeCloseFrontend(mFrontendHandle);
+                    if (res != Tuner.RESULT_SUCCESS) {
+                        TunerUtils.throwExceptionForResult(res, "failed to close frontend");
+                    }
+                }
+                mIsSharedFrontend = false;
+            }
+            mTunerResourceManager.releaseFrontend(mFrontendHandle, mClientId);
+            FrameworkStatsLog
+                    .write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
+                    FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__UNKNOWN);
+            mFrontendHandle = null;
+            mFrontend = null;
+        }
+        if (mLnb != null) {
+            mLnb.close();
+        }
+        if (mFrontendCiCamHandle != null) {
+            int result = nativeUnlinkCiCam(mFrontendCiCamId);
+            if (result == RESULT_SUCCESS) {
+                mTunerResourceManager.releaseCiCam(mFrontendCiCamHandle, mClientId);
+                mFrontendCiCamId = null;
+                mFrontendCiCamHandle = null;
+            }
+        }
+        synchronized (mDescramblers) {
+            if (!mDescramblers.isEmpty()) {
+                for (Map.Entry<Integer, WeakReference<Descrambler>> d : mDescramblers.entrySet()) {
+                    Descrambler descrambler = d.getValue().get();
+                    if (descrambler != null) {
+                        descrambler.close();
+                    }
+                    mTunerResourceManager.releaseDescrambler(d.getKey(), mClientId);
+                }
+                mDescramblers.clear();
+            }
+        }
+        synchronized (mFilters) {
+            if (!mFilters.isEmpty()) {
+                for (WeakReference<Filter> weakFilter : mFilters) {
+                    Filter filter = weakFilter.get();
+                    if (filter != null) {
+                        filter.close();
+                    }
+                }
+                mFilters.clear();
+            }
+        }
+        if (mDemuxHandle != null) {
+            int res = nativeCloseDemux(mDemuxHandle);
+            if (res != Tuner.RESULT_SUCCESS) {
+                TunerUtils.throwExceptionForResult(res, "failed to close demux");
+            }
+            mTunerResourceManager.releaseDemux(mDemuxHandle, mClientId);
+            mDemuxHandle = null;
+        }
+
+        mTunerResourceManager.unregisterClientProfile(mClientId);
+
+    }
+
+    /**
+     * Native Initialization.
+     */
+    private static native void nativeInit();
+
+    /**
+     * Native setup.
+     */
+    private native void nativeSetup();
+
+    /**
+     * Native method to get all frontend IDs.
+     */
+    private native int nativeGetTunerVersion();
+
+    /**
+     * Native method to get all frontend IDs.
+     */
+    private native List<Integer> nativeGetFrontendIds();
+
+    /**
+     * Native method to open frontend of the given ID.
+     */
+    private native Frontend nativeOpenFrontendByHandle(int handle);
+    @Result
+    private native int nativeTune(int type, FrontendSettings settings);
+    private native int nativeStopTune();
+    private native int nativeScan(int settingsType, FrontendSettings settings, int scanType);
+    private native int nativeStopScan();
+    private native int nativeSetLnb(Lnb lnb);
+    private native int nativeSetLna(boolean enable);
+    private native FrontendStatus nativeGetFrontendStatus(int[] statusTypes);
+    private native Integer nativeGetAvSyncHwId(Filter filter);
+    private native Long nativeGetAvSyncTime(int avSyncId);
+    private native int nativeConnectCiCam(int ciCamId);
+    private native int nativeLinkCiCam(int ciCamId);
+    private native int nativeDisconnectCiCam();
+    private native int nativeUnlinkCiCam(int ciCamId);
+    private native FrontendInfo nativeGetFrontendInfo(int id);
+    private native Filter nativeOpenFilter(int type, int subType, long bufferSize);
+    private native TimeFilter nativeOpenTimeFilter();
+
+    private native Lnb nativeOpenLnbByHandle(int handle);
+    private native Lnb nativeOpenLnbByName(String name);
+
+    private native Descrambler nativeOpenDescramblerByHandle(int handle);
+    private native int nativeOpenDemuxByhandle(int handle);
+
+    private native DvrRecorder nativeOpenDvrRecorder(long bufferSize);
+    private native DvrPlayback nativeOpenDvrPlayback(long bufferSize);
+
+    private native DemuxCapabilities nativeGetDemuxCapabilities();
+
+    private native int nativeCloseDemux(int handle);
+    private native int nativeCloseFrontend(int handle);
+    private native int nativeClose();
+
+
+    /**
+     * Listener for resource lost.
+     *
+     * <p>Insufficient resources are reclaimed by higher priority clients.
+     */
+    public interface OnResourceLostListener {
+        /**
+         * Invoked when resource lost.
+         *
+         * @param tuner the tuner instance whose resource is being reclaimed.
+         */
+        void onResourceLost(@NonNull Tuner tuner);
+    }
+
+    @Nullable
+    private EventHandler createEventHandler() {
+        Looper looper;
+        if ((looper = Looper.myLooper()) != null) {
+            return new EventHandler(looper);
+        } else if ((looper = Looper.getMainLooper()) != null) {
+            return new EventHandler(looper);
+        }
+        return null;
+    }
+
+    private class EventHandler extends Handler {
+        private EventHandler(Looper looper) {
+            super(looper);
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case MSG_ON_FILTER_STATUS: {
+                    Filter filter = (Filter) msg.obj;
+                    if (filter.getCallback() != null) {
+                        filter.getCallback().onFilterStatusChanged(filter, msg.arg1);
+                    }
+                    break;
+                }
+                case MSG_RESOURCE_LOST: {
+                    synchronized (mOnResourceLostListenerLock) {
+                        if (mOnResourceLostListener != null
+                                && mOnResourceLostListenerExecutor != null) {
+                            mOnResourceLostListenerExecutor.execute(
+                                    () -> mOnResourceLostListener.onResourceLost(Tuner.this));
+                        }
+                    }
+                    break;
+                }
+                default:
+                    // fall through
+            }
+        }
+    }
+
+    private class Frontend {
+        private int mId;
+
+        private Frontend(int id) {
+            mId = id;
+        }
+    }
+
+    /**
+     * Listens for tune events.
+     *
+     * <p>
+     * Tuner events are started when {@link #tune(FrontendSettings)} is called and end when {@link
+     * #cancelTuning()} is called.
+     *
+     * @param eventListener receives tune events.
+     * @throws SecurityException if the caller does not have appropriate permissions.
+     * @see #tune(FrontendSettings)
+     */
+    public void setOnTuneEventListener(@NonNull @CallbackExecutor Executor executor,
+            @NonNull OnTuneEventListener eventListener) {
+        synchronized (mOnTuneEventLock) {
+            mOnTuneEventListener = eventListener;
+            mOnTuneEventExecutor = executor;
+        }
+    }
+
+    /**
+     * Clears the {@link OnTuneEventListener} and its associated {@link Executor}.
+     *
+     * @throws SecurityException if the caller does not have appropriate permissions.
+     * @see #setOnTuneEventListener(Executor, OnTuneEventListener)
+     */
+    public void clearOnTuneEventListener() {
+        synchronized (mOnTuneEventLock) {
+            mOnTuneEventListener = null;
+            mOnTuneEventExecutor = null;
+        }
+    }
+
+    /**
+     * Tunes the frontend to using the settings given.
+     *
+     * <p>Tuner resource manager (TRM) uses the client priority value to decide whether it is able
+     * to get frontend resource. If the client can't get the resource, this call returns {@link
+     * #RESULT_UNAVAILABLE}.
+     *
+     * <p>
+     * This locks the frontend to a frequency by providing signal
+     * delivery information. If previous tuning isn't completed, this stop the previous tuning, and
+     * start a new tuning.
+     *
+     * <p>
+     * Tune is an async call, with {@link OnTuneEventListener#SIGNAL_LOCKED} and {@link
+     * OnTuneEventListener#SIGNAL_NO_SIGNAL} events sent to the {@link OnTuneEventListener}
+     * specified in {@link #setOnTuneEventListener(Executor, OnTuneEventListener)}.
+     *
+     * <p>Tuning with {@link android.media.tv.tuner.frontend.DtmbFrontendSettings} is only
+     * supported in Tuner 1.1 or higher version. Unsupported version will cause no-op. Use {@link
+     * TunerVersionChecker#getTunerVersion()} to get the version information.
+     *
+     * @param settings Signal delivery information the frontend uses to
+     *                 search and lock the signal.
+     * @return result status of tune operation.
+     * @throws SecurityException if the caller does not have appropriate permissions.
+     * @see #setOnTuneEventListener(Executor, OnTuneEventListener)
+     */
+    @Result
+    public int tune(@NonNull FrontendSettings settings) {
+        Log.d(TAG, "Tune to " + settings.getFrequency());
+        mFrontendType = settings.getType();
+        if (mFrontendType == FrontendSettings.TYPE_DTMB) {
+            if (!TunerVersionChecker.checkHigherOrEqualVersionTo(
+                    TunerVersionChecker.TUNER_VERSION_1_1, "Tuner with DTMB Frontend")) {
+                return RESULT_UNAVAILABLE;
+            }
+        }
+        if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
+            mFrontendInfo = null;
+            Log.d(TAG, "Write Stats Log for tuning.");
+            FrameworkStatsLog
+                    .write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
+                        FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__TUNING);
+            return nativeTune(settings.getType(), settings);
+        }
+        return RESULT_UNAVAILABLE;
+    }
+
+    /**
+     * Stops a previous tuning.
+     *
+     * <p>If the method completes successfully, the frontend is no longer tuned and no data
+     * will be sent to attached filters.
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int cancelTuning() {
+        return nativeStopTune();
+    }
+
+    /**
+     * Scan for channels.
+     *
+     * <p>Details for channels found are returned via {@link ScanCallback}.
+     *
+     * <p>Scanning with {@link android.media.tv.tuner.frontend.DtmbFrontendSettings} is only
+     * supported in Tuner 1.1 or higher version. Unsupported version will cause no-op. Use {@link
+     * TunerVersionChecker#getTunerVersion()} to get the version information.
+     *
+     * @param settings A {@link FrontendSettings} to configure the frontend.
+     * @param scanType The scan type.
+     * @throws SecurityException     if the caller does not have appropriate permissions.
+     * @throws IllegalStateException if {@code scan} is called again before
+     *                               {@link #cancelScanning()} is called.
+     */
+    @Result
+    public int scan(@NonNull FrontendSettings settings, @ScanType int scanType,
+            @NonNull @CallbackExecutor Executor executor, @NonNull ScanCallback scanCallback) {
+        synchronized (mScanCallbackLock) {
+            // Scan can be called again for blink scan if scanCallback and executor are same as
+            //before.
+            if (((mScanCallback != null) && (mScanCallback != scanCallback))
+                || ((mScanCallbackExecutor != null) && (mScanCallbackExecutor != executor))) {
+                throw new IllegalStateException(
+                    "Different Scan session already in progress.  stopScan must be called "
+                        + "before a new scan session can be " + "started.");
+            }
+            mFrontendType = settings.getType();
+            if (mFrontendType == FrontendSettings.TYPE_DTMB) {
+                if (!TunerVersionChecker.checkHigherOrEqualVersionTo(
+                        TunerVersionChecker.TUNER_VERSION_1_1,
+                        "Scan with DTMB Frontend")) {
+                    return RESULT_UNAVAILABLE;
+                }
+            }
+            if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
+                mScanCallback = scanCallback;
+                mScanCallbackExecutor = executor;
+                mFrontendInfo = null;
+                FrameworkStatsLog
+                    .write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
+                        FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__SCANNING);
+                return nativeScan(settings.getType(), settings, scanType);
+            }
+            return RESULT_UNAVAILABLE;
+        }
+    }
+
+    /**
+     * Stops a previous scanning.
+     *
+     * <p>
+     * The {@link ScanCallback} and it's {@link Executor} will be removed.
+     *
+     * <p>
+     * If the method completes successfully, the frontend stopped previous scanning.
+     *
+     * @throws SecurityException if the caller does not have appropriate permissions.
+     */
+    @Result
+    public int cancelScanning() {
+        synchronized (mScanCallbackLock) {
+            FrameworkStatsLog.write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
+                    FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__SCAN_STOPPED);
+
+            int retVal = nativeStopScan();
+            mScanCallback = null;
+            mScanCallbackExecutor = null;
+            return retVal;
+        }
+    }
+
+    private boolean requestFrontend() {
+        int[] feHandle = new int[1];
+        TunerFrontendRequest request = new TunerFrontendRequest();
+        request.clientId = mClientId;
+        request.frontendType = mFrontendType;
+        boolean granted = mTunerResourceManager.requestFrontend(request, feHandle);
+        if (granted) {
+            mFrontendHandle = feHandle[0];
+            mFrontend = nativeOpenFrontendByHandle(mFrontendHandle);
+        }
+        return granted;
+    }
+
+    /**
+     * Sets Low-Noise Block downconverter (LNB) for satellite frontend.
+     *
+     * <p>This assigns a hardware LNB resource to the satellite tuner. It can be
+     * called multiple times to update LNB assignment.
+     *
+     * @param lnb the LNB instance.
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    private int setLnb(@NonNull Lnb lnb) {
+        return nativeSetLnb(lnb);
+    }
+
+    /**
+     * Enable or Disable Low Noise Amplifier (LNA).
+     *
+     * @param enable {@code true} to activate LNA module; {@code false} to deactivate LNA.
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int setLnaEnabled(boolean enable) {
+        return nativeSetLna(enable);
+    }
+
+    /**
+     * Gets the statuses of the frontend.
+     *
+     * <p>This retrieve the statuses of the frontend for given status types.
+     *
+     * @param statusTypes an array of status types which the caller requests. Any types that are not
+     *        in {@link FrontendInfo#getStatusCapabilities()} would be ignored.
+     * @return statuses which response the caller's requests. {@code null} if the operation failed.
+     */
+    @Nullable
+    public FrontendStatus getFrontendStatus(@NonNull @FrontendStatusType int[] statusTypes) {
+        if (mFrontend == null) {
+            throw new IllegalStateException("frontend is not initialized");
+        }
+        return nativeGetFrontendStatus(statusTypes);
+    }
+
+    /**
+     * Gets hardware sync ID for audio and video.
+     *
+     * @param filter the filter instance for the hardware sync ID.
+     * @return the id of hardware A/V sync.
+     */
+    public int getAvSyncHwId(@NonNull Filter filter) {
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return INVALID_AV_SYNC_ID;
+        }
+        Integer id = nativeGetAvSyncHwId(filter);
+        return id == null ? INVALID_AV_SYNC_ID : id;
+    }
+
+    /**
+     * Gets the current timestamp for Audio/Video sync
+     *
+     * <p>The timestamp is maintained by hardware. The timestamp based on 90KHz, and it's format is
+     * the same as PTS (Presentation Time Stamp).
+     *
+     * @param avSyncHwId the hardware id of A/V sync.
+     * @return the current timestamp of hardware A/V sync.
+     */
+    public long getAvSyncTime(int avSyncHwId) {
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return INVALID_TIMESTAMP;
+        }
+        Long time = nativeGetAvSyncTime(avSyncHwId);
+        return time == null ? INVALID_TIMESTAMP : time;
+    }
+
+    /**
+     * Connects Conditional Access Modules (CAM) through Common Interface (CI).
+     *
+     * <p>The demux uses the output from the frontend as the input by default, and must change to
+     * use the output from CI-CAM as the input after this call.
+     *
+     * <p> Note that this API is used to connect the CI-CAM to the Demux module while
+     * {@link #connectFrontendToCiCam(int)} is used to connect CI-CAM to the Frontend module.
+     *
+     * @param ciCamId specify CI-CAM Id to connect.
+     * @return result status of the operation.
+     */
+    @Result
+    public int connectCiCam(int ciCamId) {
+        if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return nativeConnectCiCam(ciCamId);
+        }
+        return RESULT_UNAVAILABLE;
+    }
+
+    /**
+     * Connect Conditional Access Modules (CAM) Frontend to support Common Interface (CI)
+     * by-pass mode.
+     *
+     * <p>It is used by the client to link CI-CAM to a Frontend. CI by-pass mode requires that
+     * the CICAM also receives the TS concurrently from the frontend when the Demux is receiving
+     * the TS directly from the frontend.
+     *
+     * <p> Note that this API is used to connect the CI-CAM to the Frontend module while
+     * {@link #connectCiCam(int)} is used to connect CI-CAM to the Demux module.
+     *
+     * <p>Use {@link #disconnectFrontendToCiCam(int)} to disconnect.
+     *
+     * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would cause
+     * no-op and return {@link #INVALID_LTS_ID}. Use {@link TunerVersionChecker#getTunerVersion()}
+     * to check the version.
+     *
+     * @param ciCamId specify CI-CAM Id, which is the id of the Conditional Access Modules (CAM)
+     *                Common Interface (CI), to link.
+     * @return Local transport stream id when connection is successfully established. Failed
+     *         operation returns {@link #INVALID_LTS_ID} while unsupported version also returns
+     *         {@link #INVALID_LTS_ID}. Check the current HAL version using
+     *         {@link TunerVersionChecker#getTunerVersion()}.
+     */
+    public int connectFrontendToCiCam(int ciCamId) {
+        if (TunerVersionChecker.checkHigherOrEqualVersionTo(TunerVersionChecker.TUNER_VERSION_1_1,
+                "linkFrontendToCiCam")) {
+            if (checkCiCamResource(ciCamId)
+                    && checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
+                return nativeLinkCiCam(ciCamId);
+            }
+        }
+        return INVALID_LTS_ID;
+    }
+
+    /**
+     * Disconnects Conditional Access Modules (CAM).
+     *
+     * <p>The demux will use the output from the frontend as the input after this call.
+     *
+     * <p> Note that this API is used to disconnect the CI-CAM to the Demux module while
+     * {@link #disconnectFrontendToCiCam(int)} is used to disconnect CI-CAM to the Frontend module.
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int disconnectCiCam() {
+        if (mDemuxHandle != null) {
+            return nativeDisconnectCiCam();
+        }
+        return RESULT_UNAVAILABLE;
+    }
+
+    /**
+     * Disconnect Conditional Access Modules (CAM) Frontend.
+     *
+     * <p>It is used by the client to unlink CI-CAM to a Frontend.
+     *
+     * <p> Note that this API is used to disconnect the CI-CAM to the Demux module while
+     * {@link #disconnectCiCam(int)} is used to disconnect CI-CAM to the Frontend module.
+     *
+     * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would cause
+     * no-op. Use {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     *
+     * @param ciCamId specify CI-CAM Id, which is the id of the Conditional Access Modules (CAM)
+     *                Common Interface (CI), to disconnect.
+     * @return result status of the operation. Unsupported version would return
+     *         {@link #RESULT_UNAVAILABLE}
+     */
+    @Result
+    public int disconnectFrontendToCiCam(int ciCamId) {
+        if (TunerVersionChecker.checkHigherOrEqualVersionTo(TunerVersionChecker.TUNER_VERSION_1_1,
+                "unlinkFrontendToCiCam")) {
+            if (mFrontendCiCamHandle != null && mFrontendCiCamId != null
+                    && mFrontendCiCamId == ciCamId) {
+                int result = nativeUnlinkCiCam(ciCamId);
+                if (result == RESULT_SUCCESS) {
+                    mTunerResourceManager.releaseCiCam(mFrontendCiCamHandle, mClientId);
+                    mFrontendCiCamId = null;
+                    mFrontendCiCamHandle = null;
+                }
+                return result;
+            }
+        }
+        return RESULT_UNAVAILABLE;
+    }
+
+    /**
+     * Gets the currently initialized and activated frontend information. To get all the available
+     * frontend info on the device, use {@link getAvailableFrontendInfos()}.
+     *
+     * @return The active frontend information. {@code null} if the operation failed.
+     * @throws IllegalStateException if there is no active frontend currently.
+     */
+    @Nullable
+    public FrontendInfo getFrontendInfo() {
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND)) {
+            return null;
+        }
+        if (mFrontend == null) {
+            throw new IllegalStateException("frontend is not initialized");
+        }
+        if (mFrontendInfo == null) {
+            mFrontendInfo = getFrontendInfoById(mFrontend.mId);
+        }
+        return mFrontendInfo;
+    }
+
+    /**
+     * Gets a list of all the available frontend information on the device. To get the information
+     * of the currently active frontend, use {@link getFrontendInfo()}. The active frontend
+     * information is also included in the list of the available frontend information.
+     *
+     * @return The list of all the available frontend information. {@code null} if the operation
+     * failed.
+     */
+    @Nullable
+    @SuppressLint("NullableCollection")
+    public List<FrontendInfo> getAvailableFrontendInfos() {
+        FrontendInfo[] feInfoList = getFrontendInfoListInternal();
+        if (feInfoList == null) {
+            return null;
+        }
+        return Arrays.asList(feInfoList);
+    }
+
+    /** @hide */
+    public FrontendInfo getFrontendInfoById(int id) {
+        return nativeGetFrontendInfo(id);
+    }
+
+    /**
+     * Gets Demux capabilities.
+     *
+     * @return A {@link DemuxCapabilities} instance that represents the demux capabilities.
+     *         {@code null} if the operation failed.
+     */
+    @Nullable
+    public DemuxCapabilities getDemuxCapabilities() {
+        return nativeGetDemuxCapabilities();
+    }
+
+    private void onFrontendEvent(int eventType) {
+        Log.d(TAG, "Got event from tuning. Event type: " + eventType);
+        synchronized (mOnTuneEventLock) {
+            if (mOnTuneEventExecutor != null && mOnTuneEventListener != null) {
+                mOnTuneEventExecutor.execute(() -> mOnTuneEventListener.onTuneEvent(eventType));
+            }
+        }
+
+        Log.d(TAG, "Wrote Stats Log for the events from tuning.");
+        if (eventType == OnTuneEventListener.SIGNAL_LOCKED) {
+            FrameworkStatsLog
+                    .write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
+                        FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__LOCKED);
+        } else if (eventType == OnTuneEventListener.SIGNAL_NO_SIGNAL) {
+            FrameworkStatsLog
+                    .write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
+                        FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__NOT_LOCKED);
+        } else if (eventType == OnTuneEventListener.SIGNAL_LOST_LOCK) {
+            FrameworkStatsLog
+                    .write(FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
+                        FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__SIGNAL_LOST);
+        }
+    }
+
+    private void onLocked() {
+        Log.d(TAG, "Wrote Stats Log for locked event from scanning.");
+        FrameworkStatsLog.write(
+                FrameworkStatsLog.TV_TUNER_STATE_CHANGED, mUserId,
+                FrameworkStatsLog.TV_TUNER_STATE_CHANGED__STATE__LOCKED);
+
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(() -> mScanCallback.onLocked());
+            }
+        }
+    }
+
+    private void onScanStopped() {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(() -> mScanCallback.onScanStopped());
+            }
+        }
+    }
+
+    private void onProgress(int percent) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(() -> mScanCallback.onProgress(percent));
+            }
+        }
+    }
+
+    private void onFrequenciesReport(int[] frequency) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(() -> mScanCallback.onFrequenciesReported(frequency));
+            }
+        }
+    }
+
+    private void onSymbolRates(int[] rate) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(() -> mScanCallback.onSymbolRatesReported(rate));
+            }
+        }
+    }
+
+    private void onHierarchy(int hierarchy) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(() -> mScanCallback.onHierarchyReported(hierarchy));
+            }
+        }
+    }
+
+    private void onSignalType(int signalType) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(() -> mScanCallback.onSignalTypeReported(signalType));
+            }
+        }
+    }
+
+    private void onPlpIds(int[] plpIds) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(() -> mScanCallback.onPlpIdsReported(plpIds));
+            }
+        }
+    }
+
+    private void onGroupIds(int[] groupIds) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(() -> mScanCallback.onGroupIdsReported(groupIds));
+            }
+        }
+    }
+
+    private void onInputStreamIds(int[] inputStreamIds) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(
+                        () -> mScanCallback.onInputStreamIdsReported(inputStreamIds));
+            }
+        }
+    }
+
+    private void onDvbsStandard(int dvbsStandandard) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(
+                        () -> mScanCallback.onDvbsStandardReported(dvbsStandandard));
+            }
+        }
+    }
+
+    private void onDvbtStandard(int dvbtStandard) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(
+                        () -> mScanCallback.onDvbtStandardReported(dvbtStandard));
+            }
+        }
+    }
+
+    private void onAnalogSifStandard(int sif) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(() -> mScanCallback.onAnalogSifStandardReported(sif));
+            }
+        }
+    }
+
+    private void onAtsc3PlpInfos(Atsc3PlpInfo[] atsc3PlpInfos) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(
+                        () -> mScanCallback.onAtsc3PlpInfosReported(atsc3PlpInfos));
+            }
+        }
+    }
+
+    private void onModulationReported(int modulation) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(
+                        () -> mScanCallback.onModulationReported(modulation));
+            }
+        }
+    }
+
+    private void onPriorityReported(boolean isHighPriority) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(
+                        () -> mScanCallback.onPriorityReported(isHighPriority));
+            }
+        }
+    }
+
+    private void onDvbcAnnexReported(int dvbcAnnex) {
+        synchronized (mScanCallbackLock) {
+            if (mScanCallbackExecutor != null && mScanCallback != null) {
+                mScanCallbackExecutor.execute(
+                        () -> mScanCallback.onDvbcAnnexReported(dvbcAnnex));
+            }
+        }
+    }
+
+    /**
+     * Opens a filter object based on the given types and buffer size.
+     *
+     * @param mainType the main type of the filter.
+     * @param subType the subtype of the filter.
+     * @param bufferSize the buffer size of the filter to be opened in bytes. The buffer holds the
+     * data output from the filter.
+     * @param executor the executor on which callback will be invoked. The default event handler
+     * executor is used if it's {@code null}.
+     * @param cb the callback to receive notifications from filter.
+     * @return the opened filter. {@code null} if the operation failed.
+     */
+    @Nullable
+    public Filter openFilter(@Type int mainType, @Subtype int subType,
+            @BytesLong long bufferSize, @CallbackExecutor @Nullable Executor executor,
+            @Nullable FilterCallback cb) {
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return null;
+        }
+        Filter filter = nativeOpenFilter(
+                mainType, TunerUtils.getFilterSubtype(mainType, subType), bufferSize);
+        if (filter != null) {
+            filter.setType(mainType, subType);
+            filter.setCallback(cb, executor);
+            if (mHandler == null) {
+                mHandler = createEventHandler();
+            }
+            synchronized (mFilters) {
+                WeakReference<Filter> weakFilter = new WeakReference<Filter>(filter);
+                mFilters.add(weakFilter);
+                if (mFilters.size() > FILTER_CLEANUP_THRESHOLD) {
+                    Iterator<WeakReference<Filter>> iterator = mFilters.iterator();
+                    while (iterator.hasNext()) {
+                        WeakReference<Filter> wFilter = iterator.next();
+                        if (wFilter.get() == null) {
+                            iterator.remove();
+                        }
+                    }
+                }
+            }
+        }
+        return filter;
+    }
+
+    /**
+     * Opens an LNB (low-noise block downconverter) object.
+     *
+     * <p>If there is an existing Lnb object, it will be replace by the newly opened one.
+     *
+     * @param executor the executor on which callback will be invoked. The default event handler
+     * executor is used if it's {@code null}.
+     * @param cb the callback to receive notifications from LNB.
+     * @return the opened LNB object. {@code null} if the operation failed.
+     */
+    @Nullable
+    public Lnb openLnb(@CallbackExecutor @NonNull Executor executor, @NonNull LnbCallback cb) {
+        Objects.requireNonNull(executor, "executor must not be null");
+        Objects.requireNonNull(cb, "LnbCallback must not be null");
+        if (mLnb != null) {
+            mLnb.setCallback(executor, cb, this);
+            return mLnb;
+        }
+        if (checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_LNB) && mLnb != null) {
+            mLnb.setCallback(executor, cb, this);
+            setLnb(mLnb);
+            return mLnb;
+        }
+        return null;
+    }
+
+    /**
+     * Opens an LNB (low-noise block downconverter) object specified by the give name.
+     *
+     * @param name the LNB name.
+     * @param executor the executor on which callback will be invoked. The default event handler
+     * executor is used if it's {@code null}.
+     * @param cb the callback to receive notifications from LNB.
+     * @return the opened LNB object. {@code null} if the operation failed.
+     */
+    @Nullable
+    public Lnb openLnbByName(@NonNull String name, @CallbackExecutor @NonNull Executor executor,
+            @NonNull LnbCallback cb) {
+        Objects.requireNonNull(name, "LNB name must not be null");
+        Objects.requireNonNull(executor, "executor must not be null");
+        Objects.requireNonNull(cb, "LnbCallback must not be null");
+        Lnb newLnb = nativeOpenLnbByName(name);
+        if (newLnb != null) {
+            if (mLnb != null) {
+                mLnb.close();
+                mLnbHandle = null;
+            }
+            mLnb = newLnb;
+            mLnb.setCallback(executor, cb, this);
+            setLnb(mLnb);
+        }
+        return mLnb;
+    }
+
+    private boolean requestLnb() {
+        int[] lnbHandle = new int[1];
+        TunerLnbRequest request = new TunerLnbRequest();
+        request.clientId = mClientId;
+        boolean granted = mTunerResourceManager.requestLnb(request, lnbHandle);
+        if (granted) {
+            mLnbHandle = lnbHandle[0];
+            mLnb = nativeOpenLnbByHandle(mLnbHandle);
+        }
+        return granted;
+    }
+
+    /**
+     * Open a time filter object.
+     *
+     * @return the opened time filter object. {@code null} if the operation failed.
+     */
+    @Nullable
+    public TimeFilter openTimeFilter() {
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return null;
+        }
+        return nativeOpenTimeFilter();
+    }
+
+    /**
+     * Opens a Descrambler in tuner.
+     *
+     * @return a {@link Descrambler} object.
+     */
+    @RequiresPermission(android.Manifest.permission.ACCESS_TV_DESCRAMBLER)
+    @Nullable
+    public Descrambler openDescrambler() {
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return null;
+        }
+        return requestDescrambler();
+    }
+
+    /**
+     * Open a DVR (Digital Video Record) recorder instance.
+     *
+     * @param bufferSize the buffer size of the output in bytes. It's used to hold output data of
+     * the attached filters.
+     * @param executor the executor on which callback will be invoked. The default event handler
+     * executor is used if it's {@code null}.
+     * @param l the listener to receive notifications from DVR recorder.
+     * @return the opened DVR recorder object. {@code null} if the operation failed.
+     */
+    @Nullable
+    public DvrRecorder openDvrRecorder(
+            @BytesLong long bufferSize,
+            @CallbackExecutor @NonNull Executor executor,
+            @NonNull OnRecordStatusChangedListener l) {
+        Objects.requireNonNull(executor, "executor must not be null");
+        Objects.requireNonNull(l, "OnRecordStatusChangedListener must not be null");
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return null;
+        }
+        DvrRecorder dvr = nativeOpenDvrRecorder(bufferSize);
+        dvr.setListener(executor, l);
+        return dvr;
+    }
+
+    /**
+     * Open a DVR (Digital Video Record) playback instance.
+     *
+     * @param bufferSize the buffer size of the output in bytes. It's used to hold output data of
+     * the attached filters.
+     * @param executor the executor on which callback will be invoked. The default event handler
+     * executor is used if it's {@code null}.
+     * @param l the listener to receive notifications from DVR recorder.
+     * @return the opened DVR playback object. {@code null} if the operation failed.
+     */
+    @Nullable
+    public DvrPlayback openDvrPlayback(
+            @BytesLong long bufferSize,
+            @CallbackExecutor @NonNull Executor executor,
+            @NonNull OnPlaybackStatusChangedListener l) {
+        Objects.requireNonNull(executor, "executor must not be null");
+        Objects.requireNonNull(l, "OnPlaybackStatusChangedListener must not be null");
+        if (!checkResource(TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX)) {
+            return null;
+        }
+        DvrPlayback dvr = nativeOpenDvrPlayback(bufferSize);
+        dvr.setListener(executor, l);
+        return dvr;
+    }
+
+    private boolean requestDemux() {
+        int[] demuxHandle = new int[1];
+        TunerDemuxRequest request = new TunerDemuxRequest();
+        request.clientId = mClientId;
+        boolean granted = mTunerResourceManager.requestDemux(request, demuxHandle);
+        if (granted) {
+            mDemuxHandle = demuxHandle[0];
+            nativeOpenDemuxByhandle(mDemuxHandle);
+        }
+        return granted;
+    }
+
+    private Descrambler requestDescrambler() {
+        int[] descramblerHandle = new int[1];
+        TunerDescramblerRequest request = new TunerDescramblerRequest();
+        request.clientId = mClientId;
+        boolean granted = mTunerResourceManager.requestDescrambler(request, descramblerHandle);
+        if (!granted) {
+            return null;
+        }
+        int handle = descramblerHandle[0];
+        Descrambler descrambler = nativeOpenDescramblerByHandle(handle);
+        if (descrambler != null) {
+            synchronized (mDescramblers) {
+                WeakReference weakDescrambler = new WeakReference<Descrambler>(descrambler);
+                mDescramblers.put(handle, weakDescrambler);
+            }
+        } else {
+            mTunerResourceManager.releaseDescrambler(handle, mClientId);
+        }
+        return descrambler;
+    }
+
+    private boolean requestFrontendCiCam(int ciCamId) {
+        int[] ciCamHandle = new int[1];
+        TunerCiCamRequest request = new TunerCiCamRequest();
+        request.clientId = mClientId;
+        request.ciCamId = ciCamId;
+        boolean granted = mTunerResourceManager.requestCiCam(request, ciCamHandle);
+        if (granted) {
+            mFrontendCiCamHandle = ciCamHandle[0];
+            mFrontendCiCamId = ciCamId;
+        }
+        return granted;
+    }
+
+    private boolean checkResource(int resourceType)  {
+        switch (resourceType) {
+            case TunerResourceManager.TUNER_RESOURCE_TYPE_FRONTEND: {
+                if (mFrontendHandle == null && !requestFrontend()) {
+                    return false;
+                }
+                break;
+            }
+            case TunerResourceManager.TUNER_RESOURCE_TYPE_LNB: {
+                if (mLnb == null && !requestLnb()) {
+                    return false;
+                }
+                break;
+            }
+            case TunerResourceManager.TUNER_RESOURCE_TYPE_DEMUX: {
+                if (mDemuxHandle == null && !requestDemux()) {
+                    return false;
+                }
+                break;
+            }
+            default:
+                return false;
+        }
+        return true;
+    }
+
+    private boolean checkCiCamResource(int ciCamId) {
+        if (mFrontendCiCamHandle == null && !requestFrontendCiCam(ciCamId)) {
+            return false;
+        }
+        return true;
+    }
+
+    /* package */ void releaseLnb() {
+        if (mLnbHandle != null) {
+            // LNB handle can be null if it's opened by name.
+            mTunerResourceManager.releaseLnb(mLnbHandle, mClientId);
+            mLnbHandle = null;
+        }
+        mLnb = null;
+    }
+}
diff --git a/android/media/tv/tuner/TunerUtils.java b/android/media/tv/tuner/TunerUtils.java
new file mode 100644
index 0000000..a13077c
--- /dev/null
+++ b/android/media/tv/tuner/TunerUtils.java
@@ -0,0 +1,172 @@
+/*
+ * Copyright 2019 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.tv.tuner;
+
+import android.annotation.Nullable;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.filter.Filter;
+
+/**
+ * Utility class for tuner framework.
+ *
+ * @hide
+ */
+public final class TunerUtils {
+
+    /**
+     * Gets the corresponding filter subtype constant defined in tuner HAL.
+     *
+     * @param mainType filter main type.
+     * @param subtype filter subtype.
+     */
+    public static int getFilterSubtype(@Filter.Type int mainType, @Filter.Subtype int subtype) {
+        if (mainType == Filter.TYPE_TS) {
+            switch (subtype) {
+                case Filter.SUBTYPE_UNDEFINED:
+                    return Constants.DemuxTsFilterType.UNDEFINED;
+                case Filter.SUBTYPE_SECTION:
+                    return Constants.DemuxTsFilterType.SECTION;
+                case Filter.SUBTYPE_PES:
+                    return Constants.DemuxTsFilterType.PES;
+                case Filter.SUBTYPE_TS:
+                    return Constants.DemuxTsFilterType.TS;
+                case Filter.SUBTYPE_AUDIO:
+                    return Constants.DemuxTsFilterType.AUDIO;
+                case Filter.SUBTYPE_VIDEO:
+                    return Constants.DemuxTsFilterType.VIDEO;
+                case Filter.SUBTYPE_PCR:
+                    return Constants.DemuxTsFilterType.PCR;
+                case Filter.SUBTYPE_RECORD:
+                    return Constants.DemuxTsFilterType.RECORD;
+                case Filter.SUBTYPE_TEMI:
+                    return Constants.DemuxTsFilterType.TEMI;
+                default:
+                    break;
+            }
+        } else if (mainType == Filter.TYPE_MMTP) {
+            switch (subtype) {
+                case Filter.SUBTYPE_UNDEFINED:
+                    return Constants.DemuxMmtpFilterType.UNDEFINED;
+                case Filter.SUBTYPE_SECTION:
+                    return Constants.DemuxMmtpFilterType.SECTION;
+                case Filter.SUBTYPE_PES:
+                    return Constants.DemuxMmtpFilterType.PES;
+                case Filter.SUBTYPE_MMTP:
+                    return Constants.DemuxMmtpFilterType.MMTP;
+                case Filter.SUBTYPE_AUDIO:
+                    return Constants.DemuxMmtpFilterType.AUDIO;
+                case Filter.SUBTYPE_VIDEO:
+                    return Constants.DemuxMmtpFilterType.VIDEO;
+                case Filter.SUBTYPE_RECORD:
+                    return Constants.DemuxMmtpFilterType.RECORD;
+                case Filter.SUBTYPE_DOWNLOAD:
+                    return Constants.DemuxMmtpFilterType.DOWNLOAD;
+                default:
+                    break;
+            }
+
+        } else if (mainType == Filter.TYPE_IP) {
+            switch (subtype) {
+                case Filter.SUBTYPE_UNDEFINED:
+                    return Constants.DemuxIpFilterType.UNDEFINED;
+                case Filter.SUBTYPE_SECTION:
+                    return Constants.DemuxIpFilterType.SECTION;
+                case Filter.SUBTYPE_NTP:
+                    return Constants.DemuxIpFilterType.NTP;
+                case Filter.SUBTYPE_IP_PAYLOAD:
+                    return Constants.DemuxIpFilterType.IP_PAYLOAD;
+                case Filter.SUBTYPE_IP:
+                    return Constants.DemuxIpFilterType.IP;
+                case Filter.SUBTYPE_PAYLOAD_THROUGH:
+                    return Constants.DemuxIpFilterType.PAYLOAD_THROUGH;
+                default:
+                    break;
+            }
+        } else if (mainType == Filter.TYPE_TLV) {
+            switch (subtype) {
+                case Filter.SUBTYPE_UNDEFINED:
+                    return Constants.DemuxTlvFilterType.UNDEFINED;
+                case Filter.SUBTYPE_SECTION:
+                    return Constants.DemuxTlvFilterType.SECTION;
+                case Filter.SUBTYPE_TLV:
+                    return Constants.DemuxTlvFilterType.TLV;
+                case Filter.SUBTYPE_PAYLOAD_THROUGH:
+                    return Constants.DemuxTlvFilterType.PAYLOAD_THROUGH;
+                default:
+                    break;
+            }
+        } else if (mainType == Filter.TYPE_ALP) {
+            switch (subtype) {
+                case Filter.SUBTYPE_UNDEFINED:
+                    return Constants.DemuxAlpFilterType.UNDEFINED;
+                case Filter.SUBTYPE_SECTION:
+                    return Constants.DemuxAlpFilterType.SECTION;
+                case Filter.SUBTYPE_PTP:
+                    return Constants.DemuxAlpFilterType.PTP;
+                case Filter.SUBTYPE_PAYLOAD_THROUGH:
+                    return Constants.DemuxAlpFilterType.PAYLOAD_THROUGH;
+                default:
+                    break;
+            }
+        }
+        throw new IllegalArgumentException(
+                "Invalid filter types. Main type=" + mainType + ", subtype=" + subtype);
+    }
+
+    /**
+     * Gets an throwable instance for the corresponding result.
+     */
+    @Nullable
+    public static void throwExceptionForResult(
+            @Tuner.Result int r, @Nullable String msg) {
+        if (msg == null) {
+            msg = "";
+        }
+        switch (r) {
+            case Tuner.RESULT_SUCCESS:
+                return;
+            case Tuner.RESULT_INVALID_ARGUMENT:
+                throw new IllegalArgumentException(msg);
+            case Tuner.RESULT_INVALID_STATE:
+                throw new IllegalStateException(msg);
+            case Tuner.RESULT_NOT_INITIALIZED:
+                throw new IllegalStateException("Invalid state: not initialized. " + msg);
+            case Tuner.RESULT_OUT_OF_MEMORY:
+                throw new OutOfMemoryError(msg);
+            case Tuner.RESULT_UNAVAILABLE:
+                throw new IllegalStateException("Invalid state: resource unavailable. " + msg);
+            case Tuner.RESULT_UNKNOWN_ERROR:
+                throw new RuntimeException("Unknown error" + msg);
+            default:
+                break;
+        }
+        throw new RuntimeException("Unexpected result " + r + ".  " + msg);
+    }
+
+    /**
+     * Checks the state of a resource instance.
+     *
+     * @throws IllegalStateException if the resource has already been closed.
+     */
+    public static void checkResourceState(String name, boolean closed) {
+        if (closed) {
+            throw new IllegalStateException(name + " has been closed");
+        }
+    }
+
+    private TunerUtils() {}
+}
diff --git a/android/media/tv/tuner/TunerVersionChecker.java b/android/media/tv/tuner/TunerVersionChecker.java
new file mode 100644
index 0000000..b40ba1e
--- /dev/null
+++ b/android/media/tv/tuner/TunerVersionChecker.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright 2020 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.tv.tuner;
+
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+import android.annotation.TestApi;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Utility class to check the currently running Tuner Hal implementation version.
+ *
+ * APIs that are not supported by the HAL implementation version would be no-op.
+ *
+ * @hide
+ */
+@SystemApi
+public final class TunerVersionChecker {
+    private static final String TAG = "TunerVersionChecker";
+
+    private TunerVersionChecker() {}
+
+    /** @hide */
+    @IntDef(prefix = "TUNER_VERSION_", value = {TUNER_VERSION_UNKNOWN, TUNER_VERSION_1_0,
+                                                TUNER_VERSION_1_1})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TunerVersion {}
+    /**
+     * Unknown Tuner version.
+     */
+    public static final int TUNER_VERSION_UNKNOWN = 0;
+    /**
+     * Tuner version 1.0.
+     */
+    public static final int TUNER_VERSION_1_0 = (1 << 16);
+    /**
+     * Tuner version 1.1.
+     */
+    public static final int TUNER_VERSION_1_1 = ((1 << 16) | 1);
+
+    /**
+     * Get the current running Tuner version.
+     *
+     * @return Tuner version.
+     */
+    @TunerVersion
+    public static int getTunerVersion() {
+        return Tuner.getTunerVersion();
+    }
+
+    /**
+     * Check if the current running Tuner version supports the given version.
+     *
+     * <p>Note that we treat different major versions as unsupported among each other. If any
+     * feature could be supported across major versions, please use
+     * {@link #isHigherOrEqualVersionTo(int)} to check.
+     *
+     * @param version the version to support.
+     *
+     * @return true if the current version is under the same major version as the given version
+     * and has higher or the same minor version as the given version.
+     * @hide
+     */
+    @TestApi
+    public static boolean supportTunerVersion(@TunerVersion int version) {
+        int currentVersion = Tuner.getTunerVersion();
+        return isHigherOrEqualVersionTo(version)
+                && (getMajorVersion(version) == getMajorVersion(currentVersion));
+    }
+
+    /**
+     * Check if the current running Tuner version is higher than or equal to a given version.
+     *
+     * @param version the version to compare.
+     *
+     * @return true if the current version is higher or equal to the support version.
+     * @hide
+     */
+    @TestApi
+    public static boolean isHigherOrEqualVersionTo(@TunerVersion int version) {
+        int currentVersion = Tuner.getTunerVersion();
+        return currentVersion >= version;
+    }
+
+    /**
+     * Get the major version from a version number.
+     *
+     * @param version the version to be checked.
+     *
+     * @return the major version number.
+     * @hide
+     */
+    @TestApi
+    public static int getMajorVersion(@TunerVersion int version) {
+        return ((version & 0xFFFF0000) >>> 16);
+    }
+
+    /**
+     * Get the major version from a version number.
+     *
+     * @param version the version to be checked.
+     *
+     * @return the minor version number.
+     * @hide
+     */
+    @TestApi
+    public static int getMinorVersion(@TunerVersion int version) {
+        return (version & 0xFFFF);
+    }
+
+    /** @hide */
+    public static boolean checkHigherOrEqualVersionTo(
+            @TunerVersion int version, String methodName) {
+        if (!TunerVersionChecker.isHigherOrEqualVersionTo(version)) {
+            Log.e(TAG, "Current Tuner version "
+                    + TunerVersionChecker.getMajorVersion(Tuner.getTunerVersion()) + "."
+                    + TunerVersionChecker.getMinorVersion(Tuner.getTunerVersion())
+                    + " does not support " + methodName + ".");
+            return false;
+        }
+        return true;
+    }
+
+    /** @hide */
+    public static boolean checkSupportVersion(@TunerVersion int version, String methodName) {
+        if (!TunerVersionChecker.supportTunerVersion(version)) {
+            Log.e(TAG, "Current Tuner version "
+                    + TunerVersionChecker.getMajorVersion(Tuner.getTunerVersion()) + "."
+                    + TunerVersionChecker.getMinorVersion(Tuner.getTunerVersion())
+                    + " does not support " + methodName + ".");
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/android/media/tv/tuner/dvr/DvrPlayback.java b/android/media/tv/tuner/dvr/DvrPlayback.java
new file mode 100644
index 0000000..1f805d7
--- /dev/null
+++ b/android/media/tv/tuner/dvr/DvrPlayback.java
@@ -0,0 +1,272 @@
+/*
+ * Copyright 2019 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.tv.tuner.dvr;
+
+import android.annotation.BytesLong;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.Tuner;
+import android.media.tv.tuner.Tuner.Result;
+import android.media.tv.tuner.TunerUtils;
+import android.media.tv.tuner.filter.Filter;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.util.Log;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
+
+/**
+ * Digital Video Record (DVR) class which provides playback control on Demux's input buffer.
+ *
+ * <p>It's used to play recorded programs.
+ *
+ * @hide
+ */
+@SystemApi
+public class DvrPlayback implements AutoCloseable {
+
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "PLAYBACK_STATUS_",
+            value = {PLAYBACK_STATUS_EMPTY, PLAYBACK_STATUS_ALMOST_EMPTY,
+                    PLAYBACK_STATUS_ALMOST_FULL, PLAYBACK_STATUS_FULL})
+    @interface PlaybackStatus {}
+
+    /**
+     * The space of the playback is empty.
+     */
+    public static final int PLAYBACK_STATUS_EMPTY = Constants.PlaybackStatus.SPACE_EMPTY;
+    /**
+     * The space of the playback is almost empty.
+     *
+     * <p> the threshold is set in {@link DvrSettings}.
+     */
+    public static final int PLAYBACK_STATUS_ALMOST_EMPTY =
+            Constants.PlaybackStatus.SPACE_ALMOST_EMPTY;
+    /**
+     * The space of the playback is almost full.
+     *
+     * <p> the threshold is set in {@link DvrSettings}.
+     */
+    public static final int PLAYBACK_STATUS_ALMOST_FULL =
+            Constants.PlaybackStatus.SPACE_ALMOST_FULL;
+    /**
+     * The space of the playback is full.
+     */
+    public static final int PLAYBACK_STATUS_FULL = Constants.PlaybackStatus.SPACE_FULL;
+
+    private static final String TAG = "TvTunerPlayback";
+
+    private long mNativeContext;
+    private OnPlaybackStatusChangedListener mListener;
+    private Executor mExecutor;
+    private int mUserId;
+    private static int sInstantId = 0;
+    private int mSegmentId = 0;
+    private int mUnderflow;
+    private final Object mListenerLock = new Object();
+
+    private native int nativeAttachFilter(Filter filter);
+    private native int nativeDetachFilter(Filter filter);
+    private native int nativeConfigureDvr(DvrSettings settings);
+    private native int nativeStartDvr();
+    private native int nativeStopDvr();
+    private native int nativeFlushDvr();
+    private native int nativeClose();
+    private native void nativeSetFileDescriptor(int fd);
+    private native long nativeRead(long size);
+    private native long nativeRead(byte[] bytes, long offset, long size);
+
+    private DvrPlayback() {
+        mUserId = Process.myUid();
+        mSegmentId = (sInstantId & 0x0000ffff) << 16;
+        sInstantId++;
+    }
+
+    /** @hide */
+    public void setListener(
+            @NonNull Executor executor, @NonNull OnPlaybackStatusChangedListener listener) {
+        synchronized (mListenerLock) {
+            mExecutor = executor;
+            mListener = listener;
+        }
+    }
+
+    private void onPlaybackStatusChanged(int status) {
+        if (status == PLAYBACK_STATUS_EMPTY) {
+            mUnderflow++;
+        }
+        synchronized (mListenerLock) {
+            if (mExecutor != null && mListener != null) {
+                mExecutor.execute(() -> mListener.onPlaybackStatusChanged(status));
+            }
+        }
+    }
+
+
+    /**
+     * Attaches a filter to DVR interface for playback.
+     *
+     * @deprecated attaching filters is not valid in Dvr Playback use case. This API is a no-op.
+     *             Filters opened by {@link Tuner#openFilter} are used for DVR playback.
+     *
+     * @param filter the filter to be attached.
+     * @return result status of the operation.
+     */
+    @Result
+    @Deprecated
+    public int attachFilter(@NonNull Filter filter) {
+        // no-op
+        return Tuner.RESULT_UNAVAILABLE;
+    }
+
+    /**
+     * Detaches a filter from DVR interface.
+     *
+     * @deprecated detaching filters is not valid in Dvr Playback use case. This API is a no-op.
+     *             Filters opened by {@link Tuner#openFilter} are used for DVR playback.
+     *
+     * @param filter the filter to be detached.
+     * @return result status of the operation.
+     */
+    @Result
+    @Deprecated
+    public int detachFilter(@NonNull Filter filter) {
+        // no-op
+        return Tuner.RESULT_UNAVAILABLE;
+    }
+
+    /**
+     * Configures the DVR.
+     *
+     * @param settings the settings of the DVR interface.
+     * @return result status of the operation.
+     */
+    @Result
+    public int configure(@NonNull DvrSettings settings) {
+        return nativeConfigureDvr(settings);
+    }
+
+    /**
+     * Starts DVR.
+     *
+     * <p>Starts consuming playback data or producing data for recording.
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int start() {
+        mSegmentId =  (mSegmentId & 0xffff0000) | (((mSegmentId & 0x0000ffff) + 1) & 0x0000ffff);
+        mUnderflow = 0;
+        Log.d(TAG, "Write Stats Log for Playback.");
+        FrameworkStatsLog
+                .write(FrameworkStatsLog.TV_TUNER_DVR_STATUS, mUserId,
+                    FrameworkStatsLog.TV_TUNER_DVR_STATUS__TYPE__PLAYBACK,
+                    FrameworkStatsLog.TV_TUNER_DVR_STATUS__STATE__STARTED, mSegmentId, 0);
+        return nativeStartDvr();
+    }
+
+    /**
+     * Stops DVR.
+     *
+     * <p>Stops consuming playback data or producing data for recording.
+     * <p>Does nothing if the filter is stopped or not started.</p>
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int stop() {
+        Log.d(TAG, "Write Stats Log for Playback.");
+        FrameworkStatsLog
+                .write(FrameworkStatsLog.TV_TUNER_DVR_STATUS, mUserId,
+                    FrameworkStatsLog.TV_TUNER_DVR_STATUS__TYPE__PLAYBACK,
+                    FrameworkStatsLog.TV_TUNER_DVR_STATUS__STATE__STOPPED, mSegmentId, mUnderflow);
+        return nativeStopDvr();
+    }
+
+    /**
+     * Flushed DVR data.
+     *
+     * <p>The data in DVR buffer is cleared.
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int flush() {
+        return nativeFlushDvr();
+    }
+
+    /**
+     * Closes the DVR instance to release resources.
+     */
+    @Override
+    public void close() {
+        int res = nativeClose();
+        if (res != Tuner.RESULT_SUCCESS) {
+            TunerUtils.throwExceptionForResult(res, "failed to close DVR playback");
+        }
+    }
+
+    /**
+     * Sets file descriptor to read data.
+     *
+     * <p>When a read operation of the filter object is happening, this method should not be
+     * called.
+     *
+     * @param fd the file descriptor to read data.
+     * @see #read(long)
+     * @see #read(byte[], long, long)
+     */
+    public void setFileDescriptor(@NonNull ParcelFileDescriptor fd) {
+        nativeSetFileDescriptor(fd.getFd());
+    }
+
+    /**
+     * Reads data from the file for DVR playback.
+     *
+     * @param size the maximum number of bytes to read.
+     * @return the number of bytes read.
+     */
+    @BytesLong
+    public long read(@BytesLong long size) {
+        return nativeRead(size);
+    }
+
+    /**
+     * Reads data from the buffer for DVR playback and copies to the given byte array.
+     *
+     * @param bytes the byte array to store the data.
+     * @param offset the index of the first byte in {@code bytes} to copy to.
+     * @param size the maximum number of bytes to read.
+     * @return the number of bytes read.
+     */
+    @BytesLong
+    public long read(@NonNull byte[] bytes, @BytesLong long offset, @BytesLong long size) {
+        if (size + offset > bytes.length) {
+            throw new ArrayIndexOutOfBoundsException(
+                    "Array length=" + bytes.length + ", offset=" + offset + ", size=" + size);
+        }
+        return nativeRead(bytes, offset, size);
+    }
+}
diff --git a/android/media/tv/tuner/dvr/DvrRecorder.java b/android/media/tv/tuner/dvr/DvrRecorder.java
new file mode 100644
index 0000000..2b69466
--- /dev/null
+++ b/android/media/tv/tuner/dvr/DvrRecorder.java
@@ -0,0 +1,246 @@
+/*
+ * Copyright 2019 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.tv.tuner.dvr;
+
+import android.annotation.BytesLong;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.Tuner;
+import android.media.tv.tuner.Tuner.Result;
+import android.media.tv.tuner.TunerUtils;
+import android.media.tv.tuner.filter.Filter;
+import android.os.ParcelFileDescriptor;
+import android.os.Process;
+import android.util.Log;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.util.concurrent.Executor;
+
+
+/**
+ * Digital Video Record (DVR) recorder class which provides record control on Demux's output buffer.
+ *
+ * @hide
+ */
+@SystemApi
+public class DvrRecorder implements AutoCloseable {
+    private static final String TAG = "TvTunerRecord";
+    private long mNativeContext;
+    private OnRecordStatusChangedListener mListener;
+    private Executor mExecutor;
+    private int mUserId;
+    private static int sInstantId = 0;
+    private int mSegmentId = 0;
+    private int mOverflow;
+    private Boolean mIsStopped = true;
+    private final Object mListenerLock = new Object();
+
+    private native int nativeAttachFilter(Filter filter);
+    private native int nativeDetachFilter(Filter filter);
+    private native int nativeConfigureDvr(DvrSettings settings);
+    private native int nativeStartDvr();
+    private native int nativeStopDvr();
+    private native int nativeFlushDvr();
+    private native int nativeClose();
+    private native void nativeSetFileDescriptor(int fd);
+    private native long nativeWrite(long size);
+    private native long nativeWrite(byte[] bytes, long offset, long size);
+
+    private DvrRecorder() {
+        mUserId = Process.myUid();
+        mSegmentId = (sInstantId & 0x0000ffff) << 16;
+        sInstantId++;
+    }
+
+    /** @hide */
+    public void setListener(
+            @NonNull Executor executor, @NonNull OnRecordStatusChangedListener listener) {
+        synchronized (mListenerLock) {
+            mExecutor = executor;
+            mListener = listener;
+        }
+    }
+
+    private void onRecordStatusChanged(int status) {
+        if (status == Filter.STATUS_OVERFLOW) {
+            mOverflow++;
+        }
+        synchronized (mListenerLock) {
+            if (mExecutor != null && mListener != null) {
+                mExecutor.execute(() -> mListener.onRecordStatusChanged(status));
+            }
+        }
+    }
+
+
+    /**
+     * Attaches a filter to DVR interface for recording.
+     *
+     * <p>There can be multiple filters attached. Attached filters are independent, so the order
+     * doesn't matter.
+     *
+     * @param filter the filter to be attached.
+     * @return result status of the operation.
+     */
+    @Result
+    public int attachFilter(@NonNull Filter filter) {
+        return nativeAttachFilter(filter);
+    }
+
+    /**
+     * Detaches a filter from DVR interface.
+     *
+     * @param filter the filter to be detached.
+     * @return result status of the operation.
+     */
+    @Result
+    public int detachFilter(@NonNull Filter filter) {
+        return nativeDetachFilter(filter);
+    }
+
+    /**
+     * Configures the DVR.
+     *
+     * @param settings the settings of the DVR interface.
+     * @return result status of the operation.
+     */
+    @Result
+    public int configure(@NonNull DvrSettings settings) {
+        return nativeConfigureDvr(settings);
+    }
+
+    /**
+     * Starts DVR.
+     *
+     * <p>Starts consuming playback data or producing data for recording.
+     * <p>Does nothing if the filter is stopped or not started.</p>
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int start() {
+        mSegmentId =  (mSegmentId & 0xffff0000) | (((mSegmentId & 0x0000ffff) + 1) & 0x0000ffff);
+        mOverflow = 0;
+        Log.d(TAG, "Write Stats Log for Record.");
+        FrameworkStatsLog
+                .write(FrameworkStatsLog.TV_TUNER_DVR_STATUS, mUserId,
+                    FrameworkStatsLog.TV_TUNER_DVR_STATUS__TYPE__RECORD,
+                    FrameworkStatsLog.TV_TUNER_DVR_STATUS__STATE__STARTED, mSegmentId, 0);
+        synchronized (mIsStopped) {
+            int result = nativeStartDvr();
+            if (result == Tuner.RESULT_SUCCESS) {
+                mIsStopped = false;
+            }
+            return result;
+        }
+    }
+
+    /**
+     * Stops DVR.
+     *
+     * <p>Stops consuming playback data or producing data for recording.
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int stop() {
+        Log.d(TAG, "Write Stats Log for Playback.");
+        FrameworkStatsLog
+                .write(FrameworkStatsLog.TV_TUNER_DVR_STATUS, mUserId,
+                    FrameworkStatsLog.TV_TUNER_DVR_STATUS__TYPE__RECORD,
+                    FrameworkStatsLog.TV_TUNER_DVR_STATUS__STATE__STOPPED, mSegmentId, mOverflow);
+        synchronized (mIsStopped) {
+            int result = nativeStopDvr();
+            if (result == Tuner.RESULT_SUCCESS) {
+                mIsStopped = true;
+            }
+            return result;
+        }
+    }
+
+    /**
+     * Flushed DVR data.
+     *
+     * <p>The data in DVR buffer is cleared.
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int flush() {
+        synchronized (mIsStopped) {
+            if (mIsStopped) {
+                return nativeFlushDvr();
+            }
+            Log.w(TAG, "Cannot flush non-stopped Record DVR.");
+            return Tuner.RESULT_INVALID_STATE;
+        }
+    }
+
+    /**
+     * Closes the DVR instance to release resources.
+     */
+    @Override
+    public void close() {
+        int res = nativeClose();
+        if (res != Tuner.RESULT_SUCCESS) {
+            TunerUtils.throwExceptionForResult(res, "failed to close DVR recorder");
+        }
+    }
+
+    /**
+     * Sets file descriptor to write data.
+     *
+     * <p>When a write operation of the filter object is happening, this method should not be
+     * called.
+     *
+     * @param fd the file descriptor to write data.
+     * @see #write(long)
+     * @see #write(byte[], long, long)
+     */
+    public void setFileDescriptor(@NonNull ParcelFileDescriptor fd) {
+        nativeSetFileDescriptor(fd.getFd());
+    }
+
+    /**
+     * Writes recording data to file.
+     *
+     * @param size the maximum number of bytes to write.
+     * @return the number of bytes written.
+     */
+    @BytesLong
+    public long write(@BytesLong long size) {
+        return nativeWrite(size);
+    }
+
+    /**
+     * Writes recording data to buffer.
+     *
+     * @param bytes the byte array stores the data to be written to DVR.
+     * @param offset the index of the first byte in {@code bytes} to be written to DVR.
+     * @param size the maximum number of bytes to write.
+     * @return the number of bytes written.
+     */
+    @BytesLong
+    public long write(@NonNull byte[] bytes, @BytesLong long offset, @BytesLong long size) {
+        if (size + offset > bytes.length) {
+            throw new ArrayIndexOutOfBoundsException(
+                    "Array length=" + bytes.length + ", offset=" + offset + ", size=" + size);
+        }
+        return nativeWrite(bytes, offset, size);
+    }
+}
diff --git a/android/media/tv/tuner/dvr/DvrSettings.java b/android/media/tv/tuner/dvr/DvrSettings.java
new file mode 100644
index 0000000..60f0d16
--- /dev/null
+++ b/android/media/tv/tuner/dvr/DvrSettings.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2019 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.tv.tuner.dvr;
+
+import android.annotation.BytesLong;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.filter.Filter;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * DVR settings used to configure {@link DvrPlayback} and {@link DvrRecorder}.
+ *
+ * @hide
+ */
+@SystemApi
+public class DvrSettings {
+
+    /** @hide */
+    @IntDef(prefix = "DATA_FORMAT_",
+            value = {DATA_FORMAT_TS, DATA_FORMAT_PES, DATA_FORMAT_ES, DATA_FORMAT_SHV_TLV})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DataFormat {}
+
+    /**
+     * Transport Stream.
+     */
+    public static final int DATA_FORMAT_TS = Constants.DataFormat.TS;
+    /**
+     * Packetized Elementary Stream.
+     */
+    public static final int DATA_FORMAT_PES = Constants.DataFormat.PES;
+    /**
+     * Elementary Stream.
+     */
+    public static final int DATA_FORMAT_ES = Constants.DataFormat.ES;
+    /**
+     * TLV (type-length-value) Stream for SHV
+     */
+    public static final int DATA_FORMAT_SHV_TLV = Constants.DataFormat.SHV_TLV;
+
+
+    @Filter.Status
+    private final int mStatusMask;
+    @BytesLong
+    private final long mLowThreshold;
+    @BytesLong
+    private final long mHighThreshold;
+    @BytesLong
+    private final long mPacketSize;
+    @DataFormat
+    private final int mDataFormat;
+
+    private DvrSettings(@Filter.Status int statusMask, @BytesLong long lowThreshold,
+            @BytesLong long highThreshold, @BytesLong long packetSize, @DataFormat int dataFormat) {
+        mStatusMask = statusMask;
+        mLowThreshold = lowThreshold;
+        mHighThreshold = highThreshold;
+        mPacketSize = packetSize;
+        mDataFormat = dataFormat;
+    }
+
+    /**
+     * Gets status mask.
+     */
+    @Filter.Status
+    public int getStatusMask() {
+        return mStatusMask;
+    }
+
+    /**
+     * Gets low threshold in bytes.
+     */
+    @BytesLong
+    public long getLowThreshold() {
+        return mLowThreshold;
+    }
+
+    /**
+     * Sets high threshold in bytes.
+     */
+    @BytesLong
+    public long getHighThreshold() {
+        return mHighThreshold;
+    }
+
+    /**
+     * Gets packet size in bytes.
+     */
+    @BytesLong
+    public long getPacketSize() {
+        return mPacketSize;
+    }
+
+    /**
+     * Gets data format.
+     */
+    @DataFormat
+    public int getDataFormat() {
+        return mDataFormat;
+    }
+
+    /**
+     * Creates a builder for {@link DvrSettings}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link DvrSettings}.
+     */
+    public static final class Builder {
+        private int mStatusMask;
+        private long mLowThreshold;
+        private long mHighThreshold;
+        private long mPacketSize;
+        @DataFormat
+        private int mDataFormat;
+
+        /**
+         * Sets status mask.
+         *
+         * <p>Use Filter.STATUS_ for {@link DvrRecorder} and DvrPlayback.STATUS_ for
+         * {@link DvrPlayback}.
+         * <p>If status mask is not set, no status is send to the listener.
+         */
+        @NonNull
+        public Builder setStatusMask(@Filter.Status int statusMask) {
+            this.mStatusMask = statusMask;
+            return this;
+        }
+
+        /**
+         * Sets low threshold in bytes.
+         */
+        @NonNull
+        public Builder setLowThreshold(@BytesLong long lowThreshold) {
+            this.mLowThreshold = lowThreshold;
+            return this;
+        }
+
+        /**
+         * Sets high threshold in bytes.
+         */
+        @NonNull
+        public Builder setHighThreshold(@BytesLong long highThreshold) {
+            this.mHighThreshold = highThreshold;
+            return this;
+        }
+
+        /**
+         * Sets packet size in bytes.
+         */
+        @NonNull
+        public Builder setPacketSize(@BytesLong long packetSize) {
+            this.mPacketSize = packetSize;
+            return this;
+        }
+
+        /**
+         * Sets data format.
+         */
+        @NonNull
+        public Builder setDataFormat(@DataFormat int dataFormat) {
+            this.mDataFormat = dataFormat;
+            return this;
+        }
+
+        /**
+         * Builds a {@link DvrSettings} object.
+         */
+        @NonNull
+        public DvrSettings build() {
+            return new DvrSettings(
+                    mStatusMask, mLowThreshold, mHighThreshold, mPacketSize, mDataFormat);
+        }
+    }
+}
diff --git a/android/media/tv/tuner/dvr/OnPlaybackStatusChangedListener.java b/android/media/tv/tuner/dvr/OnPlaybackStatusChangedListener.java
new file mode 100644
index 0000000..a9a1779
--- /dev/null
+++ b/android/media/tv/tuner/dvr/OnPlaybackStatusChangedListener.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2019 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.tv.tuner.dvr;
+
+import android.annotation.SystemApi;
+
+/**
+ * Listener interface for receiving information from DVR playback.
+ *
+ * @hide
+ */
+@SystemApi
+public interface OnPlaybackStatusChangedListener {
+    /**
+     * Invoked when playback status changed.
+     */
+    void onPlaybackStatusChanged(@DvrPlayback.PlaybackStatus int status);
+}
diff --git a/android/media/tv/tuner/dvr/OnRecordStatusChangedListener.java b/android/media/tv/tuner/dvr/OnRecordStatusChangedListener.java
new file mode 100644
index 0000000..cb6ccab
--- /dev/null
+++ b/android/media/tv/tuner/dvr/OnRecordStatusChangedListener.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2019 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.tv.tuner.dvr;
+
+import android.annotation.SystemApi;
+import android.media.tv.tuner.filter.Filter;
+
+/**
+ * Listener interface for receiving information from DVR recorder.
+ *
+ * @hide
+ */
+@SystemApi
+public interface OnRecordStatusChangedListener {
+    /**
+     * Invoked when record status changed.
+     */
+    void onRecordStatusChanged(@Filter.Status int status);
+}
diff --git a/android/media/tv/tuner/filter/AlpFilterConfiguration.java b/android/media/tv/tuner/filter/AlpFilterConfiguration.java
new file mode 100644
index 0000000..29bc2c9
--- /dev/null
+++ b/android/media/tv/tuner/filter/AlpFilterConfiguration.java
@@ -0,0 +1,167 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Filter configuration for a ALP filter.
+ *
+ * @hide
+ */
+@SystemApi
+public final class AlpFilterConfiguration extends FilterConfiguration {
+    /**
+     * IPv4 packet type.
+     */
+    public static final int PACKET_TYPE_IPV4 = 0;
+    /**
+     * Compressed packet type.
+     */
+    public static final int PACKET_TYPE_COMPRESSED = 2;
+    /**
+     * Signaling packet type.
+     */
+    public static final int PACKET_TYPE_SIGNALING = 4;
+    /**
+     * Extension packet type.
+     */
+    public static final int PACKET_TYPE_EXTENSION = 6;
+    /**
+     * MPEG-2 TS packet type.
+     */
+    public static final int PACKET_TYPE_MPEG2_TS = 7;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "LENGTH_TYPE_", value =
+            {LENGTH_TYPE_UNDEFINED, LENGTH_TYPE_WITHOUT_ADDITIONAL_HEADER,
+            LENGTH_TYPE_WITH_ADDITIONAL_HEADER})
+    public @interface LengthType {}
+
+    /**
+     * Length type not defined.
+     */
+    public static final int LENGTH_TYPE_UNDEFINED = Constants.DemuxAlpLengthType.UNDEFINED;
+    /**
+     * Length does NOT include additional header.
+     */
+    public static final int LENGTH_TYPE_WITHOUT_ADDITIONAL_HEADER =
+            Constants.DemuxAlpLengthType.WITHOUT_ADDITIONAL_HEADER;
+    /**
+     * Length includes additional header.
+     */
+    public static final int LENGTH_TYPE_WITH_ADDITIONAL_HEADER =
+            Constants.DemuxAlpLengthType.WITH_ADDITIONAL_HEADER;
+
+
+    private final int mPacketType;
+    private final int mLengthType;
+
+    private AlpFilterConfiguration(Settings settings, int packetType, int lengthType) {
+        super(settings);
+        mPacketType = packetType;
+        mLengthType = lengthType;
+    }
+
+    @Override
+    public int getType() {
+        return Filter.TYPE_ALP;
+    }
+
+    /**
+     * Gets packet type.
+     *
+     * <p>The meaning of each packet type value is shown in ATSC A/330:2019 table 5.2.
+     */
+    public int getPacketType() {
+        return mPacketType;
+    }
+    /**
+     * Gets length type.
+     */
+    @LengthType
+    public int getLengthType() {
+        return mLengthType;
+    }
+
+    /**
+     * Creates a builder for {@link AlpFilterConfiguration}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link AlpFilterConfiguration}.
+     */
+    public static final class Builder {
+        private int mPacketType = PACKET_TYPE_IPV4;
+        private int mLengthType = LENGTH_TYPE_UNDEFINED;
+        private Settings mSettings;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets packet type.
+         *
+         * <p>The meaning of each packet type value is shown in ATSC A/330:2019 table 5.2.
+         * <p>Default value is {@link #PACKET_TYPE_IPV4}.
+         */
+        @NonNull
+        public Builder setPacketType(int packetType) {
+            mPacketType = packetType;
+            return this;
+        }
+        /**
+         * Sets length type.
+         *
+         * <p>Default value is {@link #LENGTH_TYPE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setLengthType(@LengthType int lengthType) {
+            mLengthType = lengthType;
+            return this;
+        }
+
+        /**
+         * Sets filter settings.
+         */
+        @NonNull
+        public Builder setSettings(@Nullable Settings settings) {
+            mSettings = settings;
+            return this;
+        }
+
+        /**
+         * Builds a {@link AlpFilterConfiguration} object.
+         */
+        @NonNull
+        public AlpFilterConfiguration build() {
+            return new AlpFilterConfiguration(mSettings, mPacketType, mLengthType);
+        }
+    }
+}
diff --git a/android/media/tv/tuner/filter/AudioDescriptor.java b/android/media/tv/tuner/filter/AudioDescriptor.java
new file mode 100644
index 0000000..7b1576a
--- /dev/null
+++ b/android/media/tv/tuner/filter/AudioDescriptor.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.SystemApi;
+
+/**
+ * Meta data from AD (Audio Descriptor) according to ETSI TS 101 154 V2.1.1.
+ *
+ * @hide
+ */
+@SystemApi
+public class AudioDescriptor {
+    private final byte mAdFade;
+    private final byte mAdPan;
+    private final char mVersionTextTag;
+    private final byte mAdGainCenter;
+    private final byte mAdGainFront;
+    private final byte mAdGainSurround;
+
+    // This constructor is used by JNI code only
+    private AudioDescriptor(byte adFade, byte adPan, char versionTextTag, byte adGainCenter,
+            byte adGainFront, byte adGainSurround) {
+        mAdFade = adFade;
+        mAdPan = adPan;
+        mVersionTextTag = versionTextTag;
+        mAdGainCenter = adGainCenter;
+        mAdGainFront = adGainFront;
+        mAdGainSurround = adGainSurround;
+    }
+
+    /**
+     * Gets AD fade byte.
+     *
+     * <p>Takes values between 0x00 (representing no fade of the main programme sound) and 0xFF
+     * (representing a full fade). Over the range 0x00 to 0xFE one lsb represents a step in
+     * attenuation of the programme sound of 0.3 dB giving a range of 76.2 dB. The fade value of
+     * 0xFF represents no programme sound at all (i.e. mute).
+     */
+    public byte getAdFade() {
+        return mAdFade;
+    }
+
+    /**
+     * Gets AD pan byte.
+     *
+     * <p>Takes values between 0x00 representing a central forward presentation of the audio
+     * description and 0xFF, each increment representing a 360/256 degree step clockwise looking
+     * down on the listener (i.e. just over 1.4 degrees).
+     */
+    public byte getAdPan() {
+        return mAdPan;
+    }
+
+    /**
+     * Gets AD version tag. A single ASCII character version indicates the version.
+     *
+     * <p>A single ASCII character version designator (here "1" indicates revision 1).
+     */
+    public char getAdVersionTextTag() {
+        return mVersionTextTag;
+    }
+
+    /**
+     * Gets AD gain byte center in dB.
+     *
+     * <p>Represents a signed value in dB. Takes values between 0x7F (representing +76.2 dB boost of
+     * the main programme center) and 0x80 (representing a full fade). Over the range 0x00 to 0x7F
+     * one lsb represents a step in boost of the programme center of 0.6 dB giving a maximum boost
+     * of +76.2 dB. Over the range 0x81 to 0x00 one lsb represents a step in attenuation of the
+     * programme center of 0.6 dB giving a maximum attenuation of -76.2 dB. The gain value of 0x80
+     * represents no main center level at all (i.e. mute).
+     */
+    public byte getAdGainCenter() {
+        return mAdGainCenter;
+    }
+
+    /**
+     * Gets AD gain byte front in dB.
+     *
+     * <p>Same as {@link #getAdGainCenter()}, but applied to left and right front channel.
+     */
+    public byte getAdGainFront() {
+        return mAdGainFront;
+    }
+
+    /**
+     * Gets AD gain byte surround in dB.
+     *
+     * <p>Same as {@link #getAdGainCenter()}, but applied to all surround channels
+     */
+    public byte getAdGainSurround() {
+        return mAdGainSurround;
+    }
+}
diff --git a/android/media/tv/tuner/filter/AvSettings.java b/android/media/tv/tuner/filter/AvSettings.java
new file mode 100644
index 0000000..25457a7
--- /dev/null
+++ b/android/media/tv/tuner/filter/AvSettings.java
@@ -0,0 +1,295 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_1.Constants;
+import android.media.tv.tuner.TunerUtils;
+import android.media.tv.tuner.TunerVersionChecker;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Filter Settings for a Video and Audio.
+ *
+ * @hide
+ */
+@SystemApi
+public class AvSettings extends Settings {
+    /** @hide */
+    @IntDef(prefix = "VIDEO_STREAM_TYPE_",
+            value = {VIDEO_STREAM_TYPE_UNDEFINED, VIDEO_STREAM_TYPE_RESERVED,
+                    VIDEO_STREAM_TYPE_MPEG1, VIDEO_STREAM_TYPE_MPEG2,
+                    VIDEO_STREAM_TYPE_MPEG4P2, VIDEO_STREAM_TYPE_AVC, VIDEO_STREAM_TYPE_HEVC,
+                    VIDEO_STREAM_TYPE_VC1, VIDEO_STREAM_TYPE_VP8, VIDEO_STREAM_TYPE_VP9,
+                    VIDEO_STREAM_TYPE_AV1, VIDEO_STREAM_TYPE_AVS, VIDEO_STREAM_TYPE_AVS2})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface VideoStreamType {}
+
+    /*
+     * Undefined Video stream type
+     */
+    public static final int VIDEO_STREAM_TYPE_UNDEFINED = Constants.VideoStreamType.UNDEFINED;
+    /*
+     * ITU-T | ISO/IEC Reserved
+     */
+    public static final int VIDEO_STREAM_TYPE_RESERVED = Constants.VideoStreamType.RESERVED;
+    /*
+     * ISO/IEC 11172
+     */
+    public static final int VIDEO_STREAM_TYPE_MPEG1 = Constants.VideoStreamType.MPEG1;
+    /*
+     * ITU-T Rec.H.262 and ISO/IEC 13818-2
+     */
+    public static final int VIDEO_STREAM_TYPE_MPEG2 = Constants.VideoStreamType.MPEG2;
+    /*
+     * ISO/IEC 14496-2 (MPEG-4 H.263 based video)
+     */
+    public static final int VIDEO_STREAM_TYPE_MPEG4P2 = Constants.VideoStreamType.MPEG4P2;
+    /*
+     * ITU-T Rec.H.264 and ISO/IEC 14496-10
+     */
+    public static final int VIDEO_STREAM_TYPE_AVC = Constants.VideoStreamType.AVC;
+    /*
+     * ITU-T Rec. H.265 and ISO/IEC 23008-2
+     */
+    public static final int VIDEO_STREAM_TYPE_HEVC = Constants.VideoStreamType.HEVC;
+    /*
+     * Microsoft VC.1
+     */
+    public static final int VIDEO_STREAM_TYPE_VC1 = Constants.VideoStreamType.VC1;
+    /*
+     * Google VP8
+     */
+    public static final int VIDEO_STREAM_TYPE_VP8 = Constants.VideoStreamType.VP8;
+    /*
+     * Google VP9
+     */
+    public static final int VIDEO_STREAM_TYPE_VP9 = Constants.VideoStreamType.VP9;
+    /*
+     * AOMedia Video 1
+     */
+    public static final int VIDEO_STREAM_TYPE_AV1 = Constants.VideoStreamType.AV1;
+    /*
+     * Chinese Standard
+     */
+    public static final int VIDEO_STREAM_TYPE_AVS = Constants.VideoStreamType.AVS;
+    /*
+     * New Chinese Standard
+     */
+    public static final int VIDEO_STREAM_TYPE_AVS2 = Constants.VideoStreamType.AVS2;
+
+    /** @hide */
+    @IntDef(prefix = "AUDIO_STREAM_TYPE_",
+            value = {AUDIO_STREAM_TYPE_UNDEFINED, AUDIO_STREAM_TYPE_PCM, AUDIO_STREAM_TYPE_MP3,
+                    AUDIO_STREAM_TYPE_MPEG1, AUDIO_STREAM_TYPE_MPEG2, AUDIO_STREAM_TYPE_MPEGH,
+                    AUDIO_STREAM_TYPE_AAC, AUDIO_STREAM_TYPE_AC3, AUDIO_STREAM_TYPE_EAC3,
+                    AUDIO_STREAM_TYPE_AC4, AUDIO_STREAM_TYPE_DTS, AUDIO_STREAM_TYPE_DTS_HD,
+                    AUDIO_STREAM_TYPE_WMA, AUDIO_STREAM_TYPE_OPUS, AUDIO_STREAM_TYPE_VORBIS,
+                    AUDIO_STREAM_TYPE_DRA})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AudioStreamType {}
+
+    /*
+     * Undefined Audio stream type
+     */
+    public static final int AUDIO_STREAM_TYPE_UNDEFINED = Constants.AudioStreamType.UNDEFINED;
+    /*
+     * Uncompressed Audio
+     */
+    public static final int AUDIO_STREAM_TYPE_PCM = Constants.AudioStreamType.PCM;
+    /*
+     * MPEG Audio Layer III versions
+     */
+    public static final int AUDIO_STREAM_TYPE_MP3 = Constants.AudioStreamType.MP3;
+    /*
+     * ISO/IEC 11172 Audio
+     */
+    public static final int AUDIO_STREAM_TYPE_MPEG1 = Constants.AudioStreamType.MPEG1;
+    /*
+     * ISO/IEC 13818-3
+     */
+    public static final int AUDIO_STREAM_TYPE_MPEG2 = Constants.AudioStreamType.MPEG2;
+    /*
+     * ISO/IEC 23008-3 (MPEG-H Part 3)
+     */
+    public static final int AUDIO_STREAM_TYPE_MPEGH = Constants.AudioStreamType.MPEGH;
+    /*
+     * ISO/IEC 14496-3
+     */
+    public static final int AUDIO_STREAM_TYPE_AAC = Constants.AudioStreamType.AAC;
+    /*
+     * Dolby Digital
+     */
+    public static final int AUDIO_STREAM_TYPE_AC3 = Constants.AudioStreamType.AC3;
+    /*
+     * Dolby Digital Plus
+     */
+    public static final int AUDIO_STREAM_TYPE_EAC3 = Constants.AudioStreamType.EAC3;
+    /*
+     * Dolby AC-4
+     */
+    public static final int AUDIO_STREAM_TYPE_AC4 = Constants.AudioStreamType.AC4;
+    /*
+     * Basic DTS
+     */
+    public static final int AUDIO_STREAM_TYPE_DTS = Constants.AudioStreamType.DTS;
+    /*
+     * High Resolution DTS
+     */
+    public static final int AUDIO_STREAM_TYPE_DTS_HD = Constants.AudioStreamType.DTS_HD;
+    /*
+     * Windows Media Audio
+     */
+    public static final int AUDIO_STREAM_TYPE_WMA = Constants.AudioStreamType.WMA;
+    /*
+     * Opus Interactive Audio Codec
+     */
+    public static final int AUDIO_STREAM_TYPE_OPUS = Constants.AudioStreamType.OPUS;
+    /*
+     * VORBIS Interactive Audio Codec
+     */
+    public static final int AUDIO_STREAM_TYPE_VORBIS = Constants.AudioStreamType.VORBIS;
+    /*
+     * SJ/T 11368-2006
+     */
+    public static final int AUDIO_STREAM_TYPE_DRA = Constants.AudioStreamType.DRA;
+
+
+    private final boolean mIsPassthrough;
+    private int mAudioStreamType = AUDIO_STREAM_TYPE_UNDEFINED;
+    private int mVideoStreamType = VIDEO_STREAM_TYPE_UNDEFINED;
+
+    private AvSettings(int mainType, boolean isAudio, boolean isPassthrough,
+            int audioStreamType, int videoStreamType) {
+        super(TunerUtils.getFilterSubtype(
+                mainType,
+                isAudio
+                        ? Filter.SUBTYPE_AUDIO
+                        : Filter.SUBTYPE_VIDEO));
+        mIsPassthrough = isPassthrough;
+        mAudioStreamType = audioStreamType;
+        mVideoStreamType = videoStreamType;
+    }
+
+    /**
+     * Checks whether it's passthrough.
+     */
+    public boolean isPassthrough() {
+        return mIsPassthrough;
+    }
+
+    /**
+     * Get the Audio Stream Type.
+     */
+    @AudioStreamType
+    public int getAudioStreamType() {
+        return mAudioStreamType;
+    }
+
+    /**
+     * Get the Video Stream Type.
+     */
+    @VideoStreamType
+    public int getVideoStreamType() {
+        return mVideoStreamType;
+    }
+
+    /**
+     * Creates a builder for {@link AvSettings}.
+     *
+     * @param mainType the filter main type.
+     * @param isAudio {@code true} if it's audio settings; {@code false} if it's video settings.
+     */
+    @NonNull
+    public static Builder builder(@Filter.Type int mainType, boolean isAudio) {
+        return new Builder(mainType, isAudio);
+    }
+
+    /**
+     * Builder for {@link AvSettings}.
+     */
+    public static class Builder {
+        private final int mMainType;
+        private final boolean mIsAudio;
+        private boolean mIsPassthrough;
+        private int mAudioStreamType = AUDIO_STREAM_TYPE_UNDEFINED;
+        private int mVideoStreamType = VIDEO_STREAM_TYPE_UNDEFINED;
+
+        private Builder(int mainType, boolean isAudio) {
+            mMainType = mainType;
+            mIsAudio = isAudio;
+        }
+
+        /**
+         * Sets whether it's passthrough.
+         */
+        @NonNull
+        public Builder setPassthrough(boolean isPassthrough) {
+            mIsPassthrough = isPassthrough;
+            return this;
+        }
+
+        /**
+         * Sets the Audio Stream Type.
+         *
+         * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would cause
+         * no-op. Use {@link TunerVersionChecker#getTunerVersion()} to check the version.
+         *
+         * @param audioStreamType the audio stream type to set.
+         */
+        @NonNull
+        public Builder setAudioStreamType(@AudioStreamType int audioStreamType) {
+            if (TunerVersionChecker.checkHigherOrEqualVersionTo(
+                    TunerVersionChecker.TUNER_VERSION_1_1, "setAudioStreamType") && mIsAudio) {
+                mAudioStreamType = audioStreamType;
+                mVideoStreamType = VIDEO_STREAM_TYPE_UNDEFINED;
+            }
+            return this;
+        }
+
+        /**
+         * Sets the Video Stream Type.
+         *
+         * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would cause
+         * no-op. Use {@link TunerVersionChecker#getTunerVersion()} to check the version.
+         *
+         * @param videoStreamType the video stream type to set.
+         */
+        @NonNull
+        public Builder setVideoStreamType(@VideoStreamType int videoStreamType) {
+            if (TunerVersionChecker.checkHigherOrEqualVersionTo(
+                    TunerVersionChecker.TUNER_VERSION_1_1, "setVideoStreamType") && !mIsAudio) {
+                mVideoStreamType = videoStreamType;
+                mAudioStreamType = AUDIO_STREAM_TYPE_UNDEFINED;
+            }
+            return this;
+        }
+
+        /**
+         * Builds a {@link AvSettings} object.
+         */
+        @NonNull
+        public AvSettings build() {
+            return new AvSettings(mMainType, mIsAudio, mIsPassthrough,
+                    mAudioStreamType, mVideoStreamType);
+        }
+    }
+}
diff --git a/android/media/tv/tuner/filter/DownloadEvent.java b/android/media/tv/tuner/filter/DownloadEvent.java
new file mode 100644
index 0000000..394211b
--- /dev/null
+++ b/android/media/tv/tuner/filter/DownloadEvent.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.IntRange;
+import android.annotation.SystemApi;
+
+/**
+ * Filter event sent from {@link Filter} objects with download type.
+ *
+ * @hide
+ */
+@SystemApi
+public class DownloadEvent extends FilterEvent {
+    private final int mItemId;
+    private final int mMpuSequenceNumber;
+    private final int mItemFragmentIndex;
+    private final int mLastItemFragmentIndex;
+    private final int mDataLength;
+
+    // This constructor is used by JNI code only
+    private DownloadEvent(int itemId, int mpuSequenceNumber, int itemFragmentIndex,
+            int lastItemFragmentIndex, int dataLength) {
+        mItemId = itemId;
+        mMpuSequenceNumber = mpuSequenceNumber;
+        mItemFragmentIndex = itemFragmentIndex;
+        mLastItemFragmentIndex = lastItemFragmentIndex;
+        mDataLength = dataLength;
+    }
+
+    /**
+     * Gets item ID.
+     */
+    public int getItemId() {
+        return mItemId;
+    }
+
+    /**
+     * Gets MPU sequence number of filtered data.
+     */
+    @IntRange(from = 0)
+    public int getMpuSequenceNumber() {
+        return mMpuSequenceNumber;
+    }
+
+    /**
+     * Gets current index of the current item.
+     *
+     * An item can be stored in different fragments.
+     */
+    public int getItemFragmentIndex() {
+        return mItemFragmentIndex;
+    }
+
+    /**
+     * Gets last index of the current item.
+     */
+    public int getLastItemFragmentIndex() {
+        return mLastItemFragmentIndex;
+    }
+
+    /**
+     * Gets data size in bytes of filtered data.
+     */
+    public int getDataLength() {
+        return mDataLength;
+    }
+}
+
diff --git a/android/media/tv/tuner/filter/DownloadSettings.java b/android/media/tv/tuner/filter/DownloadSettings.java
new file mode 100644
index 0000000..7ba923e
--- /dev/null
+++ b/android/media/tv/tuner/filter/DownloadSettings.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.TunerUtils;
+
+/**
+ * Filter Settings for a Download.
+ *
+ * @hide
+ */
+@SystemApi
+public class DownloadSettings extends Settings {
+    private final int mDownloadId;
+
+    private DownloadSettings(int mainType, int downloadId) {
+        super(TunerUtils.getFilterSubtype(mainType, Filter.SUBTYPE_DOWNLOAD));
+        mDownloadId = downloadId;
+    }
+
+    /**
+     * Gets download ID.
+     */
+    public int getDownloadId() {
+        return mDownloadId;
+    }
+
+    /**
+     * Creates a builder for {@link DownloadSettings}.
+     *
+     * @param mainType the filter main type.
+     */
+    @NonNull
+    public static Builder builder(@Filter.Type int mainType) {
+        return new Builder(mainType);
+    }
+
+    /**
+     * Builder for {@link DownloadSettings}.
+     */
+    public static class Builder {
+        private final int mMainType;
+        private int mDownloadId;
+
+        private Builder(int mainType) {
+            mMainType = mainType;
+        }
+
+        /**
+         * Sets download ID.
+         */
+        @NonNull
+        public Builder setDownloadId(int downloadId) {
+            mDownloadId = downloadId;
+            return this;
+        }
+
+        /**
+         * Builds a {@link DownloadSettings} object.
+         */
+        @NonNull
+        public DownloadSettings build() {
+            return new DownloadSettings(mMainType, mDownloadId);
+        }
+    }
+}
diff --git a/android/media/tv/tuner/filter/Filter.java b/android/media/tv/tuner/filter/Filter.java
new file mode 100644
index 0000000..33742ff
--- /dev/null
+++ b/android/media/tv/tuner/filter/Filter.java
@@ -0,0 +1,498 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.BytesLong;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.Tuner;
+import android.media.tv.tuner.Tuner.Result;
+import android.media.tv.tuner.TunerUtils;
+import android.media.tv.tuner.TunerVersionChecker;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
+
+/**
+ * Tuner data filter.
+ *
+ * <p>This class is used to filter wanted data according to the filter's configuration.
+ *
+ * @hide
+ */
+@SystemApi
+public class Filter implements AutoCloseable {
+    /** @hide */
+    @IntDef(prefix = "TYPE_",
+            value = {TYPE_TS, TYPE_MMTP, TYPE_IP, TYPE_TLV, TYPE_ALP})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {}
+
+    /**
+     * Undefined filter type.
+     */
+    public static final int TYPE_UNDEFINED = 0;
+    /**
+     * TS filter type.
+     */
+    public static final int TYPE_TS = Constants.DemuxFilterMainType.TS;
+    /**
+     * MMTP filter type.
+     */
+    public static final int TYPE_MMTP = Constants.DemuxFilterMainType.MMTP;
+    /**
+     * IP filter type.
+     */
+    public static final int TYPE_IP = Constants.DemuxFilterMainType.IP;
+    /**
+     * TLV filter type.
+     */
+    public static final int TYPE_TLV = Constants.DemuxFilterMainType.TLV;
+    /**
+     * ALP filter type.
+     */
+    public static final int TYPE_ALP = Constants.DemuxFilterMainType.ALP;
+
+    /** @hide */
+    @IntDef(prefix = "SUBTYPE_",
+            value = {SUBTYPE_UNDEFINED, SUBTYPE_SECTION, SUBTYPE_PES, SUBTYPE_AUDIO, SUBTYPE_VIDEO,
+                    SUBTYPE_DOWNLOAD, SUBTYPE_RECORD, SUBTYPE_TS, SUBTYPE_PCR, SUBTYPE_TEMI,
+                    SUBTYPE_MMTP, SUBTYPE_NTP, SUBTYPE_IP_PAYLOAD, SUBTYPE_IP,
+                    SUBTYPE_PAYLOAD_THROUGH, SUBTYPE_TLV, SUBTYPE_PTP, })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Subtype {}
+    /**
+     * Filter subtype undefined.
+     */
+    public static final int SUBTYPE_UNDEFINED = 0;
+    /**
+     * Section filter subtype.
+     */
+    public static final int SUBTYPE_SECTION = 1;
+    /**
+     * PES filter subtype.
+     */
+    public static final int SUBTYPE_PES = 2;
+    /**
+     * Audio filter subtype.
+     */
+    public static final int SUBTYPE_AUDIO = 3;
+    /**
+     * Video filter subtype.
+     */
+    public static final int SUBTYPE_VIDEO = 4;
+    /**
+     * Download filter subtype.
+     */
+    public static final int SUBTYPE_DOWNLOAD = 5;
+    /**
+     * Record filter subtype.
+     */
+    public static final int SUBTYPE_RECORD = 6;
+    /**
+     * TS filter subtype.
+     */
+    public static final int SUBTYPE_TS = 7;
+    /**
+     * PCR filter subtype.
+     */
+    public static final int SUBTYPE_PCR = 8;
+    /**
+     * TEMI filter subtype.
+     */
+    public static final int SUBTYPE_TEMI = 9;
+    /**
+     * MMTP filter subtype.
+     */
+    public static final int SUBTYPE_MMTP = 10;
+    /**
+     * NTP filter subtype.
+     */
+    public static final int SUBTYPE_NTP = 11;
+    /**
+     * Payload filter subtype.
+     */
+    public static final int SUBTYPE_IP_PAYLOAD = 12;
+    /**
+     * IP filter subtype.
+     */
+    public static final int SUBTYPE_IP = 13;
+    /**
+     * Payload through filter subtype.
+     */
+    public static final int SUBTYPE_PAYLOAD_THROUGH = 14;
+    /**
+     * TLV filter subtype.
+     */
+    public static final int SUBTYPE_TLV = 15;
+    /**
+     * PTP filter subtype.
+     */
+    public static final int SUBTYPE_PTP = 16;
+
+
+    /** @hide */
+    @IntDef(flag = true, prefix = "STATUS_", value = {STATUS_DATA_READY, STATUS_LOW_WATER,
+            STATUS_HIGH_WATER, STATUS_OVERFLOW})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Status {}
+
+    /**
+     * The status of a filter that the data in the filter buffer is ready to be read.
+     */
+    public static final int STATUS_DATA_READY = Constants.DemuxFilterStatus.DATA_READY;
+    /**
+     * The status of a filter that the amount of available data in the filter buffer is at low
+     * level.
+     *
+     * The value is set to 25 percent of the buffer size by default. It can be changed when
+     * configuring the filter.
+     */
+    public static final int STATUS_LOW_WATER = Constants.DemuxFilterStatus.LOW_WATER;
+    /**
+     * The status of a filter that the amount of available data in the filter buffer is at high
+     * level.
+     * The value is set to 75 percent of the buffer size by default. It can be changed when
+     * configuring the filter.
+     */
+    public static final int STATUS_HIGH_WATER = Constants.DemuxFilterStatus.HIGH_WATER;
+    /**
+     * The status of a filter that the filter buffer is full and newly filtered data is being
+     * discarded.
+     */
+    public static final int STATUS_OVERFLOW = Constants.DemuxFilterStatus.OVERFLOW;
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "SCRAMBLING_STATUS_",
+            value = {SCRAMBLING_STATUS_UNKNOWN, SCRAMBLING_STATUS_NOT_SCRAMBLED,
+                    SCRAMBLING_STATUS_SCRAMBLED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScramblingStatus {}
+
+    /**
+     * Content’s scrambling status is unknown
+     */
+    public static final int SCRAMBLING_STATUS_UNKNOWN =
+            android.hardware.tv.tuner.V1_1.Constants.ScramblingStatus.UNKNOWN;
+    /**
+     * Content is not scrambled.
+     */
+    public static final int SCRAMBLING_STATUS_NOT_SCRAMBLED =
+            android.hardware.tv.tuner.V1_1.Constants.ScramblingStatus.NOT_SCRAMBLED;
+    /**
+     * Content is scrambled.
+     */
+    public static final int SCRAMBLING_STATUS_SCRAMBLED =
+            android.hardware.tv.tuner.V1_1.Constants.ScramblingStatus.SCRAMBLED;
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "MONITOR_EVENT_",
+            value = {MONITOR_EVENT_SCRAMBLING_STATUS, MONITOR_EVENT_IP_CID_CHANGE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface MonitorEventMask {}
+
+    /**
+     * Monitor scrambling status change.
+     */
+    public static final int MONITOR_EVENT_SCRAMBLING_STATUS =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxFilterMonitorEventType.SCRAMBLING_STATUS;
+    /**
+     * Monitor ip cid change.
+     */
+    public static final int MONITOR_EVENT_IP_CID_CHANGE =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxFilterMonitorEventType.IP_CID_CHANGE;
+
+    private static final String TAG = "Filter";
+
+    private long mNativeContext;
+    private FilterCallback mCallback;
+    private Executor mExecutor;
+    private final Object mCallbackLock = new Object();
+    private final long mId;
+    private int mMainType;
+    private int mSubtype;
+    private Filter mSource;
+    private boolean mStarted;
+    private boolean mIsClosed = false;
+    private final Object mLock = new Object();
+
+    private native int nativeConfigureFilter(
+            int type, int subType, FilterConfiguration settings);
+    private native int nativeGetId();
+    private native long nativeGetId64Bit();
+    private native int nativeConfigureMonitorEvent(int monitorEventMask);
+    private native int nativeSetDataSource(Filter source);
+    private native int nativeStartFilter();
+    private native int nativeStopFilter();
+    private native int nativeFlushFilter();
+    private native int nativeRead(byte[] buffer, long offset, long size);
+    private native int nativeClose();
+
+    // Called by JNI
+    private Filter(long id) {
+        mId = id;
+    }
+
+    private void onFilterStatus(int status) {
+        synchronized (mCallbackLock) {
+            if (mCallback != null && mExecutor != null) {
+                mExecutor.execute(() -> mCallback.onFilterStatusChanged(this, status));
+            }
+        }
+    }
+
+    private void onFilterEvent(FilterEvent[] events) {
+        synchronized (mCallbackLock) {
+            if (mCallback != null && mExecutor != null) {
+                mExecutor.execute(() -> mCallback.onFilterEvent(this, events));
+            }
+        }
+    }
+
+    /** @hide */
+    public void setType(@Type int mainType, @Subtype int subtype) {
+        mMainType = mainType;
+        mSubtype = TunerUtils.getFilterSubtype(mainType, subtype);
+    }
+
+    /** @hide */
+    public void setCallback(FilterCallback cb, Executor executor) {
+        synchronized (mCallbackLock) {
+            mCallback = cb;
+            mExecutor = executor;
+        }
+    }
+
+    /** @hide */
+    public FilterCallback getCallback() {
+        synchronized (mCallbackLock) {
+            return mCallback;
+        }
+    }
+
+    /**
+     * Configures the filter.
+     *
+     * <p>Recofiguring must happen after stopping the filter.
+     *
+     * <p>When stopping, reconfiguring and restarting the filter, the client should discard all
+     * coming events until it receives {@link RestartEvent} through {@link FilterCallback} to avoid
+     * using the events from the previous configuration.
+     *
+     * @param config the configuration of the filter.
+     * @return result status of the operation.
+     */
+    @Result
+    public int configure(@NonNull FilterConfiguration config) {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            Settings s = config.getSettings();
+            int subType = (s == null) ? mSubtype : s.getType();
+            if (mMainType != config.getType() || mSubtype != subType) {
+                throw new IllegalArgumentException("Invalid filter config. filter main type="
+                        + mMainType + ", filter subtype=" + mSubtype + ". config main type="
+                        + config.getType() + ", config subtype=" + subType);
+            }
+            return nativeConfigureFilter(config.getType(), subType, config);
+        }
+    }
+
+    /**
+     * Gets the filter Id in 32-bit. For any Tuner SoC that supports 64-bit filter architecture,
+     * use {@link #getIdLong()}.
+     */
+    public int getId() {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            return nativeGetId();
+        }
+    }
+
+    /**
+     * Gets the 64-bit filter Id. For any Tuner SoC that supports 32-bit filter architecture,
+     * use {@link #getId()}.
+     */
+    public long getIdLong() {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            return nativeGetId64Bit();
+        }
+    }
+
+    /**
+     * Configure the Filter to monitor scrambling status and ip cid change. Set corresponding bit
+     * to monitor the change. Reset to stop monitoring.
+     *
+     * <p>{@link ScramblingStatusEvent} should be sent at the following two scenarios:
+     * <ul>
+     *   <li>When this method is called with {@link #MONITOR_EVENT_SCRAMBLING_STATUS}, the first
+     *       detected scrambling status should be sent.
+     *   <li>When the Scrambling status transits into different status, event should be sent.
+     *     <ul/>
+     *
+     * <p>{@link IpCidChangeEvent} should be sent at the following two scenarios:
+     * <ul>
+     *   <li>When this method is called with {@link #MONITOR_EVENT_IP_CID_CHANGE}, the first
+     *       detected CID for the IP should be sent.
+     *   <li>When the CID is changed to different value for the IP filter, event should be sent.
+     *     <ul/>
+     *
+     * <p>This configuration is only supported in Tuner 1.1 or higher version. Unsupported version
+     * will cause no-op. Use {@link TunerVersionChecker#getTunerVersion()} to get the version
+     * information.
+     *
+     * @param monitorEventMask Types of event to be monitored. Set corresponding bit to
+     *                         monitor it. Reset to stop monitoring.
+     * @return result status of the operation.
+     */
+    @Result
+    public int setMonitorEventMask(@MonitorEventMask int monitorEventMask) {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            if (!TunerVersionChecker.checkHigherOrEqualVersionTo(
+                    TunerVersionChecker.TUNER_VERSION_1_1, "setMonitorEventMask")) {
+                return Tuner.RESULT_UNAVAILABLE;
+            }
+            return nativeConfigureMonitorEvent(monitorEventMask);
+        }
+    }
+
+    /**
+     * Sets the filter's data source.
+     *
+     * A filter uses demux as data source by default. If the data was packetized
+     * by multiple protocols, multiple filters may need to work together to
+     * extract all protocols' header. Then a filter's data source can be output
+     * from another filter.
+     *
+     * @param source the filter instance which provides data input. Switch to
+     * use demux as data source if the filter instance is NULL.
+     * @return result status of the operation.
+     * @throws IllegalStateException if the data source has been set.
+     */
+    @Result
+    public int setDataSource(@Nullable Filter source) {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            if (mSource != null) {
+                throw new IllegalStateException("Data source is existing");
+            }
+            int res = nativeSetDataSource(source);
+            if (res == Tuner.RESULT_SUCCESS) {
+                mSource = source;
+            }
+            return res;
+        }
+    }
+
+    /**
+     * Starts filtering data.
+     *
+     * <p>Does nothing if the filter is already started.
+     *
+     * <p>When stopping, reconfiguring and restarting the filter, the client should discard all
+     * coming events until it receives {@link RestartEvent} through {@link FilterCallback} to avoid
+     * using the events from the previous configuration.
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int start() {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            return nativeStartFilter();
+        }
+    }
+
+
+    /**
+     * Stops filtering data.
+     *
+     * <p>Does nothing if the filter is stopped or not started.
+     *
+     * <p>Filter must be stopped to reconfigure.
+     *
+     * <p>When stopping, reconfiguring and restarting the filter, the client should discard all
+     * coming events until it receives {@link RestartEvent} through {@link FilterCallback} to avoid
+     * using the events from the previous configuration.
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int stop() {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            return nativeStopFilter();
+        }
+    }
+
+    /**
+     * Flushes the filter.
+     *
+     * <p>The data which is already produced by filter but not consumed yet will
+     * be cleared.
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int flush() {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            return nativeFlushFilter();
+        }
+    }
+
+    /**
+     * Copies filtered data from filter output to the given byte array.
+     *
+     * @param buffer the buffer to store the filtered data.
+     * @param offset the index of the first byte in {@code buffer} to write.
+     * @param size the maximum number of bytes to read.
+     * @return the number of bytes read.
+     */
+    public int read(@NonNull byte[] buffer, @BytesLong long offset, @BytesLong long size) {
+        synchronized (mLock) {
+            TunerUtils.checkResourceState(TAG, mIsClosed);
+            size = Math.min(size, buffer.length - offset);
+            return nativeRead(buffer, offset, size);
+        }
+    }
+
+    /**
+     * Stops filtering data and releases the Filter instance.
+     */
+    @Override
+    public void close() {
+        synchronized (mLock) {
+            if (mIsClosed) {
+                return;
+            }
+            int res = nativeClose();
+            if (res != Tuner.RESULT_SUCCESS) {
+                TunerUtils.throwExceptionForResult(res, "Failed to close filter.");
+            } else {
+                mIsClosed = true;
+            }
+        }
+    }
+}
diff --git a/android/media/tv/tuner/filter/FilterCallback.java b/android/media/tv/tuner/filter/FilterCallback.java
new file mode 100644
index 0000000..2ad6bd1
--- /dev/null
+++ b/android/media/tv/tuner/filter/FilterCallback.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * Callback interface for receiving information from the corresponding filters.
+ *
+ * @hide
+ */
+@SystemApi
+public interface FilterCallback {
+    /**
+     * Invoked when there are filter events.
+     *
+     * @param filter the corresponding filter which sent the events.
+     * @param events the filter events sent from the filter.
+     */
+    void onFilterEvent(@NonNull Filter filter, @NonNull FilterEvent[] events);
+    /**
+     * Invoked when filter status changed.
+     *
+     * @param filter the corresponding filter whose status is changed.
+     * @param status the new status of the filter.
+     */
+    void onFilterStatusChanged(@NonNull Filter filter, @Filter.Status int status);
+}
diff --git a/android/media/tv/tuner/filter/FilterConfiguration.java b/android/media/tv/tuner/filter/FilterConfiguration.java
new file mode 100644
index 0000000..dd7e5fc
--- /dev/null
+++ b/android/media/tv/tuner/filter/FilterConfiguration.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+
+/**
+ * Filter configuration used to configure filters.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class FilterConfiguration {
+
+    @Nullable
+    /* package */ final Settings mSettings;
+
+    /* package */ FilterConfiguration(Settings settings) {
+        mSettings = settings;
+    }
+
+    /**
+     * Gets filter configuration type.
+     */
+    @Filter.Type
+    public abstract int getType();
+
+    /**
+     * Gets filter Settings.
+     */
+    @Nullable
+    public Settings getSettings() {
+        return mSettings;
+    }
+}
diff --git a/android/media/tv/tuner/filter/FilterEvent.java b/android/media/tv/tuner/filter/FilterEvent.java
new file mode 100644
index 0000000..56a77d4
--- /dev/null
+++ b/android/media/tv/tuner/filter/FilterEvent.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.SystemApi;
+
+/**
+ * An entity class that is passed to the filter callbacks.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class FilterEvent {
+}
diff --git a/android/media/tv/tuner/filter/IpCidChangeEvent.java b/android/media/tv/tuner/filter/IpCidChangeEvent.java
new file mode 100644
index 0000000..2894c02
--- /dev/null
+++ b/android/media/tv/tuner/filter/IpCidChangeEvent.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2020 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.tv.tuner.filter;
+
+import android.annotation.SystemApi;
+
+/**
+ * Ip Cid Change event sent from {@link Filter} objects new ip cid.
+ *
+ * <p>This event is only sent in Tuner 1.1 or higher version. Use
+ * {@link TunerVersionChecker#getTunerVersion()} to get the version information.
+ *
+ * @hide
+ */
+@SystemApi
+public final class IpCidChangeEvent extends FilterEvent {
+    private final int mCid;
+
+    private IpCidChangeEvent(int cid) {
+        mCid = cid;
+    }
+
+    /**
+     * Gets ip cid.
+     *
+     * <p>This event is only sent in Tuner 1.1 or higher version. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to get the version information.
+     */
+    public int getIpCid() {
+        return mCid;
+    }
+}
diff --git a/android/media/tv/tuner/filter/IpFilterConfiguration.java b/android/media/tv/tuner/filter/IpFilterConfiguration.java
new file mode 100644
index 0000000..4b69807
--- /dev/null
+++ b/android/media/tv/tuner/filter/IpFilterConfiguration.java
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.Size;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.TunerVersionChecker;
+
+/**
+ * Filter configuration for a IP filter.
+ *
+ * @hide
+ */
+@SystemApi
+public final class IpFilterConfiguration extends FilterConfiguration {
+    /**
+     * Undefined filter type.
+     */
+    public static final int INVALID_IP_FILTER_CONTEXT_ID =
+            android.hardware.tv.tuner.V1_1.Constants.Constant.INVALID_IP_FILTER_CONTEXT_ID;
+
+    private final byte[] mSrcIpAddress;
+    private final byte[] mDstIpAddress;
+    private final int mSrcPort;
+    private final int mDstPort;
+    private final boolean mPassthrough;
+    private final int mIpFilterContextId;
+
+    private IpFilterConfiguration(Settings settings, byte[] srcAddr, byte[] dstAddr, int srcPort,
+            int dstPort, boolean passthrough, int ipCid) {
+        super(settings);
+        mSrcIpAddress = srcAddr;
+        mDstIpAddress = dstAddr;
+        mSrcPort = srcPort;
+        mDstPort = dstPort;
+        mPassthrough = passthrough;
+        mIpFilterContextId = ipCid;
+    }
+
+    @Override
+    public int getType() {
+        return Filter.TYPE_IP;
+    }
+
+    /**
+     * Gets source IP address.
+     */
+    @Size(min = 4, max = 16)
+    @NonNull
+    public byte[] getSrcIpAddress() {
+        return mSrcIpAddress;
+    }
+    /**
+     * Gets destination IP address.
+     */
+    @Size(min = 4, max = 16)
+    @NonNull
+    public byte[] getDstIpAddress() {
+        return mDstIpAddress;
+    }
+    /**
+     * Gets source port.
+     */
+    public int getSrcPort() {
+        return mSrcPort;
+    }
+    /**
+     * Gets destination port.
+     */
+    public int getDstPort() {
+        return mDstPort;
+    }
+    /**
+     * Checks whether the filter is passthrough.
+     *
+     * @return {@code true} if the data from IP subtype go to next filter directly;
+     *         {@code false} otherwise.
+     */
+    public boolean isPassthrough() {
+        return mPassthrough;
+    }
+    /**
+     * Gets the ip filter context id. Default value is {@link #INVALID_IP_FILTER_CONTEXT_ID}.
+     *
+     * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would return
+     * default value. Use {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    @IntRange(from = 0, to = 0xefff)
+    public int getIpFilterContextId() {
+        return mIpFilterContextId;
+    }
+
+    /**
+     * Creates a builder for {@link IpFilterConfiguration}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link IpFilterConfiguration}.
+     */
+    public static final class Builder {
+        private byte[] mSrcIpAddress = {0, 0, 0, 0};
+        private byte[] mDstIpAddress = {0, 0, 0, 0};
+        private int mSrcPort = 0;
+        private int mDstPort = 0;
+        private boolean mPassthrough = false;
+        private Settings mSettings;
+        private int mIpCid = INVALID_IP_FILTER_CONTEXT_ID;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets source IP address.
+         *
+         * <p>Default value is 0.0.0.0, an invalid IP address.
+         */
+        @NonNull
+        public Builder setSrcIpAddress(@NonNull byte[] srcIpAddress) {
+            mSrcIpAddress = srcIpAddress;
+            return this;
+        }
+        /**
+         * Sets destination IP address.
+         *
+         * <p>Default value is 0.0.0.0, an invalid IP address.
+         */
+        @NonNull
+        public Builder setDstIpAddress(@NonNull byte[] dstIpAddress) {
+            mDstIpAddress = dstIpAddress;
+            return this;
+        }
+        /**
+         * Sets source port.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        public Builder setSrcPort(int srcPort) {
+            mSrcPort = srcPort;
+            return this;
+        }
+        /**
+         * Sets destination port.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        public Builder setDstPort(int dstPort) {
+            mDstPort = dstPort;
+            return this;
+        }
+        /**
+         * Sets passthrough.
+         *
+         * <p>Default value is {@code false}.
+         */
+        @NonNull
+        public Builder setPassthrough(boolean passthrough) {
+            mPassthrough = passthrough;
+            return this;
+        }
+
+        /**
+         * Sets filter settings.
+         */
+        @NonNull
+        public Builder setSettings(@Nullable Settings settings) {
+            mSettings = settings;
+            return this;
+        }
+
+        /**
+         * Sets the ip filter context id. Default value is {@link #INVALID_IP_FILTER_CONTEXT_ID}.
+         *
+         * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would cause
+         * no-op. Use {@link TunerVersionChecker#getTunerVersion()} to check the version.
+         */
+        @NonNull
+        public Builder setIpFilterContextId(int ipContextId) {
+            if (TunerVersionChecker.checkHigherOrEqualVersionTo(
+                        TunerVersionChecker.TUNER_VERSION_1_1, "setIpFilterContextId")) {
+                mIpCid = ipContextId;
+            }
+            return this;
+        }
+
+        /**
+         * Builds a {@link IpFilterConfiguration} object.
+         */
+        @NonNull
+        public IpFilterConfiguration build() {
+            int ipAddrLength = mSrcIpAddress.length;
+            if (ipAddrLength != mDstIpAddress.length || (ipAddrLength != 4 && ipAddrLength != 16)) {
+                throw new IllegalArgumentException(
+                    "The lengths of src and dst IP address must be 4 or 16 and must be the same."
+                            + "srcLength=" + ipAddrLength + ", dstLength=" + mDstIpAddress.length);
+            }
+            return new IpFilterConfiguration(mSettings, mSrcIpAddress, mDstIpAddress, mSrcPort,
+                    mDstPort, mPassthrough, mIpCid);
+        }
+    }
+}
diff --git a/android/media/tv/tuner/filter/IpPayloadEvent.java b/android/media/tv/tuner/filter/IpPayloadEvent.java
new file mode 100644
index 0000000..42a124f
--- /dev/null
+++ b/android/media/tv/tuner/filter/IpPayloadEvent.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.SystemApi;
+
+/**
+ * Filter event sent from {@link Filter} objects with IP payload type.
+ *
+ * @hide
+ */
+@SystemApi
+public class IpPayloadEvent extends FilterEvent {
+    private final int mDataLength;
+
+    // This constructor is used by JNI code only
+    private IpPayloadEvent(int dataLength) {
+        mDataLength = dataLength;
+    }
+
+    /**
+     * Gets data size in bytes of filtered data.
+     */
+    public int getDataLength() {
+        return mDataLength;
+    }
+}
diff --git a/android/media/tv/tuner/filter/MediaEvent.java b/android/media/tv/tuner/filter/MediaEvent.java
new file mode 100644
index 0000000..dbd85e9
--- /dev/null
+++ b/android/media/tv/tuner/filter/MediaEvent.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.BytesLong;
+import android.annotation.IntRange;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.media.MediaCodec.LinearBlock;
+
+/**
+ * Filter event sent from {@link Filter} objects with media type.
+ *
+ * @hide
+ */
+@SystemApi
+public class MediaEvent extends FilterEvent {
+    private long mNativeContext;
+    private boolean mReleased = false;
+    private final Object mLock = new Object();
+
+    private native Long nativeGetAudioHandle();
+    private native LinearBlock nativeGetLinearBlock();
+    private native void nativeFinalize();
+
+    private final int mStreamId;
+    private final boolean mIsPtsPresent;
+    private final long mPts;
+    private final long mDataLength;
+    private final long mOffset;
+    private LinearBlock mLinearBlock;
+    private final boolean mIsSecureMemory;
+    private final long mDataId;
+    private final int mMpuSequenceNumber;
+    private final boolean mIsPrivateData;
+    private final AudioDescriptor mExtraMetaData;
+
+    // This constructor is used by JNI code only
+    private MediaEvent(int streamId, boolean isPtsPresent, long pts, long dataLength, long offset,
+            LinearBlock buffer, boolean isSecureMemory, long dataId, int mpuSequenceNumber,
+            boolean isPrivateData, AudioDescriptor extraMetaData) {
+        mStreamId = streamId;
+        mIsPtsPresent = isPtsPresent;
+        mPts = pts;
+        mDataLength = dataLength;
+        mOffset = offset;
+        mLinearBlock = buffer;
+        mIsSecureMemory = isSecureMemory;
+        mDataId = dataId;
+        mMpuSequenceNumber = mpuSequenceNumber;
+        mIsPrivateData = isPrivateData;
+        mExtraMetaData = extraMetaData;
+    }
+
+    /**
+     * Gets stream ID.
+     */
+    public int getStreamId() {
+        return mStreamId;
+    }
+
+    /**
+     * Returns whether PTS (Presentation Time Stamp) is present.
+     *
+     * @return {@code true} if PTS is present in PES header; {@code false} otherwise.
+     */
+    public boolean isPtsPresent() {
+        return mIsPtsPresent;
+    }
+
+    /**
+     * Gets PTS (Presentation Time Stamp) for audio or video frame.
+     */
+    public long getPts() {
+        return mPts;
+    }
+
+    /**
+     * Gets data size in bytes of audio or video frame.
+     */
+    @BytesLong
+    public long getDataLength() {
+        return mDataLength;
+    }
+
+    /**
+     * The offset in the memory block which is shared among multiple Media Events.
+     */
+    @BytesLong
+    public long getOffset() {
+        return mOffset;
+    }
+
+    /**
+     * Gets a linear block associated to the memory where audio or video data stays.
+     */
+    @Nullable
+    public LinearBlock getLinearBlock() {
+        synchronized (mLock) {
+            if (mLinearBlock == null) {
+                mLinearBlock = nativeGetLinearBlock();
+            }
+            return mLinearBlock;
+        }
+    }
+
+    /**
+     * Returns whether the data is secure.
+     *
+     * @return {@code true} if the data is in secure area, and isn't mappable;
+     *         {@code false} otherwise.
+     */
+    public boolean isSecureMemory() {
+        return mIsSecureMemory;
+    }
+
+    /**
+     * Gets the ID which is used by HAL to provide additional information for AV data.
+     *
+     * <p>For secure audio, it's the audio handle used by Audio Track.
+     */
+    public long getAvDataId() {
+        return mDataId;
+    }
+
+    /**
+     * Gets the audio handle.
+     *
+     * <p>Client gets audio handle from {@link MediaEvent}, and queues it to
+     * {@link android.media.AudioTrack} in
+     * {@link android.media.AudioTrack#ENCAPSULATION_MODE_HANDLE} format.
+     *
+     * @return the audio handle.
+     * @see android.media.AudioTrack#ENCAPSULATION_MODE_HANDLE
+     */
+    public long getAudioHandle() {
+        nativeGetAudioHandle();
+        return mDataId;
+    }
+
+    /**
+     * Gets MPU sequence number of filtered data.
+     */
+    @IntRange(from = 0)
+    public int getMpuSequenceNumber() {
+        return mMpuSequenceNumber;
+    }
+
+    /**
+     * Returns whether the data is private.
+     *
+     * @return {@code true} if the data is in private; {@code false} otherwise.
+     */
+    public boolean isPrivateData() {
+        return mIsPrivateData;
+    }
+
+    /**
+     * Gets audio extra metadata.
+     */
+    @Nullable
+    public AudioDescriptor getExtraMetaData() {
+        return mExtraMetaData;
+    }
+
+
+    /**
+     * Finalize the MediaEvent object.
+     * @hide
+     */
+    @Override
+    protected void finalize() {
+        release();
+    }
+
+    /**
+     * Releases the MediaEvent object.
+     */
+    public void release() {
+        synchronized (mLock) {
+            if (mReleased) {
+                return;
+            }
+            nativeFinalize();
+            mNativeContext = 0;
+            mReleased = true;
+        }
+    }
+}
diff --git a/android/media/tv/tuner/filter/MmtpFilterConfiguration.java b/android/media/tv/tuner/filter/MmtpFilterConfiguration.java
new file mode 100644
index 0000000..2aa40f9
--- /dev/null
+++ b/android/media/tv/tuner/filter/MmtpFilterConfiguration.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.Tuner;
+
+/**
+ * Filter configuration for a MMTP filter.
+ *
+ * @hide
+ */
+@SystemApi
+public final class MmtpFilterConfiguration extends FilterConfiguration {
+    private final int mMmtpPid;
+
+    private MmtpFilterConfiguration(Settings settings, int mmtpPid) {
+        super(settings);
+        mMmtpPid = mmtpPid;
+    }
+
+    @Override
+    public int getType() {
+        return Filter.TYPE_MMTP;
+    }
+
+    /**
+     * Gets MMTP Packet ID.
+     *
+     * <p>Packet ID is used to specify packets in MMTP.
+     */
+    public int getMmtpPacketId() {
+        return mMmtpPid;
+    }
+
+    /**
+     * Creates a builder for {@link MmtpFilterConfiguration}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link MmtpFilterConfiguration}.
+     */
+    public static final class Builder {
+        private int mMmtpPid = Tuner.INVALID_TS_PID;
+        private Settings mSettings;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets MMTP Packet ID.
+         *
+         * <p>Default value is {@link Tuner#INVALID_TS_PID}.
+         */
+        @NonNull
+        public Builder setMmtpPacketId(int mmtpPid) {
+            mMmtpPid = mmtpPid;
+            return this;
+        }
+
+        /**
+         * Sets filter settings.
+         */
+        @NonNull
+        public Builder setSettings(@Nullable Settings settings) {
+            mSettings = settings;
+            return this;
+        }
+
+        /**
+         * Builds a {@link IpFilterConfiguration} object.
+         */
+        @NonNull
+        public MmtpFilterConfiguration build() {
+            return new MmtpFilterConfiguration(mSettings, mMmtpPid);
+        }
+    }
+}
diff --git a/android/media/tv/tuner/filter/MmtpRecordEvent.java b/android/media/tv/tuner/filter/MmtpRecordEvent.java
new file mode 100644
index 0000000..58a81d9
--- /dev/null
+++ b/android/media/tv/tuner/filter/MmtpRecordEvent.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.BytesLong;
+import android.annotation.IntRange;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.filter.RecordSettings.ScHevcIndex;
+
+/**
+ * Filter event sent from {@link Filter} objects with MPEG media Transport Protocol(MMTP) type.
+ *
+ * @hide
+ */
+@SystemApi
+public class MmtpRecordEvent extends FilterEvent {
+    private final int mScHevcIndexMask;
+    private final long mDataLength;
+    private final int mMpuSequenceNumber;
+    private final long mPts;
+    private final int mFirstMbInSlice;
+    private final int mTsIndexMask;
+
+    // This constructor is used by JNI code only
+    private MmtpRecordEvent(int scHevcIndexMask, long dataLength, int mpuSequenceNumber, long pts,
+            int firstMbInSlice, int tsIndexMask) {
+        mScHevcIndexMask = scHevcIndexMask;
+        mDataLength = dataLength;
+        mMpuSequenceNumber = mpuSequenceNumber;
+        mPts = pts;
+        mFirstMbInSlice = firstMbInSlice;
+        mTsIndexMask = tsIndexMask;
+    }
+
+    /**
+     * Gets indexes which can be tagged by NAL unit group in HEVC according to ISO/IEC 23008-2.
+     */
+    @ScHevcIndex
+    public int getScHevcIndexMask() {
+        return mScHevcIndexMask;
+    }
+
+    /**
+     * Gets data size in bytes of filtered data.
+     */
+    @BytesLong
+    public long getDataLength() {
+        return mDataLength;
+    }
+
+    /**
+     * Get the MPU sequence number of the filtered data.
+     *
+     * <p>This field is only supported in Tuner 1.1 or higher version. Unsupported version will
+     * return {@link android.media.tv.tuner.Tuner#INVALID_MMTP_RECORD_EVENT_MPT_SEQUENCE_NUM}. Use
+     * {@link android.media.tv.tuner.TunerVersionChecker#getTunerVersion()} to get the version
+     * information.
+     */
+    @IntRange(from = 0)
+    public int getMpuSequenceNumber() {
+        return mMpuSequenceNumber;
+    }
+
+    /**
+     * Get the Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz
+     * and has the same format as the PTS in ISO/IEC 13818-1.
+     *
+     * <p>This field is only supported in Tuner 1.1 or higher version. Unsupported version will
+     * return {@link android.media.tv.tuner.Tuner#INVALID_TIMESTAMP}. Use
+     * {@link android.media.tv.tuner.TunerVersionChecker#getTunerVersion()} to get the version
+     * information.
+     */
+    public long getPts() {
+        return mPts;
+    }
+
+    /**
+     * Get the address of the first macroblock in the slice defined in ITU-T Rec. H.264.
+     *
+     * <p>This field is only supported in Tuner 1.1 or higher version. Unsupported version will
+     * return {@link android.media.tv.tuner.Tuner#INVALID_FIRST_MACROBLOCK_IN_SLICE}. Use
+     * {@link android.media.tv.tuner.TunerVersionChecker#getTunerVersion()} to get the version
+     * information.
+     */
+    public int getFirstMacroblockInSlice() {
+        return mFirstMbInSlice;
+    }
+
+    /**
+     * Get the offset of the recorded keyframe from MMT Packet Table.
+     *
+     * <p>This field is only supported in Tuner 1.1 or higher version. Unsupported version will
+     * return {@link RecordSettings#TS_INDEX_INVALID}. Use
+     * {@link android.media.tv.tuner.TunerVersionChecker#getTunerVersion()} to get the
+     * version information.
+     */
+    @RecordSettings.TsIndexMask
+    public int getTsIndexMask() {
+        return mTsIndexMask;
+    }
+}
diff --git a/android/media/tv/tuner/filter/PesEvent.java b/android/media/tv/tuner/filter/PesEvent.java
new file mode 100644
index 0000000..bfb7460
--- /dev/null
+++ b/android/media/tv/tuner/filter/PesEvent.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.IntRange;
+import android.annotation.SystemApi;
+
+/**
+ * Filter event sent from {@link Filter} objects with PES type.
+ *
+ * @hide
+ */
+@SystemApi
+public class PesEvent extends FilterEvent {
+    private final int mStreamId;
+    private final int mDataLength;
+    private final int mMpuSequenceNumber;
+
+    // This constructor is used by JNI code only
+    private PesEvent(int streamId, int dataLength, int mpuSequenceNumber) {
+        mStreamId = streamId;
+        mDataLength = dataLength;
+        mMpuSequenceNumber = mpuSequenceNumber;
+    }
+
+    /**
+     * Gets stream ID.
+     */
+    public int getStreamId() {
+        return mStreamId;
+    }
+
+    /**
+     * Gets data size in bytes of filtered data.
+     */
+    public int getDataLength() {
+        return mDataLength;
+    }
+
+    /**
+     * Gets MPU sequence number of filtered data.
+     */
+    @IntRange(from = 0)
+    public int getMpuSequenceNumber() {
+        return mMpuSequenceNumber;
+    }
+}
diff --git a/android/media/tv/tuner/filter/PesSettings.java b/android/media/tv/tuner/filter/PesSettings.java
new file mode 100644
index 0000000..2f551cc
--- /dev/null
+++ b/android/media/tv/tuner/filter/PesSettings.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.TunerUtils;
+
+/**
+ * Filter Settings for a PES Data.
+ *
+ * @hide
+ */
+@SystemApi
+public class PesSettings extends Settings {
+    private final int mStreamId;
+    private final boolean mIsRaw;
+
+    private PesSettings(@Filter.Type int mainType, int streamId, boolean isRaw) {
+        super(TunerUtils.getFilterSubtype(mainType, Filter.SUBTYPE_PES));
+        mStreamId = streamId;
+        mIsRaw = isRaw;
+    }
+
+    /**
+     * Gets stream ID.
+     */
+    public int getStreamId() {
+        return mStreamId;
+    }
+
+    /**
+     * Returns whether the data is raw.
+     *
+     * @return {@code true} if the data is raw. Filter sends onFilterStatus callback
+     * instead of onFilterEvent for raw data. {@code false} otherwise.
+     */
+    public boolean isRaw() {
+        return mIsRaw;
+    }
+
+    /**
+     * Creates a builder for {@link PesSettings}.
+     *
+     * @param mainType the filter main type of the settings.
+     */
+    @NonNull
+    public static Builder builder(@Filter.Type int mainType) {
+        return new Builder(mainType);
+    }
+
+    /**
+     * Builder for {@link PesSettings}.
+     */
+    public static class Builder {
+        private final int mMainType;
+        private int mStreamId;
+        private boolean mIsRaw;
+
+        private Builder(int mainType) {
+            mMainType = mainType;
+        }
+
+        /**
+         * Sets stream ID.
+         *
+         * @param streamId the stream ID.
+         */
+        @NonNull
+        public Builder setStreamId(int streamId) {
+            mStreamId = streamId;
+            return this;
+        }
+
+        /**
+         * Sets whether the data is raw.
+         *
+         * @param isRaw {@code true} if the data is raw. Filter sends onFilterStatus callback
+         * instead of onFilterEvent for raw data. {@code false} otherwise.
+         */
+        @NonNull
+        public Builder setRaw(boolean isRaw) {
+            mIsRaw = isRaw;
+            return this;
+        }
+
+        /**
+         * Builds a {@link PesSettings} object.
+         */
+        @NonNull
+        public PesSettings build() {
+            return new PesSettings(mMainType, mStreamId, mIsRaw);
+        }
+    }
+}
diff --git a/android/media/tv/tuner/filter/RecordSettings.java b/android/media/tv/tuner/filter/RecordSettings.java
new file mode 100644
index 0000000..91992af
--- /dev/null
+++ b/android/media/tv/tuner/filter/RecordSettings.java
@@ -0,0 +1,384 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.TunerUtils;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * The Settings for the record in DVR.
+ *
+ * @hide
+ */
+@SystemApi
+public class RecordSettings extends Settings {
+    /**
+     * Indexes can be tagged through TS (Transport Stream) header.
+     *
+     * @hide
+     */
+    @IntDef(flag = true,
+            value = {TS_INDEX_INVALID, TS_INDEX_FIRST_PACKET, TS_INDEX_PAYLOAD_UNIT_START_INDICATOR,
+                    TS_INDEX_CHANGE_TO_NOT_SCRAMBLED, TS_INDEX_CHANGE_TO_EVEN_SCRAMBLED,
+                    TS_INDEX_CHANGE_TO_ODD_SCRAMBLED, TS_INDEX_DISCONTINUITY_INDICATOR,
+                    TS_INDEX_RANDOM_ACCESS_INDICATOR, TS_INDEX_PRIORITY_INDICATOR,
+                    TS_INDEX_PCR_FLAG, TS_INDEX_OPCR_FLAG, TS_INDEX_SPLICING_POINT_FLAG,
+                    TS_INDEX_PRIVATE_DATA, TS_INDEX_ADAPTATION_EXTENSION_FLAG,
+                    MPT_INDEX_MPT, MPT_INDEX_VIDEO, MPT_INDEX_AUDIO,
+                    MPT_INDEX_TIMESTAMP_TARGET_VIDEO,
+                    MPT_INDEX_TIMESTAMP_TARGET_AUDIO})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TsIndexMask {}
+
+    /**
+     * Invalid Transport Stream (TS) index.
+     */
+    public static final int TS_INDEX_INVALID = 0;
+    /**
+     * TS index FIRST_PACKET.
+     */
+    public static final int TS_INDEX_FIRST_PACKET = Constants.DemuxTsIndex.FIRST_PACKET;
+    /**
+     * TS index PAYLOAD_UNIT_START_INDICATOR.
+     */
+    public static final int TS_INDEX_PAYLOAD_UNIT_START_INDICATOR =
+            Constants.DemuxTsIndex.PAYLOAD_UNIT_START_INDICATOR;
+    /**
+     * TS index CHANGE_TO_NOT_SCRAMBLED.
+     */
+    public static final int TS_INDEX_CHANGE_TO_NOT_SCRAMBLED =
+            Constants.DemuxTsIndex.CHANGE_TO_NOT_SCRAMBLED;
+    /**
+     * TS index CHANGE_TO_EVEN_SCRAMBLED.
+     */
+    public static final int TS_INDEX_CHANGE_TO_EVEN_SCRAMBLED =
+            Constants.DemuxTsIndex.CHANGE_TO_EVEN_SCRAMBLED;
+    /**
+     * TS index CHANGE_TO_ODD_SCRAMBLED.
+     */
+    public static final int TS_INDEX_CHANGE_TO_ODD_SCRAMBLED =
+            Constants.DemuxTsIndex.CHANGE_TO_ODD_SCRAMBLED;
+    /**
+     * TS index DISCONTINUITY_INDICATOR.
+     */
+    public static final int TS_INDEX_DISCONTINUITY_INDICATOR =
+            Constants.DemuxTsIndex.DISCONTINUITY_INDICATOR;
+    /**
+     * TS index RANDOM_ACCESS_INDICATOR.
+     */
+    public static final int TS_INDEX_RANDOM_ACCESS_INDICATOR =
+            Constants.DemuxTsIndex.RANDOM_ACCESS_INDICATOR;
+    /**
+     * TS index PRIORITY_INDICATOR.
+     */
+    public static final int TS_INDEX_PRIORITY_INDICATOR = Constants.DemuxTsIndex.PRIORITY_INDICATOR;
+    /**
+     * TS index PCR_FLAG.
+     */
+    public static final int TS_INDEX_PCR_FLAG = Constants.DemuxTsIndex.PCR_FLAG;
+    /**
+     * TS index OPCR_FLAG.
+     */
+    public static final int TS_INDEX_OPCR_FLAG = Constants.DemuxTsIndex.OPCR_FLAG;
+    /**
+     * TS index SPLICING_POINT_FLAG.
+     */
+    public static final int TS_INDEX_SPLICING_POINT_FLAG =
+            Constants.DemuxTsIndex.SPLICING_POINT_FLAG;
+    /**
+     * TS index PRIVATE_DATA.
+     */
+    public static final int TS_INDEX_PRIVATE_DATA = Constants.DemuxTsIndex.PRIVATE_DATA;
+    /**
+     * TS index ADAPTATION_EXTENSION_FLAG.
+     */
+    public static final int TS_INDEX_ADAPTATION_EXTENSION_FLAG =
+            Constants.DemuxTsIndex.ADAPTATION_EXTENSION_FLAG;
+    /**
+     * Index the address of MPEG Media Transport Packet Table(MPT).
+     */
+    public static final int MPT_INDEX_MPT =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxTsIndex.MPT_INDEX_MPT;
+    /**
+     * Index the address of Video.
+     */
+    public static final int MPT_INDEX_VIDEO =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxTsIndex.MPT_INDEX_VIDEO;
+    /**
+     * Index the address of Audio.
+     */
+    public static final int MPT_INDEX_AUDIO =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxTsIndex.MPT_INDEX_AUDIO;
+    /**
+     * Index to indicate this is a target of timestamp extraction for video.
+     */
+    public static final int MPT_INDEX_TIMESTAMP_TARGET_VIDEO =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxTsIndex.MPT_INDEX_TIMESTAMP_TARGET_VIDEO;
+    /**
+     * Index to indicate this is a target of timestamp extraction for audio.
+     */
+    public static final int MPT_INDEX_TIMESTAMP_TARGET_AUDIO =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxTsIndex.MPT_INDEX_TIMESTAMP_TARGET_AUDIO;
+
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "INDEX_TYPE_", value =
+            {INDEX_TYPE_NONE, INDEX_TYPE_SC, INDEX_TYPE_SC_HEVC})
+    public @interface ScIndexType {}
+
+    /**
+     * Start Code Index is not used.
+     */
+    public static final int INDEX_TYPE_NONE = Constants.DemuxRecordScIndexType.NONE;
+    /**
+     * Start Code index.
+     */
+    public static final int INDEX_TYPE_SC = Constants.DemuxRecordScIndexType.SC;
+    /**
+     * Start Code index for HEVC.
+     */
+    public static final int INDEX_TYPE_SC_HEVC = Constants.DemuxRecordScIndexType.SC_HEVC;
+
+    /**
+     * Indexes can be tagged by Start Code in PES (Packetized Elementary Stream)
+     * according to ISO/IEC 13818-1.
+     * @hide
+     */
+    @IntDef(prefix = "SC_INDEX_",
+            flag = true,
+            value = {SC_INDEX_I_FRAME, SC_INDEX_P_FRAME, SC_INDEX_B_FRAME,
+                    SC_INDEX_SEQUENCE, SC_INDEX_I_SLICE, SC_INDEX_P_SLICE,
+                    SC_INDEX_B_SLICE, SC_INDEX_SI_SLICE, SC_INDEX_SP_SLICE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScIndex {}
+
+    /**
+     * SC index for a new I-frame.
+     */
+    public static final int SC_INDEX_I_FRAME = Constants.DemuxScIndex.I_FRAME;
+    /**
+     * SC index for a new P-frame.
+     */
+    public static final int SC_INDEX_P_FRAME = Constants.DemuxScIndex.P_FRAME;
+    /**
+     * SC index for a new B-frame.
+     */
+    public static final int SC_INDEX_B_FRAME = Constants.DemuxScIndex.B_FRAME;
+    /**
+     * SC index for a new sequence.
+     */
+    public static final int SC_INDEX_SEQUENCE = Constants.DemuxScIndex.SEQUENCE;
+    /**
+     * All blocks are coded as I blocks.
+     */
+    public static final int SC_INDEX_I_SLICE =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxScIndex.I_SLICE;
+    /**
+     * Blocks are coded as I or P blocks.
+     */
+    public static final int SC_INDEX_P_SLICE =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxScIndex.P_SLICE;
+    /**
+     * Blocks are coded as I, P or B blocks.
+     */
+    public static final int SC_INDEX_B_SLICE =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxScIndex.B_SLICE;
+    /**
+     * A so-called switching I slice that is coded.
+     */
+    public static final int SC_INDEX_SI_SLICE =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxScIndex.SI_SLICE;
+    /**
+     * A so-called switching P slice that is coded.
+     */
+    public static final int SC_INDEX_SP_SLICE =
+            android.hardware.tv.tuner.V1_1.Constants.DemuxScIndex.SP_SLICE;
+
+    /**
+     * Indexes can be tagged by NAL unit group in HEVC according to ISO/IEC 23008-2.
+     *
+     * @hide
+     */
+    @IntDef(flag = true,
+            value = {SC_HEVC_INDEX_SPS, SC_HEVC_INDEX_AUD, SC_HEVC_INDEX_SLICE_CE_BLA_W_LP,
+            SC_HEVC_INDEX_SLICE_BLA_W_RADL, SC_HEVC_INDEX_SLICE_BLA_N_LP,
+            SC_HEVC_INDEX_SLICE_IDR_W_RADL, SC_HEVC_INDEX_SLICE_IDR_N_LP,
+            SC_HEVC_INDEX_SLICE_TRAIL_CRA})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScHevcIndex {}
+
+    /**
+     * SC HEVC index SPS.
+     */
+    public static final int SC_HEVC_INDEX_SPS = Constants.DemuxScHevcIndex.SPS;
+    /**
+     * SC HEVC index AUD.
+     */
+    public static final int SC_HEVC_INDEX_AUD = Constants.DemuxScHevcIndex.AUD;
+    /**
+     * SC HEVC index SLICE_CE_BLA_W_LP.
+     */
+    public static final int SC_HEVC_INDEX_SLICE_CE_BLA_W_LP =
+            Constants.DemuxScHevcIndex.SLICE_CE_BLA_W_LP;
+    /**
+     * SC HEVC index SLICE_BLA_W_RADL.
+     */
+    public static final int SC_HEVC_INDEX_SLICE_BLA_W_RADL =
+            Constants.DemuxScHevcIndex.SLICE_BLA_W_RADL;
+    /**
+     * SC HEVC index SLICE_BLA_N_LP.
+     */
+    public static final int SC_HEVC_INDEX_SLICE_BLA_N_LP =
+            Constants.DemuxScHevcIndex.SLICE_BLA_N_LP;
+    /**
+     * SC HEVC index SLICE_IDR_W_RADL.
+     */
+    public static final int SC_HEVC_INDEX_SLICE_IDR_W_RADL =
+            Constants.DemuxScHevcIndex.SLICE_IDR_W_RADL;
+    /**
+     * SC HEVC index SLICE_IDR_N_LP.
+     */
+    public static final int SC_HEVC_INDEX_SLICE_IDR_N_LP =
+            Constants.DemuxScHevcIndex.SLICE_IDR_N_LP;
+    /**
+     * SC HEVC index SLICE_TRAIL_CRA.
+     */
+    public static final int SC_HEVC_INDEX_SLICE_TRAIL_CRA =
+            Constants.DemuxScHevcIndex.SLICE_TRAIL_CRA;
+
+    /**
+     * @hide
+     */
+    @IntDef(flag = true,
+            prefix = "SC_",
+            value = {
+                SC_INDEX_I_FRAME,
+                SC_INDEX_P_FRAME,
+                SC_INDEX_B_FRAME,
+                SC_INDEX_SEQUENCE,
+                SC_HEVC_INDEX_SPS,
+                SC_HEVC_INDEX_AUD,
+                SC_HEVC_INDEX_SLICE_CE_BLA_W_LP,
+                SC_HEVC_INDEX_SLICE_BLA_W_RADL,
+                SC_HEVC_INDEX_SLICE_BLA_N_LP,
+                SC_HEVC_INDEX_SLICE_IDR_W_RADL,
+                SC_HEVC_INDEX_SLICE_IDR_N_LP,
+                SC_HEVC_INDEX_SLICE_TRAIL_CRA,
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScIndexMask {}
+
+
+
+    private final int mTsIndexMask;
+    private final int mScIndexType;
+    private final int mScIndexMask;
+
+    private RecordSettings(int mainType, int tsIndexType, int scIndexType, int scIndexMask) {
+        super(TunerUtils.getFilterSubtype(mainType, Filter.SUBTYPE_RECORD));
+        mTsIndexMask = tsIndexType;
+        mScIndexType = scIndexType;
+        mScIndexMask = scIndexMask;
+    }
+
+    /**
+     * Gets TS index mask.
+     */
+    @TsIndexMask
+    public int getTsIndexMask() {
+        return mTsIndexMask;
+    }
+    /**
+     * Gets Start Code index type.
+     */
+    @ScIndexType
+    public int getScIndexType() {
+        return mScIndexType;
+    }
+    /**
+     * Gets Start Code index mask.
+     */
+    @ScIndexMask
+    public int getScIndexMask() {
+        return mScIndexMask;
+    }
+
+    /**
+     * Creates a builder for {@link RecordSettings}.
+     *
+     * @param mainType the filter main type.
+     */
+    @NonNull
+    public static Builder builder(@Filter.Type int mainType) {
+        return new Builder(mainType);
+    }
+
+    /**
+     * Builder for {@link RecordSettings}.
+     */
+    public static class Builder {
+        private final int mMainType;
+        private int mTsIndexMask;
+        private int mScIndexType;
+        private int mScIndexMask;
+
+        private Builder(int mainType) {
+            mMainType = mainType;
+        }
+
+        /**
+         * Sets TS index mask.
+         */
+        @NonNull
+        public Builder setTsIndexMask(@TsIndexMask int indexMask) {
+            mTsIndexMask = indexMask;
+            return this;
+        }
+        /**
+         * Sets index type.
+         */
+        @NonNull
+        public Builder setScIndexType(@ScIndexType int indexType) {
+            mScIndexType = indexType;
+            return this;
+        }
+        /**
+         * Sets Start Code index mask.
+         */
+        @NonNull
+        public Builder setScIndexMask(@ScIndexMask int indexMask) {
+            mScIndexMask = indexMask;
+            return this;
+        }
+
+        /**
+         * Builds a {@link RecordSettings} object.
+         */
+        @NonNull
+        public RecordSettings build() {
+            return new RecordSettings(mMainType, mTsIndexMask, mScIndexType, mScIndexMask);
+        }
+    }
+
+}
diff --git a/android/media/tv/tuner/filter/RestartEvent.java b/android/media/tv/tuner/filter/RestartEvent.java
new file mode 100644
index 0000000..9c5992a
--- /dev/null
+++ b/android/media/tv/tuner/filter/RestartEvent.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2020 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.tv.tuner.filter;
+
+import android.annotation.SystemApi;
+
+/**
+ * An Event that the client would receive after starting a filter. This event is optional to be
+ * received on the newly opened and started filter. It must be received after stopping,
+ * reconfiguring and restarting a Filter to differentiate the valid reconfigured events from the
+ * previous events.
+ *
+ * <p>After stopping and restarting the filter, the client has to discard all coming events until
+ * it receives {@link RestartEvent} to avoid using the events from the previous configuration.
+ *
+ * <p>Recofiguring must happen after stopping the filter.
+ *
+ * @see Filter#stop()
+ * @see Filter#start()
+ * @see Filter#configure(FilterConfiguration)
+ *
+ * @hide
+ */
+@SystemApi
+public final class RestartEvent extends FilterEvent {
+    /**
+     * The stard id reserved for the newly opened filter's first start event.
+     */
+    public static final int NEW_FILTER_FIRST_START_ID = 0;
+
+    private final int mStartId;
+
+    // This constructor is used by JNI code only
+    private RestartEvent(int startId) {
+        mStartId = startId;
+    }
+
+    /**
+     * Gets the start id sent via the current Restart Event.
+     *
+     * <p>An unique ID to mark the start point of receiving the valid reconfigured filter events.
+     * The client must receive at least once after the filter is reconfigured and restarted.
+     *
+     * <p>{@link #NEW_FILTER_FIRST_START_ID} is reserved for the newly opened filter's first start.
+     * It's optional to be received.
+     */
+    public int getStartId() {
+        return mStartId;
+    }
+}
diff --git a/android/media/tv/tuner/filter/ScramblingStatusEvent.java b/android/media/tv/tuner/filter/ScramblingStatusEvent.java
new file mode 100644
index 0000000..103d024
--- /dev/null
+++ b/android/media/tv/tuner/filter/ScramblingStatusEvent.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2020 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.tv.tuner.filter;
+
+import android.annotation.SystemApi;
+
+/**
+ * Scrambling Status event sent from {@link Filter} objects with Scrambling Status type.
+ *
+ * <p>This event is only sent in Tuner 1.1 or higher version. Use
+ * {@link TunerVersionChecker#getTunerVersion()} to get the version information.
+ *
+ * @hide
+ */
+@SystemApi
+public final class ScramblingStatusEvent extends FilterEvent {
+    private final int mScramblingStatus;
+
+    private ScramblingStatusEvent(@Filter.ScramblingStatus int scramblingStatus) {
+        mScramblingStatus = scramblingStatus;
+    }
+
+    /**
+     * Gets Scrambling Status Type.
+     *
+     * <p>This event field is only sent in Tuner 1.1 or higher version. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to get the version information.
+     */
+    @Filter.ScramblingStatus
+    public int getScramblingStatus() {
+        return mScramblingStatus;
+    }
+}
diff --git a/android/media/tv/tuner/filter/SectionEvent.java b/android/media/tv/tuner/filter/SectionEvent.java
new file mode 100644
index 0000000..ff12492
--- /dev/null
+++ b/android/media/tv/tuner/filter/SectionEvent.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.SystemApi;
+
+/**
+ * Filter event sent from {@link Filter} objects with section type.
+ *
+ * @hide
+ */
+@SystemApi
+public class SectionEvent extends FilterEvent {
+    private final int mTableId;
+    private final int mVersion;
+    private final int mSectionNum;
+    private final int mDataLength;
+
+    // This constructor is used by JNI code only
+    private SectionEvent(int tableId, int version, int sectionNum, int dataLength) {
+        mTableId = tableId;
+        mVersion = version;
+        mSectionNum = sectionNum;
+        mDataLength = dataLength;
+    }
+
+    /**
+     * Gets table ID of filtered data.
+     */
+    public int getTableId() {
+        return mTableId;
+    }
+
+    /**
+     * Gets version number of filtered data.
+     */
+    public int getVersion() {
+        return mVersion;
+    }
+
+    /**
+     * Gets section number of filtered data.
+     */
+    public int getSectionNumber() {
+        return mSectionNum;
+    }
+
+    /**
+     * Gets data size in bytes of filtered data.
+     */
+    public int getDataLength() {
+        return mDataLength;
+    }
+}
diff --git a/android/media/tv/tuner/filter/SectionSettings.java b/android/media/tv/tuner/filter/SectionSettings.java
new file mode 100644
index 0000000..58e22c9
--- /dev/null
+++ b/android/media/tv/tuner/filter/SectionSettings.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.TunerUtils;
+
+/**
+ * Filter Settings for Section data according to ISO/IEC 13818-1.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class SectionSettings extends Settings {
+    final boolean mCrcEnabled;
+    final boolean mIsRepeat;
+    final boolean mIsRaw;
+
+    SectionSettings(int mainType, boolean crcEnabled, boolean isRepeat, boolean isRaw) {
+        super(TunerUtils.getFilterSubtype(mainType, Filter.SUBTYPE_SECTION));
+        mCrcEnabled = crcEnabled;
+        mIsRepeat = isRepeat;
+        mIsRaw = isRaw;
+    }
+
+    /**
+     * Returns whether the filter enables CRC (Cyclic redundancy check) and discards data which
+     * doesn't pass the check.
+     */
+    public boolean isCrcEnabled() {
+        return mCrcEnabled;
+    }
+    /**
+     * Returns whether the filter repeats the data with the same version.
+     */
+    public boolean isRepeat() {
+        return mIsRepeat;
+    }
+    /**
+     * Returns whether the filter sends {@link FilterCallback#onFilterStatusChanged} instead of
+     * {@link FilterCallback#onFilterEvent}.
+     */
+    public boolean isRaw() {
+        return mIsRaw;
+    }
+
+    /**
+     * Builder for {@link SectionSettings}.
+     *
+     * @param <T> The subclass to be built.
+     */
+    public abstract static class Builder<T extends Builder<T>> {
+        final int mMainType;
+        boolean mCrcEnabled;
+        boolean mIsRepeat;
+        boolean mIsRaw;
+
+        Builder(int mainType) {
+            mMainType = mainType;
+        }
+
+        /**
+         * Sets whether the filter enables CRC (Cyclic redundancy check) and discards data which
+         * doesn't pass the check.
+         */
+        @NonNull
+        public T setCrcEnabled(boolean crcEnabled) {
+            mCrcEnabled = crcEnabled;
+            return self();
+        }
+        /**
+         * Sets whether the filter repeats the data with the same version.
+         */
+        @NonNull
+        public T setRepeat(boolean isRepeat) {
+            mIsRepeat = isRepeat;
+            return self();
+        }
+        /**
+         * Sets whether the filter send onFilterStatus instead of
+         * {@link FilterCallback#onFilterEvent}.
+         */
+        @NonNull
+        public T setRaw(boolean isRaw) {
+            mIsRaw = isRaw;
+            return self();
+        }
+
+        /* package */ abstract T self();
+    }
+}
diff --git a/android/media/tv/tuner/filter/SectionSettingsWithSectionBits.java b/android/media/tv/tuner/filter/SectionSettingsWithSectionBits.java
new file mode 100644
index 0000000..edfe85e
--- /dev/null
+++ b/android/media/tv/tuner/filter/SectionSettingsWithSectionBits.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * Bits Settings for Section Filters.
+ *
+ * @hide
+ */
+@SystemApi
+public class SectionSettingsWithSectionBits extends SectionSettings {
+    private final byte[] mFilter;
+    private final byte[] mMask;
+    private final byte[] mMode;
+
+
+    private SectionSettingsWithSectionBits(int mainType, boolean isCheckCrc, boolean isRepeat,
+            boolean isRaw, byte[] filter, byte[] mask, byte[] mode) {
+        super(mainType, isCheckCrc, isRepeat, isRaw);
+        mFilter = filter;
+        mMask = mask;
+        mMode = mode;
+    }
+
+    /**
+     * Gets the bytes configured for Section Filter
+     */
+    @NonNull
+    public byte[] getFilterBytes() {
+        return mFilter;
+    }
+    /**
+     * Gets bit mask.
+     *
+     * <p>The bits in the bytes are used for filtering.
+     */
+    @NonNull
+    public byte[] getMask() {
+        return mMask;
+    }
+    /**
+     * Gets mode.
+     *
+     * <p>Do positive match at the bit position of the configured bytes when the bit at same
+     * position of the mode is 0.
+     * <p>Do negative match at the bit position of the configured bytes when the bit at same
+     * position of the mode is 1.
+     */
+    @NonNull
+    public byte[] getMode() {
+        return mMode;
+    }
+
+    /**
+     * Creates a builder for {@link SectionSettingsWithSectionBits}.
+     *
+     * @param mainType the filter main type.
+     */
+    @NonNull
+    public static Builder builder(@Filter.Type int mainType) {
+        return new Builder(mainType);
+    }
+
+    /**
+     * Builder for {@link SectionSettingsWithSectionBits}.
+     */
+    public static class Builder extends SectionSettings.Builder<Builder> {
+        private byte[] mFilter = {};
+        private byte[] mMask = {};
+        private byte[] mMode = {};
+
+        private Builder(int mainType) {
+            super(mainType);
+        }
+
+        /**
+         * Sets filter bytes.
+         *
+         * <p>Default value is an empty byte array.
+         */
+        @NonNull
+        public Builder setFilter(@NonNull byte[] filter) {
+            mFilter = filter;
+            return this;
+        }
+        /**
+         * Sets bit mask.
+         *
+         * <p>Default value is an empty byte array.
+         */
+        @NonNull
+        public Builder setMask(@NonNull byte[] mask) {
+            mMask = mask;
+            return this;
+        }
+        /**
+         * Sets mode.
+         *
+         * <p>Default value is an empty byte array.
+         */
+        @NonNull
+        public Builder setMode(@NonNull byte[] mode) {
+            mMode = mode;
+            return this;
+        }
+
+        /**
+         * Builds a {@link SectionSettingsWithSectionBits} object.
+         */
+        @NonNull
+        public SectionSettingsWithSectionBits build() {
+            return new SectionSettingsWithSectionBits(
+                    mMainType, mCrcEnabled, mIsRepeat, mIsRaw, mFilter, mMask, mMode);
+        }
+
+        @Override
+        Builder self() {
+            return this;
+        }
+    }
+}
diff --git a/android/media/tv/tuner/filter/SectionSettingsWithTableInfo.java b/android/media/tv/tuner/filter/SectionSettingsWithTableInfo.java
new file mode 100644
index 0000000..fc6451f
--- /dev/null
+++ b/android/media/tv/tuner/filter/SectionSettingsWithTableInfo.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * Table information for Section Filter.
+ *
+ * @hide
+ */
+@SystemApi
+public class SectionSettingsWithTableInfo extends SectionSettings {
+    private final int mTableId;
+    private final int mVersion;
+
+    private SectionSettingsWithTableInfo(int mainType, boolean isCheckCrc, boolean isRepeat,
+            boolean isRaw, int tableId, int version) {
+        super(mainType, isCheckCrc, isRepeat, isRaw);
+        mTableId = tableId;
+        mVersion = version;
+    }
+
+    /**
+     * Gets table ID.
+     */
+    public int getTableId() {
+        return mTableId;
+    }
+    /**
+     * Gets version.
+     */
+    public int getVersion() {
+        return mVersion;
+    }
+
+    /**
+     * Creates a builder for {@link SectionSettingsWithTableInfo}.
+     *
+     * @param mainType the filter main type.
+     */
+    @NonNull
+    public static Builder builder(@Filter.Type int mainType) {
+        return new Builder(mainType);
+    }
+
+    /**
+     * Builder for {@link SectionSettingsWithTableInfo}.
+     */
+    public static class Builder extends SectionSettings.Builder<Builder> {
+        private int mTableId;
+        private int mVersion;
+
+        private Builder(int mainType) {
+            super(mainType);
+        }
+
+        /**
+         * Sets table ID.
+         */
+        @NonNull
+        public Builder setTableId(int tableId) {
+            mTableId = tableId;
+            return this;
+        }
+        /**
+         * Sets version.
+         */
+        @NonNull
+        public Builder setVersion(int version) {
+            mVersion = version;
+            return this;
+        }
+
+        /**
+         * Builds a {@link SectionSettingsWithTableInfo} object.
+         */
+        @NonNull
+        public SectionSettingsWithTableInfo build() {
+            return new SectionSettingsWithTableInfo(
+                    mMainType, mCrcEnabled, mIsRepeat, mIsRaw, mTableId, mVersion);
+        }
+
+        @Override
+        Builder self() {
+            return this;
+        }
+    }
+
+}
diff --git a/android/media/tv/tuner/filter/Settings.java b/android/media/tv/tuner/filter/Settings.java
new file mode 100644
index 0000000..f89bc06
--- /dev/null
+++ b/android/media/tv/tuner/filter/Settings.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.SystemApi;
+
+/**
+ * Settings for filters of different subtypes.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class Settings {
+    private final int mType;
+
+    /* package */ Settings(int type) {
+        mType = type;
+    }
+
+    /**
+     * Gets filter settings type.
+     */
+    public int getType() {
+        return mType;
+    }
+}
diff --git a/android/media/tv/tuner/filter/TemiEvent.java b/android/media/tv/tuner/filter/TemiEvent.java
new file mode 100644
index 0000000..9bee928
--- /dev/null
+++ b/android/media/tv/tuner/filter/TemiEvent.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * Filter event sent from {@link Filter} objects for Timed External Media Information (TEMI) data.
+ *
+ * @hide
+ */
+@SystemApi
+public class TemiEvent extends FilterEvent {
+    private final long mPts;
+    private final byte mDescrTag;
+    private final byte[] mDescrData;
+
+    // This constructor is used by JNI code only
+    private TemiEvent(long pts, byte descrTag, byte[] descrData) {
+        mPts = pts;
+        mDescrTag = descrTag;
+        mDescrData = descrData;
+    }
+
+
+    /**
+     * Gets PTS (Presentation Time Stamp) for audio or video frame.
+     */
+    public long getPts() {
+        return mPts;
+    }
+
+    /**
+     * Gets TEMI (Timed External Media Information) descriptor tag.
+     */
+    public byte getDescriptorTag() {
+        return mDescrTag;
+    }
+
+    /**
+     * Gets TEMI (Timed External Media Information) descriptor.
+     */
+    @NonNull
+    public byte[] getDescriptorData() {
+        return mDescrData;
+    }
+}
diff --git a/android/media/tv/tuner/filter/TimeFilter.java b/android/media/tv/tuner/filter/TimeFilter.java
new file mode 100644
index 0000000..93599e6
--- /dev/null
+++ b/android/media/tv/tuner/filter/TimeFilter.java
@@ -0,0 +1,139 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.SystemApi;
+import android.media.tv.tuner.Tuner;
+import android.media.tv.tuner.Tuner.Result;
+import android.media.tv.tuner.TunerUtils;
+
+/**
+ *  A timer filter is used to filter data based on timestamps.
+ *
+ *  <p> If the timestamp is set, data is discarded if its timestamp is smaller than the
+ *  timestamp in this time filter.
+ *
+ *  <p> The format of the timestamps is the same as PTS defined in ISO/IEC 13818-1:2019. The
+ *  timestamps may or may not be related to PTS or DTS.
+ *
+ * @hide
+ */
+@SystemApi
+public class TimeFilter implements AutoCloseable {
+
+
+    private native int nativeSetTimestamp(long timestamp);
+    private native int nativeClearTimestamp();
+    private native Long nativeGetTimestamp();
+    private native Long nativeGetSourceTime();
+    private native int nativeClose();
+
+    private long mNativeContext;
+
+    private boolean mEnable = false;
+
+    // Called by JNI code
+    private TimeFilter() {
+    }
+
+    /**
+     * Set timestamp for time based filter.
+     *
+     * It is used to set initial timestamp and enable time filtering. Once set, the time will be
+     * increased automatically like a clock. Contents are discarded if their timestamps are
+     * older than the time in the time filter.
+     *
+     * This method can be called more than once to reset the initial timestamp.
+     *
+     * @param timestamp initial timestamp for the time filter before it's increased. It's
+     * based on the 90KHz counter, and it's the same format as PTS (Presentation Time Stamp)
+     * defined in ISO/IEC 13818-1:2019. The timestamps may or may not be related to PTS or DTS.
+     * @return result status of the operation.
+     */
+    @Result
+    public int setCurrentTimestamp(long timestamp) {
+        int res = nativeSetTimestamp(timestamp);
+        if (res == Tuner.RESULT_SUCCESS) {
+            mEnable = true;
+        }
+        return res;
+    }
+
+    /**
+     * Clear the timestamp in the time filter.
+     *
+     * It is used to clear the time value of the time filter. Time filtering is disabled then.
+     *
+     * @return result status of the operation.
+     */
+    @Result
+    public int clearTimestamp() {
+        int res = nativeClearTimestamp();
+        if (res == Tuner.RESULT_SUCCESS) {
+            mEnable = false;
+        }
+        return res;
+    }
+
+    /**
+     * Get the current time in the time filter.
+     *
+     * It is used to inquiry current time in the time filter.
+     *
+     * @return current timestamp in the time filter. It's based on the 90KHz counter, and it's
+     * the same format as PTS (Presentation Time Stamp) defined in ISO/IEC 13818-1:2019. The
+     * timestamps may or may not be related to PTS or DTS. Returns
+     * {@link Tuner#INVALID_TIMESTAMP} if the timestamp is never set.
+     */
+    public long getTimeStamp() {
+        if (!mEnable) {
+            return Tuner.INVALID_TIMESTAMP;
+        }
+        return nativeGetTimestamp();
+    }
+
+    /**
+     * Get the timestamp from the beginning of incoming data stream.
+     *
+     * It is used to inquiry the timestamp from the beginning of incoming data stream.
+     *
+     * @return first timestamp of incoming data stream. It's based on the 90KHz counter, and
+     * it's the same format as PTS (Presentation Time Stamp) defined in ISO/IEC 13818-1:2019.
+     * The timestamps may or may not be related to PTS or DTS. Returns
+     * {@link Tuner#INVALID_TIMESTAMP} if the timestamp is not available.
+     */
+    public long getSourceTime() {
+        if (!mEnable) {
+            return Tuner.INVALID_TIMESTAMP;
+        }
+        return nativeGetSourceTime();
+    }
+
+    /**
+     * Close the Time Filter instance
+     *
+     * It is to release the TimeFilter instance. Resources are reclaimed so the instance must
+     * not be accessed after this method is called.
+     */
+    @Override
+    public void close() {
+        int res = nativeClose();
+        if (res != Tuner.RESULT_SUCCESS) {
+            TunerUtils.throwExceptionForResult(res, "Failed to close time filter.");
+        }
+    }
+}
diff --git a/android/media/tv/tuner/filter/TlvFilterConfiguration.java b/android/media/tv/tuner/filter/TlvFilterConfiguration.java
new file mode 100644
index 0000000..9bb408d
--- /dev/null
+++ b/android/media/tv/tuner/filter/TlvFilterConfiguration.java
@@ -0,0 +1,164 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+
+/**
+ * Filter configuration for a TLV filter.
+ *
+ * @hide
+ */
+@SystemApi
+public final class TlvFilterConfiguration extends FilterConfiguration {
+    /**
+     * IPv4 packet type.
+     */
+    public static final int PACKET_TYPE_IPV4 = 0x01;
+    /**
+     * IPv6 packet type.
+     */
+    public static final int PACKET_TYPE_IPV6 = 0x02;
+    /**
+     * Compressed packet type.
+     */
+    public static final int PACKET_TYPE_COMPRESSED = 0x03;
+    /**
+     * Signaling packet type.
+     */
+    public static final int PACKET_TYPE_SIGNALING = 0xFE;
+    /**
+     * NULL packet type.
+     */
+    public static final int PACKET_TYPE_NULL = 0xFF;
+
+    private final int mPacketType;
+    private final boolean mIsCompressedIpPacket;
+    private final boolean mPassthrough;
+
+    private TlvFilterConfiguration(Settings settings, int packetType, boolean isCompressed,
+            boolean passthrough) {
+        super(settings);
+        mPacketType = packetType;
+        mIsCompressedIpPacket = isCompressed;
+        mPassthrough = passthrough;
+    }
+
+    @Override
+    public int getType() {
+        return Filter.TYPE_TLV;
+    }
+
+    /**
+     * Gets packet type.
+     *
+     * <p>The description of each packet type value is shown in ITU-R BT.1869 table 2.
+     */
+    public int getPacketType() {
+        return mPacketType;
+    }
+    /**
+     * Checks whether the data is compressed IP packet.
+     *
+     * @return {@code true} if the filtered data is compressed IP packet; {@code false} otherwise.
+     */
+    public boolean isCompressedIpPacket() {
+        return mIsCompressedIpPacket;
+    }
+    /**
+     * Checks whether it's passthrough.
+     *
+     * @return {@code true} if the data from TLV subtype go to next filter directly;
+     *         {@code false} otherwise.
+     */
+    public boolean isPassthrough() {
+        return mPassthrough;
+    }
+
+    /**
+     * Creates a builder for {@link TlvFilterConfiguration}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link TlvFilterConfiguration}.
+     */
+    public static final class Builder {
+        private int mPacketType = PACKET_TYPE_NULL;
+        private boolean mIsCompressedIpPacket = false;
+        private boolean mPassthrough = false;
+        private Settings mSettings;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets packet type.
+         *
+         * <p>The description of each packet type value is shown in ITU-R BT.1869 table 2.
+         * <p>Default value is {@link #PACKET_TYPE_NULL}.
+         */
+        @NonNull
+        public Builder setPacketType(int packetType) {
+            mPacketType = packetType;
+            return this;
+        }
+        /**
+         * Sets whether the data is compressed IP packet.
+         *
+         * <p>Default value is {@code false}.
+         */
+        @NonNull
+        public Builder setCompressedIpPacket(boolean isCompressedIpPacket) {
+            mIsCompressedIpPacket = isCompressedIpPacket;
+            return this;
+        }
+        /**
+         * Sets whether it's passthrough.
+         *
+         * <p>Default value is {@code false}.
+         */
+        @NonNull
+        public Builder setPassthrough(boolean passthrough) {
+            mPassthrough = passthrough;
+            return this;
+        }
+
+        /**
+         * Sets filter settings.
+         */
+        @NonNull
+        public Builder setSettings(@Nullable Settings settings) {
+            mSettings = settings;
+            return this;
+        }
+
+        /**
+         * Builds a {@link TlvFilterConfiguration} object.
+         */
+        @NonNull
+        public TlvFilterConfiguration build() {
+            return new TlvFilterConfiguration(
+                    mSettings, mPacketType, mIsCompressedIpPacket, mPassthrough);
+        }
+    }
+}
diff --git a/android/media/tv/tuner/filter/TsFilterConfiguration.java b/android/media/tv/tuner/filter/TsFilterConfiguration.java
new file mode 100644
index 0000000..d4a1856
--- /dev/null
+++ b/android/media/tv/tuner/filter/TsFilterConfiguration.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+
+/**
+ * Filter configuration for a TS filter.
+ *
+ * @hide
+ */
+@SystemApi
+public final class TsFilterConfiguration extends FilterConfiguration {
+    private final int mTpid;
+
+    private TsFilterConfiguration(Settings settings, int tpid) {
+        super(settings);
+        mTpid = tpid;
+    }
+
+    @Override
+    public int getType() {
+        return Filter.TYPE_TS;
+    }
+
+    /**
+     * Gets Tag Protocol ID.
+     */
+    public int getTpid() {
+        return mTpid;
+    }
+
+    /**
+     * Creates a builder for {@link TsFilterConfiguration}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link TsFilterConfiguration}.
+     */
+    public static final class Builder {
+        private int mTpid = 0;
+        private Settings mSettings;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets Tag Protocol ID.
+         *
+         * <p>Default value is 0.
+         *
+         * @param tpid the Tag Protocol ID.
+         */
+        @NonNull
+        public Builder setTpid(int tpid) {
+            mTpid = tpid;
+            return this;
+        }
+
+        /**
+         * Sets filter settings.
+         */
+        @NonNull
+        public Builder setSettings(@Nullable Settings settings) {
+            mSettings = settings;
+            return this;
+        }
+
+        /**
+         * Builds a {@link TsFilterConfiguration} object.
+         */
+        @NonNull
+        public TsFilterConfiguration build() {
+            return new TsFilterConfiguration(mSettings, mTpid);
+        }
+    }
+}
diff --git a/android/media/tv/tuner/filter/TsRecordEvent.java b/android/media/tv/tuner/filter/TsRecordEvent.java
new file mode 100644
index 0000000..bf2c000
--- /dev/null
+++ b/android/media/tv/tuner/filter/TsRecordEvent.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2019 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.tv.tuner.filter;
+
+import android.annotation.BytesLong;
+import android.annotation.SystemApi;
+
+
+/**
+ * Filter event sent from {@link Filter} objects for TS record data.
+ *
+ * @hide
+ */
+@SystemApi
+public class TsRecordEvent extends FilterEvent {
+
+    private final int mPid;
+    private final int mTsIndexMask;
+    private final int mScIndexMask;
+    private final long mDataLength;
+    private final long mPts;
+    private final int mFirstMbInSlice;
+
+    // This constructor is used by JNI code only
+    private TsRecordEvent(int pid, int tsIndexMask, int scIndexMask, long dataLength, long pts,
+            int firstMbInSlice) {
+        mPid = pid;
+        mTsIndexMask = tsIndexMask;
+        mScIndexMask = scIndexMask;
+        mDataLength = dataLength;
+        mPts = pts;
+        mFirstMbInSlice = firstMbInSlice;
+    }
+
+    /**
+     * Gets packet ID.
+     */
+    public int getPacketId() {
+        return mPid;
+    }
+
+    /**
+     * Gets TS (transport stream) index mask.
+     */
+    @RecordSettings.TsIndexMask
+    public int getTsIndexMask() {
+        return mTsIndexMask;
+    }
+    /**
+     * Gets SC (Start Code) index mask.
+     *
+     * <p>The index type is SC or SC-HEVC, and is set when configuring the filter.
+     */
+    @RecordSettings.ScIndexMask
+    public int getScIndexMask() {
+        return mScIndexMask;
+    }
+
+    /**
+     * Gets data size in bytes of filtered data.
+     */
+    @BytesLong
+    public long getDataLength() {
+        return mDataLength;
+    }
+
+    /**
+     * Gets the Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz
+     * and has the same format as the PTS in ISO/IEC 13818-1.
+     *
+     * <p>This field is only supported in Tuner 1.1 or higher version. Unsupported version will
+     * return {@link android.media.tv.tuner.Tuner#INVALID_TIMESTAMP}. Use
+     * {@link android.media.tv.tuner.TunerVersionChecker#getTunerVersion()} to get the version
+     * information.
+     */
+    public long getPts() {
+        return mPts;
+    }
+
+    /**
+     * Get the address of the first macroblock in the slice defined in ITU-T Rec. H.264.
+     *
+     * <p>This field is only supported in Tuner 1.1 or higher version. Unsupported version will
+     * return {@link android.media.tv.tuner.Tuner#INVALID_FIRST_MACROBLOCK_IN_SLICE}. Use
+     * {@link android.media.tv.tuner.TunerVersionChecker#getTunerVersion()} to get the version
+     * information.
+     */
+    public int getFirstMacroblockInSlice() {
+        return mFirstMbInSlice;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/AnalogFrontendCapabilities.java b/android/media/tv/tuner/frontend/AnalogFrontendCapabilities.java
new file mode 100644
index 0000000..096bc67
--- /dev/null
+++ b/android/media/tv/tuner/frontend/AnalogFrontendCapabilities.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/**
+ * Capabilities for analog tuners.
+ *
+ * @hide
+ */
+@SystemApi
+public class AnalogFrontendCapabilities extends FrontendCapabilities {
+    @AnalogFrontendSettings.SignalType
+    private final int mTypeCap;
+    @AnalogFrontendSettings.SifStandard
+    private final int mSifStandardCap;
+
+    // Called by JNI code.
+    private AnalogFrontendCapabilities(int typeCap, int sifStandardCap) {
+        mTypeCap = typeCap;
+        mSifStandardCap = sifStandardCap;
+    }
+
+    /**
+     * Gets analog signal type capability.
+     */
+    @AnalogFrontendSettings.SignalType
+    public int getSignalTypeCapability() {
+        return mTypeCap;
+    }
+    /**
+     * Gets Standard Interchange Format (SIF) capability.
+     */
+    @AnalogFrontendSettings.SifStandard
+    public int getSifStandardCapability() {
+        return mSifStandardCap;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/AnalogFrontendSettings.java b/android/media/tv/tuner/frontend/AnalogFrontendSettings.java
new file mode 100644
index 0000000..b2c3fd2
--- /dev/null
+++ b/android/media/tv/tuner/frontend/AnalogFrontendSettings.java
@@ -0,0 +1,311 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.TunerVersionChecker;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Frontend settings for analog tuner.
+ *
+ * @hide
+ */
+@SystemApi
+public class AnalogFrontendSettings extends FrontendSettings {
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "SIGNAL_TYPE_",
+            value = {SIGNAL_TYPE_UNDEFINED, SIGNAL_TYPE_AUTO, SIGNAL_TYPE_PAL, SIGNAL_TYPE_PAL_M,
+              SIGNAL_TYPE_PAL_N, SIGNAL_TYPE_PAL_60, SIGNAL_TYPE_NTSC, SIGNAL_TYPE_NTSC_443,
+              SIGNAL_TYPE_SECAM})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SignalType {}
+
+    /**
+     * Undefined analog signal type.
+     */
+    public static final int SIGNAL_TYPE_UNDEFINED = Constants.FrontendAnalogType.UNDEFINED;
+    /**
+     * AUTO analog signal type.
+     */
+    public static final int SIGNAL_TYPE_AUTO = Constants.FrontendAnalogType.AUTO;
+    /**
+     * PAL analog signal type.
+     */
+    public static final int SIGNAL_TYPE_PAL = Constants.FrontendAnalogType.PAL;
+    /**
+     * PAL M analog signal type.
+     */
+    public static final int SIGNAL_TYPE_PAL_M = Constants.FrontendAnalogType.PAL_M;
+    /**
+     * PAL N analog signal type.
+     */
+    public static final int SIGNAL_TYPE_PAL_N = Constants.FrontendAnalogType.PAL_N;
+    /**
+     * PAL 60 analog signal type.
+     */
+    public static final int SIGNAL_TYPE_PAL_60 = Constants.FrontendAnalogType.PAL_60;
+    /**
+     * NTSC analog signal type.
+     */
+    public static final int SIGNAL_TYPE_NTSC = Constants.FrontendAnalogType.NTSC;
+    /**
+     * NTSC 443 analog signal type.
+     */
+    public static final int SIGNAL_TYPE_NTSC_443 = Constants.FrontendAnalogType.NTSC_443;
+    /**
+     * SECM analog signal type.
+     */
+    public static final int SIGNAL_TYPE_SECAM = Constants.FrontendAnalogType.SECAM;
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "SIF_",
+            value = {SIF_UNDEFINED, SIF_AUTO, SIF_BG, SIF_BG_A2, SIF_BG_NICAM, SIF_I, SIF_DK,
+            SIF_DK1_A2, SIF_DK2_A2, SIF_DK3_A2, SIF_DK_NICAM, SIF_L, SIF_M, SIF_M_BTSC, SIF_M_A2,
+            SIF_M_EIAJ, SIF_I_NICAM, SIF_L_NICAM, SIF_L_PRIME})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SifStandard {}
+
+    /**
+     * Undefined Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_UNDEFINED = Constants.FrontendAnalogSifStandard.UNDEFINED;
+    /**
+     * Audo Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_AUTO = Constants.FrontendAnalogSifStandard.AUTO;
+     /**
+     * BG Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_BG = Constants.FrontendAnalogSifStandard.BG;
+    /**
+     * BG-A2 Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_BG_A2 = Constants.FrontendAnalogSifStandard.BG_A2;
+    /**
+     * BG-NICAM Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_BG_NICAM = Constants.FrontendAnalogSifStandard.BG_NICAM;
+    /**
+     * I Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_I = Constants.FrontendAnalogSifStandard.I;
+    /**
+     * DK Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_DK = Constants.FrontendAnalogSifStandard.DK;
+    /**
+     * DK1 A2 Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_DK1_A2 = Constants.FrontendAnalogSifStandard.DK1_A2;
+    /**
+     * DK2 A2 Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_DK2_A2 = Constants.FrontendAnalogSifStandard.DK2_A2;
+    /**
+     * DK3 A2 Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_DK3_A2 = Constants.FrontendAnalogSifStandard.DK3_A2;
+    /**
+     * DK-NICAM Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_DK_NICAM = Constants.FrontendAnalogSifStandard.DK_NICAM;
+    /**
+     * L Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_L = Constants.FrontendAnalogSifStandard.L;
+    /**
+     * M Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_M = Constants.FrontendAnalogSifStandard.M;
+    /**
+     * M-BTSC Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_M_BTSC = Constants.FrontendAnalogSifStandard.M_BTSC;
+    /**
+     * M-A2 Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_M_A2 = Constants.FrontendAnalogSifStandard.M_A2;
+    /**
+     * M-EIAJ Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_M_EIAJ = Constants.FrontendAnalogSifStandard.M_EIAJ;
+    /**
+     * I-NICAM Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_I_NICAM = Constants.FrontendAnalogSifStandard.I_NICAM;
+    /**
+     * L-NICAM Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_L_NICAM = Constants.FrontendAnalogSifStandard.L_NICAM;
+    /**
+     * L-PRIME Analog Standard Interchange Format (SIF).
+     */
+    public static final int SIF_L_PRIME = Constants.FrontendAnalogSifStandard.L_PRIME;
+
+    /** @hide */
+    @IntDef(prefix = "AFT_FLAG_",
+            value = {AFT_FLAG_UNDEFINED, AFT_FLAG_TRUE, AFT_FLAG_FALSE})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface AftFlag {}
+
+    /**
+     * Aft flag is not defined.
+     */
+    public static final int AFT_FLAG_UNDEFINED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendAnalogAftFlag.UNDEFINED;
+    /**
+     * Aft flag is set true.
+     */
+    public static final int AFT_FLAG_TRUE =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendAnalogAftFlag.AFT_TRUE;
+    /**
+     * Aft flag is not set.
+     */
+    public static final int AFT_FLAG_FALSE =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendAnalogAftFlag.AFT_FALSE;
+
+
+    private final int mSignalType;
+    private final int mSifStandard;
+    private final int mAftFlag;
+
+    @Override
+    public int getType() {
+        return FrontendSettings.TYPE_ANALOG;
+    }
+
+
+    /**
+     * Gets analog signal type.
+     */
+    @SignalType
+    public int getSignalType() {
+        return mSignalType;
+    }
+
+    /**
+     * Gets Standard Interchange Format (SIF).
+     */
+    @SifStandard
+    public int getSifStandard() {
+        return mSifStandard;
+    }
+
+    /**
+     * Gets AFT flag.
+     */
+    @AftFlag
+    public int getAftFlag() {
+        return mAftFlag;
+    }
+
+    /**
+     * Creates a builder for {@link AnalogFrontendSettings}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    private AnalogFrontendSettings(int frequency, int signalType, int sifStandard, int aftFlag) {
+        super(frequency);
+        mSignalType = signalType;
+        mSifStandard = sifStandard;
+        mAftFlag = aftFlag;
+    }
+
+    /**
+     * Builder for {@link AnalogFrontendSettings}.
+     */
+    public static class Builder {
+        private int mFrequency = 0;
+        private int mSignalType = SIGNAL_TYPE_UNDEFINED;
+        private int mSifStandard = SIF_UNDEFINED;
+        private int mAftFlag = AFT_FLAG_UNDEFINED;
+
+        private Builder() {}
+
+        /**
+         * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        @IntRange(from = 1)
+        public Builder setFrequency(int frequency) {
+            mFrequency = frequency;
+            return this;
+        }
+
+        /**
+         * Set Aft flag.
+         *
+         * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would cause
+         * no-op. Use {@link TunerVersionChecker#getTunerVersion()} to check the version.
+         *
+         * @param aftFlag the value to set the aft flag. The default value is
+         * {@link #AFT_FLAG_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setAftFlag(@AftFlag int aftFlag) {
+            if (TunerVersionChecker.checkHigherOrEqualVersionTo(
+                    TunerVersionChecker.TUNER_VERSION_1_1, "setAftFlag")) {
+                mAftFlag = aftFlag;
+            }
+            return this;
+        }
+
+        /**
+         * Sets analog signal type.
+         *
+         * <p>Default value is {@link #SIGNAL_TYPE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setSignalType(@SignalType int signalType) {
+            mSignalType = signalType;
+            return this;
+        }
+
+        /**
+         * Sets Standard Interchange Format (SIF).
+         *
+         * <p>Default value is {@link #SIF_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setSifStandard(@SifStandard int sifStandard) {
+            mSifStandard = sifStandard;
+            return this;
+        }
+
+        /**
+         * Builds a {@link AnalogFrontendSettings} object.
+         */
+        @NonNull
+        public AnalogFrontendSettings build() {
+            return new AnalogFrontendSettings(mFrequency, mSignalType, mSifStandard, mAftFlag);
+        }
+    }
+}
diff --git a/android/media/tv/tuner/frontend/Atsc3FrontendCapabilities.java b/android/media/tv/tuner/frontend/Atsc3FrontendCapabilities.java
new file mode 100644
index 0000000..7730912
--- /dev/null
+++ b/android/media/tv/tuner/frontend/Atsc3FrontendCapabilities.java
@@ -0,0 +1,87 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/**
+ * ATSC-3 Capabilities.
+ *
+ * @hide
+ */
+@SystemApi
+public class Atsc3FrontendCapabilities extends FrontendCapabilities {
+    private final int mBandwidthCap;
+    private final int mModulationCap;
+    private final int mTimeInterleaveModeCap;
+    private final int mCodeRateCap;
+    private final int mFecCap;
+    private final int mDemodOutputFormatCap;
+
+    private Atsc3FrontendCapabilities(int bandwidthCap, int modulationCap,
+            int timeInterleaveModeCap, int codeRateCap, int fecCap, int demodOutputFormatCap) {
+        mBandwidthCap = bandwidthCap;
+        mModulationCap = modulationCap;
+        mTimeInterleaveModeCap = timeInterleaveModeCap;
+        mCodeRateCap = codeRateCap;
+        mFecCap = fecCap;
+        mDemodOutputFormatCap = demodOutputFormatCap;
+    }
+
+    /**
+     * Gets bandwidth capability.
+     */
+    @Atsc3FrontendSettings.Bandwidth
+    public int getBandwidthCapability() {
+        return mBandwidthCap;
+    }
+    /**
+     * Gets modulation capability.
+     */
+    @Atsc3FrontendSettings.Modulation
+    public int getModulationCapability() {
+        return mModulationCap;
+    }
+    /**
+     * Gets time interleave mod capability.
+     */
+    @Atsc3FrontendSettings.TimeInterleaveMode
+    public int getTimeInterleaveModeCapability() {
+        return mTimeInterleaveModeCap;
+    }
+    /**
+     * Gets code rate capability.
+     */
+    @Atsc3FrontendSettings.CodeRate
+    public int getPlpCodeRateCapability() {
+        return mCodeRateCap;
+    }
+    /**
+     * Gets FEC capability.
+     */
+    @Atsc3FrontendSettings.Fec
+    public int getFecCapability() {
+        return mFecCap;
+    }
+    /**
+     * Gets demodulator output format capability.
+     */
+    @Atsc3FrontendSettings.DemodOutputFormat
+    public int getDemodOutputFormatCapability() {
+        return mDemodOutputFormatCap;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/Atsc3FrontendSettings.java b/android/media/tv/tuner/frontend/Atsc3FrontendSettings.java
new file mode 100644
index 0000000..ed1ce2d
--- /dev/null
+++ b/android/media/tv/tuner/frontend/Atsc3FrontendSettings.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Frontend settings for ATSC-3.
+ *
+ * @hide
+ */
+@SystemApi
+public class Atsc3FrontendSettings extends FrontendSettings {
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "BANDWIDTH_",
+            value = {BANDWIDTH_UNDEFINED, BANDWIDTH_AUTO, BANDWIDTH_BANDWIDTH_6MHZ,
+                    BANDWIDTH_BANDWIDTH_7MHZ, BANDWIDTH_BANDWIDTH_8MHZ})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Bandwidth {}
+
+    /**
+     * Bandwidth not defined.
+     */
+    public static final int BANDWIDTH_UNDEFINED =
+            Constants.FrontendAtsc3Bandwidth.UNDEFINED;
+    /**
+     * Hardware is able to detect and set bandwidth automatically
+     */
+    public static final int BANDWIDTH_AUTO = Constants.FrontendAtsc3Bandwidth.AUTO;
+    /**
+     * 6 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_BANDWIDTH_6MHZ =
+            Constants.FrontendAtsc3Bandwidth.BANDWIDTH_6MHZ;
+    /**
+     * 7 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_BANDWIDTH_7MHZ =
+            Constants.FrontendAtsc3Bandwidth.BANDWIDTH_7MHZ;
+    /**
+     * 8 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_BANDWIDTH_8MHZ =
+            Constants.FrontendAtsc3Bandwidth.BANDWIDTH_8MHZ;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "MODULATION_",
+            value = {MODULATION_UNDEFINED, MODULATION_AUTO,
+                    MODULATION_MOD_QPSK, MODULATION_MOD_16QAM,
+                    MODULATION_MOD_64QAM, MODULATION_MOD_256QAM,
+                    MODULATION_MOD_1024QAM, MODULATION_MOD_4096QAM})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Modulation {}
+
+    /**
+     * Modulation undefined.
+     */
+    public static final int MODULATION_UNDEFINED = Constants.FrontendAtsc3Modulation.UNDEFINED;
+    /**
+     * Hardware is able to detect and set modulation automatically.
+     */
+    public static final int MODULATION_AUTO = Constants.FrontendAtsc3Modulation.AUTO;
+    /**
+     * QPSK modulation.
+     */
+    public static final int MODULATION_MOD_QPSK = Constants.FrontendAtsc3Modulation.MOD_QPSK;
+    /**
+     * 16QAM modulation.
+     */
+    public static final int MODULATION_MOD_16QAM = Constants.FrontendAtsc3Modulation.MOD_16QAM;
+    /**
+     * 64QAM modulation.
+     */
+    public static final int MODULATION_MOD_64QAM = Constants.FrontendAtsc3Modulation.MOD_64QAM;
+    /**
+     * 256QAM modulation.
+     */
+    public static final int MODULATION_MOD_256QAM = Constants.FrontendAtsc3Modulation.MOD_256QAM;
+    /**
+     * 1024QAM modulation.
+     */
+    public static final int MODULATION_MOD_1024QAM = Constants.FrontendAtsc3Modulation.MOD_1024QAM;
+    /**
+     * 4096QAM modulation.
+     */
+    public static final int MODULATION_MOD_4096QAM = Constants.FrontendAtsc3Modulation.MOD_4096QAM;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "TIME_INTERLEAVE_MODE_",
+            value = {TIME_INTERLEAVE_MODE_UNDEFINED, TIME_INTERLEAVE_MODE_AUTO,
+                    TIME_INTERLEAVE_MODE_CTI, TIME_INTERLEAVE_MODE_HTI})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TimeInterleaveMode {}
+
+    /**
+     * Time interleave mode undefined.
+     */
+    public static final int TIME_INTERLEAVE_MODE_UNDEFINED =
+            Constants.FrontendAtsc3TimeInterleaveMode.UNDEFINED;
+    /**
+     * Hardware is able to detect and set Time Interleave Mode automatically.
+     */
+    public static final int TIME_INTERLEAVE_MODE_AUTO =
+            Constants.FrontendAtsc3TimeInterleaveMode.AUTO;
+    /**
+     * CTI Time Interleave Mode.
+     */
+    public static final int TIME_INTERLEAVE_MODE_CTI =
+            Constants.FrontendAtsc3TimeInterleaveMode.CTI;
+    /**
+     * HTI Time Interleave Mode.
+     */
+    public static final int TIME_INTERLEAVE_MODE_HTI =
+            Constants.FrontendAtsc3TimeInterleaveMode.HTI;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "CODERATE_",
+            value = {CODERATE_UNDEFINED, CODERATE_AUTO, CODERATE_2_15, CODERATE_3_15, CODERATE_4_15,
+                    CODERATE_5_15, CODERATE_6_15, CODERATE_7_15, CODERATE_8_15, CODERATE_9_15,
+                    CODERATE_10_15, CODERATE_11_15, CODERATE_12_15, CODERATE_13_15})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CodeRate {}
+
+    /**
+     * Code rate undefined.
+     */
+    public static final int CODERATE_UNDEFINED = Constants.FrontendAtsc3CodeRate.UNDEFINED;
+    /**
+     * Hardware is able to detect and set code rate automatically
+     */
+    public static final int CODERATE_AUTO = Constants.FrontendAtsc3CodeRate.AUTO;
+    /**
+     * 2/15 code rate.
+     */
+    public static final int CODERATE_2_15 = Constants.FrontendAtsc3CodeRate.CODERATE_2_15;
+    /**
+     * 3/15 code rate.
+     */
+    public static final int CODERATE_3_15 = Constants.FrontendAtsc3CodeRate.CODERATE_3_15;
+    /**
+     * 4/15 code rate.
+     */
+    public static final int CODERATE_4_15 = Constants.FrontendAtsc3CodeRate.CODERATE_4_15;
+    /**
+     * 5/15 code rate.
+     */
+    public static final int CODERATE_5_15 = Constants.FrontendAtsc3CodeRate.CODERATE_5_15;
+    /**
+     * 6/15 code rate.
+     */
+    public static final int CODERATE_6_15 = Constants.FrontendAtsc3CodeRate.CODERATE_6_15;
+    /**
+     * 7/15 code rate.
+     */
+    public static final int CODERATE_7_15 = Constants.FrontendAtsc3CodeRate.CODERATE_7_15;
+    /**
+     * 8/15 code rate.
+     */
+    public static final int CODERATE_8_15 = Constants.FrontendAtsc3CodeRate.CODERATE_8_15;
+    /**
+     * 9/15 code rate.
+     */
+    public static final int CODERATE_9_15 = Constants.FrontendAtsc3CodeRate.CODERATE_9_15;
+    /**
+     * 10/15 code rate.
+     */
+    public static final int CODERATE_10_15 = Constants.FrontendAtsc3CodeRate.CODERATE_10_15;
+    /**
+     * 11/15 code rate.
+     */
+    public static final int CODERATE_11_15 = Constants.FrontendAtsc3CodeRate.CODERATE_11_15;
+    /**
+     * 12/15 code rate.
+     */
+    public static final int CODERATE_12_15 = Constants.FrontendAtsc3CodeRate.CODERATE_12_15;
+    /**
+     * 13/15 code rate.
+     */
+    public static final int CODERATE_13_15 = Constants.FrontendAtsc3CodeRate.CODERATE_13_15;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "FEC_",
+            value = {FEC_UNDEFINED, FEC_AUTO, FEC_BCH_LDPC_16K, FEC_BCH_LDPC_64K, FEC_CRC_LDPC_16K,
+                    FEC_CRC_LDPC_64K, FEC_LDPC_16K, FEC_LDPC_64K})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Fec {}
+
+    /**
+     * Forward Error Correction undefined.
+     */
+    public static final int FEC_UNDEFINED = Constants.FrontendAtsc3Fec.UNDEFINED;
+    /**
+     * Hardware is able to detect and set FEC automatically
+     */
+    public static final int FEC_AUTO = Constants.FrontendAtsc3Fec.AUTO;
+    /**
+     * BCH LDPC 16K Forward Error Correction
+     */
+    public static final int FEC_BCH_LDPC_16K = Constants.FrontendAtsc3Fec.BCH_LDPC_16K;
+    /**
+     * BCH LDPC 64K Forward Error Correction
+     */
+    public static final int FEC_BCH_LDPC_64K = Constants.FrontendAtsc3Fec.BCH_LDPC_64K;
+    /**
+     * CRC LDPC 16K Forward Error Correction
+     */
+    public static final int FEC_CRC_LDPC_16K = Constants.FrontendAtsc3Fec.CRC_LDPC_16K;
+    /**
+     * CRC LDPC 64K Forward Error Correction
+     */
+    public static final int FEC_CRC_LDPC_64K = Constants.FrontendAtsc3Fec.CRC_LDPC_64K;
+    /**
+     * LDPC 16K Forward Error Correction
+     */
+    public static final int FEC_LDPC_16K = Constants.FrontendAtsc3Fec.LDPC_16K;
+    /**
+     * LDPC 64K Forward Error Correction
+     */
+    public static final int FEC_LDPC_64K = Constants.FrontendAtsc3Fec.LDPC_64K;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "DEMOD_OUTPUT_FORMAT_",
+            value = {DEMOD_OUTPUT_FORMAT_UNDEFINED, DEMOD_OUTPUT_FORMAT_ATSC3_LINKLAYER_PACKET,
+                    DEMOD_OUTPUT_FORMAT_BASEBAND_PACKET})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DemodOutputFormat {}
+
+    /**
+     * Demod output format undefined.
+     */
+    public static final int DEMOD_OUTPUT_FORMAT_UNDEFINED =
+            Constants.FrontendAtsc3DemodOutputFormat.UNDEFINED;
+    /**
+     * ALP format. Typically used in US region.
+     */
+    public static final int DEMOD_OUTPUT_FORMAT_ATSC3_LINKLAYER_PACKET =
+            Constants.FrontendAtsc3DemodOutputFormat.ATSC3_LINKLAYER_PACKET;
+    /**
+     * BaseBand packet format. Typically used in Korea region.
+     */
+    public static final int DEMOD_OUTPUT_FORMAT_BASEBAND_PACKET =
+            Constants.FrontendAtsc3DemodOutputFormat.BASEBAND_PACKET;
+
+    private final int mBandwidth;
+    private final int mDemodOutputFormat;
+    private final Atsc3PlpSettings[] mPlpSettings;
+
+    private Atsc3FrontendSettings(int frequency, int bandwidth, int demodOutputFormat,
+            Atsc3PlpSettings[] plpSettings) {
+        super(frequency);
+        mBandwidth = bandwidth;
+        mDemodOutputFormat = demodOutputFormat;
+        mPlpSettings = plpSettings;
+    }
+
+    /**
+     * Gets bandwidth.
+     */
+    @Bandwidth
+    public int getBandwidth() {
+        return mBandwidth;
+    }
+    /**
+     * Gets Demod Output Format.
+     */
+    @DemodOutputFormat
+    public int getDemodOutputFormat() {
+        return mDemodOutputFormat;
+    }
+    /**
+     * Gets PLP Settings.
+     */
+    @NonNull
+    public Atsc3PlpSettings[] getPlpSettings() {
+        return mPlpSettings;
+    }
+
+    /**
+     * Creates a builder for {@link Atsc3FrontendSettings}.
+     *
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link Atsc3FrontendSettings}.
+     */
+    public static class Builder {
+        private int mFrequency = 0;
+        private int mBandwidth = BANDWIDTH_UNDEFINED;
+        private int mDemodOutputFormat = DEMOD_OUTPUT_FORMAT_UNDEFINED;
+        private Atsc3PlpSettings[] mPlpSettings = {};
+
+        private Builder() {
+        }
+
+        /**
+         * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        @IntRange(from = 1)
+        public Builder setFrequency(int frequency) {
+            mFrequency = frequency;
+            return this;
+        }
+
+        /**
+         * Sets bandwidth.
+         *
+         * <p>Default value is {@link #BANDWIDTH_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setBandwidth(int bandwidth) {
+            mBandwidth = bandwidth;
+            return this;
+        }
+        /**
+         * Sets Demod Output Format.
+         *
+         * <p>Default value is {@link #DEMOD_OUTPUT_FORMAT_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setDemodOutputFormat(@DemodOutputFormat int demodOutputFormat) {
+            mDemodOutputFormat = demodOutputFormat;
+            return this;
+        }
+        /**
+         * Sets PLP Settings.
+         *
+         * <p>Default value an empty array.
+         */
+        @NonNull
+        public Builder setPlpSettings(@NonNull Atsc3PlpSettings[] plpSettings) {
+            mPlpSettings = plpSettings;
+            return this;
+        }
+
+        /**
+         * Builds a {@link Atsc3FrontendSettings} object.
+         */
+        @NonNull
+        public Atsc3FrontendSettings build() {
+            return new Atsc3FrontendSettings(mFrequency, mBandwidth, mDemodOutputFormat,
+                    mPlpSettings);
+        }
+    }
+
+    @Override
+    public int getType() {
+        return FrontendSettings.TYPE_ATSC3;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/Atsc3PlpInfo.java b/android/media/tv/tuner/frontend/Atsc3PlpInfo.java
new file mode 100644
index 0000000..9900fec
--- /dev/null
+++ b/android/media/tv/tuner/frontend/Atsc3PlpInfo.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2020 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.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/** PLP information for ATSC3.
+ * @hide
+ */
+@SystemApi
+public class Atsc3PlpInfo {
+    private final int mPlpId;
+    private final boolean mLlsFlag;
+
+    private Atsc3PlpInfo(int plpId, boolean llsFlag) {
+        mPlpId = plpId;
+        mLlsFlag = llsFlag;
+    }
+
+    /** Gets PLP IDs. */
+    public int getPlpId() {
+        return mPlpId;
+    }
+
+    /** Gets LLS flag. */
+    public boolean getLlsFlag() {
+        return mLlsFlag;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/Atsc3PlpSettings.java b/android/media/tv/tuner/frontend/Atsc3PlpSettings.java
new file mode 100644
index 0000000..f86eccf
--- /dev/null
+++ b/android/media/tv/tuner/frontend/Atsc3PlpSettings.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * Physical Layer Pipe (PLP) settings for ATSC-3.
+ *
+ * @hide
+ */
+@SystemApi
+public class Atsc3PlpSettings {
+    private final int mPlpId;
+    private final int mModulation;
+    private final int mInterleaveMode;
+    private final int mCodeRate;
+    private final int mFec;
+
+    private Atsc3PlpSettings(int plpId, int modulation, int interleaveMode, int codeRate, int fec) {
+        mPlpId = plpId;
+        mModulation = modulation;
+        mInterleaveMode = interleaveMode;
+        mCodeRate = codeRate;
+        mFec = fec;
+    }
+
+    /**
+     * Gets Physical Layer Pipe (PLP) ID.
+     */
+    public int getPlpId() {
+        return mPlpId;
+    }
+    /**
+     * Gets Modulation.
+     */
+    @Atsc3FrontendSettings.Modulation
+    public int getModulation() {
+        return mModulation;
+    }
+    /**
+     * Gets Interleave Mode.
+     */
+    @Atsc3FrontendSettings.TimeInterleaveMode
+    public int getInterleaveMode() {
+        return mInterleaveMode;
+    }
+    /**
+     * Gets Code Rate.
+     */
+    @Atsc3FrontendSettings.CodeRate
+    public int getCodeRate() {
+        return mCodeRate;
+    }
+    /**
+     * Gets Forward Error Correction.
+     */
+    @Atsc3FrontendSettings.Fec
+    public int getFec() {
+        return mFec;
+    }
+
+    /**
+     * Creates a builder for {@link Atsc3PlpSettings}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link Atsc3PlpSettings}.
+     */
+    public static class Builder {
+        private int mPlpId;
+        private int mModulation;
+        private int mInterleaveMode;
+        private int mCodeRate;
+        private int mFec;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets Physical Layer Pipe (PLP) ID.
+         */
+        @NonNull
+        public Builder setPlpId(int plpId) {
+            mPlpId = plpId;
+            return this;
+        }
+        /**
+         * Sets Modulation.
+         */
+        @NonNull
+        public Builder setModulation(@Atsc3FrontendSettings.Modulation int modulation) {
+            mModulation = modulation;
+            return this;
+        }
+        /**
+         * Sets Interleave Mode.
+         */
+        @NonNull
+        public Builder setInterleaveMode(
+                @Atsc3FrontendSettings.TimeInterleaveMode int interleaveMode) {
+            mInterleaveMode = interleaveMode;
+            return this;
+        }
+        /**
+         * Sets Code Rate.
+         */
+        @NonNull
+        public Builder setCodeRate(@Atsc3FrontendSettings.CodeRate int codeRate) {
+            mCodeRate = codeRate;
+            return this;
+        }
+        /**
+         * Sets Forward Error Correction.
+         */
+        @NonNull
+        public Builder setFec(@Atsc3FrontendSettings.Fec int fec) {
+            mFec = fec;
+            return this;
+        }
+
+        /**
+         * Builds a {@link Atsc3PlpSettings} object.
+         */
+        @NonNull
+        public Atsc3PlpSettings build() {
+            return new Atsc3PlpSettings(mPlpId, mModulation, mInterleaveMode, mCodeRate, mFec);
+        }
+    }
+}
diff --git a/android/media/tv/tuner/frontend/AtscFrontendCapabilities.java b/android/media/tv/tuner/frontend/AtscFrontendCapabilities.java
new file mode 100644
index 0000000..eb21caa
--- /dev/null
+++ b/android/media/tv/tuner/frontend/AtscFrontendCapabilities.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/**
+ * ATSC Capabilities.
+ *
+ * @hide
+ */
+@SystemApi
+public class AtscFrontendCapabilities extends FrontendCapabilities {
+    private final int mModulationCap;
+
+    private AtscFrontendCapabilities(int modulationCap) {
+        mModulationCap = modulationCap;
+    }
+
+    /**
+     * Gets modulation capability.
+     */
+    @AtscFrontendSettings.Modulation
+    public int getModulationCapability() {
+        return mModulationCap;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/AtscFrontendSettings.java b/android/media/tv/tuner/frontend/AtscFrontendSettings.java
new file mode 100644
index 0000000..f7244bb
--- /dev/null
+++ b/android/media/tv/tuner/frontend/AtscFrontendSettings.java
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Frontend settings for ATSC.
+ *
+ * @hide
+ */
+@SystemApi
+public class AtscFrontendSettings extends FrontendSettings {
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "MODULATION_",
+            value = {MODULATION_UNDEFINED, MODULATION_AUTO, MODULATION_MOD_8VSB,
+                    MODULATION_MOD_16VSB})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Modulation {}
+
+    /**
+     * Modulation undefined.
+     */
+    public static final int MODULATION_UNDEFINED = Constants.FrontendAtscModulation.UNDEFINED;
+    /**
+     * Hardware is able to detect and set modulation automatically
+     */
+    public static final int MODULATION_AUTO = Constants.FrontendAtscModulation.AUTO;
+    /**
+     * 8VSB Modulation.
+     */
+    public static final int MODULATION_MOD_8VSB = Constants.FrontendAtscModulation.MOD_8VSB;
+    /**
+     * 16VSB Modulation.
+     */
+    public static final int MODULATION_MOD_16VSB = Constants.FrontendAtscModulation.MOD_16VSB;
+
+
+    private final int mModulation;
+
+    private AtscFrontendSettings(int frequency, int modulation) {
+        super(frequency);
+        mModulation = modulation;
+    }
+
+    /**
+     * Gets Modulation.
+     */
+    @Modulation
+    public int getModulation() {
+        return mModulation;
+    }
+
+    /**
+     * Creates a builder for {@link AtscFrontendSettings}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link AtscFrontendSettings}.
+     */
+    public static class Builder {
+        private int mFrequency = 0;
+        private int mModulation = MODULATION_UNDEFINED;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        @IntRange(from = 1)
+        public Builder setFrequency(int frequency) {
+            mFrequency = frequency;
+            return this;
+        }
+
+        /**
+         * Sets Modulation.
+         *
+         * <p>Default value is {@link #MODULATION_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setModulation(@Modulation int modulation) {
+            mModulation = modulation;
+            return this;
+        }
+
+        /**
+         * Builds a {@link AtscFrontendSettings} object.
+         */
+        @NonNull
+        public AtscFrontendSettings build() {
+            return new AtscFrontendSettings(mFrequency, mModulation);
+        }
+    }
+
+    @Override
+    public int getType() {
+        return FrontendSettings.TYPE_ATSC;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/DtmbFrontendCapabilities.java b/android/media/tv/tuner/frontend/DtmbFrontendCapabilities.java
new file mode 100644
index 0000000..e856779
--- /dev/null
+++ b/android/media/tv/tuner/frontend/DtmbFrontendCapabilities.java
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2020 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.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/**
+ * DTMB Capabilities.
+ *
+ * <p>DTMB Frontend is only supported in Tuner HAL 1.1 or higher.
+ * @hide
+ */
+@SystemApi
+public final class DtmbFrontendCapabilities extends FrontendCapabilities {
+    private final int mModulationCap;
+    private final int mTransmissionModeCap;
+    private final int mGuardIntervalCap;
+    private final int mTimeInterleaveModeCap;
+    private final int mCodeRateCap;
+    private final int mBandwidthCap;
+
+    private DtmbFrontendCapabilities(int modulationCap, int transmissionModeCap,
+            int guardIntervalCap, int timeInterleaveModeCap, int codeRateCap, int bandwidthCap) {
+        mModulationCap = modulationCap;
+        mTransmissionModeCap = transmissionModeCap;
+        mGuardIntervalCap = guardIntervalCap;
+        mTimeInterleaveModeCap = timeInterleaveModeCap;
+        mCodeRateCap = codeRateCap;
+        mBandwidthCap = bandwidthCap;
+    }
+
+    /**
+     * Gets modulation capability.
+     *
+     * @return the bit mask of all the supported modulations.
+     */
+    @DtmbFrontendSettings.Modulation
+    public int getModulationCapability() {
+        return mModulationCap;
+    }
+
+    /**
+     * Gets Transmission Mode capability.
+     *
+     * @return the bit mask of all the supported transmission modes.
+     */
+    @DtmbFrontendSettings.TransmissionMode
+    public int getTransmissionModeCapability() {
+        return mTransmissionModeCap;
+    }
+
+    /**
+     * Gets Guard Interval capability.
+     *
+     * @return the bit mask of all the supported guard intervals.
+     */
+    @DtmbFrontendSettings.GuardInterval
+    public int getGuardIntervalCapability() {
+        return mGuardIntervalCap;
+    }
+
+    /**
+     * Gets Time Interleave Mode capability.
+     *
+     * @return the bit mask of all the supported time interleave modes.
+     */
+    @DtmbFrontendSettings.TimeInterleaveMode
+    public int getTimeInterleaveModeCapability() {
+        return mTimeInterleaveModeCap;
+    }
+
+    /**
+     * Gets Code Rate capability.
+     *
+     * @return the bit mask of all the supported code rates.
+     */
+    @DtmbFrontendSettings.CodeRate
+    public int getCodeRateCapability() {
+        return mCodeRateCap;
+    }
+
+    /**
+     * Gets Bandwidth capability.
+     *
+     * @return the bit mask of all the supported bandwidth.
+     */
+    @DtmbFrontendSettings.Bandwidth
+    public int getBandwidthCapability() {
+        return mBandwidthCap;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/DtmbFrontendSettings.java b/android/media/tv/tuner/frontend/DtmbFrontendSettings.java
new file mode 100644
index 0000000..c1d0833
--- /dev/null
+++ b/android/media/tv/tuner/frontend/DtmbFrontendSettings.java
@@ -0,0 +1,441 @@
+/*
+ * Copyright 2020 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.annotation.SystemApi;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Frontend settings for DTMB.
+ *
+ * <p>DTMB Frontend is only supported in Tuner HAL 1.1 or higher. Use {@link
+ * android.media.tv.tuner.TunerVersionChecker#getTunerVersion()} to get the version information.
+ *
+ * @hide
+ */
+@SystemApi
+public final class DtmbFrontendSettings extends FrontendSettings {
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "BANDWIDTH_",
+            value = {BANDWIDTH_UNDEFINED, BANDWIDTH_AUTO, BANDWIDTH_6MHZ, BANDWIDTH_8MHZ})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Bandwidth {}
+
+    /**
+     * Bandwidth not defined.
+     */
+    public static final int BANDWIDTH_UNDEFINED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbBandwidth.UNDEFINED;
+    /**
+     * Hardware is able to detect and set bandwidth automatically
+     */
+    public static final int BANDWIDTH_AUTO =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbBandwidth.AUTO;
+    /**
+     * 6 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_6MHZ =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbBandwidth.BANDWIDTH_6MHZ;
+    /**
+     * 8 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_8MHZ =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbBandwidth.BANDWIDTH_8MHZ;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "TIME_INTERLEAVE_MODE_",
+            value = {TIME_INTERLEAVE_MODE_UNDEFINED, TIME_INTERLEAVE_MODE_AUTO,
+                    TIME_INTERLEAVE_MODE_TIMER_INT_240, TIME_INTERLEAVE_MODE_TIMER_INT_720})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TimeInterleaveMode {}
+
+    /**
+     * Time Interleave Mode undefined.
+     */
+    public static final int TIME_INTERLEAVE_MODE_UNDEFINED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbTimeInterleaveMode.UNDEFINED;
+    /**
+     * Hardware is able to detect and set time interleave mode automatically
+     */
+    public static final int TIME_INTERLEAVE_MODE_AUTO =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbTimeInterleaveMode.AUTO;
+    /**
+     * Time Interleave Mode timer int 240.
+     */
+    public static final int TIME_INTERLEAVE_MODE_TIMER_INT_240 =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbTimeInterleaveMode.TIMER_INT_240;
+    /**
+     * Time Interleave Mode timer int 720.
+     */
+    public static final int TIME_INTERLEAVE_MODE_TIMER_INT_720 =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbTimeInterleaveMode.TIMER_INT_720;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "GUARD_INTERVAL_",
+            value = {GUARD_INTERVAL_UNDEFINED, GUARD_INTERVAL_AUTO,
+            GUARD_INTERVAL_PN_420_VARIOUS, GUARD_INTERVAL_PN_595_CONST,
+            GUARD_INTERVAL_PN_945_VARIOUS, GUARD_INTERVAL_PN_420_CONST,
+            GUARD_INTERVAL_PN_945_CONST, GUARD_INTERVAL_PN_RESERVED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface GuardInterval {}
+
+    /**
+     * Guard Interval undefined.
+     */
+    public static final int GUARD_INTERVAL_UNDEFINED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbGuardInterval.UNDEFINED;
+    /**
+     * Hardware is able to detect and set Guard Interval automatically.
+     */
+    public static final int GUARD_INTERVAL_AUTO =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbGuardInterval.AUTO;
+    /**
+     * PN_420_VARIOUS Guard Interval.
+     */
+    public static final int GUARD_INTERVAL_PN_420_VARIOUS =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbGuardInterval.PN_420_VARIOUS;
+    /**
+     * PN_595_CONST Guard Interval.
+     */
+    public static final int GUARD_INTERVAL_PN_595_CONST =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbGuardInterval.PN_595_CONST;
+    /**
+     * PN_945_VARIOUS Guard Interval.
+     */
+    public static final int GUARD_INTERVAL_PN_945_VARIOUS =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbGuardInterval.PN_945_VARIOUS;
+    /**
+     * PN_420_CONST Guard Interval.
+     */
+    public static final int GUARD_INTERVAL_PN_420_CONST =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbGuardInterval.PN_420_CONST;
+    /**
+     * PN_945_CONST Guard Interval.
+     */
+    public static final int GUARD_INTERVAL_PN_945_CONST =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbGuardInterval.PN_945_CONST;
+    /**
+     * PN_RESERVED Guard Interval.
+     */
+    public static final int GUARD_INTERVAL_PN_RESERVED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbGuardInterval.PN_RESERVED;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "MODULATION_",
+            value = {MODULATION_CONSTELLATION_UNDEFINED, MODULATION_CONSTELLATION_AUTO,
+                    MODULATION_CONSTELLATION_4QAM, MODULATION_CONSTELLATION_4QAM_NR,
+                    MODULATION_CONSTELLATION_16QAM, MODULATION_CONSTELLATION_32QAM,
+                    MODULATION_CONSTELLATION_64QAM})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Modulation {}
+
+    /**
+     * Constellation not defined.
+     */
+    public static final int MODULATION_CONSTELLATION_UNDEFINED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbModulation.UNDEFINED;
+    /**
+     * Hardware is able to detect and set Constellation automatically.
+     */
+    public static final int MODULATION_CONSTELLATION_AUTO =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbModulation.AUTO;
+    /**
+     * 4QAM Constellation.
+     */
+    public static final int MODULATION_CONSTELLATION_4QAM =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbModulation.CONSTELLATION_4QAM;
+    /**
+     * 4QAM_NR Constellation.
+     */
+    public static final int MODULATION_CONSTELLATION_4QAM_NR =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbModulation.CONSTELLATION_4QAM_NR;
+    /**
+     * 16QAM Constellation.
+     */
+    public static final int MODULATION_CONSTELLATION_16QAM =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbModulation.CONSTELLATION_16QAM;
+    /**
+     * 32QAM Constellation.
+     */
+    public static final int MODULATION_CONSTELLATION_32QAM =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbModulation.CONSTELLATION_32QAM;
+    /**
+     * 64QAM Constellation.
+     */
+    public static final int MODULATION_CONSTELLATION_64QAM =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbModulation.CONSTELLATION_64QAM;
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "CODERATE_",
+            value = {CODERATE_UNDEFINED, CODERATE_AUTO, CODERATE_2_5, CODERATE_3_5, CODERATE_4_5})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CodeRate {}
+
+    /**
+     * Code rate undefined.
+     */
+    public static final int CODERATE_UNDEFINED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbCodeRate.UNDEFINED;
+    /**
+     * Hardware is able to detect and set code rate automatically.
+     */
+    public static final int CODERATE_AUTO =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbCodeRate.AUTO;
+    /**
+     * 2/5 code rate.
+     */
+    public static final int CODERATE_2_5 =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbCodeRate.CODERATE_2_5;
+    /**
+     * 3/5 code rate.
+     */
+    public static final int CODERATE_3_5 =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbCodeRate.CODERATE_3_5;
+    /**
+     * 4/5 code rate.
+     */
+    public static final int CODERATE_4_5 =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbCodeRate.CODERATE_4_5;
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "TRANSMISSION_MODE_",
+            value = {TRANSMISSION_MODE_UNDEFINED, TRANSMISSION_MODE_AUTO,
+                    TRANSMISSION_MODE_C1, TRANSMISSION_MODE_C3780})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TransmissionMode {}
+
+    /**
+     * Transmission Mode undefined.
+     */
+    public static final int TRANSMISSION_MODE_UNDEFINED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbTransmissionMode.UNDEFINED;
+    /**
+     * Hardware is able to detect and set Transmission Mode automatically
+     */
+    public static final int TRANSMISSION_MODE_AUTO =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbTransmissionMode.AUTO;
+    /**
+     * C1 Transmission Mode.
+     */
+    public static final int TRANSMISSION_MODE_C1 =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbTransmissionMode.C1;
+    /**
+     * C3780 Transmission Mode.
+     */
+    public static final int TRANSMISSION_MODE_C3780 =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDtmbTransmissionMode.C3780;
+
+
+    private final int mModulation;
+    private final int mCodeRate;
+    private final int mTransmissionMode;
+    private final int mBandwidth;
+    private final int mGuardInterval;
+    private final int mTimeInterleaveMode;
+
+    private DtmbFrontendSettings(int frequency, int modulation, int codeRate, int transmissionMode,
+            int guardInterval, int timeInterleaveMode, int bandwidth) {
+        super(frequency);
+        mModulation = modulation;
+        mCodeRate = codeRate;
+        mTransmissionMode = transmissionMode;
+        mGuardInterval = guardInterval;
+        mTimeInterleaveMode = timeInterleaveMode;
+        mBandwidth = bandwidth;
+    }
+
+    /**
+     * Gets Modulation.
+     */
+    @Modulation
+    public int getModulation() {
+        return mModulation;
+    }
+
+    /**
+     * Gets Code Rate.
+     */
+    @Modulation
+    public int getCodeRate() {
+        return mCodeRate;
+    }
+
+    /**
+     * Gets Transmission Mode.
+     */
+    @Modulation
+    public int getTransmissionMode() {
+        return mTransmissionMode;
+    }
+
+    /**
+     * Gets Bandwidth.
+     */
+    @Modulation
+    public int getBandwidth() {
+        return mBandwidth;
+    }
+
+    /**
+     * Gets Time Interleave Mode.
+     */
+    @Modulation
+    public int getTimeInterleaveMode() {
+        return mTimeInterleaveMode;
+    }
+
+
+    /**
+     * Gets Guard Interval.
+     */
+    @Modulation
+    public int getGuardInterval() {
+        return mGuardInterval;
+    }
+
+    /**
+     * Creates a builder for {@link AtscFrontendSettings}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link AtscFrontendSettings}.
+     */
+    public static final class Builder {
+        private int mFrequency = 0;
+        private int mModulation = MODULATION_CONSTELLATION_UNDEFINED;
+        private int mCodeRate = CODERATE_UNDEFINED;
+        private int mTransmissionMode = TRANSMISSION_MODE_UNDEFINED;
+        private int mBandwidth = BANDWIDTH_UNDEFINED;
+        private int mTimeInterleaveMode = TIME_INTERLEAVE_MODE_UNDEFINED;
+        private int mGuardInterval = GUARD_INTERVAL_UNDEFINED;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        @IntRange(from = 1)
+        @SuppressLint("MissingGetterMatchingBuilder")
+        public Builder setFrequency(int frequency) {
+            mFrequency = frequency;
+            return this;
+        }
+
+        /**
+         * Sets Modulation.
+         *
+         * <p>Default value is {@link #MODULATION_CONSTELLATION_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setModulation(@Modulation int modulation) {
+            mModulation = modulation;
+            return this;
+        }
+
+        /**
+         * Sets Code Rate.
+         *
+         * <p>Default value is {@link #CODERATE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setCodeRate(@CodeRate int codeRate) {
+            mCodeRate = codeRate;
+            return this;
+        }
+
+        /**
+         * Sets Bandwidth.
+         *
+         * <p>Default value is {@link #BANDWIDTH_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setBandwidth(@Bandwidth int bandwidth) {
+            mBandwidth = bandwidth;
+            return this;
+        }
+
+        /**
+         * Sets Time Interleave Mode.
+         *
+         * <p>Default value is {@link #TIME_INTERLEAVE_MODE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setTimeInterleaveMode(@TimeInterleaveMode int timeInterleaveMode) {
+            mTimeInterleaveMode = timeInterleaveMode;
+            return this;
+        }
+
+        /**
+         * Sets Guard Interval.
+         *
+         * <p>Default value is {@link #GUARD_INTERVAL_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setGuardInterval(@GuardInterval int guardInterval) {
+            mGuardInterval = guardInterval;
+            return this;
+        }
+        /**
+         * Sets Transmission Mode.
+         *
+         * <p>Default value is {@link #TRANSMISSION_MODE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setTransmissionMode(@TransmissionMode int transmissionMode) {
+            mTransmissionMode = transmissionMode;
+            return this;
+        }
+
+        /**
+         * Builds a {@link DtmbFrontendSettings} object.
+         */
+        @NonNull
+        public DtmbFrontendSettings build() {
+            return new DtmbFrontendSettings(mFrequency, mModulation, mCodeRate,
+                    mTransmissionMode, mGuardInterval, mTimeInterleaveMode, mBandwidth);
+        }
+    }
+
+    @Override
+    public int getType() {
+        return FrontendSettings.TYPE_DTMB;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/DvbcFrontendCapabilities.java b/android/media/tv/tuner/frontend/DvbcFrontendCapabilities.java
new file mode 100644
index 0000000..0e08c15
--- /dev/null
+++ b/android/media/tv/tuner/frontend/DvbcFrontendCapabilities.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/**
+ * DVBC Capabilities.
+ *
+ * @hide
+ */
+@SystemApi
+public class DvbcFrontendCapabilities extends FrontendCapabilities {
+    private final int mModulationCap;
+    private final long mFecCap;
+    private final int mAnnexCap;
+
+    private DvbcFrontendCapabilities(int modulationCap, long fecCap, int annexCap) {
+        mModulationCap = modulationCap;
+        mFecCap = fecCap;
+        mAnnexCap = annexCap;
+    }
+
+    /**
+     * Gets modulation capability.
+     */
+    @DvbcFrontendSettings.Modulation
+    public int getModulationCapability() {
+        return mModulationCap;
+    }
+    /**
+     * Gets inner FEC capability.
+     *
+     * @deprecated Use {@link #getInnerFecCapability()} with long return value instead. This
+     *             function returns the correct cap value when the value is not bigger than the max
+     *             integer value. Otherwise it returns {@link FrontendSettings#FEC_UNDEFINED}.
+     */
+    @Deprecated
+    @FrontendSettings.InnerFec
+    public int getFecCapability() {
+        if (mFecCap > Integer.MAX_VALUE) {
+            return (int) FrontendSettings.FEC_UNDEFINED;
+        }
+        return (int) mFecCap;
+    }
+    /**
+     * Gets code rate capability.
+     */
+    @FrontendSettings.InnerFec
+    public long getCodeRateCapability() {
+        return mFecCap;
+    }
+    /**
+     * Gets annex capability.
+     */
+    @DvbcFrontendSettings.Annex
+    public int getAnnexCapability() {
+        return mAnnexCap;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/DvbcFrontendSettings.java b/android/media/tv/tuner/frontend/DvbcFrontendSettings.java
new file mode 100644
index 0000000..db28631
--- /dev/null
+++ b/android/media/tv/tuner/frontend/DvbcFrontendSettings.java
@@ -0,0 +1,487 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.TunerVersionChecker;
+import android.media.tv.tuner.frontend.FrontendSettings.FrontendSpectralInversion;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Frontend settings for DVBC.
+ *
+ * @hide
+ */
+@SystemApi
+public class DvbcFrontendSettings extends FrontendSettings {
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "MODULATION_",
+            value = {MODULATION_UNDEFINED, MODULATION_AUTO, MODULATION_MOD_16QAM,
+                    MODULATION_MOD_32QAM, MODULATION_MOD_64QAM, MODULATION_MOD_128QAM,
+                    MODULATION_MOD_256QAM})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Modulation {}
+
+    /**
+     * Modulation undefined.
+     */
+    public static final int MODULATION_UNDEFINED = Constants.FrontendDvbcModulation.UNDEFINED;
+    /**
+     * Hardware is able to detect and set modulation automatically
+     */
+    public static final int MODULATION_AUTO = Constants.FrontendDvbcModulation.AUTO;
+    /**
+     * 16QAM Modulation.
+     */
+    public static final int MODULATION_MOD_16QAM = Constants.FrontendDvbcModulation.MOD_16QAM;
+    /**
+     * 32QAM Modulation.
+     */
+    public static final int MODULATION_MOD_32QAM = Constants.FrontendDvbcModulation.MOD_32QAM;
+    /**
+     * 64QAM Modulation.
+     */
+    public static final int MODULATION_MOD_64QAM = Constants.FrontendDvbcModulation.MOD_64QAM;
+    /**
+     * 128QAM Modulation.
+     */
+    public static final int MODULATION_MOD_128QAM = Constants.FrontendDvbcModulation.MOD_128QAM;
+    /**
+     * 256QAM Modulation.
+     */
+    public static final int MODULATION_MOD_256QAM = Constants.FrontendDvbcModulation.MOD_256QAM;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "OUTER_FEC_",
+            value = {OUTER_FEC_UNDEFINED, OUTER_FEC_OUTER_FEC_NONE, OUTER_FEC_OUTER_FEC_RS})
+    public @interface OuterFec {}
+
+    /**
+     * Outer Forward Error Correction (FEC) Type undefined.
+     */
+    public static final int OUTER_FEC_UNDEFINED = Constants.FrontendDvbcOuterFec.UNDEFINED;
+    /**
+     * None Outer Forward Error Correction (FEC) Type.
+     */
+    public static final int OUTER_FEC_OUTER_FEC_NONE =
+            Constants.FrontendDvbcOuterFec.OUTER_FEC_NONE;
+    /**
+     * RS Outer Forward Error Correction (FEC) Type.
+     */
+    public static final int OUTER_FEC_OUTER_FEC_RS = Constants.FrontendDvbcOuterFec.OUTER_FEC_RS;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "ANNEX_",
+            value = {ANNEX_UNDEFINED, ANNEX_A, ANNEX_B, ANNEX_C})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Annex {}
+
+    /**
+     * Annex Type undefined.
+     */
+    public static final int ANNEX_UNDEFINED = Constants.FrontendDvbcAnnex.UNDEFINED;
+    /**
+     * Annex Type A.
+     */
+    public static final int ANNEX_A = Constants.FrontendDvbcAnnex.A;
+    /**
+     * Annex Type B.
+     */
+    public static final int ANNEX_B = Constants.FrontendDvbcAnnex.B;
+    /**
+     * Annex Type C.
+     */
+    public static final int ANNEX_C = Constants.FrontendDvbcAnnex.C;
+
+
+    /**
+     * @deprecated Use the {@code FrontendSpectralInversion} instead.
+     * @hide
+     */
+    @Deprecated
+    @IntDef(prefix = "SPECTRAL_INVERSION_",
+            value = {SPECTRAL_INVERSION_UNDEFINED, SPECTRAL_INVERSION_NORMAL,
+                    SPECTRAL_INVERSION_INVERTED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SpectralInversion {}
+
+    /**
+     * Spectral Inversion Type undefined.
+     *
+     * @deprecated Use the {@link FrontendSettings#FRONTEND_SPECTRAL_INVERSION_UNDEFINED} instead.
+     */
+    @Deprecated
+    public static final int SPECTRAL_INVERSION_UNDEFINED =
+            Constants.FrontendDvbcSpectralInversion.UNDEFINED;
+    /**
+     * Normal Spectral Inversion.
+     *
+     * @deprecated Use the {@link FrontendSettings#FRONTEND_SPECTRAL_INVERSION_NORMAL} instead.
+     */
+    @Deprecated
+    public static final int SPECTRAL_INVERSION_NORMAL =
+            Constants.FrontendDvbcSpectralInversion.NORMAL;
+    /**
+     * Inverted Spectral Inversion.
+     *
+     * @deprecated Use the {@link FrontendSettings#FRONTEND_SPECTRAL_INVERSION_INVERTED} instead.
+     */
+    @Deprecated
+    public static final int SPECTRAL_INVERSION_INVERTED =
+            Constants.FrontendDvbcSpectralInversion.INVERTED;
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "TIME_INTERLEAVE_MODE_",
+            value = {TIME_INTERLEAVE_MODE_UNDEFINED, TIME_INTERLEAVE_MODE_AUTO,
+                    TIME_INTERLEAVE_MODE_128_1_0, TIME_INTERLEAVE_MODE_128_1_1,
+                    TIME_INTERLEAVE_MODE_64_2, TIME_INTERLEAVE_MODE_32_4,
+                    TIME_INTERLEAVE_MODE_16_8, TIME_INTERLEAVE_MODE_8_16,
+                    TIME_INTERLEAVE_MODE_128_2, TIME_INTERLEAVE_MODE_128_3,
+                    TIME_INTERLEAVE_MODE_128_4})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TimeInterleaveMode {}
+
+    /**
+     * Time interleave mode undefined.
+     */
+    public static final int TIME_INTERLEAVE_MODE_UNDEFINED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendCableTimeInterleaveMode.UNDEFINED;
+    /**
+     * Hardware is able to detect and set Time Interleave Mode automatically.
+     */
+    public static final int TIME_INTERLEAVE_MODE_AUTO =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendCableTimeInterleaveMode.AUTO;
+    /**
+     * 128/1/0 Time Interleave Mode.
+     */
+    public static final int TIME_INTERLEAVE_MODE_128_1_0 = android.hardware.tv.tuner.V1_1.Constants
+            .FrontendCableTimeInterleaveMode.INTERLEAVING_128_1_0;
+    /**
+     * 128/1/1 Time Interleave Mode.
+     */
+    public static final int TIME_INTERLEAVE_MODE_128_1_1 = android.hardware.tv.tuner.V1_1.Constants
+            .FrontendCableTimeInterleaveMode.INTERLEAVING_128_1_1;
+    /**
+     * 64/2 Time Interleave Mode.
+     */
+    public static final int TIME_INTERLEAVE_MODE_64_2 = android.hardware.tv.tuner.V1_1.Constants
+            .FrontendCableTimeInterleaveMode.INTERLEAVING_64_2;
+    /**
+     * 32/4 Time Interleave Mode.
+     */
+    public static final int TIME_INTERLEAVE_MODE_32_4 = android.hardware.tv.tuner.V1_1.Constants
+            .FrontendCableTimeInterleaveMode.INTERLEAVING_32_4;
+    /**
+     * 16/8 Time Interleave Mode.
+     */
+    public static final int TIME_INTERLEAVE_MODE_16_8 = android.hardware.tv.tuner.V1_1.Constants
+            .FrontendCableTimeInterleaveMode.INTERLEAVING_16_8;
+    /**
+     * 8/16 Time Interleave Mode.
+     */
+    public static final int TIME_INTERLEAVE_MODE_8_16 = android.hardware.tv.tuner.V1_1.Constants
+            .FrontendCableTimeInterleaveMode.INTERLEAVING_8_16;
+    /**
+     * 128/2 Time Interleave Mode.
+     */
+    public static final int TIME_INTERLEAVE_MODE_128_2 = android.hardware.tv.tuner.V1_1.Constants
+            .FrontendCableTimeInterleaveMode.INTERLEAVING_128_2;
+    /**
+     * 128/3 Time Interleave Mode.
+     */
+    public static final int TIME_INTERLEAVE_MODE_128_3 = android.hardware.tv.tuner.V1_1.Constants
+            .FrontendCableTimeInterleaveMode.INTERLEAVING_128_3;
+    /**
+     * 128/4 Time Interleave Mode.
+     */
+    public static final int TIME_INTERLEAVE_MODE_128_4 = android.hardware.tv.tuner.V1_1.Constants
+            .FrontendCableTimeInterleaveMode.INTERLEAVING_128_4;
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "BANDWIDTH_",
+            value = {BANDWIDTH_UNDEFINED, BANDWIDTH_5MHZ, BANDWIDTH_6MHZ, BANDWIDTH_7MHZ,
+                    BANDWIDTH_8MHZ})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Bandwidth {}
+
+    /**
+     * Bandwidth undefined.
+     */
+    public static final int BANDWIDTH_UNDEFINED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbcBandwidth.UNDEFINED;
+    /**
+     * 5 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_5MHZ =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbcBandwidth.BANDWIDTH_5MHZ;
+    /**
+     * 6 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_6MHZ =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbcBandwidth.BANDWIDTH_6MHZ;
+    /**
+     * 7 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_7MHZ =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbcBandwidth.BANDWIDTH_7MHZ;
+    /**
+     * 8 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_8MHZ =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbcBandwidth.BANDWIDTH_8MHZ;
+
+
+    private final int mModulation;
+    private final long mInnerFec;
+    private final int mSymbolRate;
+    private final int mOuterFec;
+    private final int mAnnex;
+    private final int mSpectralInversion;
+    // Dvbc time interleave mode is only supported in Tuner 1.1 or higher.
+    private final int mInterleaveMode;
+    // Dvbc bandwidth is only supported in Tuner 1.1 or higher.
+    private final int mBandwidth;
+
+    private DvbcFrontendSettings(int frequency, int modulation, long innerFec, int symbolRate,
+            int outerFec, int annex, int spectralInversion, int interleaveMode, int bandwidth) {
+        super(frequency);
+        mModulation = modulation;
+        mInnerFec = innerFec;
+        mSymbolRate = symbolRate;
+        mOuterFec = outerFec;
+        mAnnex = annex;
+        mSpectralInversion = spectralInversion;
+        mInterleaveMode = interleaveMode;
+        mBandwidth = bandwidth;
+    }
+
+    /**
+     * Gets Modulation.
+     */
+    @Modulation
+    public int getModulation() {
+        return mModulation;
+    }
+    /**
+     * Gets Inner Forward Error Correction.
+     */
+    @InnerFec
+    public long getInnerFec() {
+        return mInnerFec;
+    }
+    /**
+     * Gets Symbol Rate in symbols per second.
+     */
+    public int getSymbolRate() {
+        return mSymbolRate;
+    }
+    /**
+     * Gets Outer Forward Error Correction.
+     */
+    @OuterFec
+    public int getOuterFec() {
+        return mOuterFec;
+    }
+    /**
+     * Gets Annex.
+     */
+    @Annex
+    public int getAnnex() {
+        return mAnnex;
+    }
+    /**
+     * Gets Spectral Inversion.
+     */
+    @FrontendSpectralInversion
+    public int getSpectralInversion() {
+        return mSpectralInversion;
+    }
+    /**
+     * Gets Time Interleave Mode.
+     */
+    @TimeInterleaveMode
+    public int getTimeInterleaveMode() {
+        return mInterleaveMode;
+    }
+    /**
+     * Gets Bandwidth.
+     */
+    @Bandwidth
+    public int getBandwidth() {
+        return mBandwidth;
+    }
+
+    /**
+     * Creates a builder for {@link DvbcFrontendSettings}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link DvbcFrontendSettings}.
+     */
+    public static class Builder {
+        private int mFrequency = 0;
+        private int mModulation = MODULATION_UNDEFINED;
+        private long mInnerFec = FEC_UNDEFINED;
+        private int mSymbolRate = 0;
+        private int mOuterFec = OUTER_FEC_UNDEFINED;
+        private int mAnnex = ANNEX_UNDEFINED;
+        private int mSpectralInversion = FrontendSettings.FRONTEND_SPECTRAL_INVERSION_UNDEFINED;
+        private int mInterleaveMode = TIME_INTERLEAVE_MODE_UNDEFINED;
+        private int mBandwidth = BANDWIDTH_UNDEFINED;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        @IntRange(from = 1)
+        public Builder setFrequency(int frequency) {
+            mFrequency = frequency;
+            return this;
+        }
+
+        /**
+         * Sets Modulation.
+         *
+         * <p>Default value is {@link #MODULATION_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setModulation(@Modulation int modulation) {
+            mModulation = modulation;
+            return this;
+        }
+        /**
+         * Sets Inner Forward Error Correction.
+         *
+         * <p>Default value is {@link #FEC_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setInnerFec(@InnerFec long fec) {
+            mInnerFec = fec;
+            return this;
+        }
+        /**
+         * Sets Symbol Rate in symbols per second.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        public Builder setSymbolRate(int symbolRate) {
+            mSymbolRate = symbolRate;
+            return this;
+        }
+        /**
+         * Sets Outer Forward Error Correction.
+         *
+         * <p>Default value is {@link #OUTER_FEC_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setOuterFec(@OuterFec int outerFec) {
+            mOuterFec = outerFec;
+            return this;
+        }
+        /**
+         * Sets Annex.
+         *
+         * <p>Default value is {@link #ANNEX_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setAnnex(@Annex int annex) {
+            mAnnex = annex;
+            return this;
+        }
+        /**
+         * Sets Spectral Inversion.
+         *
+         * <p>Default value is {@link FrontendSettings#FRONTEND_SPECTRAL_INVERSION_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setSpectralInversion(@FrontendSpectralInversion int spectralInversion) {
+            mSpectralInversion = spectralInversion;
+            return this;
+        }
+        /**
+         * Set the time interleave mode.
+         *
+         * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would cause
+         * no-op. Use {@link TunerVersionChecker#getTunerVersion()} to check the version.
+         *
+         * @param interleaveMode the value to set as the time interleave mode. Default value is
+         * {@link #TIME_INTERLEAVE_MODE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setTimeInterleaveMode(@TimeInterleaveMode int interleaveMode) {
+            if (TunerVersionChecker.checkHigherOrEqualVersionTo(
+                        TunerVersionChecker.TUNER_VERSION_1_1, "setTimeInterleaveMode")) {
+                mInterleaveMode = interleaveMode;
+            }
+            return this;
+        }
+        /**
+         * Set the Bandwidth.
+         *
+         * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would cause
+         * no-op. Use {@link TunerVersionChecker#getTunerVersion()} to check the version.
+         *
+         * @param bandwidth the value to set as the bandwidth. Default value is
+         * {@link #BANDWIDTH_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setBandwidth(@Bandwidth int bandwidth) {
+            if (TunerVersionChecker.checkHigherOrEqualVersionTo(
+                        TunerVersionChecker.TUNER_VERSION_1_1, "setBandwidth")) {
+                mBandwidth = bandwidth;
+            }
+            return this;
+        }
+
+        /**
+         * Builds a {@link DvbcFrontendSettings} object.
+         */
+        @NonNull
+        public DvbcFrontendSettings build() {
+            return new DvbcFrontendSettings(mFrequency, mModulation, mInnerFec, mSymbolRate,
+                mOuterFec, mAnnex, mSpectralInversion, mInterleaveMode, mBandwidth);
+        }
+    }
+
+    @Override
+    public int getType() {
+        return FrontendSettings.TYPE_DVBC;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/DvbsCodeRate.java b/android/media/tv/tuner/frontend/DvbsCodeRate.java
new file mode 100644
index 0000000..dcf1511
--- /dev/null
+++ b/android/media/tv/tuner/frontend/DvbsCodeRate.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * Code rate for DVBS.
+ *
+ * @hide
+ */
+@SystemApi
+public class DvbsCodeRate {
+    private final long mInnerFec;
+    private final boolean mIsLinear;
+    private final boolean mIsShortFrames;
+    private final int mBitsPer1000Symbol;
+
+    private DvbsCodeRate(long fec, boolean isLinear, boolean isShortFrames, int bitsPer1000Symbol) {
+        mInnerFec = fec;
+        mIsLinear = isLinear;
+        mIsShortFrames = isShortFrames;
+        mBitsPer1000Symbol = bitsPer1000Symbol;
+    }
+
+    /**
+     * Gets inner FEC.
+     */
+    @FrontendSettings.InnerFec
+    public long getInnerFec() {
+        return mInnerFec;
+    }
+    /**
+     * Checks whether it's linear.
+     */
+    public boolean isLinear() {
+        return mIsLinear;
+    }
+    /**
+     * Checks whether short frame enabled.
+     */
+    public boolean isShortFrameEnabled() {
+        return mIsShortFrames;
+    }
+    /**
+     * Gets bits number in 1000 symbols. 0 by default.
+     */
+    public int getBitsPer1000Symbol() {
+        return mBitsPer1000Symbol;
+    }
+
+    /**
+     * Creates a builder for {@link DvbsCodeRate}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link DvbsCodeRate}.
+     */
+    public static class Builder {
+        private long mFec;
+        private boolean mIsLinear;
+        private boolean mIsShortFrames;
+        private int mBitsPer1000Symbol;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets inner FEC.
+         */
+        @NonNull
+        public Builder setInnerFec(@FrontendSettings.InnerFec long fec) {
+            mFec = fec;
+            return this;
+        }
+        /**
+         * Sets whether it's linear.
+         */
+        @NonNull
+        public Builder setLinear(boolean isLinear) {
+            mIsLinear = isLinear;
+            return this;
+        }
+        /**
+         * Sets whether short frame enabled.
+         */
+        @NonNull
+        public Builder setShortFrameEnabled(boolean isShortFrames) {
+            mIsShortFrames = isShortFrames;
+            return this;
+        }
+        /**
+         * Sets bits number in 1000 symbols.
+         */
+        @NonNull
+        public Builder setBitsPer1000Symbol(int bitsPer1000Symbol) {
+            mBitsPer1000Symbol = bitsPer1000Symbol;
+            return this;
+        }
+
+        /**
+         * Builds a {@link DvbsCodeRate} object.
+         */
+        @NonNull
+        public DvbsCodeRate build() {
+            return new DvbsCodeRate(mFec, mIsLinear, mIsShortFrames, mBitsPer1000Symbol);
+        }
+    }
+}
diff --git a/android/media/tv/tuner/frontend/DvbsFrontendCapabilities.java b/android/media/tv/tuner/frontend/DvbsFrontendCapabilities.java
new file mode 100644
index 0000000..1e25cf2
--- /dev/null
+++ b/android/media/tv/tuner/frontend/DvbsFrontendCapabilities.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/**
+ * DVBS Capabilities.
+ *
+ * @hide
+ */
+@SystemApi
+public class DvbsFrontendCapabilities extends FrontendCapabilities {
+    private final int mModulationCap;
+    private final long mInnerFecCap;
+    private final int mStandard;
+
+    private DvbsFrontendCapabilities(int modulationCap, long innerFecCap, int standard) {
+        mModulationCap = modulationCap;
+        mInnerFecCap = innerFecCap;
+        mStandard = standard;
+    }
+
+    /**
+     * Gets modulation capability.
+     */
+    @DvbsFrontendSettings.Modulation
+    public int getModulationCapability() {
+        return mModulationCap;
+    }
+    /**
+     * Gets inner FEC capability.
+     */
+    @FrontendSettings.InnerFec
+    public long getInnerFecCapability() {
+        return mInnerFecCap;
+    }
+    /**
+     * Gets DVBS standard capability.
+     */
+    @DvbsFrontendSettings.Standard
+    public int getStandardCapability() {
+        return mStandard;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/DvbsFrontendSettings.java b/android/media/tv/tuner/frontend/DvbsFrontendSettings.java
new file mode 100644
index 0000000..f68d554
--- /dev/null
+++ b/android/media/tv/tuner/frontend/DvbsFrontendSettings.java
@@ -0,0 +1,524 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.Tuner;
+import android.media.tv.tuner.TunerVersionChecker;
+
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Frontend settings for DVBS.
+ *
+ * @hide
+ */
+@SystemApi
+public class DvbsFrontendSettings extends FrontendSettings {
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "SCAN_TYPE_",
+            value = {SCAN_TYPE_UNDEFINED, SCAN_TYPE_DIRECT, SCAN_TYPE_DISEQC,
+                    SCAN_TYPE_UNICABLE, SCAN_TYPE_JESS})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ScanType {}
+
+    /**
+     * Dvbs scan type undefined.
+     */
+    public static final int SCAN_TYPE_UNDEFINED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbsScanType.UNDEFINED;
+
+    /**
+     * Dvbs scan type DIRECT.
+     */
+    public static final int SCAN_TYPE_DIRECT =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbsScanType.DIRECT;
+
+    /**
+     * Dvbs scan type DISEQC.
+     */
+    public static final int SCAN_TYPE_DISEQC =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbsScanType.DISEQC;
+
+    /**
+     * Dvbs scan type UNICABLE.
+     */
+    public static final int SCAN_TYPE_UNICABLE =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbsScanType.UNICABLE;
+
+    /**
+     * Dvbs scan type JESS.
+     */
+    public static final int SCAN_TYPE_JESS =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbsScanType.JESS;
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "MODULATION_",
+            value = {MODULATION_UNDEFINED, MODULATION_AUTO, MODULATION_MOD_QPSK,
+                    MODULATION_MOD_8PSK, MODULATION_MOD_16QAM, MODULATION_MOD_16PSK,
+                    MODULATION_MOD_32PSK, MODULATION_MOD_ACM, MODULATION_MOD_8APSK,
+                    MODULATION_MOD_16APSK, MODULATION_MOD_32APSK, MODULATION_MOD_64APSK,
+                    MODULATION_MOD_128APSK, MODULATION_MOD_256APSK, MODULATION_MOD_RESERVED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Modulation {}
+
+    /**
+     * Modulation undefined.
+     */
+    public static final int MODULATION_UNDEFINED = Constants.FrontendDvbsModulation.UNDEFINED;
+    /**
+     * Hardware is able to detect and set modulation automatically
+     */
+    public static final int MODULATION_AUTO = Constants.FrontendDvbsModulation.AUTO;
+    /**
+     * QPSK Modulation.
+     */
+    public static final int MODULATION_MOD_QPSK = Constants.FrontendDvbsModulation.MOD_QPSK;
+    /**
+     * 8PSK Modulation.
+     */
+    public static final int MODULATION_MOD_8PSK = Constants.FrontendDvbsModulation.MOD_8PSK;
+    /**
+     * 16QAM Modulation.
+     */
+    public static final int MODULATION_MOD_16QAM = Constants.FrontendDvbsModulation.MOD_16QAM;
+    /**
+     * 16PSK Modulation.
+     */
+    public static final int MODULATION_MOD_16PSK = Constants.FrontendDvbsModulation.MOD_16PSK;
+    /**
+     * 32PSK Modulation.
+     */
+    public static final int MODULATION_MOD_32PSK = Constants.FrontendDvbsModulation.MOD_32PSK;
+    /**
+     * ACM Modulation.
+     */
+    public static final int MODULATION_MOD_ACM = Constants.FrontendDvbsModulation.MOD_ACM;
+    /**
+     * 8APSK Modulation.
+     */
+    public static final int MODULATION_MOD_8APSK = Constants.FrontendDvbsModulation.MOD_8APSK;
+    /**
+     * 16APSK Modulation.
+     */
+    public static final int MODULATION_MOD_16APSK = Constants.FrontendDvbsModulation.MOD_16APSK;
+    /**
+     * 32APSK Modulation.
+     */
+    public static final int MODULATION_MOD_32APSK = Constants.FrontendDvbsModulation.MOD_32APSK;
+    /**
+     * 64APSK Modulation.
+     */
+    public static final int MODULATION_MOD_64APSK = Constants.FrontendDvbsModulation.MOD_64APSK;
+    /**
+     * 128APSK Modulation.
+     */
+    public static final int MODULATION_MOD_128APSK = Constants.FrontendDvbsModulation.MOD_128APSK;
+    /**
+     * 256APSK Modulation.
+     */
+    public static final int MODULATION_MOD_256APSK = Constants.FrontendDvbsModulation.MOD_256APSK;
+    /**
+     * Reversed Modulation.
+     */
+    public static final int MODULATION_MOD_RESERVED = Constants.FrontendDvbsModulation.MOD_RESERVED;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "ROLLOFF_",
+            value = {ROLLOFF_UNDEFINED, ROLLOFF_0_35, ROLLOFF_0_25, ROLLOFF_0_20, ROLLOFF_0_15,
+                    ROLLOFF_0_10, ROLLOFF_0_5})
+    public @interface Rolloff {}
+
+    /**
+     * Rolloff range undefined.
+     */
+    public static final int ROLLOFF_UNDEFINED = Constants.FrontendDvbsRolloff.UNDEFINED;
+    /**
+     * Rolloff range 0,35.
+     */
+    public static final int ROLLOFF_0_35 = Constants.FrontendDvbsRolloff.ROLLOFF_0_35;
+    /**
+     * Rolloff range 0,25.
+     */
+    public static final int ROLLOFF_0_25 = Constants.FrontendDvbsRolloff.ROLLOFF_0_25;
+    /**
+     * Rolloff range 0,20.
+     */
+    public static final int ROLLOFF_0_20 = Constants.FrontendDvbsRolloff.ROLLOFF_0_20;
+    /**
+     * Rolloff range 0,15.
+     */
+    public static final int ROLLOFF_0_15 = Constants.FrontendDvbsRolloff.ROLLOFF_0_15;
+    /**
+     * Rolloff range 0,10.
+     */
+    public static final int ROLLOFF_0_10 = Constants.FrontendDvbsRolloff.ROLLOFF_0_10;
+    /**
+     * Rolloff range 0,5.
+     */
+    public static final int ROLLOFF_0_5 = Constants.FrontendDvbsRolloff.ROLLOFF_0_5;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "PILOT_",
+            value = {PILOT_UNDEFINED, PILOT_ON, PILOT_OFF, PILOT_AUTO})
+    public @interface Pilot {}
+
+    /**
+     * Pilot mode undefined.
+     */
+    public static final int PILOT_UNDEFINED = Constants.FrontendDvbsPilot.UNDEFINED;
+    /**
+     * Pilot mode on.
+     */
+    public static final int PILOT_ON = Constants.FrontendDvbsPilot.ON;
+    /**
+     * Pilot mode off.
+     */
+    public static final int PILOT_OFF = Constants.FrontendDvbsPilot.OFF;
+    /**
+     * Pilot mode auto.
+     */
+    public static final int PILOT_AUTO = Constants.FrontendDvbsPilot.AUTO;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "STANDARD_",
+            value = {STANDARD_AUTO, STANDARD_S, STANDARD_S2, STANDARD_S2X})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Standard {}
+
+    /**
+     * Standard undefined.
+     */
+    public static final int STANDARD_AUTO = Constants.FrontendDvbsStandard.AUTO;
+    /**
+     * Standard S.
+     */
+    public static final int STANDARD_S = Constants.FrontendDvbsStandard.S;
+    /**
+     * Standard S2.
+     */
+    public static final int STANDARD_S2 = Constants.FrontendDvbsStandard.S2;
+    /**
+     * Standard S2X.
+     */
+    public static final int STANDARD_S2X = Constants.FrontendDvbsStandard.S2X;
+
+    /** @hide */
+    @IntDef(prefix = "VCM_MODE_",
+            value = {VCM_MODE_UNDEFINED, VCM_MODE_AUTO, VCM_MODE_MANUAL})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface VcmMode {}
+
+    /**
+     * VCM mode undefined.
+     */
+    public static final int VCM_MODE_UNDEFINED = Constants.FrontendDvbsVcmMode.UNDEFINED;
+    /**
+     * Auto VCM mode.
+     */
+    public static final int VCM_MODE_AUTO = Constants.FrontendDvbsVcmMode.AUTO;
+    /**
+     * Manual VCM mode.
+     */
+    public static final int VCM_MODE_MANUAL = Constants.FrontendDvbsVcmMode.MANUAL;
+
+
+    private final int mModulation;
+    private final DvbsCodeRate mCodeRate;
+    private final int mSymbolRate;
+    private final int mRolloff;
+    private final int mPilot;
+    private final int mInputStreamId;
+    private final int mStandard;
+    private final int mVcmMode;
+    // Dvbs scan type is only supported in Tuner 1.1 or higher.
+    private final int mScanType;
+    // isDiseqcRxMessage is only supported in Tuner 1.1 or higher.
+    private final boolean mIsDiseqcRxMessage;
+
+    private DvbsFrontendSettings(int frequency, int modulation, DvbsCodeRate codeRate,
+            int symbolRate, int rolloff, int pilot, int inputStreamId, int standard, int vcm,
+            int scanType, boolean isDiseqcRxMessage) {
+        super(frequency);
+        mModulation = modulation;
+        mCodeRate = codeRate;
+        mSymbolRate = symbolRate;
+        mRolloff = rolloff;
+        mPilot = pilot;
+        mInputStreamId = inputStreamId;
+        mStandard = standard;
+        mVcmMode = vcm;
+        mScanType = scanType;
+        mIsDiseqcRxMessage = isDiseqcRxMessage;
+    }
+
+    /**
+     * Gets Modulation.
+     */
+    @Modulation
+    public int getModulation() {
+        return mModulation;
+    }
+    /**
+     * Gets Code rate.
+     */
+    @Nullable
+    public DvbsCodeRate getCodeRate() {
+        return mCodeRate;
+    }
+    /**
+     * Gets Symbol Rate in symbols per second.
+     */
+    public int getSymbolRate() {
+        return mSymbolRate;
+    }
+    /**
+     * Gets Rolloff.
+     */
+    @Rolloff
+    public int getRolloff() {
+        return mRolloff;
+    }
+    /**
+     * Gets Pilot mode.
+     */
+    @Pilot
+    public int getPilot() {
+        return mPilot;
+    }
+    /**
+     * Gets Input Stream ID.
+     */
+    public int getInputStreamId() {
+        return mInputStreamId;
+    }
+    /**
+     * Gets DVBS sub-standard.
+     */
+    @Standard
+    public int getStandard() {
+        return mStandard;
+    }
+    /**
+     * Gets VCM mode.
+     */
+    @VcmMode
+    public int getVcmMode() {
+        return mVcmMode;
+    }
+    /**
+     * Get scan type.
+     */
+    @ScanType
+    public int getScanType() {
+        return mScanType;
+    }
+    /**
+     * Get if the client can handle the Diseqc Rx Message or not. Default value is false.
+     *
+     * The setter {@link Builder#setCanHandleDiseqcRxMessage(boolean)} is only supported with
+     * Tuner HAL 1.1 or higher. Use {@link TunerVersionChecker#getTunerVersion()} to check the
+     * version.
+     */
+    public boolean canHandleDiseqcRxMessage() {
+        return mIsDiseqcRxMessage;
+    }
+
+    /**
+     * Creates a builder for {@link DvbsFrontendSettings}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link DvbsFrontendSettings}.
+     */
+    public static class Builder {
+        private int mFrequency = 0;
+        private int mModulation = MODULATION_UNDEFINED;
+        private DvbsCodeRate mCodeRate = null;
+        private int mSymbolRate = 0;
+        private int mRolloff = ROLLOFF_UNDEFINED;
+        private int mPilot = PILOT_UNDEFINED;
+        private int mInputStreamId = Tuner.INVALID_STREAM_ID;
+        private int mStandard = STANDARD_AUTO;
+        private int mVcmMode = VCM_MODE_UNDEFINED;
+        private int mScanType = SCAN_TYPE_UNDEFINED;
+        private boolean mIsDiseqcRxMessage = false;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        @IntRange(from = 1)
+        public Builder setFrequency(int frequency) {
+            mFrequency = frequency;
+            return this;
+        }
+
+        /**
+         * Set the scan type.
+         *
+         * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would cause
+         * no-op. Use {@link TunerVersionChecker#getTunerVersion()} to check the version.
+         *
+         * @param scanType the value to set as the scan type. Default value is
+         * {@link android.media.tv.tuner.frontend.DvbsFrontendSettings#DVBS_SCAN_TYPE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setScanType(@ScanType int scanType) {
+            if (TunerVersionChecker.checkHigherOrEqualVersionTo(
+                        TunerVersionChecker.TUNER_VERSION_1_1, "setScanType")) {
+                mScanType = scanType;
+            }
+            return this;
+        }
+
+        /**
+         * Set true to indicate the client can handle the Diseqc Messages. Note that it's still
+         * possible that the client won't receive the messages when HAL is not able to setup Rx
+         * channel in the hardware layer.
+         *
+         * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would cause
+         * no-op. Use {@link TunerVersionChecker#getTunerVersion()} to check the version.
+         */
+        @NonNull
+        public Builder setCanHandleDiseqcRxMessage(boolean canHandleDiseqcMessage) {
+            if (TunerVersionChecker.checkHigherOrEqualVersionTo(
+                        TunerVersionChecker.TUNER_VERSION_1_1, "setCanHandleDiseqcRxMessage")) {
+                mIsDiseqcRxMessage = canHandleDiseqcMessage;
+            }
+            return this;
+        }
+
+        /**
+         * Sets Modulation.
+         *
+         * <p>Default value is {@link #MODULATION_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setModulation(@Modulation int modulation) {
+            mModulation = modulation;
+            return this;
+        }
+        /**
+         * Sets Code rate.
+         *
+         * <p>Default value is {@code null}.
+         */
+        @NonNull
+        public Builder setCodeRate(@Nullable DvbsCodeRate codeRate) {
+            mCodeRate = codeRate;
+            return this;
+        }
+        /**
+         * Sets Symbol Rate.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        public Builder setSymbolRate(int symbolRate) {
+            mSymbolRate = symbolRate;
+            return this;
+        }
+        /**
+         * Sets Rolloff.
+         *
+         * <p>Default value is {@link #ROLLOFF_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setRolloff(@Rolloff int rolloff) {
+            mRolloff = rolloff;
+            return this;
+        }
+        /**
+         * Sets Pilot mode.
+         *
+         * <p>Default value is {@link #PILOT_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setPilot(@Pilot int pilot) {
+            mPilot = pilot;
+            return this;
+        }
+        /**
+         * Sets Input Stream ID.
+         *
+         * <p>Default value is {@link Tuner#INVALID_STREAM_ID}.
+         */
+        @NonNull
+        public Builder setInputStreamId(int inputStreamId) {
+            mInputStreamId = inputStreamId;
+            return this;
+        }
+        /**
+         * Sets Standard.
+         *
+         * <p>Default value is {@link #STANDARD_AUTO}.
+         */
+        @NonNull
+        public Builder setStandard(@Standard int standard) {
+            mStandard = standard;
+            return this;
+        }
+        /**
+         * Sets VCM mode.
+         *
+         * <p>Default value is {@link #VCM_MODE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setVcmMode(@VcmMode int vcm) {
+            mVcmMode = vcm;
+            return this;
+        }
+
+        /**
+         * Builds a {@link DvbsFrontendSettings} object.
+         */
+        @NonNull
+        public DvbsFrontendSettings build() {
+            return new DvbsFrontendSettings(mFrequency, mModulation, mCodeRate, mSymbolRate,
+                    mRolloff, mPilot, mInputStreamId, mStandard, mVcmMode, mScanType,
+                    mIsDiseqcRxMessage);
+        }
+    }
+
+    @Override
+    public int getType() {
+        return FrontendSettings.TYPE_DVBS;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/DvbtFrontendCapabilities.java b/android/media/tv/tuner/frontend/DvbtFrontendCapabilities.java
new file mode 100644
index 0000000..524952d
--- /dev/null
+++ b/android/media/tv/tuner/frontend/DvbtFrontendCapabilities.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/**
+ * DVBT Capabilities.
+ *
+ * @hide
+ */
+@SystemApi
+public class DvbtFrontendCapabilities extends FrontendCapabilities {
+    private final int mTransmissionModeCap;
+    private final int mBandwidthCap;
+    private final int mConstellationCap;
+    private final int mCodeRateCap;
+    private final int mHierarchyCap;
+    private final int mGuardIntervalCap;
+    private final boolean mIsT2Supported;
+    private final boolean mIsMisoSupported;
+
+    private DvbtFrontendCapabilities(int transmissionModeCap, int bandwidthCap,
+            int constellationCap, int codeRateCap, int hierarchyCap, int guardIntervalCap,
+            boolean isT2Supported, boolean isMisoSupported) {
+        mTransmissionModeCap = transmissionModeCap;
+        mBandwidthCap = bandwidthCap;
+        mConstellationCap = constellationCap;
+        mCodeRateCap = codeRateCap;
+        mHierarchyCap = hierarchyCap;
+        mGuardIntervalCap = guardIntervalCap;
+        mIsT2Supported = isT2Supported;
+        mIsMisoSupported = isMisoSupported;
+    }
+
+    /**
+     * Gets transmission mode capability.
+     */
+    @DvbtFrontendSettings.TransmissionMode
+    public int getTransmissionModeCapability() {
+        return mTransmissionModeCap;
+    }
+    /**
+     * Gets bandwidth capability.
+     */
+    @DvbtFrontendSettings.Bandwidth
+    public int getBandwidthCapability() {
+        return mBandwidthCap;
+    }
+    /**
+     * Gets constellation capability.
+     */
+    @DvbtFrontendSettings.Constellation
+    public int getConstellationCapability() {
+        return mConstellationCap;
+    }
+    /**
+     * Gets code rate capability.
+     */
+    @DvbtFrontendSettings.CodeRate
+    public int getCodeRateCapability() {
+        return mCodeRateCap;
+    }
+    /**
+     * Gets hierarchy capability.
+     */
+    @DvbtFrontendSettings.Hierarchy
+    public int getHierarchyCapability() {
+        return mHierarchyCap;
+    }
+    /**
+     * Gets guard interval capability.
+     */
+    @DvbtFrontendSettings.GuardInterval
+    public int getGuardIntervalCapability() {
+        return mGuardIntervalCap;
+    }
+    /**
+     * Returns whether T2 is supported.
+     */
+    public boolean isT2Supported() {
+        return mIsT2Supported;
+    }
+    /**
+     * Returns whether MISO is supported.
+     */
+    public boolean isMisoSupported() {
+        return mIsMisoSupported;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/DvbtFrontendSettings.java b/android/media/tv/tuner/frontend/DvbtFrontendSettings.java
new file mode 100644
index 0000000..536c7b8
--- /dev/null
+++ b/android/media/tv/tuner/frontend/DvbtFrontendSettings.java
@@ -0,0 +1,749 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.TunerVersionChecker;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Frontend settings for DVBT.
+ *
+ * @hide
+ */
+@SystemApi
+public class DvbtFrontendSettings extends FrontendSettings {
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "TRANSMISSION_MODE_",
+            value = {TRANSMISSION_MODE_UNDEFINED, TRANSMISSION_MODE_AUTO,
+                    TRANSMISSION_MODE_2K, TRANSMISSION_MODE_8K, TRANSMISSION_MODE_4K,
+                    TRANSMISSION_MODE_1K, TRANSMISSION_MODE_16K, TRANSMISSION_MODE_32K})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TransmissionMode {}
+
+    /**
+     * Transmission Mode undefined.
+     */
+    public static final int TRANSMISSION_MODE_UNDEFINED =
+            Constants.FrontendDvbtTransmissionMode.UNDEFINED;
+    /**
+     * Hardware is able to detect and set Transmission Mode automatically
+     */
+    public static final int TRANSMISSION_MODE_AUTO = Constants.FrontendDvbtTransmissionMode.AUTO;
+    /**
+     * 2K Transmission Mode.
+     */
+    public static final int TRANSMISSION_MODE_2K = Constants.FrontendDvbtTransmissionMode.MODE_2K;
+    /**
+     * 8K Transmission Mode.
+     */
+    public static final int TRANSMISSION_MODE_8K = Constants.FrontendDvbtTransmissionMode.MODE_8K;
+    /**
+     * 4K Transmission Mode.
+     */
+    public static final int TRANSMISSION_MODE_4K = Constants.FrontendDvbtTransmissionMode.MODE_4K;
+    /**
+     * 1K Transmission Mode.
+     */
+    public static final int TRANSMISSION_MODE_1K = Constants.FrontendDvbtTransmissionMode.MODE_1K;
+    /**
+     * 16K Transmission Mode.
+     */
+    public static final int TRANSMISSION_MODE_16K = Constants.FrontendDvbtTransmissionMode.MODE_16K;
+    /**
+     * 32K Transmission Mode.
+     */
+    public static final int TRANSMISSION_MODE_32K = Constants.FrontendDvbtTransmissionMode.MODE_32K;
+    /**
+     * 8K Transmission Extended Mode.
+     */
+    public static final int TRANSMISSION_MODE_EXTENDED_8K =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbtTransmissionMode.MODE_8K_E;
+    /**
+     * 16K Transmission Extended Mode.
+     */
+    public static final int TRANSMISSION_MODE_EXTENDED_16K =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbtTransmissionMode.MODE_16K_E;
+    /**
+     * 32K Transmission Extended Mode.
+     */
+    public static final int TRANSMISSION_MODE_EXTENDED_32K =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbtTransmissionMode.MODE_32K_E;
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "BANDWIDTH_",
+            value = {BANDWIDTH_UNDEFINED, BANDWIDTH_AUTO, BANDWIDTH_8MHZ, BANDWIDTH_7MHZ,
+                    BANDWIDTH_6MHZ, BANDWIDTH_5MHZ, BANDWIDTH_1_7MHZ, BANDWIDTH_10MHZ})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Bandwidth {}
+
+    /**
+     * Bandwidth undefined.
+     */
+    public static final int BANDWIDTH_UNDEFINED = Constants.FrontendDvbtBandwidth.UNDEFINED;
+    /**
+     * Hardware is able to detect and set Bandwidth automatically.
+     */
+    public static final int BANDWIDTH_AUTO = Constants.FrontendDvbtBandwidth.AUTO;
+    /**
+     * 8 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_8MHZ = Constants.FrontendDvbtBandwidth.BANDWIDTH_8MHZ;
+    /**
+     * 7 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_7MHZ = Constants.FrontendDvbtBandwidth.BANDWIDTH_7MHZ;
+    /**
+     * 6 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_6MHZ = Constants.FrontendDvbtBandwidth.BANDWIDTH_6MHZ;
+    /**
+     * 5 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_5MHZ = Constants.FrontendDvbtBandwidth.BANDWIDTH_5MHZ;
+    /**
+     * 1,7 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_1_7MHZ = Constants.FrontendDvbtBandwidth.BANDWIDTH_1_7MHZ;
+    /**
+     * 10 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_10MHZ = Constants.FrontendDvbtBandwidth.BANDWIDTH_10MHZ;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "CONSTELLATION_",
+            value = {CONSTELLATION_UNDEFINED, CONSTELLATION_AUTO, CONSTELLATION_QPSK,
+                    CONSTELLATION_16QAM, CONSTELLATION_64QAM, CONSTELLATION_256QAM,
+                    CONSTELLATION_QPSK_R, CONSTELLATION_16QAM_R, CONSTELLATION_64QAM_R,
+                    CONSTELLATION_256QAM_R})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Constellation {}
+
+    /**
+     * Constellation not defined.
+     */
+    public static final int CONSTELLATION_UNDEFINED = Constants.FrontendDvbtConstellation.UNDEFINED;
+    /**
+     * Hardware is able to detect and set Constellation automatically.
+     */
+    public static final int CONSTELLATION_AUTO = Constants.FrontendDvbtConstellation.AUTO;
+    /**
+     * QPSK Constellation.
+     */
+    public static final int CONSTELLATION_QPSK =
+            Constants.FrontendDvbtConstellation.CONSTELLATION_QPSK;
+    /**
+     * 16QAM Constellation.
+     */
+    public static final int CONSTELLATION_16QAM =
+            Constants.FrontendDvbtConstellation.CONSTELLATION_16QAM;
+    /**
+     * 64QAM Constellation.
+     */
+    public static final int CONSTELLATION_64QAM =
+            Constants.FrontendDvbtConstellation.CONSTELLATION_64QAM;
+    /**
+     * 256QAM Constellation.
+     */
+    public static final int CONSTELLATION_256QAM =
+            Constants.FrontendDvbtConstellation.CONSTELLATION_256QAM;
+    /**
+     * QPSK Rotated Constellation.
+     */
+    public static final int CONSTELLATION_QPSK_R =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbtConstellation
+                    .CONSTELLATION_QPSK_R;
+    /**
+     * 16QAM Rotated Constellation.
+     */
+    public static final int CONSTELLATION_16QAM_R =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbtConstellation
+                    .CONSTELLATION_16QAM_R;
+    /**
+     * 64QAM Rotated Constellation.
+     */
+    public static final int CONSTELLATION_64QAM_R =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbtConstellation
+                    .CONSTELLATION_64QAM_R;
+    /**
+     * 256QAM Rotated Constellation.
+     */
+    public static final int CONSTELLATION_256QAM_R =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendDvbtConstellation
+                    .CONSTELLATION_256QAM_R;
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "HIERARCHY_",
+            value = {HIERARCHY_UNDEFINED, HIERARCHY_AUTO, HIERARCHY_NON_NATIVE, HIERARCHY_1_NATIVE,
+            HIERARCHY_2_NATIVE, HIERARCHY_4_NATIVE, HIERARCHY_NON_INDEPTH, HIERARCHY_1_INDEPTH,
+            HIERARCHY_2_INDEPTH, HIERARCHY_4_INDEPTH})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Hierarchy {}
+
+    /**
+     * Hierarchy undefined.
+     */
+    public static final int HIERARCHY_UNDEFINED = Constants.FrontendDvbtHierarchy.UNDEFINED;
+    /**
+     * Hardware is able to detect and set Hierarchy automatically.
+     */
+    public static final int HIERARCHY_AUTO = Constants.FrontendDvbtHierarchy.AUTO;
+    /**
+     * Non-native Hierarchy
+     */
+    public static final int HIERARCHY_NON_NATIVE =
+            Constants.FrontendDvbtHierarchy.HIERARCHY_NON_NATIVE;
+    /**
+     * 1-native Hierarchy
+     */
+    public static final int HIERARCHY_1_NATIVE = Constants.FrontendDvbtHierarchy.HIERARCHY_1_NATIVE;
+    /**
+     * 2-native Hierarchy
+     */
+    public static final int HIERARCHY_2_NATIVE = Constants.FrontendDvbtHierarchy.HIERARCHY_2_NATIVE;
+    /**
+     * 4-native Hierarchy
+     */
+    public static final int HIERARCHY_4_NATIVE = Constants.FrontendDvbtHierarchy.HIERARCHY_4_NATIVE;
+    /**
+     * Non-indepth Hierarchy
+     */
+    public static final int HIERARCHY_NON_INDEPTH =
+            Constants.FrontendDvbtHierarchy.HIERARCHY_NON_INDEPTH;
+    /**
+     * 1-indepth Hierarchy
+     */
+    public static final int HIERARCHY_1_INDEPTH =
+            Constants.FrontendDvbtHierarchy.HIERARCHY_1_INDEPTH;
+    /**
+     * 2-indepth Hierarchy
+     */
+    public static final int HIERARCHY_2_INDEPTH =
+            Constants.FrontendDvbtHierarchy.HIERARCHY_2_INDEPTH;
+    /**
+     * 4-indepth Hierarchy
+     */
+    public static final int HIERARCHY_4_INDEPTH =
+            Constants.FrontendDvbtHierarchy.HIERARCHY_4_INDEPTH;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "CODERATE_",
+            value = {CODERATE_UNDEFINED, CODERATE_AUTO, CODERATE_1_2, CODERATE_2_3, CODERATE_3_4,
+            CODERATE_5_6, CODERATE_7_8, CODERATE_3_5, CODERATE_4_5, CODERATE_6_7, CODERATE_8_9})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CodeRate {}
+
+    /**
+     * Code rate undefined.
+     */
+    public static final int CODERATE_UNDEFINED =
+            Constants.FrontendDvbtCoderate.UNDEFINED;
+    /**
+     * Hardware is able to detect and set code rate automatically.
+     */
+    public static final int CODERATE_AUTO = Constants.FrontendDvbtCoderate.AUTO;
+    /**
+     * 1/2 code rate.
+     */
+    public static final int CODERATE_1_2 = Constants.FrontendDvbtCoderate.CODERATE_1_2;
+    /**
+     * 2/3 code rate.
+     */
+    public static final int CODERATE_2_3 = Constants.FrontendDvbtCoderate.CODERATE_2_3;
+    /**
+     * 3/4 code rate.
+     */
+    public static final int CODERATE_3_4 = Constants.FrontendDvbtCoderate.CODERATE_3_4;
+    /**
+     * 5/6 code rate.
+     */
+    public static final int CODERATE_5_6 = Constants.FrontendDvbtCoderate.CODERATE_5_6;
+    /**
+     * 7/8 code rate.
+     */
+    public static final int CODERATE_7_8 = Constants.FrontendDvbtCoderate.CODERATE_7_8;
+    /**
+     * 4/5 code rate.
+     */
+    public static final int CODERATE_3_5 = Constants.FrontendDvbtCoderate.CODERATE_3_5;
+    /**
+     * 4/5 code rate.
+     */
+    public static final int CODERATE_4_5 = Constants.FrontendDvbtCoderate.CODERATE_4_5;
+    /**
+     * 6/7 code rate.
+     */
+    public static final int CODERATE_6_7 = Constants.FrontendDvbtCoderate.CODERATE_6_7;
+    /**
+     * 8/9 code rate.
+     */
+    public static final int CODERATE_8_9 = Constants.FrontendDvbtCoderate.CODERATE_8_9;
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "GUARD_INTERVAL_",
+            value = {GUARD_INTERVAL_UNDEFINED, GUARD_INTERVAL_AUTO,
+            GUARD_INTERVAL_1_32, GUARD_INTERVAL_1_16,
+            GUARD_INTERVAL_1_8, GUARD_INTERVAL_1_4,
+            GUARD_INTERVAL_1_128,
+            GUARD_INTERVAL_19_128,
+            GUARD_INTERVAL_19_256})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface GuardInterval {}
+
+    /**
+     * Guard Interval undefined.
+     */
+    public static final int GUARD_INTERVAL_UNDEFINED =
+            Constants.FrontendDvbtGuardInterval.UNDEFINED;
+    /**
+     * Hardware is able to detect and set Guard Interval automatically.
+     */
+    public static final int GUARD_INTERVAL_AUTO = Constants.FrontendDvbtGuardInterval.AUTO;
+    /**
+     * 1/32 Guard Interval.
+     */
+    public static final int GUARD_INTERVAL_1_32 =
+            Constants.FrontendDvbtGuardInterval.INTERVAL_1_32;
+    /**
+     * 1/16 Guard Interval.
+     */
+    public static final int GUARD_INTERVAL_1_16 =
+            Constants.FrontendDvbtGuardInterval.INTERVAL_1_16;
+    /**
+     * 1/8 Guard Interval.
+     */
+    public static final int GUARD_INTERVAL_1_8 =
+            Constants.FrontendDvbtGuardInterval.INTERVAL_1_8;
+    /**
+     * 1/4 Guard Interval.
+     */
+    public static final int GUARD_INTERVAL_1_4 =
+            Constants.FrontendDvbtGuardInterval.INTERVAL_1_4;
+    /**
+     * 1/128 Guard Interval.
+     */
+    public static final int GUARD_INTERVAL_1_128 =
+            Constants.FrontendDvbtGuardInterval.INTERVAL_1_128;
+    /**
+     * 19/128 Guard Interval.
+     */
+    public static final int GUARD_INTERVAL_19_128 =
+            Constants.FrontendDvbtGuardInterval.INTERVAL_19_128;
+    /**
+     * 19/256 Guard Interval.
+     */
+    public static final int GUARD_INTERVAL_19_256 =
+            Constants.FrontendDvbtGuardInterval.INTERVAL_19_256;
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "STANDARD",
+            value = {STANDARD_AUTO, STANDARD_T, STANDARD_T2}
+    )
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Standard {}
+
+    /**
+     * Hardware is able to detect and set Standard automatically.
+     */
+    public static final int STANDARD_AUTO = Constants.FrontendDvbtStandard.AUTO;
+    /**
+     * T standard.
+     */
+    public static final int STANDARD_T = Constants.FrontendDvbtStandard.T;
+    /**
+     * T2 standard.
+     */
+    public static final int STANDARD_T2 = Constants.FrontendDvbtStandard.T2;
+
+    /** @hide */
+    @IntDef(prefix = "PLP_MODE_",
+            value = {PLP_MODE_UNDEFINED, PLP_MODE_AUTO, PLP_MODE_MANUAL})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface PlpMode {}
+
+    /**
+     * Physical Layer Pipe (PLP) Mode undefined.
+     */
+    public static final int PLP_MODE_UNDEFINED = Constants.FrontendDvbtPlpMode.UNDEFINED;
+    /**
+     * Hardware is able to detect and set Physical Layer Pipe (PLP) Mode automatically.
+     */
+    public static final int PLP_MODE_AUTO = Constants.FrontendDvbtPlpMode.AUTO;
+    /**
+     * Physical Layer Pipe (PLP) manual Mode.
+     */
+    public static final int PLP_MODE_MANUAL = Constants.FrontendDvbtPlpMode.MANUAL;
+
+    private int mTransmissionMode;
+    private final int mBandwidth;
+    private final int mConstellation;
+    private final int mHierarchy;
+    private final int mHpCodeRate;
+    private final int mLpCodeRate;
+    private final int mGuardInterval;
+    private final boolean mIsHighPriority;
+    private final int mStandard;
+    private final boolean mIsMiso;
+    private final int mPlpMode;
+    private final int mPlpId;
+    private final int mPlpGroupId;
+
+    private DvbtFrontendSettings(int frequency, int transmissionMode, int bandwidth,
+            int constellation, int hierarchy, int hpCodeRate, int lpCodeRate, int guardInterval,
+            boolean isHighPriority, int standard, boolean isMiso, int plpMode, int plpId,
+            int plpGroupId) {
+        super(frequency);
+        mTransmissionMode = transmissionMode;
+        mBandwidth = bandwidth;
+        mConstellation = constellation;
+        mHierarchy = hierarchy;
+        mHpCodeRate = hpCodeRate;
+        mLpCodeRate = lpCodeRate;
+        mGuardInterval = guardInterval;
+        mIsHighPriority = isHighPriority;
+        mStandard = standard;
+        mIsMiso = isMiso;
+        mPlpMode = plpMode;
+        mPlpId = plpId;
+        mPlpGroupId = plpGroupId;
+    }
+
+    /**
+     * Gets Transmission Mode.
+     */
+    @TransmissionMode
+    public int getTransmissionMode() {
+        return mTransmissionMode;
+    }
+    /**
+     * Gets Bandwidth.
+     */
+    @Bandwidth
+    public int getBandwidth() {
+        return mBandwidth;
+    }
+    /**
+     * Gets Constellation.
+     */
+    @Constellation
+    public int getConstellation() {
+        return mConstellation;
+    }
+    /**
+     * Gets Hierarchy.
+     */
+    @Hierarchy
+    public int getHierarchy() {
+        return mHierarchy;
+    }
+    /**
+     * Gets Code Rate for High Priority level.
+     */
+    @CodeRate
+    public int getHighPriorityCodeRate() {
+        return mHpCodeRate;
+    }
+    /**
+     * Gets Code Rate for Low Priority level.
+     */
+    @CodeRate
+    public int getLowPriorityCodeRate() {
+        return mLpCodeRate;
+    }
+    /**
+     * Gets Guard Interval.
+     */
+    @GuardInterval
+    public int getGuardInterval() {
+        return mGuardInterval;
+    }
+    /**
+     * Checks whether it's high priority.
+     */
+    public boolean isHighPriority() {
+        return mIsHighPriority;
+    }
+    /**
+     * Gets Standard.
+     */
+    @Standard
+    public int getStandard() {
+        return mStandard;
+    }
+    /**
+     * Gets whether it's MISO.
+     */
+    public boolean isMiso() {
+        return mIsMiso;
+    }
+    /**
+     * Gets Physical Layer Pipe (PLP) Mode.
+     */
+    @PlpMode
+    public int getPlpMode() {
+        return mPlpMode;
+    }
+    /**
+     * Gets Physical Layer Pipe (PLP) ID.
+     */
+    public int getPlpId() {
+        return mPlpId;
+    }
+    /**
+     * Gets Physical Layer Pipe (PLP) group ID.
+     */
+    public int getPlpGroupId() {
+        return mPlpGroupId;
+    }
+
+    private static boolean isExtendedTransmissionMode(@TransmissionMode int transmissionMode) {
+        return transmissionMode == TRANSMISSION_MODE_EXTENDED_8K
+                || transmissionMode == TRANSMISSION_MODE_EXTENDED_16K
+                || transmissionMode == TRANSMISSION_MODE_EXTENDED_32K;
+    }
+
+    private static boolean isExtendedConstellation(@Constellation int constellation) {
+        return constellation == CONSTELLATION_QPSK_R
+                || constellation == CONSTELLATION_16QAM_R
+                || constellation == CONSTELLATION_64QAM_R
+                || constellation == CONSTELLATION_256QAM_R;
+    }
+
+    /**
+     * Creates a builder for {@link DvbtFrontendSettings}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link DvbtFrontendSettings}.
+     */
+    public static class Builder {
+        private int mFrequency = 0;
+        private int mTransmissionMode = TRANSMISSION_MODE_UNDEFINED;
+        private int mBandwidth = BANDWIDTH_UNDEFINED;
+        private int mConstellation = CONSTELLATION_UNDEFINED;
+        private int mHierarchy = HIERARCHY_UNDEFINED;
+        private int mHpCodeRate = CODERATE_UNDEFINED;
+        private int mLpCodeRate = CODERATE_UNDEFINED;
+        private int mGuardInterval = GUARD_INTERVAL_UNDEFINED;
+        private boolean mIsHighPriority = false;
+        private int mStandard = STANDARD_AUTO;
+        private boolean mIsMiso = false;
+        private int mPlpMode = PLP_MODE_UNDEFINED;
+        private int mPlpId = 0;
+        private int mPlpGroupId = 0;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        @IntRange(from = 1)
+        public Builder setFrequency(int frequency) {
+            mFrequency = frequency;
+            return this;
+        }
+
+        /**
+         * Sets Transmission Mode.
+         *
+         * <p>{@link #TRANSMISSION_MODE_EXTENDED_8K}, {@link #TRANSMISSION_MODE_EXTENDED_16K} and
+         * {@link #TRANSMISSION_MODE_EXTENDED_32K} are only supported by Tuner HAL 1.1 or higher.
+         * Unsupported version would cause no-op. Use {@link TunerVersionChecker#getTunerVersion()}
+         * to check the version.
+         *
+         * <p>Default value is {@link #TRANSMISSION_MODE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setTransmissionMode(@TransmissionMode int transmissionMode) {
+            if (!isExtendedTransmissionMode(transmissionMode)
+                    || TunerVersionChecker.checkHigherOrEqualVersionTo(
+                            TunerVersionChecker.TUNER_VERSION_1_1, "set TransmissionMode Ext")) {
+                mTransmissionMode = transmissionMode;
+            }
+            return this;
+        }
+
+        /**
+         * Sets Bandwidth.
+         *
+         * <p>Default value is {@link #BANDWIDTH_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setBandwidth(@Bandwidth int bandwidth) {
+            mBandwidth = bandwidth;
+            return this;
+        }
+        /**
+         * Sets Constellation.
+         *
+         * <p>{@link #CONSTELLATION_QPSK_R}, {@link #CONSTELLATION_16QAM_R},
+         * {@link #CONSTELLATION_64QAM_R} and {@link #CONSTELLATION_256QAM_Rare} are only supported
+         * by Tuner HAL 1.1 or higher. Unsupported version would cause no-op. Use
+         * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+         *
+         * <p>Default value is {@link #CONSTELLATION_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setConstellation(@Constellation int constellation) {
+            if (!isExtendedConstellation(constellation)
+                    || TunerVersionChecker.checkHigherOrEqualVersionTo(
+                            TunerVersionChecker.TUNER_VERSION_1_1, "set Constellation Ext")) {
+                mConstellation = constellation;
+            }
+            return this;
+        }
+        /**
+         * Sets Hierarchy.
+         *
+         * <p>Default value is {@link #HIERARCHY_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setHierarchy(@Hierarchy int hierarchy) {
+            mHierarchy = hierarchy;
+            return this;
+        }
+        /**
+         * Sets Code Rate for High Priority level.
+         *
+         * <p>Default value is {@link #CODERATE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setHighPriorityCodeRate(@CodeRate int hpCodeRate) {
+            mHpCodeRate = hpCodeRate;
+            return this;
+        }
+        /**
+         * Sets Code Rate for Low Priority level.
+         *
+         * <p>Default value is {@link #CODERATE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setLowPriorityCodeRate(@CodeRate int lpCodeRate) {
+            mLpCodeRate = lpCodeRate;
+            return this;
+        }
+        /**
+         * Sets Guard Interval.
+         *
+         * <p>Default value is {@link #GUARD_INTERVAL_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setGuardInterval(@GuardInterval int guardInterval) {
+            mGuardInterval = guardInterval;
+            return this;
+        }
+        /**
+         * Sets whether it's high priority.
+         *
+         * <p>Default value is {@code false}.
+         */
+        @NonNull
+        public Builder setHighPriority(boolean isHighPriority) {
+            mIsHighPriority = isHighPriority;
+            return this;
+        }
+        /**
+         * Sets Standard.
+         *
+         * <p>Default value is {@link #STANDARD_AUTO}.
+         */
+        @NonNull
+        public Builder setStandard(@Standard int standard) {
+            mStandard = standard;
+            return this;
+        }
+        /**
+         * Sets whether it's MISO.
+         *
+         * <p>Default value is {@code false}.
+         */
+        @NonNull
+        public Builder setMiso(boolean isMiso) {
+            mIsMiso = isMiso;
+            return this;
+        }
+        /**
+         * Sets Physical Layer Pipe (PLP) Mode.
+         *
+         * <p>Default value is {@link #PLP_MODE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setPlpMode(@PlpMode int plpMode) {
+            mPlpMode = plpMode;
+            return this;
+        }
+        /**
+         * Sets Physical Layer Pipe (PLP) ID.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        public Builder setPlpId(int plpId) {
+            mPlpId = plpId;
+            return this;
+        }
+        /**
+         * Sets Physical Layer Pipe (PLP) group ID.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        public Builder setPlpGroupId(int plpGroupId) {
+            mPlpGroupId = plpGroupId;
+            return this;
+        }
+
+        /**
+         * Builds a {@link DvbtFrontendSettings} object.
+         */
+        @NonNull
+        public DvbtFrontendSettings build() {
+            return new DvbtFrontendSettings(mFrequency, mTransmissionMode, mBandwidth,
+                    mConstellation, mHierarchy, mHpCodeRate, mLpCodeRate, mGuardInterval,
+                    mIsHighPriority, mStandard, mIsMiso, mPlpMode, mPlpId, mPlpGroupId);
+        }
+    }
+
+    @Override
+    public int getType() {
+        return FrontendSettings.TYPE_DVBT;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/FrontendCapabilities.java b/android/media/tv/tuner/frontend/FrontendCapabilities.java
new file mode 100644
index 0000000..c03133d
--- /dev/null
+++ b/android/media/tv/tuner/frontend/FrontendCapabilities.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/**
+ * Frontend capabilities.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class FrontendCapabilities {
+}
diff --git a/android/media/tv/tuner/frontend/FrontendInfo.java b/android/media/tv/tuner/frontend/FrontendInfo.java
new file mode 100644
index 0000000..e96cae6
--- /dev/null
+++ b/android/media/tv/tuner/frontend/FrontendInfo.java
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.media.tv.tuner.frontend.FrontendSettings.Type;
+import android.media.tv.tuner.frontend.FrontendStatus.FrontendStatusType;
+import android.util.Range;
+
+import java.util.Arrays;
+import java.util.Objects;
+
+/**
+ * This class is used to specify meta information of a frontend.
+ *
+ * @hide
+ */
+@SystemApi
+public class FrontendInfo {
+    private final int mId;
+    private final int mType;
+    private final Range<Integer> mFrequencyRange;
+    private final Range<Integer> mSymbolRateRange;
+    private final int mAcquireRange;
+    private final int mExclusiveGroupId;
+    private final int[] mStatusCaps;
+    private final FrontendCapabilities mFrontendCap;
+
+    private FrontendInfo(int id, int type, int minFrequency, int maxFrequency, int minSymbolRate,
+            int maxSymbolRate, int acquireRange, int exclusiveGroupId, int[] statusCaps,
+            FrontendCapabilities frontendCap) {
+        mId = id;
+        mType = type;
+        // if max Frequency is negative, we set it as max value of the Integer.
+        if (maxFrequency < 0) {
+            maxFrequency = Integer.MAX_VALUE;
+        }
+        mFrequencyRange = new Range<>(minFrequency, maxFrequency);
+        mSymbolRateRange = new Range<>(minSymbolRate, maxSymbolRate);
+        mAcquireRange = acquireRange;
+        mExclusiveGroupId = exclusiveGroupId;
+        mStatusCaps = statusCaps;
+        mFrontendCap = frontendCap;
+    }
+
+    /**
+     * Gets frontend ID.
+     *
+     * @return the frontend ID or {@link android.media.tv.tuner.Tuner#INVALID_FRONTEND_ID}
+     *         if invalid
+     */
+    public int getId() {
+        return mId;
+    }
+    /**
+     * Gets frontend type.
+     */
+    @Type
+    public int getType() {
+        return mType;
+    }
+
+    /**
+     * Gets supported frequency range in Hz.
+     */
+    @NonNull
+    public Range<Integer> getFrequencyRange() {
+        return mFrequencyRange;
+    }
+
+    /**
+     * Gets symbol rate range in symbols per second.
+     */
+    @NonNull
+    public Range<Integer> getSymbolRateRange() {
+        return mSymbolRateRange;
+    }
+
+    /**
+     * Gets acquire range in Hz.
+     *
+     * <p>The maximum frequency difference the frontend can detect.
+     */
+    public int getAcquireRange() {
+        return mAcquireRange;
+    }
+    /**
+     * Gets exclusive group ID.
+     *
+     * <p>Frontends with the same exclusive group ID indicates they can't function at same time. For
+     * instance, they share some hardware modules.
+     */
+    public int getExclusiveGroupId() {
+        return mExclusiveGroupId;
+    }
+    /**
+     * Gets status capabilities.
+     *
+     * @return An array of supported status types.
+     */
+    @FrontendStatusType
+    @NonNull
+    public int[] getStatusCapabilities() {
+        return mStatusCaps;
+    }
+    /**
+     * Gets frontend capabilities.
+     */
+    @NonNull
+    public FrontendCapabilities getFrontendCapabilities() {
+        return mFrontendCap;
+    }
+
+
+    /** @hide */
+    @Override
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        }
+        if (o == null || !(o instanceof FrontendInfo)) {
+            return false;
+        }
+        // TODO: compare FrontendCapabilities
+        FrontendInfo info = (FrontendInfo) o;
+        return mId == info.getId() && mType == info.getType()
+                && Objects.equals(mFrequencyRange, info.getFrequencyRange())
+                && Objects.equals(mSymbolRateRange, info.getSymbolRateRange())
+                && mAcquireRange == info.getAcquireRange()
+                && mExclusiveGroupId == info.getExclusiveGroupId()
+                && Arrays.equals(mStatusCaps, info.getStatusCapabilities());
+    }
+
+    /** @hide */
+    @Override
+    public int hashCode() {
+        return mId;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/FrontendSettings.java b/android/media/tv/tuner/frontend/FrontendSettings.java
new file mode 100644
index 0000000..4bfe807
--- /dev/null
+++ b/android/media/tv/tuner/frontend/FrontendSettings.java
@@ -0,0 +1,357 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.LongDef;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.Tuner;
+import android.media.tv.tuner.TunerVersionChecker;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Frontend settings for tune and scan operations.
+ *
+ * @hide
+ */
+@SystemApi
+public abstract class FrontendSettings {
+    /** @hide */
+    @IntDef(prefix = "TYPE_",
+            value = {TYPE_UNDEFINED, TYPE_ANALOG, TYPE_ATSC, TYPE_ATSC3, TYPE_DVBC, TYPE_DVBS,
+                    TYPE_DVBT, TYPE_ISDBS, TYPE_ISDBS3, TYPE_ISDBT, TYPE_DTMB})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Type {}
+
+    /**
+     * Undefined frontend type.
+     */
+    public static final int TYPE_UNDEFINED = Constants.FrontendType.UNDEFINED;
+    /**
+     * Analog frontend type.
+     */
+    public static final int TYPE_ANALOG = Constants.FrontendType.ANALOG;
+    /**
+     * Advanced Television Systems Committee (ATSC) frontend type.
+     */
+    public static final int TYPE_ATSC = Constants.FrontendType.ATSC;
+    /**
+     * Advanced Television Systems Committee 3.0 (ATSC-3) frontend type.
+     */
+    public static final int TYPE_ATSC3 = Constants.FrontendType.ATSC3;
+    /**
+     * Digital Video Broadcasting-Cable (DVB-C) frontend type.
+     */
+    public static final int TYPE_DVBC = Constants.FrontendType.DVBC;
+    /**
+     * Digital Video Broadcasting-Satellite (DVB-S) frontend type.
+     */
+    public static final int TYPE_DVBS = Constants.FrontendType.DVBS;
+    /**
+     * Digital Video Broadcasting-Terrestrial (DVB-T) frontend type.
+     */
+    public static final int TYPE_DVBT = Constants.FrontendType.DVBT;
+    /**
+     * Integrated Services Digital Broadcasting-Satellite (ISDB-S) frontend type.
+     */
+    public static final int TYPE_ISDBS = Constants.FrontendType.ISDBS;
+    /**
+     * Integrated Services Digital Broadcasting-Satellite 3 (ISDB-S3) frontend type.
+     */
+    public static final int TYPE_ISDBS3 = Constants.FrontendType.ISDBS3;
+    /**
+     * Integrated Services Digital Broadcasting-Terrestrial (ISDB-T) frontend type.
+     */
+    public static final int TYPE_ISDBT = Constants.FrontendType.ISDBT;
+    /**
+     * Digital Terrestrial Multimedia Broadcast standard (DTMB) frontend type.
+     */
+    public static final int TYPE_DTMB = android.hardware.tv.tuner.V1_1.Constants.FrontendType.DTMB;
+
+
+    /** @hide */
+    @LongDef(flag = true,
+            prefix = "FEC_",
+            value = {FEC_UNDEFINED, FEC_AUTO, FEC_1_2, FEC_1_3, FEC_1_4, FEC_1_5, FEC_2_3, FEC_2_5,
+            FEC_2_9, FEC_3_4, FEC_3_5, FEC_4_5, FEC_4_15, FEC_5_6, FEC_5_9, FEC_6_7, FEC_7_8,
+            FEC_7_9, FEC_7_15, FEC_8_9, FEC_8_15, FEC_9_10, FEC_9_20, FEC_11_15, FEC_11_20,
+            FEC_11_45, FEC_13_18, FEC_13_45, FEC_14_45, FEC_23_36, FEC_25_36, FEC_26_45, FEC_28_45,
+            FEC_29_45, FEC_31_45, FEC_32_45, FEC_77_90})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface InnerFec {}
+
+    /**
+     * FEC not defined.
+     */
+    public static final long FEC_UNDEFINED = Constants.FrontendInnerFec.FEC_UNDEFINED;
+    /**
+     * hardware is able to detect and set FEC automatically.
+     */
+    public static final long FEC_AUTO = Constants.FrontendInnerFec.AUTO;
+    /**
+     * 1/2 conv. code rate.
+     */
+    public static final long FEC_1_2 = Constants.FrontendInnerFec.FEC_1_2;
+    /**
+     * 1/3 conv. code rate.
+     */
+    public static final long FEC_1_3 = Constants.FrontendInnerFec.FEC_1_3;
+    /**
+     * 1/4 conv. code rate.
+     */
+    public static final long FEC_1_4 = Constants.FrontendInnerFec.FEC_1_4;
+    /**
+     * 1/5 conv. code rate.
+     */
+    public static final long FEC_1_5 = Constants.FrontendInnerFec.FEC_1_5;
+    /**
+     * 2/3 conv. code rate.
+     */
+    public static final long FEC_2_3 = Constants.FrontendInnerFec.FEC_2_3;
+    /**
+     * 2/5 conv. code rate.
+     */
+    public static final long FEC_2_5 = Constants.FrontendInnerFec.FEC_2_5;
+    /**
+     * 2/9 conv. code rate.
+     */
+    public static final long FEC_2_9 = Constants.FrontendInnerFec.FEC_2_9;
+    /**
+     * 3/4 conv. code rate.
+     */
+    public static final long FEC_3_4 = Constants.FrontendInnerFec.FEC_3_4;
+    /**
+     * 3/5 conv. code rate.
+     */
+    public static final long FEC_3_5 = Constants.FrontendInnerFec.FEC_3_5;
+    /**
+     * 4/5 conv. code rate.
+     */
+    public static final long FEC_4_5 = Constants.FrontendInnerFec.FEC_4_5;
+    /**
+     * 4/15 conv. code rate.
+     */
+    public static final long FEC_4_15 = Constants.FrontendInnerFec.FEC_4_15;
+    /**
+     * 5/6 conv. code rate.
+     */
+    public static final long FEC_5_6 = Constants.FrontendInnerFec.FEC_5_6;
+    /**
+     * 5/9 conv. code rate.
+     */
+    public static final long FEC_5_9 = Constants.FrontendInnerFec.FEC_5_9;
+    /**
+     * 6/7 conv. code rate.
+     */
+    public static final long FEC_6_7 = Constants.FrontendInnerFec.FEC_6_7;
+    /**
+     * 7/8 conv. code rate.
+     */
+    public static final long FEC_7_8 = Constants.FrontendInnerFec.FEC_7_8;
+    /**
+     * 7/9 conv. code rate.
+     */
+    public static final long FEC_7_9 = Constants.FrontendInnerFec.FEC_7_9;
+    /**
+     * 7/15 conv. code rate.
+     */
+    public static final long FEC_7_15 = Constants.FrontendInnerFec.FEC_7_15;
+    /**
+     * 8/9 conv. code rate.
+     */
+    public static final long FEC_8_9 = Constants.FrontendInnerFec.FEC_8_9;
+    /**
+     * 8/15 conv. code rate.
+     */
+    public static final long FEC_8_15 = Constants.FrontendInnerFec.FEC_8_15;
+    /**
+     * 9/10 conv. code rate.
+     */
+    public static final long FEC_9_10 = Constants.FrontendInnerFec.FEC_9_10;
+    /**
+     * 9/20 conv. code rate.
+     */
+    public static final long FEC_9_20 = Constants.FrontendInnerFec.FEC_9_20;
+    /**
+     * 11/15 conv. code rate.
+     */
+    public static final long FEC_11_15 = Constants.FrontendInnerFec.FEC_11_15;
+    /**
+     * 11/20 conv. code rate.
+     */
+    public static final long FEC_11_20 = Constants.FrontendInnerFec.FEC_11_20;
+    /**
+     * 11/45 conv. code rate.
+     */
+    public static final long FEC_11_45 = Constants.FrontendInnerFec.FEC_11_45;
+    /**
+     * 13/18 conv. code rate.
+     */
+    public static final long FEC_13_18 = Constants.FrontendInnerFec.FEC_13_18;
+    /**
+     * 13/45 conv. code rate.
+     */
+    public static final long FEC_13_45 = Constants.FrontendInnerFec.FEC_13_45;
+    /**
+     * 14/45 conv. code rate.
+     */
+    public static final long FEC_14_45 = Constants.FrontendInnerFec.FEC_14_45;
+    /**
+     * 23/36 conv. code rate.
+     */
+    public static final long FEC_23_36 = Constants.FrontendInnerFec.FEC_23_36;
+    /**
+     * 25/36 conv. code rate.
+     */
+    public static final long FEC_25_36 = Constants.FrontendInnerFec.FEC_25_36;
+    /**
+     * 26/45 conv. code rate.
+     */
+    public static final long FEC_26_45 = Constants.FrontendInnerFec.FEC_26_45;
+    /**
+     * 28/45 conv. code rate.
+     */
+    public static final long FEC_28_45 = Constants.FrontendInnerFec.FEC_28_45;
+    /**
+     * 29/45 conv. code rate.
+     */
+    public static final long FEC_29_45 = Constants.FrontendInnerFec.FEC_29_45;
+    /**
+     * 31/45 conv. code rate.
+     */
+    public static final long FEC_31_45 = Constants.FrontendInnerFec.FEC_31_45;
+    /**
+     * 32/45 conv. code rate.
+     */
+    public static final long FEC_32_45 = Constants.FrontendInnerFec.FEC_32_45;
+    /**
+     * 77/90 conv. code rate.
+     */
+    public static final long FEC_77_90 = Constants.FrontendInnerFec.FEC_77_90;
+
+    /** @hide */
+    @IntDef(prefix = "FRONTEND_SPECTRAL_INVERSION_",
+            value = {FRONTEND_SPECTRAL_INVERSION_UNDEFINED, FRONTEND_SPECTRAL_INVERSION_NORMAL,
+                    FRONTEND_SPECTRAL_INVERSION_INVERTED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FrontendSpectralInversion {}
+
+    /**
+     * Spectral Inversion Type undefined.
+     */
+    public static final int FRONTEND_SPECTRAL_INVERSION_UNDEFINED =
+            Constants.FrontendDvbcSpectralInversion.UNDEFINED;
+    /**
+     * Normal Spectral Inversion.
+     */
+    public static final int FRONTEND_SPECTRAL_INVERSION_NORMAL =
+            Constants.FrontendDvbcSpectralInversion.NORMAL;
+    /**
+     * Inverted Spectral Inversion.
+     */
+    public static final int FRONTEND_SPECTRAL_INVERSION_INVERTED =
+            Constants.FrontendDvbcSpectralInversion.INVERTED;
+
+
+
+    private final int mFrequency;
+    // End frequency is only supported in Tuner 1.1 or higher.
+    private int mEndFrequency = Tuner.INVALID_FRONTEND_SETTING_FREQUENCY;
+    // General spectral inversion is only supported in Tuner 1.1 or higher.
+    private int mSpectralInversion = FRONTEND_SPECTRAL_INVERSION_UNDEFINED;
+
+    FrontendSettings(int frequency) {
+        mFrequency = frequency;
+    }
+
+    /**
+     * Returns the frontend type.
+     */
+    @Type
+    public abstract int getType();
+
+    /**
+     * Gets the frequency.
+     *
+     * @return the frequency in Hz.
+     */
+    public int getFrequency() {
+        return mFrequency;
+    }
+
+    /**
+     * Get the end frequency.
+     *
+     * @return the end frequency in Hz.
+     */
+    @IntRange(from = 1)
+    public int getEndFrequency() {
+        return mEndFrequency;
+    }
+
+    /**
+     * Get the spectral inversion.
+     *
+     * @return the value of the spectral inversion.
+     */
+    @FrontendSpectralInversion
+    public int getFrontendSpectralInversion() {
+        return mSpectralInversion;
+    }
+
+    /**
+     * Set Spectral Inversion.
+     *
+     * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would cause
+     * no-op. Use {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     *
+     * @param inversion the value to set as the spectral inversion. Default value is {@link
+     * #FRONTEND_SPECTRAL_INVERSION_UNDEFINED}.
+     */
+    public void setSpectralInversion(@FrontendSpectralInversion int inversion) {
+        if (TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "setSpectralInversion")) {
+            mSpectralInversion = inversion;
+        }
+    }
+
+    /**
+     * Set End Frequency. This API is only supported with Tuner HAL 1.1 or higher. Otherwise it
+     * would be no-op.
+     *
+     * <p>This API is only supported by Tuner HAL 1.1 or higher. Unsupported version would cause
+     * no-op. Use {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     *
+     * @param endFrequency the end frequency used during blind scan. The default value is
+     * {@link android.media.tv.tuner.Tuner#INVALID_FRONTEND_SETTING_FREQUENCY}.
+     * @throws IllegalArgumentException if the {@code endFrequency} is not greater than 0.
+     */
+    @IntRange(from = 1)
+    public void setEndFrequency(int endFrequency) {
+        if (TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "setEndFrequency")) {
+            if (endFrequency < 1) {
+                throw new IllegalArgumentException("endFrequency must be greater than 0");
+            }
+            mEndFrequency = endFrequency;
+        }
+    }
+}
diff --git a/android/media/tv/tuner/frontend/FrontendStatus.java b/android/media/tv/tuner/frontend/FrontendStatus.java
new file mode 100644
index 0000000..b82a5a9
--- /dev/null
+++ b/android/media/tv/tuner/frontend/FrontendStatus.java
@@ -0,0 +1,954 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.Lnb;
+import android.media.tv.tuner.TunerVersionChecker;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * A Frontend Status class that contains the metrics of the active frontend.
+ *
+ * @hide
+ */
+@SystemApi
+public class FrontendStatus {
+
+    /** @hide */
+    @IntDef({FRONTEND_STATUS_TYPE_DEMOD_LOCK, FRONTEND_STATUS_TYPE_SNR, FRONTEND_STATUS_TYPE_BER,
+            FRONTEND_STATUS_TYPE_PER, FRONTEND_STATUS_TYPE_PRE_BER,
+            FRONTEND_STATUS_TYPE_SIGNAL_QUALITY, FRONTEND_STATUS_TYPE_SIGNAL_STRENGTH,
+            FRONTEND_STATUS_TYPE_SYMBOL_RATE, FRONTEND_STATUS_TYPE_FEC,
+            FRONTEND_STATUS_TYPE_MODULATION, FRONTEND_STATUS_TYPE_SPECTRAL,
+            FRONTEND_STATUS_TYPE_LNB_VOLTAGE, FRONTEND_STATUS_TYPE_PLP_ID,
+            FRONTEND_STATUS_TYPE_EWBS, FRONTEND_STATUS_TYPE_AGC, FRONTEND_STATUS_TYPE_LNA,
+            FRONTEND_STATUS_TYPE_LAYER_ERROR, FRONTEND_STATUS_TYPE_MER,
+            FRONTEND_STATUS_TYPE_FREQ_OFFSET, FRONTEND_STATUS_TYPE_HIERARCHY,
+            FRONTEND_STATUS_TYPE_RF_LOCK, FRONTEND_STATUS_TYPE_ATSC3_PLP_INFO,
+            FRONTEND_STATUS_TYPE_BERS, FRONTEND_STATUS_TYPE_CODERATES,
+            FRONTEND_STATUS_TYPE_BANDWIDTH, FRONTEND_STATUS_TYPE_GUARD_INTERVAL,
+            FRONTEND_STATUS_TYPE_TRANSMISSION_MODE, FRONTEND_STATUS_TYPE_UEC,
+            FRONTEND_STATUS_TYPE_T2_SYSTEM_ID, FRONTEND_STATUS_TYPE_INTERLEAVINGS,
+            FRONTEND_STATUS_TYPE_ISDBT_SEGMENTS, FRONTEND_STATUS_TYPE_TS_DATA_RATES,
+            FRONTEND_STATUS_TYPE_MODULATIONS_EXT, FRONTEND_STATUS_TYPE_ROLL_OFF,
+            FRONTEND_STATUS_TYPE_IS_MISO_ENABLED, FRONTEND_STATUS_TYPE_IS_LINEAR,
+            FRONTEND_STATUS_TYPE_IS_SHORT_FRAMES_ENABLED})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FrontendStatusType {}
+
+    /**
+     * Lock status for Demod.
+     */
+    public static final int FRONTEND_STATUS_TYPE_DEMOD_LOCK =
+            Constants.FrontendStatusType.DEMOD_LOCK;
+    /**
+     * Signal to Noise Ratio.
+     */
+    public static final int FRONTEND_STATUS_TYPE_SNR = Constants.FrontendStatusType.SNR;
+    /**
+     * Bit Error Ratio.
+     */
+    public static final int FRONTEND_STATUS_TYPE_BER = Constants.FrontendStatusType.BER;
+    /**
+     * Packages Error Ratio.
+     */
+    public static final int FRONTEND_STATUS_TYPE_PER = Constants.FrontendStatusType.PER;
+    /**
+     * Bit Error Ratio before FEC.
+     */
+    public static final int FRONTEND_STATUS_TYPE_PRE_BER = Constants.FrontendStatusType.PRE_BER;
+    /**
+     * Signal Quality (0..100). Good data over total data in percent can be
+     * used as a way to present Signal Quality.
+     */
+    public static final int FRONTEND_STATUS_TYPE_SIGNAL_QUALITY =
+            Constants.FrontendStatusType.SIGNAL_QUALITY;
+    /**
+     * Signal Strength.
+     */
+    public static final int FRONTEND_STATUS_TYPE_SIGNAL_STRENGTH =
+            Constants.FrontendStatusType.SIGNAL_STRENGTH;
+    /**
+     * Symbol Rate in symbols per second.
+     */
+    public static final int FRONTEND_STATUS_TYPE_SYMBOL_RATE =
+            Constants.FrontendStatusType.SYMBOL_RATE;
+    /**
+     * Forward Error Correction Type.
+     */
+    public static final int FRONTEND_STATUS_TYPE_FEC = Constants.FrontendStatusType.FEC;
+    /**
+     * Modulation Type.
+     */
+    public static final int FRONTEND_STATUS_TYPE_MODULATION =
+            Constants.FrontendStatusType.MODULATION;
+    /**
+     * Spectral Inversion Type.
+     */
+    public static final int FRONTEND_STATUS_TYPE_SPECTRAL = Constants.FrontendStatusType.SPECTRAL;
+    /**
+     * LNB Voltage.
+     */
+    public static final int FRONTEND_STATUS_TYPE_LNB_VOLTAGE =
+            Constants.FrontendStatusType.LNB_VOLTAGE;
+    /**
+     * Physical Layer Pipe ID.
+     */
+    public static final int FRONTEND_STATUS_TYPE_PLP_ID = Constants.FrontendStatusType.PLP_ID;
+    /**
+     * Status for Emergency Warning Broadcasting System.
+     */
+    public static final int FRONTEND_STATUS_TYPE_EWBS = Constants.FrontendStatusType.EWBS;
+    /**
+     * Automatic Gain Control.
+     */
+    public static final int FRONTEND_STATUS_TYPE_AGC = Constants.FrontendStatusType.AGC;
+    /**
+     * Low Noise Amplifier.
+     */
+    public static final int FRONTEND_STATUS_TYPE_LNA = Constants.FrontendStatusType.LNA;
+    /**
+     * Error status by layer.
+     */
+    public static final int FRONTEND_STATUS_TYPE_LAYER_ERROR =
+            Constants.FrontendStatusType.LAYER_ERROR;
+    /**
+     * Modulation Error Ratio.
+     */
+    public static final int FRONTEND_STATUS_TYPE_MER = Constants.FrontendStatusType.MER;
+    /**
+     * Difference between tuning frequency and actual locked frequency.
+     */
+    public static final int FRONTEND_STATUS_TYPE_FREQ_OFFSET =
+            Constants.FrontendStatusType.FREQ_OFFSET;
+    /**
+     * Hierarchy for DVBT.
+     */
+    public static final int FRONTEND_STATUS_TYPE_HIERARCHY = Constants.FrontendStatusType.HIERARCHY;
+    /**
+     * Lock status for RF.
+     */
+    public static final int FRONTEND_STATUS_TYPE_RF_LOCK = Constants.FrontendStatusType.RF_LOCK;
+    /**
+     * PLP information in a frequency band for ATSC-3.0 frontend.
+     */
+    public static final int FRONTEND_STATUS_TYPE_ATSC3_PLP_INFO =
+            Constants.FrontendStatusType.ATSC3_PLP_INFO;
+    /**
+     * BERS Type. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_BERS =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.BERS;
+    /**
+     * Coderate Type. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_CODERATES =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.CODERATES;
+    /**
+     * Bandwidth Type. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_BANDWIDTH =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.BANDWIDTH;
+    /**
+     * Guard Interval Type. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_GUARD_INTERVAL =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.GUARD_INTERVAL;
+    /**
+     * Transmission Mode Type. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_TRANSMISSION_MODE =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.TRANSMISSION_MODE;
+    /**
+     * UEC Type. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_UEC =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.UEC;
+    /**
+     * T2 System Id Type. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_T2_SYSTEM_ID =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.T2_SYSTEM_ID;
+    /**
+     * Interleavings Type. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_INTERLEAVINGS =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.INTERLEAVINGS;
+    /**
+     * ISDBT Segments Type. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_ISDBT_SEGMENTS =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.ISDBT_SEGMENTS;
+    /**
+     * TS Data Rates Type. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_TS_DATA_RATES =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.TS_DATA_RATES;
+    /**
+     * Extended Modulations Type. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_MODULATIONS_EXT =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.MODULATIONS;
+    /**
+     * Roll Off Type status of the frontend. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_ROLL_OFF =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.ROLL_OFF;
+    /**
+     * If the frontend currently supports MISO or not. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_IS_MISO_ENABLED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.IS_MISO;
+    /**
+     * If the frontend code rate is linear or not. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_IS_LINEAR =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.IS_LINEAR;
+    /**
+     * If short frames is enabled or not. Only supported in Tuner HAL 1.1 or higher.
+     */
+    public static final int FRONTEND_STATUS_TYPE_IS_SHORT_FRAMES_ENABLED =
+            android.hardware.tv.tuner.V1_1.Constants.FrontendStatusTypeExt1_1.IS_SHORT_FRAMES;
+
+    /** @hide */
+    @IntDef(value = {
+            AtscFrontendSettings.MODULATION_UNDEFINED,
+            AtscFrontendSettings.MODULATION_AUTO,
+            AtscFrontendSettings.MODULATION_MOD_8VSB,
+            AtscFrontendSettings.MODULATION_MOD_16VSB,
+            Atsc3FrontendSettings.MODULATION_UNDEFINED,
+            Atsc3FrontendSettings.MODULATION_AUTO,
+            Atsc3FrontendSettings.MODULATION_MOD_QPSK,
+            Atsc3FrontendSettings.MODULATION_MOD_16QAM,
+            Atsc3FrontendSettings.MODULATION_MOD_64QAM,
+            Atsc3FrontendSettings.MODULATION_MOD_256QAM,
+            Atsc3FrontendSettings.MODULATION_MOD_1024QAM,
+            Atsc3FrontendSettings.MODULATION_MOD_4096QAM,
+            DtmbFrontendSettings.MODULATION_CONSTELLATION_UNDEFINED,
+            DtmbFrontendSettings.MODULATION_CONSTELLATION_AUTO,
+            DtmbFrontendSettings.MODULATION_CONSTELLATION_4QAM,
+            DtmbFrontendSettings.MODULATION_CONSTELLATION_4QAM_NR,
+            DtmbFrontendSettings.MODULATION_CONSTELLATION_16QAM,
+            DtmbFrontendSettings.MODULATION_CONSTELLATION_32QAM,
+            DtmbFrontendSettings.MODULATION_CONSTELLATION_64QAM,
+            DvbcFrontendSettings.MODULATION_UNDEFINED,
+            DvbcFrontendSettings.MODULATION_AUTO,
+            DvbcFrontendSettings.MODULATION_MOD_16QAM,
+            DvbcFrontendSettings.MODULATION_MOD_32QAM,
+            DvbcFrontendSettings.MODULATION_MOD_64QAM,
+            DvbcFrontendSettings.MODULATION_MOD_128QAM,
+            DvbcFrontendSettings.MODULATION_MOD_256QAM,
+            DvbsFrontendSettings.MODULATION_UNDEFINED,
+            DvbsFrontendSettings.MODULATION_AUTO,
+            DvbsFrontendSettings.MODULATION_MOD_QPSK,
+            DvbsFrontendSettings.MODULATION_MOD_8PSK,
+            DvbsFrontendSettings.MODULATION_MOD_16QAM,
+            DvbsFrontendSettings.MODULATION_MOD_16PSK,
+            DvbsFrontendSettings.MODULATION_MOD_32PSK,
+            DvbsFrontendSettings.MODULATION_MOD_ACM,
+            DvbsFrontendSettings.MODULATION_MOD_8APSK,
+            DvbsFrontendSettings.MODULATION_MOD_16APSK,
+            DvbsFrontendSettings.MODULATION_MOD_32APSK,
+            DvbsFrontendSettings.MODULATION_MOD_64APSK,
+            DvbsFrontendSettings.MODULATION_MOD_128APSK,
+            DvbsFrontendSettings.MODULATION_MOD_256APSK,
+            DvbsFrontendSettings.MODULATION_MOD_RESERVED,
+            DvbtFrontendSettings.CONSTELLATION_UNDEFINED,
+            DvbtFrontendSettings.CONSTELLATION_AUTO,
+            DvbtFrontendSettings.CONSTELLATION_QPSK,
+            DvbtFrontendSettings.CONSTELLATION_16QAM,
+            DvbtFrontendSettings.CONSTELLATION_64QAM,
+            DvbtFrontendSettings.CONSTELLATION_256QAM,
+            DvbtFrontendSettings.CONSTELLATION_QPSK_R,
+            DvbtFrontendSettings.CONSTELLATION_16QAM_R,
+            DvbtFrontendSettings.CONSTELLATION_64QAM_R,
+            DvbtFrontendSettings.CONSTELLATION_256QAM_R,
+            IsdbsFrontendSettings.MODULATION_UNDEFINED,
+            IsdbsFrontendSettings.MODULATION_AUTO,
+            IsdbsFrontendSettings.MODULATION_MOD_BPSK,
+            IsdbsFrontendSettings.MODULATION_MOD_QPSK,
+            IsdbsFrontendSettings.MODULATION_MOD_TC8PSK,
+            Isdbs3FrontendSettings.MODULATION_UNDEFINED,
+            Isdbs3FrontendSettings.MODULATION_AUTO,
+            Isdbs3FrontendSettings.MODULATION_MOD_BPSK,
+            Isdbs3FrontendSettings.MODULATION_MOD_QPSK,
+            Isdbs3FrontendSettings.MODULATION_MOD_8PSK,
+            Isdbs3FrontendSettings.MODULATION_MOD_16APSK,
+            Isdbs3FrontendSettings.MODULATION_MOD_32APSK,
+            IsdbtFrontendSettings.MODULATION_UNDEFINED,
+            IsdbtFrontendSettings.MODULATION_AUTO,
+            IsdbtFrontendSettings.MODULATION_MOD_DQPSK,
+            IsdbtFrontendSettings.MODULATION_MOD_QPSK,
+            IsdbtFrontendSettings.MODULATION_MOD_16QAM,
+            IsdbtFrontendSettings.MODULATION_MOD_64QAM})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FrontendModulation {}
+
+    /** @hide */
+    @IntDef(value = {
+            Atsc3FrontendSettings.TIME_INTERLEAVE_MODE_UNDEFINED,
+            Atsc3FrontendSettings.TIME_INTERLEAVE_MODE_AUTO,
+            Atsc3FrontendSettings.TIME_INTERLEAVE_MODE_CTI,
+            Atsc3FrontendSettings.TIME_INTERLEAVE_MODE_HTI,
+            DtmbFrontendSettings.TIME_INTERLEAVE_MODE_UNDEFINED,
+            DtmbFrontendSettings.TIME_INTERLEAVE_MODE_AUTO,
+            DtmbFrontendSettings.TIME_INTERLEAVE_MODE_TIMER_INT_240,
+            DtmbFrontendSettings.TIME_INTERLEAVE_MODE_TIMER_INT_720,
+            DvbcFrontendSettings.TIME_INTERLEAVE_MODE_UNDEFINED,
+            DvbcFrontendSettings.TIME_INTERLEAVE_MODE_AUTO,
+            DvbcFrontendSettings.TIME_INTERLEAVE_MODE_128_1_0,
+            DvbcFrontendSettings.TIME_INTERLEAVE_MODE_128_1_1,
+            DvbcFrontendSettings.TIME_INTERLEAVE_MODE_64_2,
+            DvbcFrontendSettings.TIME_INTERLEAVE_MODE_32_4,
+            DvbcFrontendSettings.TIME_INTERLEAVE_MODE_16_8,
+            DvbcFrontendSettings.TIME_INTERLEAVE_MODE_8_16,
+            DvbcFrontendSettings.TIME_INTERLEAVE_MODE_128_2,
+            DvbcFrontendSettings.TIME_INTERLEAVE_MODE_128_3,
+            DvbcFrontendSettings.TIME_INTERLEAVE_MODE_128_4})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FrontendInterleaveMode {}
+
+    /** @hide */
+    @IntDef(value = {
+            Atsc3FrontendSettings.BANDWIDTH_UNDEFINED,
+            Atsc3FrontendSettings.BANDWIDTH_AUTO,
+            Atsc3FrontendSettings.BANDWIDTH_BANDWIDTH_6MHZ,
+            Atsc3FrontendSettings.BANDWIDTH_BANDWIDTH_7MHZ,
+            Atsc3FrontendSettings.BANDWIDTH_BANDWIDTH_8MHZ,
+            DtmbFrontendSettings.BANDWIDTH_UNDEFINED,
+            DtmbFrontendSettings.BANDWIDTH_AUTO,
+            DtmbFrontendSettings.BANDWIDTH_6MHZ,
+            DtmbFrontendSettings.BANDWIDTH_8MHZ,
+            DvbtFrontendSettings.BANDWIDTH_UNDEFINED,
+            DvbtFrontendSettings.BANDWIDTH_AUTO,
+            DvbtFrontendSettings.BANDWIDTH_8MHZ,
+            DvbtFrontendSettings.BANDWIDTH_7MHZ,
+            DvbtFrontendSettings.BANDWIDTH_6MHZ,
+            DvbtFrontendSettings.BANDWIDTH_5MHZ,
+            DvbtFrontendSettings.BANDWIDTH_1_7MHZ,
+            DvbtFrontendSettings.BANDWIDTH_10MHZ,
+            IsdbtFrontendSettings.BANDWIDTH_UNDEFINED,
+            IsdbtFrontendSettings.BANDWIDTH_AUTO,
+            IsdbtFrontendSettings.BANDWIDTH_8MHZ,
+            IsdbtFrontendSettings.BANDWIDTH_7MHZ,
+            IsdbtFrontendSettings.BANDWIDTH_6MHZ})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FrontendBandwidth {}
+
+    /** @hide */
+    @IntDef(value = {
+            DtmbFrontendSettings.TRANSMISSION_MODE_UNDEFINED,
+            DtmbFrontendSettings.TRANSMISSION_MODE_AUTO,
+            DtmbFrontendSettings.TRANSMISSION_MODE_C1,
+            DtmbFrontendSettings.TRANSMISSION_MODE_C3780,
+            DvbtFrontendSettings.TRANSMISSION_MODE_UNDEFINED,
+            DvbtFrontendSettings.TRANSMISSION_MODE_AUTO,
+            DvbtFrontendSettings.TRANSMISSION_MODE_2K,
+            DvbtFrontendSettings.TRANSMISSION_MODE_8K,
+            DvbtFrontendSettings.TRANSMISSION_MODE_4K,
+            DvbtFrontendSettings.TRANSMISSION_MODE_1K,
+            DvbtFrontendSettings.TRANSMISSION_MODE_16K,
+            DvbtFrontendSettings.TRANSMISSION_MODE_32K,
+            IsdbtFrontendSettings.MODE_UNDEFINED,
+            IsdbtFrontendSettings.MODE_AUTO,
+            IsdbtFrontendSettings.MODE_1,
+            IsdbtFrontendSettings.MODE_2,
+            IsdbtFrontendSettings.MODE_3})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FrontendTransmissionMode {}
+
+    /** @hide */
+    @IntDef(value = {
+            DtmbFrontendSettings.GUARD_INTERVAL_UNDEFINED,
+            DtmbFrontendSettings.GUARD_INTERVAL_AUTO,
+            DtmbFrontendSettings.GUARD_INTERVAL_PN_420_VARIOUS,
+            DtmbFrontendSettings.GUARD_INTERVAL_PN_595_CONST,
+            DtmbFrontendSettings.GUARD_INTERVAL_PN_945_VARIOUS,
+            DtmbFrontendSettings.GUARD_INTERVAL_PN_420_CONST,
+            DtmbFrontendSettings.GUARD_INTERVAL_PN_945_CONST,
+            DtmbFrontendSettings.GUARD_INTERVAL_PN_RESERVED,
+            DvbtFrontendSettings.GUARD_INTERVAL_UNDEFINED,
+            DvbtFrontendSettings.GUARD_INTERVAL_AUTO,
+            DvbtFrontendSettings.GUARD_INTERVAL_1_32,
+            DvbtFrontendSettings.GUARD_INTERVAL_1_16,
+            DvbtFrontendSettings.GUARD_INTERVAL_1_8,
+            DvbtFrontendSettings.GUARD_INTERVAL_1_4,
+            DvbtFrontendSettings.GUARD_INTERVAL_1_128,
+            DvbtFrontendSettings.GUARD_INTERVAL_19_128,
+            DvbtFrontendSettings.GUARD_INTERVAL_19_256,
+            DvbtFrontendSettings.GUARD_INTERVAL_19_128})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FrontendGuardInterval {}
+
+    /** @hide */
+    @IntDef(value = {
+            DvbsFrontendSettings.ROLLOFF_UNDEFINED,
+            DvbsFrontendSettings.ROLLOFF_0_35,
+            DvbsFrontendSettings.ROLLOFF_0_25,
+            DvbsFrontendSettings.ROLLOFF_0_20,
+            DvbsFrontendSettings.ROLLOFF_0_15,
+            DvbsFrontendSettings.ROLLOFF_0_10,
+            DvbsFrontendSettings.ROLLOFF_0_5,
+            Isdbs3FrontendSettings.ROLLOFF_UNDEFINED,
+            Isdbs3FrontendSettings.ROLLOFF_0_03,
+            IsdbsFrontendSettings.ROLLOFF_UNDEFINED,
+            IsdbsFrontendSettings.ROLLOFF_0_35})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FrontendRollOff {}
+
+    private Boolean mIsDemodLocked;
+    private Integer mSnr;
+    private Integer mBer;
+    private Integer mPer;
+    private Integer mPerBer;
+    private Integer mSignalQuality;
+    private Integer mSignalStrength;
+    private Integer mSymbolRate;
+    private Long mInnerFec;
+    private Integer mModulation;
+    private Integer mInversion;
+    private Integer mLnbVoltage;
+    private Integer mPlpId;
+    private Boolean mIsEwbs;
+    private Integer mAgc;
+    private Boolean mIsLnaOn;
+    private boolean[] mIsLayerErrors;
+    private Integer mMer;
+    private Integer mFreqOffset;
+    private Integer mHierarchy;
+    private Boolean mIsRfLocked;
+    private Atsc3PlpTuningInfo[] mPlpInfo;
+    private int[] mBers;
+    private int[] mCodeRates;
+    private Integer mBandwidth;
+    private Integer mGuardInterval;
+    private Integer mTransmissionMode;
+    private Integer mUec;
+    private Integer mSystemId;
+    private int[] mInterleaving;
+    private int[] mTsDataRate;
+    private int[] mIsdbtSegment;
+    private int[] mModulationsExt;
+    private Integer mRollOff;
+    private Boolean mIsMisoEnabled;
+    private Boolean mIsLinear;
+    private Boolean mIsShortFrames;
+
+
+    // Constructed and fields set by JNI code.
+    private FrontendStatus() {
+    }
+
+    /**
+     * Gets if the demod is currently locked or not.
+     */
+    public boolean isDemodLocked() {
+        if (mIsDemodLocked == null) {
+            throw new IllegalStateException("DemodLocked status is empty");
+        }
+        return mIsDemodLocked;
+    }
+    /**
+     * Gets the current Signal to Noise Ratio in thousandths of a deciBel (0.001dB).
+     */
+    public int getSnr() {
+        if (mSnr == null) {
+            throw new IllegalStateException("Snr status is empty");
+        }
+        return mSnr;
+    }
+    /**
+     * Gets the current Bit Error Ratio.
+     *
+     * <p>The number of error bit per 1 billion bits.
+     */
+    public int getBer() {
+        if (mBer == null) {
+            throw new IllegalStateException("Ber status is empty");
+        }
+        return mBer;
+    }
+
+    /**
+     * Gets the current Packages Error Ratio.
+     *
+     * <p>The number of error package per 1 billion packages.
+     */
+    public int getPer() {
+        if (mPer == null) {
+            throw new IllegalStateException("Per status is empty");
+        }
+        return mPer;
+    }
+    /**
+     * Gets the current Bit Error Ratio before Forward Error Correction (FEC).
+     *
+     * <p>The number of error bit per 1 billion bits before FEC.
+     */
+    public int getPerBer() {
+        if (mPerBer == null) {
+            throw new IllegalStateException("PerBer status is empty");
+        }
+        return mPerBer;
+    }
+    /**
+     * Gets the current Signal Quality in percent.
+     */
+    public int getSignalQuality() {
+        if (mSignalQuality == null) {
+            throw new IllegalStateException("SignalQuality status is empty");
+        }
+        return mSignalQuality;
+    }
+    /**
+     * Gets the current Signal Strength in thousandths of a dBm (0.001dBm).
+     */
+    public int getSignalStrength() {
+        if (mSignalStrength == null) {
+            throw new IllegalStateException("SignalStrength status is empty");
+        }
+        return mSignalStrength;
+    }
+    /**
+     * Gets the current symbol rate in symbols per second.
+     */
+    public int getSymbolRate() {
+        if (mSymbolRate == null) {
+            throw new IllegalStateException("SymbolRate status is empty");
+        }
+        return mSymbolRate;
+    }
+    /**
+     *  Gets the current Inner Forward Error Correction type as specified in ETSI EN 300 468 V1.15.1
+     *  and ETSI EN 302 307-2 V1.1.1.
+     */
+    @FrontendSettings.InnerFec
+    public long getInnerFec() {
+        if (mInnerFec == null) {
+            throw new IllegalStateException("InnerFec status is empty");
+        }
+        return mInnerFec;
+    }
+    /**
+     * Gets the currently modulation information.
+     */
+    @FrontendModulation
+    public int getModulation() {
+        if (mModulation == null) {
+            throw new IllegalStateException("Modulation status is empty");
+        }
+        return mModulation;
+    }
+    /**
+     * Gets the currently Spectral Inversion information for DVBC.
+     */
+    @FrontendSettings.FrontendSpectralInversion
+    public int getSpectralInversion() {
+        if (mInversion == null) {
+            throw new IllegalStateException("SpectralInversion status is empty");
+        }
+        return mInversion;
+    }
+    /**
+     * Gets the current Power Voltage Type for LNB.
+     */
+    @Lnb.Voltage
+    public int getLnbVoltage() {
+        if (mLnbVoltage == null) {
+            throw new IllegalStateException("LnbVoltage status is empty");
+        }
+        return mLnbVoltage;
+    }
+    /**
+     * Gets the current Physical Layer Pipe ID.
+     */
+    public int getPlpId() {
+        if (mPlpId == null) {
+            throw new IllegalStateException("PlpId status is empty");
+        }
+        return mPlpId;
+    }
+    /**
+     * Checks whether it's Emergency Warning Broadcasting System
+     */
+    public boolean isEwbs() {
+        if (mIsEwbs == null) {
+            throw new IllegalStateException("Ewbs status is empty");
+        }
+        return mIsEwbs;
+    }
+    /**
+     * Gets the current Automatic Gain Control value which is normalized from 0 to 255.
+     */
+    public int getAgc() {
+        if (mAgc == null) {
+            throw new IllegalStateException("Agc status is empty");
+        }
+        return mAgc;
+    }
+    /**
+     * Checks LNA (Low Noise Amplifier) is on or not.
+     */
+    public boolean isLnaOn() {
+        if (mIsLnaOn == null) {
+            throw new IllegalStateException("LnaOn status is empty");
+        }
+        return mIsLnaOn;
+    }
+    /**
+     * Gets the current Error information by layer.
+     */
+    @NonNull
+    public boolean[] getLayerErrors() {
+        if (mIsLayerErrors == null) {
+            throw new IllegalStateException("LayerErrors status is empty");
+        }
+        return mIsLayerErrors;
+    }
+    /**
+     * Gets the current Modulation Error Ratio in thousandths of a deciBel (0.001dB).
+     */
+    public int getMer() {
+        if (mMer == null) {
+            throw new IllegalStateException("Mer status is empty");
+        }
+        return mMer;
+    }
+    /**
+     * Gets the current frequency difference in Hz.
+     *
+     * <p>Difference between tuning frequency and actual locked frequency.
+     */
+    public int getFreqOffset() {
+        if (mFreqOffset == null) {
+            throw new IllegalStateException("FreqOffset status is empty");
+        }
+        return mFreqOffset;
+    }
+    /**
+     * Gets the current hierarchy Type for DVBT.
+     */
+    @DvbtFrontendSettings.Hierarchy
+    public int getHierarchy() {
+        if (mHierarchy == null) {
+            throw new IllegalStateException("Hierarchy status is empty");
+        }
+        return mHierarchy;
+    }
+    /**
+     * Gets if the RF is locked or not.
+     */
+    public boolean isRfLocked() {
+        if (mIsRfLocked == null) {
+            throw new IllegalStateException("isRfLocked status is empty");
+        }
+        return mIsRfLocked;
+    }
+    /**
+     * Gets an array of the current tuned PLPs information of ATSC3 frontend.
+     */
+    @NonNull
+    public Atsc3PlpTuningInfo[] getAtsc3PlpTuningInfo() {
+        if (mPlpInfo == null) {
+            throw new IllegalStateException("Atsc3PlpTuningInfo status is empty");
+        }
+        return mPlpInfo;
+    }
+
+    /**
+     * Gets an array of the current extended bit error ratio.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    @NonNull
+    public int[] getBers() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "getBers status");
+        if (mBers == null) {
+            throw new IllegalStateException("Bers status is empty");
+        }
+        return mBers;
+    }
+
+    /**
+     * Gets an array of the current code rates.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    @NonNull
+    @FrontendSettings.InnerFec
+    public int[] getCodeRates() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "getCodeRates status");
+        if (mCodeRates == null) {
+            throw new IllegalStateException("CodeRates status is empty");
+        }
+        return mCodeRates;
+    }
+
+    /**
+     * Gets the current bandwidth information.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    @FrontendBandwidth
+    public int getBandwidth() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "getBandwidth status");
+        if (mBandwidth == null) {
+            throw new IllegalStateException("Bandwidth status is empty");
+        }
+        return mBandwidth;
+    }
+
+    /**
+     * Gets the current guard interval information.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    @FrontendGuardInterval
+    public int getGuardInterval() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "getGuardInterval status");
+        if (mGuardInterval == null) {
+            throw new IllegalStateException("GuardInterval status is empty");
+        }
+        return mGuardInterval;
+    }
+
+    /**
+     * Gets the current transmission mode information.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    @FrontendTransmissionMode
+    public int getTransmissionMode() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "getTransmissionMode status");
+        if (mTransmissionMode == null) {
+            throw new IllegalStateException("TransmissionMode status is empty");
+        }
+        return mTransmissionMode;
+    }
+
+    /**
+     * Gets the current Uncorrectable Error Counts of the frontend's Physical Layer Pipe (PLP)
+     * since the last tune operation.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    public int getUec() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "getUec status");
+        if (mUec == null) {
+            throw new IllegalStateException("Uec status is empty");
+        }
+        return mUec;
+    }
+
+    /**
+     * Gets the current DVB-T2 system id.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    @IntRange(from = 0, to = 0xffff)
+    public int getSystemId() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "getSystemId status");
+        if (mSystemId == null) {
+            throw new IllegalStateException("SystemId status is empty");
+        }
+        return mSystemId;
+    }
+
+    /**
+     * Gets an array of the current interleaving mode information.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    @NonNull
+    @FrontendInterleaveMode
+    public int[] getInterleaving() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "getInterleaving status");
+        if (mInterleaving == null) {
+            throw new IllegalStateException("Interleaving status is empty");
+        }
+        return mInterleaving;
+    }
+
+    /**
+     * Gets an array of the current segments information in ISDB-T Specification of all the
+     * channels.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    @NonNull
+    @IntRange(from = 0, to = 0xff)
+    public int[] getIsdbtSegment() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "getIsdbtSegment status");
+        if (mIsdbtSegment == null) {
+            throw new IllegalStateException("IsdbtSegment status is empty");
+        }
+        return mIsdbtSegment;
+    }
+
+    /**
+     * Gets an array of the Transport Stream Data Rate in BPS of the current channel.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    @NonNull
+    public int[] getTsDataRate() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "getTsDataRate status");
+        if (mTsDataRate == null) {
+            throw new IllegalStateException("TsDataRate status is empty");
+        }
+        return mTsDataRate;
+    }
+
+    /**
+     * Gets an array of the current extended modulations information.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    @NonNull
+    @FrontendModulation
+    public int[] getExtendedModulations() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "getExtendedModulations status");
+        if (mModulationsExt == null) {
+            throw new IllegalStateException("ExtendedModulations status is empty");
+        }
+        return mModulationsExt;
+    }
+
+    /**
+     * Gets the current roll off information.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    @FrontendRollOff
+    public int getRollOff() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "getRollOff status");
+        if (mRollOff == null) {
+            throw new IllegalStateException("RollOff status is empty");
+        }
+        return mRollOff;
+    }
+
+    /**
+     * Gets is MISO enabled or not.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    public boolean isMisoEnabled() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "isMisoEnabled status");
+        if (mIsMisoEnabled == null) {
+            throw new IllegalStateException("isMisoEnabled status is empty");
+        }
+        return mIsMisoEnabled;
+    }
+
+    /**
+     * Gets is the Code Rate of the frontend is linear or not.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    public boolean isLinear() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "isLinear status");
+        if (mIsLinear == null) {
+            throw new IllegalStateException("isLinear status is empty");
+        }
+        return mIsLinear;
+    }
+
+    /**
+     * Gets is the Short Frames enabled or not.
+     *
+     * <p>This query is only supported by Tuner HAL 1.1 or higher. Use
+     * {@link TunerVersionChecker#getTunerVersion()} to check the version.
+     */
+    public boolean isShortFramesEnabled() {
+        TunerVersionChecker.checkHigherOrEqualVersionTo(
+                TunerVersionChecker.TUNER_VERSION_1_1, "isShortFramesEnabled status");
+        if (mIsShortFrames == null) {
+            throw new IllegalStateException("isShortFramesEnabled status is empty");
+        }
+        return mIsShortFrames;
+    }
+
+    /**
+     * Information of each tuning Physical Layer Pipes.
+     */
+    public static class Atsc3PlpTuningInfo {
+        private final int mPlpId;
+        private final boolean mIsLocked;
+        private final int mUec;
+
+        private Atsc3PlpTuningInfo(int plpId, boolean isLocked, int uec) {
+            mPlpId = plpId;
+            mIsLocked = isLocked;
+            mUec = uec;
+        }
+
+        /**
+         * Gets Physical Layer Pipe ID.
+         */
+        public int getPlpId() {
+            return mPlpId;
+        }
+        /**
+         * Gets Demod Lock/Unlock status of this particular PLP.
+         */
+        public boolean isLocked() {
+            return mIsLocked;
+        }
+        /**
+         * Gets Uncorrectable Error Counts (UEC) of this particular PLP since last tune operation.
+         */
+        public int getUec() {
+            return mUec;
+        }
+    }
+}
diff --git a/android/media/tv/tuner/frontend/Isdbs3FrontendCapabilities.java b/android/media/tv/tuner/frontend/Isdbs3FrontendCapabilities.java
new file mode 100644
index 0000000..573f379
--- /dev/null
+++ b/android/media/tv/tuner/frontend/Isdbs3FrontendCapabilities.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/**
+ * ISDBS-3 Capabilities.
+ *
+ * @hide
+ */
+@SystemApi
+public class Isdbs3FrontendCapabilities extends FrontendCapabilities {
+    private final int mModulationCap;
+    private final int mCodeRateCap;
+
+    private Isdbs3FrontendCapabilities(int modulationCap, int codeRateCap) {
+        mModulationCap = modulationCap;
+        mCodeRateCap = codeRateCap;
+    }
+
+    /**
+     * Gets modulation capability.
+     */
+    @Isdbs3FrontendSettings.Modulation
+    public int getModulationCapability() {
+        return mModulationCap;
+    }
+    /**
+     * Gets code rate capability.
+     */
+    @Isdbs3FrontendSettings.CodeRate
+    public int getCodeRateCapability() {
+        return mCodeRateCap;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/Isdbs3FrontendSettings.java b/android/media/tv/tuner/frontend/Isdbs3FrontendSettings.java
new file mode 100644
index 0000000..02cdb96
--- /dev/null
+++ b/android/media/tv/tuner/frontend/Isdbs3FrontendSettings.java
@@ -0,0 +1,321 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.Tuner;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Frontend settings for ISDBS-3.
+ *
+ * @hide
+ */
+@SystemApi
+public class Isdbs3FrontendSettings extends FrontendSettings {
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "MODULATION_",
+            value = {MODULATION_UNDEFINED, MODULATION_AUTO, MODULATION_MOD_BPSK,
+            MODULATION_MOD_QPSK, MODULATION_MOD_8PSK, MODULATION_MOD_16APSK,
+            MODULATION_MOD_32APSK})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Modulation {}
+
+    /**
+     * Modulation undefined.
+     */
+    public static final int MODULATION_UNDEFINED = Constants.FrontendIsdbs3Modulation.UNDEFINED;
+    /**
+     * Hardware is able to detect and set modulation automatically.
+     */
+    public static final int MODULATION_AUTO = Constants.FrontendIsdbs3Modulation.AUTO;
+    /**
+     * BPSK Modulation.
+     */
+    public static final int MODULATION_MOD_BPSK = Constants.FrontendIsdbs3Modulation.MOD_BPSK;
+    /**
+     * QPSK Modulation.
+     */
+    public static final int MODULATION_MOD_QPSK = Constants.FrontendIsdbs3Modulation.MOD_QPSK;
+    /**
+     * 8PSK Modulation.
+     */
+    public static final int MODULATION_MOD_8PSK = Constants.FrontendIsdbs3Modulation.MOD_8PSK;
+    /**
+     * 16APSK Modulation.
+     */
+    public static final int MODULATION_MOD_16APSK = Constants.FrontendIsdbs3Modulation.MOD_16APSK;
+    /**
+     * 32APSK Modulation.
+     */
+    public static final int MODULATION_MOD_32APSK = Constants.FrontendIsdbs3Modulation.MOD_32APSK;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(flag = true,
+            prefix = "CODERATE_",
+            value = {CODERATE_UNDEFINED, CODERATE_AUTO, CODERATE_1_3, CODERATE_2_5, CODERATE_1_2,
+                    CODERATE_3_5, CODERATE_2_3, CODERATE_3_4, CODERATE_7_9, CODERATE_4_5,
+                    CODERATE_5_6, CODERATE_7_8, CODERATE_9_10})
+    public @interface CodeRate {}
+
+    /**
+     * Code rate undefined.
+     */
+    public static final int CODERATE_UNDEFINED = Constants.FrontendIsdbs3Coderate.UNDEFINED;
+    /**
+     * Hardware is able to detect and set code rate automatically.
+     */
+    public static final int CODERATE_AUTO = Constants.FrontendIsdbs3Coderate.AUTO;
+    /**
+     * 1/3 code rate.
+     */
+    public static final int CODERATE_1_3 = Constants.FrontendIsdbs3Coderate.CODERATE_1_3;
+    /**
+     * 2/5 code rate.
+     */
+    public static final int CODERATE_2_5 = Constants.FrontendIsdbs3Coderate.CODERATE_2_5;
+    /**
+     * 1/2 code rate.
+     */
+    public static final int CODERATE_1_2 = Constants.FrontendIsdbs3Coderate.CODERATE_1_2;
+    /**
+     * 3/5 code rate.
+     */
+    public static final int CODERATE_3_5 = Constants.FrontendIsdbs3Coderate.CODERATE_3_5;
+    /**
+     * 2/3 code rate.
+     */
+    public static final int CODERATE_2_3 = Constants.FrontendIsdbs3Coderate.CODERATE_2_3;
+    /**
+     * 3/4 code rate.
+     */
+    public static final int CODERATE_3_4 = Constants.FrontendIsdbs3Coderate.CODERATE_3_4;
+    /**
+     * 7/9 code rate.
+     */
+    public static final int CODERATE_7_9 = Constants.FrontendIsdbs3Coderate.CODERATE_7_9;
+    /**
+     * 4/5 code rate.
+     */
+    public static final int CODERATE_4_5 = Constants.FrontendIsdbs3Coderate.CODERATE_4_5;
+    /**
+     * 5/6 code rate.
+     */
+    public static final int CODERATE_5_6 = Constants.FrontendIsdbs3Coderate.CODERATE_5_6;
+    /**
+     * 7/8 code rate.
+     */
+    public static final int CODERATE_7_8 = Constants.FrontendIsdbs3Coderate.CODERATE_7_8;
+    /**
+     * 9/10 code rate.
+     */
+    public static final int CODERATE_9_10 = Constants.FrontendIsdbs3Coderate.CODERATE_9_10;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "ROLLOFF_",
+            value = {ROLLOFF_UNDEFINED, ROLLOFF_0_03})
+    public @interface Rolloff {}
+
+    /**
+     * Rolloff type undefined.
+     */
+    public static final int ROLLOFF_UNDEFINED = Constants.FrontendIsdbs3Rolloff.UNDEFINED;
+    /**
+     * 0,03 Rolloff.
+     */
+    public static final int ROLLOFF_0_03 = Constants.FrontendIsdbs3Rolloff.ROLLOFF_0_03;
+
+
+    private final int mStreamId;
+    private final int mStreamIdType;
+    private final int mModulation;
+    private final int mCodeRate;
+    private final int mSymbolRate;
+    private final int mRolloff;
+
+    private Isdbs3FrontendSettings(int frequency, int streamId, int streamIdType, int modulation,
+            int codeRate, int symbolRate, int rolloff) {
+        super(frequency);
+        mStreamId = streamId;
+        mStreamIdType = streamIdType;
+        mModulation = modulation;
+        mCodeRate = codeRate;
+        mSymbolRate = symbolRate;
+        mRolloff = rolloff;
+    }
+
+    /**
+     * Gets Stream ID.
+     */
+    public int getStreamId() {
+        return mStreamId;
+    }
+    /**
+     * Gets Stream ID Type.
+     */
+    @IsdbsFrontendSettings.StreamIdType
+    public int getStreamIdType() {
+        return mStreamIdType;
+    }
+    /**
+     * Gets Modulation.
+     */
+    @Modulation
+    public int getModulation() {
+        return mModulation;
+    }
+    /**
+     * Gets Code rate.
+     */
+    @CodeRate
+    public int getCodeRate() {
+        return mCodeRate;
+    }
+    /**
+     * Gets Symbol Rate in symbols per second.
+     */
+    public int getSymbolRate() {
+        return mSymbolRate;
+    }
+    /**
+     * Gets Roll off type.
+     */
+    @Rolloff
+    public int getRolloff() {
+        return mRolloff;
+    }
+
+    /**
+     * Creates a builder for {@link Isdbs3FrontendSettings}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link Isdbs3FrontendSettings}.
+     */
+    public static class Builder {
+        private int mFrequency = 0;
+        private int mStreamId = Tuner.INVALID_STREAM_ID;
+        private int mStreamIdType = IsdbsFrontendSettings.STREAM_ID_TYPE_ID;
+        private int mModulation = MODULATION_UNDEFINED;
+        private int mCodeRate = CODERATE_UNDEFINED;
+        private int mSymbolRate = 0;
+        private int mRolloff = ROLLOFF_UNDEFINED;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        @IntRange(from = 1)
+        public Builder setFrequency(int frequency) {
+            mFrequency = frequency;
+            return this;
+        }
+
+        /**
+         * Sets Stream ID.
+         *
+         * <p>Default value is {@link Tuner#INVALID_STREAM_ID}.
+         */
+        @NonNull
+        public Builder setStreamId(int streamId) {
+            mStreamId = streamId;
+            return this;
+        }
+        /**
+         * Sets StreamIdType.
+         *
+         * <p>Default value is {@link IsdbsFrontendSettings#STREAM_ID_TYPE_ID}.
+         */
+        @NonNull
+        public Builder setStreamIdType(@IsdbsFrontendSettings.StreamIdType int streamIdType) {
+            mStreamIdType = streamIdType;
+            return this;
+        }
+        /**
+         * Sets Modulation.
+         *
+         * <p>Default value is {@link #MODULATION_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setModulation(@Modulation int modulation) {
+            mModulation = modulation;
+            return this;
+        }
+        /**
+         * Sets Code rate.
+         *
+         * <p>Default value is {@link #CODERATE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setCodeRate(@CodeRate int codeRate) {
+            mCodeRate = codeRate;
+            return this;
+        }
+        /**
+         * Sets Symbol Rate in symbols per second.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        public Builder setSymbolRate(int symbolRate) {
+            mSymbolRate = symbolRate;
+            return this;
+        }
+        /**
+         * Sets Roll off type.
+         *
+         * <p>Default value is {@link #ROLLOFF_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setRolloff(@Rolloff int rolloff) {
+            mRolloff = rolloff;
+            return this;
+        }
+
+        /**
+         * Builds a {@link Isdbs3FrontendSettings} object.
+         */
+        @NonNull
+        public Isdbs3FrontendSettings build() {
+            return new Isdbs3FrontendSettings(mFrequency, mStreamId, mStreamIdType, mModulation,
+                    mCodeRate, mSymbolRate, mRolloff);
+        }
+    }
+
+    @Override
+    public int getType() {
+        return FrontendSettings.TYPE_ISDBS3;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/IsdbsFrontendCapabilities.java b/android/media/tv/tuner/frontend/IsdbsFrontendCapabilities.java
new file mode 100644
index 0000000..38d2f1d
--- /dev/null
+++ b/android/media/tv/tuner/frontend/IsdbsFrontendCapabilities.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/**
+ * ISDBS Capabilities.
+ *
+ * @hide
+ */
+@SystemApi
+public class IsdbsFrontendCapabilities extends FrontendCapabilities {
+    private final int mModulationCap;
+    private final int mCodeRateCap;
+
+    private IsdbsFrontendCapabilities(int modulationCap, int codeRateCap) {
+        mModulationCap = modulationCap;
+        mCodeRateCap = codeRateCap;
+    }
+
+    /**
+     * Gets modulation capability.
+     */
+    @IsdbsFrontendSettings.Modulation
+    public int getModulationCapability() {
+        return mModulationCap;
+    }
+    /**
+     * Gets code rate capability.
+     */
+    @IsdbsFrontendSettings.CodeRate
+    public int getCodeRateCapability() {
+        return mCodeRateCap;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/IsdbsFrontendSettings.java b/android/media/tv/tuner/frontend/IsdbsFrontendSettings.java
new file mode 100644
index 0000000..3cc1aab
--- /dev/null
+++ b/android/media/tv/tuner/frontend/IsdbsFrontendSettings.java
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.Tuner;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Frontend settings for ISDBS.
+ *
+ * @hide
+ */
+@SystemApi
+public class IsdbsFrontendSettings extends FrontendSettings {
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "STREAM_ID_TYPE_",
+            value = {STREAM_ID_TYPE_ID, STREAM_ID_TYPE_RELATIVE_NUMBER})
+    public @interface StreamIdType {}
+
+    /**
+     * Uses stream ID.
+     */
+    public static final int STREAM_ID_TYPE_ID = Constants.FrontendIsdbsStreamIdType.STREAM_ID;
+    /**
+     * Uses relative number.
+     */
+    public static final int STREAM_ID_TYPE_RELATIVE_NUMBER =
+            Constants.FrontendIsdbsStreamIdType.RELATIVE_STREAM_NUMBER;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "MODULATION_",
+            value = {MODULATION_UNDEFINED, MODULATION_AUTO, MODULATION_MOD_BPSK,
+                    MODULATION_MOD_QPSK, MODULATION_MOD_TC8PSK})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Modulation {}
+
+    /**
+     * Modulation undefined.
+     */
+    public static final int MODULATION_UNDEFINED = Constants.FrontendIsdbsModulation.UNDEFINED;
+    /**
+     * Hardware is able to detect and set modulation automatically
+     */
+    public static final int MODULATION_AUTO = Constants.FrontendIsdbsModulation.AUTO;
+    /**
+     * BPSK Modulation.
+     */
+    public static final int MODULATION_MOD_BPSK = Constants.FrontendIsdbsModulation.MOD_BPSK;
+    /**
+     * QPSK Modulation.
+     */
+    public static final int MODULATION_MOD_QPSK = Constants.FrontendIsdbsModulation.MOD_QPSK;
+    /**
+     * TC8PSK Modulation.
+     */
+    public static final int MODULATION_MOD_TC8PSK = Constants.FrontendIsdbsModulation.MOD_TC8PSK;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "CODERATE_",
+            value = {CODERATE_UNDEFINED, CODERATE_AUTO, CODERATE_1_2, CODERATE_2_3, CODERATE_3_4,
+                    CODERATE_5_6, CODERATE_7_8})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface CodeRate {}
+
+    /**
+     * Code rate undefined.
+     */
+    public static final int CODERATE_UNDEFINED = Constants.FrontendIsdbsCoderate.UNDEFINED;
+    /**
+     * Hardware is able to detect and set code rate automatically.
+     */
+    public static final int CODERATE_AUTO = Constants.FrontendIsdbsCoderate.AUTO;
+    /**
+     * 1/2 code rate.
+     */
+    public static final int CODERATE_1_2 = Constants.FrontendIsdbsCoderate.CODERATE_1_2;
+    /**
+     * 2/3 code rate.
+     */
+    public static final int CODERATE_2_3 = Constants.FrontendIsdbsCoderate.CODERATE_2_3;
+    /**
+     * 3/4 code rate.
+     */
+    public static final int CODERATE_3_4 = Constants.FrontendIsdbsCoderate.CODERATE_3_4;
+    /**
+     * 5/6 code rate.
+     */
+    public static final int CODERATE_5_6 = Constants.FrontendIsdbsCoderate.CODERATE_5_6;
+    /**
+     * 7/8 code rate.
+     */
+    public static final int CODERATE_7_8 = Constants.FrontendIsdbsCoderate.CODERATE_7_8;
+
+    /** @hide */
+    @Retention(RetentionPolicy.SOURCE)
+    @IntDef(prefix = "ROLLOFF_",
+            value = {ROLLOFF_UNDEFINED, ROLLOFF_0_35})
+    public @interface Rolloff {}
+
+    /**
+     * Rolloff type undefined.
+     */
+    public static final int ROLLOFF_UNDEFINED = Constants.FrontendIsdbsRolloff.UNDEFINED;
+    /**
+     * 0,35 rolloff.
+     */
+    public static final int ROLLOFF_0_35 = Constants.FrontendIsdbsRolloff.ROLLOFF_0_35;
+
+
+    private final int mStreamId;
+    private final int mStreamIdType;
+    private final int mModulation;
+    private final int mCodeRate;
+    private final int mSymbolRate;
+    private final int mRolloff;
+
+    private IsdbsFrontendSettings(int frequency, int streamId, int streamIdType, int modulation,
+            int codeRate, int symbolRate, int rolloff) {
+        super(frequency);
+        mStreamId = streamId;
+        mStreamIdType = streamIdType;
+        mModulation = modulation;
+        mCodeRate = codeRate;
+        mSymbolRate = symbolRate;
+        mRolloff = rolloff;
+    }
+
+    /**
+     * Gets Stream ID.
+     */
+    public int getStreamId() {
+        return mStreamId;
+    }
+    /**
+     * Gets Stream ID Type.
+     */
+    @StreamIdType
+    public int getStreamIdType() {
+        return mStreamIdType;
+    }
+    /**
+     * Gets Modulation.
+     */
+    @Modulation
+    public int getModulation() {
+        return mModulation;
+    }
+    /**
+     * Gets Code rate.
+     */
+    @CodeRate
+    public int getCodeRate() {
+        return mCodeRate;
+    }
+    /**
+     * Gets Symbol Rate in symbols per second.
+     */
+    public int getSymbolRate() {
+        return mSymbolRate;
+    }
+    /**
+     * Gets Roll off type.
+     */
+    @Rolloff
+    public int getRolloff() {
+        return mRolloff;
+    }
+
+    /**
+     * Creates a builder for {@link IsdbsFrontendSettings}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link IsdbsFrontendSettings}.
+     */
+    public static class Builder {
+        private int mFrequency = 0;
+        private int mStreamId = Tuner.INVALID_STREAM_ID;
+        private int mStreamIdType = STREAM_ID_TYPE_ID;
+        private int mModulation = MODULATION_UNDEFINED;
+        private int mCodeRate = CODERATE_UNDEFINED;
+        private int mSymbolRate = 0;
+        private int mRolloff = ROLLOFF_UNDEFINED;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        @IntRange(from = 1)
+        public Builder setFrequency(int frequency) {
+            mFrequency = frequency;
+            return this;
+        }
+
+        /**
+         * Sets Stream ID.
+         *
+         * <p>Default value is {@link Tuner#INVALID_STREAM_ID}.
+         */
+        @NonNull
+        public Builder setStreamId(int streamId) {
+            mStreamId = streamId;
+            return this;
+        }
+        /**
+         * Sets StreamIdType.
+         *
+         * <p>Default value is {@link #STREAM_ID_TYPE_ID}.
+         */
+        @NonNull
+        public Builder setStreamIdType(@StreamIdType int streamIdType) {
+            mStreamIdType = streamIdType;
+            return this;
+        }
+        /**
+         * Sets Modulation.
+         *
+         * <p>Default value is {@link #MODULATION_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setModulation(@Modulation int modulation) {
+            mModulation = modulation;
+            return this;
+        }
+        /**
+         * Sets Code rate.
+         *
+         * <p>Default value is {@link #CODERATE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setCodeRate(@CodeRate int codeRate) {
+            mCodeRate = codeRate;
+            return this;
+        }
+        /**
+         * Sets Symbol Rate in symbols per second.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        public Builder setSymbolRate(int symbolRate) {
+            mSymbolRate = symbolRate;
+            return this;
+        }
+        /**
+         * Sets Roll off type.
+         *
+         * <p>Default value is {@link #ROLLOFF_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setRolloff(@Rolloff int rolloff) {
+            mRolloff = rolloff;
+            return this;
+        }
+
+        /**
+         * Builds a {@link IsdbsFrontendSettings} object.
+         */
+        @NonNull
+        public IsdbsFrontendSettings build() {
+            return new IsdbsFrontendSettings(mFrequency, mStreamId, mStreamIdType, mModulation,
+                    mCodeRate, mSymbolRate, mRolloff);
+        }
+    }
+
+    @Override
+    public int getType() {
+        return FrontendSettings.TYPE_ISDBS;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/IsdbtFrontendCapabilities.java b/android/media/tv/tuner/frontend/IsdbtFrontendCapabilities.java
new file mode 100644
index 0000000..ffebc5a
--- /dev/null
+++ b/android/media/tv/tuner/frontend/IsdbtFrontendCapabilities.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.SystemApi;
+
+/**
+ * ISDBT Capabilities.
+ *
+ * @hide
+ */
+@SystemApi
+public class IsdbtFrontendCapabilities extends FrontendCapabilities {
+    private final int mModeCap;
+    private final int mBandwidthCap;
+    private final int mModulationCap;
+    private final int mCodeRateCap;
+    private final int mGuardIntervalCap;
+
+    private IsdbtFrontendCapabilities(int modeCap, int bandwidthCap, int modulationCap,
+            int codeRateCap, int guardIntervalCap) {
+        mModeCap = modeCap;
+        mBandwidthCap = bandwidthCap;
+        mModulationCap = modulationCap;
+        mCodeRateCap = codeRateCap;
+        mGuardIntervalCap = guardIntervalCap;
+    }
+
+    /**
+     * Gets mode capability.
+     */
+    @IsdbtFrontendSettings.Mode
+    public int getModeCapability() {
+        return mModeCap;
+    }
+    /**
+     * Gets bandwidth capability.
+     */
+    @IsdbtFrontendSettings.Bandwidth
+    public int getBandwidthCapability() {
+        return mBandwidthCap;
+    }
+    /**
+     * Gets modulation capability.
+     */
+    @IsdbtFrontendSettings.Modulation
+    public int getModulationCapability() {
+        return mModulationCap;
+    }
+    /**
+     * Gets code rate capability.
+     */
+    @DvbtFrontendSettings.CodeRate
+    public int getCodeRateCapability() {
+        return mCodeRateCap;
+    }
+    /**
+     * Gets guard interval capability.
+     */
+    @DvbtFrontendSettings.GuardInterval
+    public int getGuardIntervalCapability() {
+        return mGuardIntervalCap;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/IsdbtFrontendSettings.java b/android/media/tv/tuner/frontend/IsdbtFrontendSettings.java
new file mode 100644
index 0000000..6a14d08
--- /dev/null
+++ b/android/media/tv/tuner/frontend/IsdbtFrontendSettings.java
@@ -0,0 +1,298 @@
+/*
+ * Copyright 2019 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+import android.media.tv.tuner.frontend.DvbtFrontendSettings.CodeRate;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Frontend settings for ISDBT.
+ *
+ * @hide
+ */
+@SystemApi
+public class IsdbtFrontendSettings extends FrontendSettings {
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "MODULATION_",
+            value = {MODULATION_UNDEFINED, MODULATION_AUTO, MODULATION_MOD_DQPSK,
+                    MODULATION_MOD_QPSK, MODULATION_MOD_16QAM, MODULATION_MOD_64QAM})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Modulation {}
+
+    /**
+     * Modulation undefined.
+     */
+    public static final int MODULATION_UNDEFINED = Constants.FrontendIsdbtModulation.UNDEFINED;
+    /**
+     * Hardware is able to detect and set modulation automatically
+     */
+    public static final int MODULATION_AUTO = Constants.FrontendIsdbtModulation.AUTO;
+    /**
+     * DQPSK Modulation.
+     */
+    public static final int MODULATION_MOD_DQPSK = Constants.FrontendIsdbtModulation.MOD_DQPSK;
+    /**
+     * QPSK Modulation.
+     */
+    public static final int MODULATION_MOD_QPSK = Constants.FrontendIsdbtModulation.MOD_QPSK;
+    /**
+     * 16QAM Modulation.
+     */
+    public static final int MODULATION_MOD_16QAM = Constants.FrontendIsdbtModulation.MOD_16QAM;
+    /**
+     * 64QAM Modulation.
+     */
+    public static final int MODULATION_MOD_64QAM = Constants.FrontendIsdbtModulation.MOD_64QAM;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "MODE_",
+            value = {MODE_UNDEFINED, MODE_AUTO, MODE_1, MODE_2, MODE_3})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Mode {}
+
+    /**
+     * Mode undefined.
+     */
+    public static final int MODE_UNDEFINED = Constants.FrontendIsdbtMode.UNDEFINED;
+    /**
+     * Hardware is able to detect and set Mode automatically.
+     */
+    public static final int MODE_AUTO = Constants.FrontendIsdbtMode.AUTO;
+    /**
+     * Mode 1
+     */
+    public static final int MODE_1 = Constants.FrontendIsdbtMode.MODE_1;
+    /**
+     * Mode 2
+     */
+    public static final int MODE_2 = Constants.FrontendIsdbtMode.MODE_2;
+    /**
+     * Mode 3
+     */
+    public static final int MODE_3 = Constants.FrontendIsdbtMode.MODE_3;
+
+
+    /** @hide */
+    @IntDef(flag = true,
+            prefix = "BANDWIDTH_",
+            value = {BANDWIDTH_UNDEFINED, BANDWIDTH_AUTO, BANDWIDTH_8MHZ, BANDWIDTH_7MHZ,
+                    BANDWIDTH_6MHZ})
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface Bandwidth {}
+
+    /**
+     * Bandwidth undefined.
+     */
+    public static final int BANDWIDTH_UNDEFINED = Constants.FrontendIsdbtBandwidth.UNDEFINED;
+    /**
+     * Hardware is able to detect and set Bandwidth automatically.
+     */
+    public static final int BANDWIDTH_AUTO = Constants.FrontendIsdbtBandwidth.AUTO;
+    /**
+     * 8 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_8MHZ = Constants.FrontendIsdbtBandwidth.BANDWIDTH_8MHZ;
+    /**
+     * 7 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_7MHZ = Constants.FrontendIsdbtBandwidth.BANDWIDTH_7MHZ;
+    /**
+     * 6 MHz bandwidth.
+     */
+    public static final int BANDWIDTH_6MHZ = Constants.FrontendIsdbtBandwidth.BANDWIDTH_6MHZ;
+
+    private final int mModulation;
+    private final int mBandwidth;
+    private final int mMode;
+    private final int mCodeRate;
+    private final int mGuardInterval;
+    private final int mServiceAreaId;
+
+    private IsdbtFrontendSettings(int frequency, int modulation, int bandwidth, int mode,
+            int codeRate, int guardInterval, int serviceAreaId) {
+        super(frequency);
+        mModulation = modulation;
+        mBandwidth = bandwidth;
+        mMode = mode;
+        mCodeRate = codeRate;
+        mGuardInterval = guardInterval;
+        mServiceAreaId = serviceAreaId;
+    }
+
+    /**
+     * Gets Modulation.
+     */
+    @Modulation
+    public int getModulation() {
+        return mModulation;
+    }
+    /**
+     * Gets Bandwidth.
+     */
+    @Bandwidth
+    public int getBandwidth() {
+        return mBandwidth;
+    }
+    /**
+     * Gets ISDBT mode.
+     */
+    @Mode
+    public int getMode() {
+        return mMode;
+    }
+    /**
+     * Gets Code rate.
+     */
+    @CodeRate
+    public int getCodeRate() {
+        return mCodeRate;
+    }
+    /**
+     * Gets Guard Interval.
+     */
+    @DvbtFrontendSettings.GuardInterval
+    public int getGuardInterval() {
+        return mGuardInterval;
+    }
+    /**
+     * Gets Service Area ID.
+     */
+    public int getServiceAreaId() {
+        return mServiceAreaId;
+    }
+
+    /**
+     * Creates a builder for {@link IsdbtFrontendSettings}.
+     */
+    @NonNull
+    public static Builder builder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link IsdbtFrontendSettings}.
+     */
+    public static class Builder {
+        private int mFrequency = 0;
+        private int mModulation = MODULATION_UNDEFINED;
+        private int mBandwidth = BANDWIDTH_UNDEFINED;
+        private int mMode = MODE_UNDEFINED;
+        private int mCodeRate = DvbtFrontendSettings.CODERATE_UNDEFINED;
+        private int mGuardInterval = DvbtFrontendSettings.GUARD_INTERVAL_UNDEFINED;
+        private int mServiceAreaId = 0;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets frequency in Hz.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        @IntRange(from = 1)
+        public Builder setFrequency(int frequency) {
+            mFrequency = frequency;
+            return this;
+        }
+
+        /**
+         * Sets Modulation.
+         *
+         * <p>Default value is {@link #MODULATION_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setModulation(@Modulation int modulation) {
+            mModulation = modulation;
+            return this;
+        }
+        /**
+         * Sets Bandwidth.
+         *
+         * <p>Default value is {@link #BANDWIDTH_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setBandwidth(@Bandwidth int bandwidth) {
+            mBandwidth = bandwidth;
+            return this;
+        }
+        /**
+         * Sets ISDBT mode.
+         *
+         * <p>Default value is {@link #MODE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setMode(@Mode int mode) {
+            mMode = mode;
+            return this;
+        }
+        /**
+         * Sets Code rate.
+         *
+         * <p>Default value is {@link DvbtFrontendSettings#CODERATE_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setCodeRate(@DvbtFrontendSettings.CodeRate int codeRate) {
+            mCodeRate = codeRate;
+            return this;
+        }
+        /**
+         * Sets Guard Interval.
+         *
+         * <p>Default value is {@link DvbtFrontendSettings#GUARD_INTERVAL_UNDEFINED}.
+         */
+        @NonNull
+        public Builder setGuardInterval(@DvbtFrontendSettings.GuardInterval int guardInterval) {
+            mGuardInterval = guardInterval;
+            return this;
+        }
+        /**
+         * Sets Service Area ID.
+         *
+         * <p>Default value is 0.
+         */
+        @NonNull
+        public Builder setServiceAreaId(int serviceAreaId) {
+            mServiceAreaId = serviceAreaId;
+            return this;
+        }
+
+        /**
+         * Builds a {@link IsdbtFrontendSettings} object.
+         */
+        @NonNull
+        public IsdbtFrontendSettings build() {
+            return new IsdbtFrontendSettings(mFrequency, mModulation, mBandwidth, mMode, mCodeRate,
+                    mGuardInterval, mServiceAreaId);
+        }
+    }
+
+    @Override
+    public int getType() {
+        return FrontendSettings.TYPE_ISDBT;
+    }
+}
diff --git a/android/media/tv/tuner/frontend/OnTuneEventListener.java b/android/media/tv/tuner/frontend/OnTuneEventListener.java
new file mode 100644
index 0000000..5cf0d31
--- /dev/null
+++ b/android/media/tv/tuner/frontend/OnTuneEventListener.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2020 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.tv.tuner.frontend;
+
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+import android.hardware.tv.tuner.V1_0.Constants;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Listens for tune events.
+ *
+ * @hide
+ */
+@SystemApi
+public interface OnTuneEventListener {
+
+    /** @hide */
+    @IntDef(prefix = "SIGNAL_", value = {SIGNAL_LOCKED, SIGNAL_NO_SIGNAL, SIGNAL_LOST_LOCK})
+    @Retention(RetentionPolicy.SOURCE)
+    @interface TuneEvent {}
+
+    /** The frontend has locked to the signal specified by the tune method. */
+    int SIGNAL_LOCKED = Constants.FrontendEventType.LOCKED;
+    /** The frontend is unable to lock to the signal specified by the tune method. */
+    int SIGNAL_NO_SIGNAL = Constants.FrontendEventType.NO_SIGNAL;
+    /** The frontend has lost the lock to the signal specified by the tune method. */
+    int SIGNAL_LOST_LOCK = Constants.FrontendEventType.LOST_LOCK;
+
+    /** Tune Event from the frontend */
+    void onTuneEvent(@TuneEvent int tuneEvent);
+}
diff --git a/android/media/tv/tuner/frontend/ScanCallback.java b/android/media/tv/tuner/frontend/ScanCallback.java
new file mode 100644
index 0000000..27627d7
--- /dev/null
+++ b/android/media/tv/tuner/frontend/ScanCallback.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2020 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.tv.tuner.frontend;
+
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+
+/**
+ * Scan callback.
+ *
+ * @hide
+ */
+@SystemApi
+public interface ScanCallback {
+
+    /** Scan locked the signal. */
+    void onLocked();
+
+    /** Scan stopped. */
+    void onScanStopped();
+
+    /** scan progress percent (0..100) */
+    void onProgress(@IntRange(from = 0, to = 100) int percent);
+
+    /** Signal frequencies in Hertz */
+    void onFrequenciesReported(@NonNull int[] frequency);
+
+    /** Symbols per second */
+    void onSymbolRatesReported(@NonNull int[] rate);
+
+    /** Locked Plp Ids for DVBT2 frontend. */
+    void onPlpIdsReported(@NonNull int[] plpIds);
+
+    /** Locked group Ids for DVBT2 frontend. */
+    void onGroupIdsReported(@NonNull int[] groupIds);
+
+    /** Stream Ids. */
+    void onInputStreamIdsReported(@NonNull int[] inputStreamIds);
+
+    /** Locked signal standard for DVBS. */
+    void onDvbsStandardReported(@DvbsFrontendSettings.Standard int dvbsStandard);
+
+    /** Locked signal standard. for DVBT */
+    void onDvbtStandardReported(@DvbtFrontendSettings.Standard int dvbtStandard);
+
+    /** Locked signal SIF standard for Analog. */
+    void onAnalogSifStandardReported(@AnalogFrontendSettings.SifStandard int sif);
+
+    /** PLP status in a tuned frequency band for ATSC3 frontend. */
+    void onAtsc3PlpInfosReported(@NonNull Atsc3PlpInfo[] atsc3PlpInfos);
+
+    /** Frontend hierarchy. */
+    void onHierarchyReported(@DvbtFrontendSettings.Hierarchy int hierarchy);
+
+    /** Frontend signal type. */
+    void onSignalTypeReported(@AnalogFrontendSettings.SignalType int signalType);
+
+    /** Frontend modulation reported. */
+    default void onModulationReported(@FrontendStatus.FrontendModulation int modulation) {}
+
+    /** Frontend scan message priority reported. */
+    default void onPriorityReported(boolean isHighPriority) {}
+
+    /** DVBC Frontend Annex reported. */
+    default void onDvbcAnnexReported(@DvbcFrontendSettings.Annex int dvbcAnnex) {}
+}
diff --git a/android/media/tv/tunerresourcemanager/TunerResourceManager.java b/android/media/tv/tunerresourcemanager/TunerResourceManager.java
new file mode 100644
index 0000000..e399fbd
--- /dev/null
+++ b/android/media/tv/tunerresourcemanager/TunerResourceManager.java
@@ -0,0 +1,582 @@
+/*
+ * Copyright 2020 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.tv.tunerresourcemanager;
+
+import android.annotation.CallbackExecutor;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresFeature;
+import android.annotation.SystemService;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.media.tv.tuner.TunerFrontendInfo;
+import android.os.Binder;
+import android.os.RemoteException;
+import android.util.Log;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.concurrent.Executor;
+
+/**
+ * Interface of the Tuner Resource Manager(TRM). It manages resources used by TV Tuners.
+ * <p>Resources include:
+ * <ul>
+ * <li>TunerFrontend {@link android.media.tv.tuner.frontend}.
+ * <li>TunerLnb {@link android.media.tv.tuner.Lnb}.
+ * <li>MediaCas {@link android.media.MediaCas}.
+ * <ul>
+ *
+ * <p>Expected workflow is:
+ * <ul>
+ * <li>Tuner Java/MediaCas/TIF update resources of the current device with TRM.
+ * <li>Client registers its profile through {@link #registerClientProfile(ResourceClientProfile,
+ * Executor, ResourcesReclaimListener, int[])}.
+ * <li>Client requests resources through request APIs.
+ * <li>If the resource needs to be handed to a higher priority client from a lower priority
+ * one, TRM calls IResourcesReclaimListener registered by the lower priority client to release
+ * the resource.
+ * <ul>
+ *
+ * <p>TRM also exposes its priority comparison algorithm as a helping method to other services.
+ * {@see #isHigherPriority(ResourceClientProfile, ResourceClientProfile)}.
+ *
+ * @hide
+ */
+@RequiresFeature(PackageManager.FEATURE_LIVE_TV)
+@SystemService(Context.TV_TUNER_RESOURCE_MGR_SERVICE)
+public class TunerResourceManager {
+    private static final String TAG = "TunerResourceManager";
+    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
+
+    public static final int INVALID_RESOURCE_HANDLE = -1;
+    public static final int INVALID_OWNER_ID = -1;
+    /**
+     * Tuner resource type to help generate resource handle
+     */
+    @IntDef({
+        TUNER_RESOURCE_TYPE_FRONTEND,
+        TUNER_RESOURCE_TYPE_DEMUX,
+        TUNER_RESOURCE_TYPE_DESCRAMBLER,
+        TUNER_RESOURCE_TYPE_LNB,
+        TUNER_RESOURCE_TYPE_CAS_SESSION,
+        TUNER_RESOURCE_TYPE_FRONTEND_CICAM,
+        TUNER_RESOURCE_TYPE_MAX,
+     })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface TunerResourceType {}
+
+    public static final int TUNER_RESOURCE_TYPE_FRONTEND = 0;
+    public static final int TUNER_RESOURCE_TYPE_DEMUX = 1;
+    public static final int TUNER_RESOURCE_TYPE_DESCRAMBLER = 2;
+    public static final int TUNER_RESOURCE_TYPE_LNB = 3;
+    public static final int TUNER_RESOURCE_TYPE_CAS_SESSION = 4;
+    public static final int TUNER_RESOURCE_TYPE_FRONTEND_CICAM = 5;
+    public static final int TUNER_RESOURCE_TYPE_MAX = 6;
+
+    private final ITunerResourceManager mService;
+    private final int mUserId;
+
+    /**
+     * @hide
+     */
+    public TunerResourceManager(ITunerResourceManager service, int userId) {
+        mService = service;
+        mUserId = userId;
+    }
+
+    /**
+     * This API is used by the client to register their profile with the Tuner Resource manager.
+     *
+     * <p>The profile contains information that can show the base priority score of the client.
+     *
+     * @param profile {@link ResourceClientProfile} profile of the current client. Undefined use
+     *                case would cause IllegalArgumentException.
+     * @param executor the executor on which the listener would be invoked.
+     * @param listener {@link ResourcesReclaimListener} callback to reclaim clients' resources when
+     *                 needed.
+     * @param clientId returned a clientId from the resource manager when the
+     *                 the client registeres.
+     * @throws IllegalArgumentException when {@code profile} contains undefined use case.
+     */
+    public void registerClientProfile(@NonNull ResourceClientProfile profile,
+                        @NonNull @CallbackExecutor Executor executor,
+                        @NonNull ResourcesReclaimListener listener,
+                        @NonNull int[] clientId) {
+        // TODO: throw new IllegalArgumentException("Unknown client use case")
+        // when the use case is not defined.
+        try {
+            mService.registerClientProfile(profile,
+                    new IResourcesReclaimListener.Stub() {
+                    @Override
+                public void onReclaimResources() {
+                        final long identity = Binder.clearCallingIdentity();
+                        try {
+                            executor.execute(() -> listener.onReclaimResources());
+                        } finally {
+                            Binder.restoreCallingIdentity(identity);
+                        }
+                    }
+                }, clientId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * This API is used by the client to unregister their profile with the
+     * Tuner Resource manager.
+     *
+     * @param clientId the client id that needs to be unregistered.
+     */
+    public void unregisterClientProfile(int clientId) {
+        try {
+            mService.unregisterClientProfile(clientId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * This API is used by client to update its registered {@link ResourceClientProfile}.
+     *
+     * <p>We recommend creating a new tuner instance for different use cases instead of using this
+     * API since different use cases may need different resources.
+     *
+     * <p>If TIS updates use case, it needs to ensure underneath resources are exchangeable between
+     * two different use cases.
+     *
+     * <p>Only the arbitrary priority and niceValue are allowed to be updated.
+     *
+     * @param clientId the id of the client that is updating its profile.
+     * @param priority the priority that the client would like to update to.
+     * @param niceValue the nice value that the client would like to update to.
+     *
+     * @return true if the update is successful.
+     */
+    public boolean updateClientPriority(int clientId, int priority, int niceValue) {
+        boolean result = false;
+        try {
+            result = mService.updateClientPriority(clientId, priority, niceValue);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return result;
+    }
+
+    /**
+     * Updates the current TRM of the TunerHAL Frontend information.
+     *
+     * <p><strong>Note:</strong> This update must happen before the first
+     * {@link #requestFrontend(TunerFrontendRequest, int[])} and
+     * {@link #releaseFrontend(int, int)} call.
+     *
+     * @param infos an array of the available {@link TunerFrontendInfo} information.
+     */
+    public void setFrontendInfoList(@NonNull TunerFrontendInfo[] infos) {
+        try {
+            mService.setFrontendInfoList(infos);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Updates the TRM of the current CAS information.
+     *
+     * <p><strong>Note:</strong> This update must happen before the first
+     * {@link #requestCasSession(CasSessionRequest, int[])} and {@link #releaseCasSession(int, int)}
+     * call.
+     *
+     * @param casSystemId id of the updating CAS system.
+     * @param maxSessionNum the max session number of the CAS system that is updated.
+     */
+    public void updateCasInfo(int casSystemId, int maxSessionNum) {
+        try {
+            mService.updateCasInfo(casSystemId, maxSessionNum);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Updates the TRM of the current Lnb information.
+     *
+     * <p><strong>Note:</strong> This update must happen before the first
+     * {@link #requestLnb(TunerLnbRequest, int[])} and {@link #releaseLnb(int, int)} call.
+     *
+     * @param lnbIds ids of the updating lnbs.
+     */
+    public void setLnbInfoList(int[] lnbIds) {
+        try {
+            mService.setLnbInfoList(lnbIds);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Requests a frontend resource.
+     *
+     * <p>There are three possible scenarios:
+     * <ul>
+     * <li>If there is frontend available, the API would send the id back.
+     *
+     * <li>If no Frontend is available but the current request info can show higher priority than
+     * other uses of Frontend, the API will send
+     * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
+     * handle the resource reclaim on the holder of lower priority and notify the holder of its
+     * resource loss.
+     *
+     * <li>If no frontend can be granted, the API would return false.
+     * <ul>
+     *
+     * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
+     * before this request.
+     *
+     * @param request {@link TunerFrontendRequest} information of the current request.
+     * @param frontendHandle a one-element array to return the granted frontendHandle. If
+     *                       no frontend granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
+     *
+     * @return true if there is frontend granted.
+     */
+    public boolean requestFrontend(@NonNull TunerFrontendRequest request,
+                @Nullable int[] frontendHandle) {
+        boolean result = false;
+        try {
+            result = mService.requestFrontend(request, frontendHandle);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return result;
+    }
+
+    /**
+     * Requests from the client to share frontend with an existing client.
+     *
+     * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
+     * before this request.
+     *
+     * @param selfClientId the id of the client that sends the request.
+     * @param targetClientId the id of the client to share the frontend with.
+     */
+    public void shareFrontend(int selfClientId, int targetClientId) {
+        try {
+            mService.shareFrontend(selfClientId, targetClientId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Requests a Tuner Demux resource.
+     *
+     * <p>There are three possible scenarios:
+     * <ul>
+     * <li>If there is Demux available, the API would send the handle back.
+     *
+     * <li>If no Demux is available but the current request has a higher priority than other uses of
+     * demuxes, the API will send {@link IResourcesReclaimListener#onReclaimResources()} to the
+     * {@link Tuner}. Tuner would handle the resource reclaim on the holder of lower priority and
+     * notify the holder of its resource loss.
+     *
+     * <li>If no Demux system can be granted, the API would return false.
+     * <ul>
+     *
+     * @param request {@link TunerDemuxRequest} information of the current request.
+     * @param demuxHandle a one-element array to return the granted Demux handle.
+     *                    If no Demux granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
+     *
+     * @return true if there is Demux granted.
+     */
+    public boolean requestDemux(@NonNull TunerDemuxRequest request, @NonNull int[] demuxHandle) {
+        boolean result = false;
+        try {
+            result = mService.requestDemux(request, demuxHandle);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return result;
+    }
+
+    /**
+     * Requests a Tuner Descrambler resource.
+     *
+     * <p>There are three possible scenarios:
+     * <ul>
+     * <li>If there is Descrambler available, the API would send the handle back.
+     *
+     * <li>If no Descrambler is available but the current request has a higher priority than other
+     * uses of descramblers, the API will send
+     * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
+     * handle the resource reclaim on the holder of lower priority and notify the holder of its
+     * resource loss.
+     *
+     * <li>If no Descrambler system can be granted, the API would return false.
+     * <ul>
+     *
+     * @param request {@link TunerDescramblerRequest} information of the current request.
+     * @param descramblerHandle a one-element array to return the granted Descrambler handle.
+     *                          If no Descrambler granted, this will return
+     *                          {@link #INVALID_RESOURCE_HANDLE}.
+     *
+     * @return true if there is Descrambler granted.
+     */
+    public boolean requestDescrambler(@NonNull TunerDescramblerRequest request,
+                @NonNull int[] descramblerHandle) {
+        boolean result = false;
+        try {
+            result = mService.requestDescrambler(request, descramblerHandle);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return result;
+    }
+
+    /**
+     * Requests a CAS session resource.
+     *
+     * <p>There are three possible scenarios:
+     * <ul>
+     * <li>If there is Cas session available, the API would send the id back.
+     *
+     * <li>If no Cas system is available but the current request info can show higher priority than
+     * other uses of the cas sessions under the requested cas system, the API will send
+     * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
+     * handle the resource reclaim on the holder of lower priority and notify the holder of its
+     * resource loss.
+     *
+     * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
+     * request.
+     *
+     * @param request {@link CasSessionRequest} information of the current request.
+     * @param casSessionHandle a one-element array to return the granted cas session handel.
+     *                         If no CAS granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
+     *
+     * @return true if there is CAS session granted.
+     */
+    public boolean requestCasSession(@NonNull CasSessionRequest request,
+                @NonNull int[] casSessionHandle) {
+        boolean result = false;
+        try {
+            result = mService.requestCasSession(request, casSessionHandle);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return result;
+    }
+
+    /**
+     * Requests a CiCam resource.
+     *
+     * <p>There are three possible scenarios:
+     * <ul>
+     * <li>If there is CiCam available, the API would send the id back.
+     *
+     * <li>If no CiCam is available but the current request info can show higher priority than
+     * other uses of the CiCam, the API will send
+     * {@link IResourcesReclaimListener#onReclaimResources()} to the {@link Tuner}. Tuner would
+     * handle the resource reclaim on the holder of lower priority and notify the holder of its
+     * resource loss.
+     *
+     * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
+     * request.
+     *
+     * @param request {@link TunerCiCamRequest} information of the current request.
+     * @param ciCamHandle a one-element array to return the granted ciCam handle.
+     *                    If no ciCam granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
+     *
+     * @return true if there is ciCam granted.
+     */
+    public boolean requestCiCam(TunerCiCamRequest request, int[] ciCamHandle) {
+        boolean result = false;
+        try {
+            result = mService.requestCiCam(request, ciCamHandle);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return result;
+    }
+
+    /**
+     * Requests a Tuner Lnb resource.
+     *
+     * <p>There are three possible scenarios:
+     * <ul>
+     * <li>If there is Lnb available, the API would send the id back.
+     *
+     * <li>If no Lnb is available but the current request has a higher priority than other uses of
+     * lnbs, the API will send {@link IResourcesReclaimListener#onReclaimResources()} to the
+     * {@link Tuner}. Tuner would handle the resource reclaim on the holder of lower priority and
+     * notify the holder of its resource loss.
+     *
+     * <li>If no Lnb system can be granted, the API would return false.
+     * <ul>
+     *
+     * <p><strong>Note:</strong> {@link #setLnbInfoList(int[])} must be called before this request.
+     *
+     * @param request {@link TunerLnbRequest} information of the current request.
+     * @param lnbHandle a one-element array to return the granted Lnb handle.
+     *                  If no Lnb granted, this will return {@link #INVALID_RESOURCE_HANDLE}.
+     *
+     * @return true if there is Lnb granted.
+     */
+    public boolean requestLnb(@NonNull TunerLnbRequest request, @NonNull int[] lnbHandle) {
+        boolean result = false;
+        try {
+            result = mService.requestLnb(request, lnbHandle);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+        return result;
+    }
+
+    /**
+     * Notifies the TRM that the given frontend has been released.
+     *
+     * <p>Client must call this whenever it releases a Tuner frontend.
+     *
+     * <p><strong>Note:</strong> {@link #setFrontendInfoList(TunerFrontendInfo[])} must be called
+     * before this release.
+     *
+     * @param frontendHandle the handle of the released frontend.
+     * @param clientId the id of the client that is releasing the frontend.
+     */
+    public void releaseFrontend(int frontendHandle, int clientId) {
+        try {
+            mService.releaseFrontend(frontendHandle, clientId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Notifies the TRM that the Demux with the given handle has been released.
+     *
+     * <p>Client must call this whenever it releases an Demux.
+     *
+     * @param demuxHandle the handle of the released Tuner Demux.
+     * @param clientId the id of the client that is releasing the demux.
+     */
+    public void releaseDemux(int demuxHandle, int clientId) {
+        try {
+            mService.releaseDemux(demuxHandle, clientId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Notifies the TRM that the Descrambler with the given handle has been released.
+     *
+     * <p>Client must call this whenever it releases an Descrambler.
+     *
+     * @param descramblerHandle the handle of the released Tuner Descrambler.
+     * @param clientId the id of the client that is releasing the descrambler.
+     */
+    public void releaseDescrambler(int descramblerHandle, int clientId) {
+        try {
+            mService.releaseDescrambler(descramblerHandle, clientId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Notifies the TRM that the given Cas session has been released.
+     *
+     * <p>Client must call this whenever it releases a Cas session.
+     *
+     * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
+     * release.
+     *
+     * @param casSessionHandle the handle of the released CAS session.
+     * @param clientId the id of the client that is releasing the cas session.
+     */
+    public void releaseCasSession(int casSessionHandle, int clientId) {
+        try {
+            mService.releaseCasSession(casSessionHandle, clientId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Notifies the TRM that the given CiCam has been released.
+     *
+     * <p>Client must call this whenever it releases a CiCam.
+     *
+     * <p><strong>Note:</strong> {@link #updateCasInfo(int, int)} must be called before this
+     * release.
+     *
+     * @param ciCamHandle the handle of the releasing CiCam.
+     * @param clientId the id of the client that is releasing the CiCam.
+     */
+    public void releaseCiCam(int ciCamHandle, int clientId) {
+        try {
+            mService.releaseCiCam(ciCamHandle, clientId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Notifies the TRM that the Lnb with the given id has been released.
+     *
+     * <p>Client must call this whenever it releases an Lnb.
+     *
+     * <p><strong>Note:</strong> {@link #setLnbInfoList(int[])} must be called before this release.
+     *
+     * @param lnbHandle the handle of the released Tuner Lnb.
+     * @param clientId the id of the client that is releasing the lnb.
+     */
+    public void releaseLnb(int lnbHandle, int clientId) {
+        try {
+            mService.releaseLnb(lnbHandle, clientId);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Compare two clients' priority.
+     *
+     * @param challengerProfile the {@link ResourceClientProfile} of the challenger.
+     * @param holderProfile the {@link ResourceClientProfile} of the holder of the resource.
+     *
+     * @return true if the challenger has higher priority than the holder.
+     */
+    public boolean isHigherPriority(ResourceClientProfile challengerProfile,
+            ResourceClientProfile holderProfile) {
+        try {
+            return mService.isHigherPriority(challengerProfile, holderProfile);
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Interface used to receive events from TunerResourceManager.
+     */
+    public abstract static class ResourcesReclaimListener {
+        /*
+         * To reclaim all the resources of the callack owner.
+         */
+        public abstract void onReclaimResources();
+    }
+}
diff --git a/android/media/voice/KeyphraseModelManager.java b/android/media/voice/KeyphraseModelManager.java
new file mode 100644
index 0000000..8ec8967
--- /dev/null
+++ b/android/media/voice/KeyphraseModelManager.java
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) 2020 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.voice;
+
+import android.Manifest;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.SystemApi;
+import android.hardware.soundtrigger.SoundTrigger;
+import android.os.RemoteException;
+import android.os.ServiceSpecificException;
+import android.util.Slog;
+
+import com.android.internal.app.IVoiceInteractionManagerService;
+
+import java.util.Locale;
+import java.util.Objects;
+
+/**
+ * This class provides management of voice based sound recognition models. Usage of this class is
+ * restricted to system or signature applications only. This allows OEMs to write apps that can
+ * manage voice based sound trigger models.
+ * Callers of this class are expected to have whitelist manifest permission MANAGE_VOICE_KEYPHRASES.
+ * Callers of this class are expected to be the designated voice interaction service via
+ * {@link Settings.Secure.VOICE_INTERACTION_SERVICE} or a bundled voice model enrollment application
+ * detected by {@link android.hardware.soundtrigger.KeyphraseEnrollmentInfo}.
+ * @hide
+ */
+@SystemApi
+public final class KeyphraseModelManager {
+    private static final boolean DBG = false;
+    private static final String TAG = "KeyphraseModelManager";
+
+    private final IVoiceInteractionManagerService mVoiceInteractionManagerService;
+
+    /**
+     * @hide
+     */
+    public KeyphraseModelManager(
+            IVoiceInteractionManagerService voiceInteractionManagerService) {
+        if (DBG) {
+            Slog.i(TAG, "KeyphraseModelManager created.");
+        }
+        mVoiceInteractionManagerService = voiceInteractionManagerService;
+    }
+
+
+    /**
+     * Gets the registered sound model for keyphrase detection for the current user.
+     * The keyphraseId and locale passed must match a supported model passed in via
+     * {@link #updateKeyphraseSoundModel}.
+     * If the active voice interaction service changes from the current user, all requests will be
+     * rejected, and any registered models will be unregistered.
+     * Caller must either be the active voice interaction service via
+     * {@link Settings.Secure.VOICE_INTERACTION_SERVICE}, or the caller must be a voice model
+     * enrollment application detected by
+     * {@link android.hardware.soundtrigger.KeyphraseEnrollmentInfo}.
+     *
+     * @param keyphraseId The unique identifier for the keyphrase.
+     * @param locale The locale language tag supported by the desired model.
+     * @return Registered keyphrase sound model matching the keyphrase ID and locale. May be null if
+     * no matching sound model exists.
+     * @throws SecurityException Thrown when caller does not have MANAGE_VOICE_KEYPHRASES permission
+     *                           or if the caller is not the active voice interaction service.
+     */
+    @RequiresPermission(Manifest.permission.MANAGE_VOICE_KEYPHRASES)
+    @Nullable
+    public SoundTrigger.KeyphraseSoundModel getKeyphraseSoundModel(int keyphraseId,
+            @NonNull Locale locale) {
+        Objects.requireNonNull(locale);
+        try {
+            return mVoiceInteractionManagerService.getKeyphraseSoundModel(keyphraseId,
+                    locale.toLanguageTag());
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Add or update the given keyphrase sound model to the registered models pool for the current
+     * user.
+     * If a model exists with the same Keyphrase ID, locale, and user list. The registered model
+     * will be overwritten with the new model.
+     * If the active voice interaction service changes from the current user, all requests will be
+     * rejected, and any registered models will be unregistered.
+     * Caller must either be the active voice interaction service via
+     * {@link Settings.Secure.VOICE_INTERACTION_SERVICE}, or the caller must be a voice model
+     * enrollment application detected by
+     * {@link android.hardware.soundtrigger.KeyphraseEnrollmentInfo}.
+     *
+     * @param model Keyphrase sound model to be updated.
+     * @throws ServiceSpecificException Thrown with error code if failed to update the keyphrase
+     *                           sound model.
+     * @throws SecurityException Thrown when caller does not have MANAGE_VOICE_KEYPHRASES permission
+     *                           or if the caller is not the active voice interaction service.
+     */
+    @RequiresPermission(Manifest.permission.MANAGE_VOICE_KEYPHRASES)
+    public void updateKeyphraseSoundModel(@NonNull SoundTrigger.KeyphraseSoundModel model) {
+        Objects.requireNonNull(model);
+        try {
+            int status = mVoiceInteractionManagerService.updateKeyphraseSoundModel(model);
+            if (status != SoundTrigger.STATUS_OK) {
+                throw new ServiceSpecificException(status);
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Delete keyphrase sound model from the registered models pool for the current user matching\
+     * the keyphrase ID and locale.
+     * The keyphraseId and locale passed must match a supported model passed in via
+     * {@link #updateKeyphraseSoundModel}.
+     * If the active voice interaction service changes from the current user, all requests will be
+     * rejected, and any registered models will be unregistered.
+     * Caller must either be the active voice interaction service via
+     * {@link Settings.Secure.VOICE_INTERACTION_SERVICE}, or the caller must be a voice model
+     * enrollment application detected by
+     * {@link android.hardware.soundtrigger.KeyphraseEnrollmentInfo}.
+     *
+     * @param keyphraseId The unique identifier for the keyphrase.
+     * @param locale The locale language tag supported by the desired model.
+     * @throws ServiceSpecificException Thrown with error code if failed to delete the keyphrase
+     *                           sound model.
+     * @throws SecurityException Thrown when caller does not have MANAGE_VOICE_KEYPHRASES permission
+     *                           or if the caller is not the active voice interaction service.
+     */
+    @RequiresPermission(Manifest.permission.MANAGE_VOICE_KEYPHRASES)
+    public void deleteKeyphraseSoundModel(int keyphraseId, @NonNull Locale locale) {
+        Objects.requireNonNull(locale);
+        try {
+            int status = mVoiceInteractionManagerService.deleteKeyphraseSoundModel(keyphraseId,
+                    locale.toLanguageTag());
+            if (status != SoundTrigger.STATUS_OK) {
+                throw new ServiceSpecificException(status);
+            }
+        } catch (RemoteException e) {
+            throw e.rethrowFromSystemServer();
+        }
+    }
+}
