Remove MediaComponents

Test: build
Change-Id: I50da7f34858a4739777d84abdde8a502537bf57e
diff --git a/packages/MediaComponents/apex/Android.bp b/packages/MediaComponents/apex/Android.bp
deleted file mode 100644
index d89eb77..0000000
--- a/packages/MediaComponents/apex/Android.bp
+++ /dev/null
@@ -1,41 +0,0 @@
-filegroup {
-    name: "media_aidl",
-    srcs: [
-        "java/android/media/**/*.aidl",
-        "java/android/service/**/*.aidl",
-    ],
-    exclude_srcs: [
-        // Exclude these aidls to avoid errors such as
-        // "Refusing to generate code with unstructured parcelables."
-        "java/android/media/MediaDescription.aidl",
-        "java/android/media/MediaMetadata.aidl",
-        // TODO(insun): check why MediaParceledListSlice.aidl should be added here
-        "java/android/media/MediaParceledListSlice.aidl",
-        "java/android/media/Rating.aidl",
-        "java/android/media/browse/MediaBrowser.aidl",
-        "java/android/media/session/MediaSession.aidl",
-        "java/android/media/session/ParcelableVolumeInfo.aidl",
-        "java/android/media/session/PlaybackState.aidl",
-    ],
-}
-
-java_library {
-    name: "media",
-    installable: true,
-    sdk_version: "system_current",
-    srcs: [
-        "java/android/media/**/*.java",
-        "java/android/service/**/*.java",
-        ":media_aidl",
-        ":framework-media-annotation-srcs",
-    ],
-    aidl: {
-        local_include_dirs: ["java"],
-        include_dirs: [
-            "frameworks/base/core/java",
-            // for android.graphics.Bitmap
-            // from IMediaBrowserServiceCallback
-            "frameworks/base/graphics/java",
-            ],
-    },
-}
diff --git a/packages/MediaComponents/apex/java/android/media/IRemoteVolumeController.aidl b/packages/MediaComponents/apex/java/android/media/IRemoteVolumeController.aidl
deleted file mode 100644
index e4a4a42..0000000
--- a/packages/MediaComponents/apex/java/android/media/IRemoteVolumeController.aidl
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * 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.media.session.ISessionController;
-
-/**
- * AIDL for the MediaSessionService to report interesting events on remote playback
- * to a volume control dialog. See also IVolumeController for the AudioService half.
- * TODO add in better support for multiple remote sessions.
- * @hide
- */
-oneway interface IRemoteVolumeController {
-    void remoteVolumeChanged(ISessionController session, int flags);
-    // sets the default session to use with the slider, replaces remoteSliderVisibility
-    // on IVolumeController
-    void updateRemoteController(ISessionController session);
-}
diff --git a/packages/MediaComponents/apex/java/android/media/ISessionTokensListener.aidl b/packages/MediaComponents/apex/java/android/media/ISessionTokensListener.aidl
deleted file mode 100644
index c83a19e..0000000
--- a/packages/MediaComponents/apex/java/android/media/ISessionTokensListener.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.os.Bundle;
-
-/**
- * Listens for changes to the list of session tokens.
- * @hide
- */
-oneway interface ISessionTokensListener {
-    void onSessionTokensChanged(in List<Bundle> tokens);
-}
diff --git a/packages/MediaComponents/apex/java/android/media/MediaDescription.aidl b/packages/MediaComponents/apex/java/android/media/MediaDescription.aidl
deleted file mode 100644
index 6f934f7..0000000
--- a/packages/MediaComponents/apex/java/android/media/MediaDescription.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 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;
-
-parcelable MediaDescription;
diff --git a/packages/MediaComponents/apex/java/android/media/MediaDescription.java b/packages/MediaComponents/apex/java/android/media/MediaDescription.java
deleted file mode 100644
index 31079e5..0000000
--- a/packages/MediaComponents/apex/java/android/media/MediaDescription.java
+++ /dev/null
@@ -1,383 +0,0 @@
-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 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;
-        }
-
-        public MediaDescription build() {
-            return new MediaDescription(mMediaId, mTitle, mSubtitle, mDescription, mIcon, mIconUri,
-                    mExtras, mMediaUri);
-        }
-    }
-}
diff --git a/packages/MediaComponents/apex/java/android/media/MediaMetadata.aidl b/packages/MediaComponents/apex/java/android/media/MediaMetadata.aidl
deleted file mode 100644
index 66ee483..0000000
--- a/packages/MediaComponents/apex/java/android/media/MediaMetadata.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 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;
-
-parcelable MediaMetadata;
diff --git a/packages/MediaComponents/apex/java/android/media/MediaMetadata.java b/packages/MediaComponents/apex/java/android/media/MediaMetadata.java
deleted file mode 100644
index adfd20b..0000000
--- a/packages/MediaComponents/apex/java/android/media/MediaMetadata.java
+++ /dev/null
@@ -1,941 +0,0 @@
-/*
- * 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.StringDef;
-import android.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.net.Uri;
-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.Set;
-import java.util.Objects;
-
-/**
- * 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 MediaDescription mDescription;
-
-    private MediaMetadata(Bundle bundle) {
-        mBundle = new Bundle(bundle);
-    }
-
-    private MediaMetadata(Parcel in) {
-        mBundle = in.readBundle();
-    }
-
-    /**
-     * 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;
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeBundle(mBundle);
-    }
-
-    /**
-     * 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
-    public static String getKeyFromMetadataEditorKey(int editorKey) {
-        return EDITOR_KEY_MAPPING.get(editorKey, null);
-    }
-
-    public static final 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;
-
-        /**
-         * 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);
-        }
-
-        /**
-         * Create a Builder using a {@link MediaMetadata} instance to set
-         * initial values, but replace bitmaps with a scaled down copy if they
-         * are larger than maxBitmapSize.
-         *
-         * @param source The original metadata to copy.
-         * @param maxBitmapSize The maximum height/width for bitmaps contained
-         *            in the metadata.
-         * @hide
-         */
-        public Builder(MediaMetadata source, int maxBitmapSize) {
-            this(source);
-            for (String key : mBundle.keySet()) {
-                Object value = mBundle.get(key);
-                if (value != null && value instanceof Bitmap) {
-                    Bitmap bmp = (Bitmap) value;
-                    if (bmp.getHeight() > maxBitmapSize || bmp.getWidth() > maxBitmapSize) {
-                        putBitmap(key, scaleBitmap(bmp, maxBitmapSize));
-                    }
-                }
-            }
-        }
-
-        /**
-         * 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 when
-         * {@link android.media.session.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;
-        }
-
-        /**
-         * Creates a {@link MediaMetadata} instance with the specified fields.
-         *
-         * @return The new MediaMetadata instance
-         */
-        public MediaMetadata build() {
-            return new MediaMetadata(mBundle);
-        }
-
-        private Bitmap scaleBitmap(Bitmap bmp, int maxSize) {
-            float maxSizeF = maxSize;
-            float widthScale = maxSizeF / bmp.getWidth();
-            float heightScale = maxSizeF / bmp.getHeight();
-            float scale = Math.min(widthScale, heightScale);
-            int height = (int) (bmp.getHeight() * scale);
-            int width = (int) (bmp.getWidth() * scale);
-            return Bitmap.createScaledBitmap(bmp, width, height, true);
-        }
-    }
-}
diff --git a/packages/MediaComponents/apex/java/android/media/MediaParceledListSlice.aidl b/packages/MediaComponents/apex/java/android/media/MediaParceledListSlice.aidl
deleted file mode 100644
index 228ea9c..0000000
--- a/packages/MediaComponents/apex/java/android/media/MediaParceledListSlice.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/* 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;
-
-/** @hide */
-parcelable MediaParceledListSlice;
\ No newline at end of file
diff --git a/packages/MediaComponents/apex/java/android/media/MediaParceledListSlice.java b/packages/MediaComponents/apex/java/android/media/MediaParceledListSlice.java
deleted file mode 100644
index ec3fdb7..0000000
--- a/packages/MediaComponents/apex/java/android/media/MediaParceledListSlice.java
+++ /dev/null
@@ -1,202 +0,0 @@
-/*
- * Copyright 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media;
-
-import android.annotation.UnsupportedAppUsage;
-import android.os.Binder;
-import android.os.Build;
-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.Collections;
-import java.util.List;
-
-/**
- * Transfer a large list of objects across an IPC. Splits into multiple transactions if needed.
- * Note: Only use classes declared final in order to avoid subclasses overriding reading/writing
- * parcel logic.
- *
- * TODO: Add test for sending large data
- * @hide
- */
-public class MediaParceledListSlice<T extends Parcelable> implements Parcelable {
-    private static final String TAG = "MediaParceledListSlice";
-    private static final boolean DEBUG = false;
-
-    private static final int MAX_IPC_SIZE = 64 * 1024; // IBinder.MAX_IPC_SIZE
-
-    final List<T> mList;
-
-    public MediaParceledListSlice(List<T> list) {
-        if (list == null) {
-            throw new IllegalArgumentException("list shouldn't be null");
-        }
-        mList = list;
-    }
-
-    MediaParceledListSlice(Parcel p) {
-        final int itemCount = p.readInt();
-        mList = new ArrayList<>(itemCount);
-        if (DEBUG) {
-            Log.d(TAG, "Retrieving " + itemCount + " items");
-        }
-        if (itemCount <= 0) {
-            return;
-        }
-
-        int i = 0;
-        while (i < itemCount) {
-            if (p.readInt() == 0) {
-                break;
-            }
-
-            final T parcelable = p.readParcelable(null);
-            mList.add(parcelable);
-
-            if (DEBUG) {
-                Log.d(TAG, "Read inline #" + i + ": " + mList.get(mList.size() - 1));
-            }
-            i++;
-        }
-        if (i >= itemCount) {
-            return;
-        }
-        final IBinder retriever = p.readStrongBinder();
-        while (i < itemCount) {
-            if (DEBUG) {
-                Log.d(TAG, "Reading more @" + i + " of " + itemCount + ": 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 " + itemCount, e);
-                return;
-            }
-            while (i < itemCount && reply.readInt() != 0) {
-                final T parcelable = reply.readParcelable(null);
-                mList.add(parcelable);
-
-                if (DEBUG) {
-                    Log.d(TAG, "Read extra #" + i + ": " + mList.get(mList.size() - 1));
-                }
-                i++;
-            }
-            reply.recycle();
-            data.recycle();
-        }
-    }
-
-    public List<T> getList() {
-        return mList;
-    }
-
-    /**
-     * 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 itemCount = mList.size();
-        dest.writeInt(itemCount);
-        if (DEBUG) {
-            Log.d(TAG, "Writing " + itemCount + " items");
-        }
-        if (itemCount > 0) {
-            int i = 0;
-            while (i < itemCount && dest.dataSize() < MAX_IPC_SIZE) {
-                dest.writeInt(1);
-
-                final T parcelable = mList.get(i);
-                dest.writeParcelable(parcelable, flags);
-
-                if (DEBUG) {
-                    Log.d(TAG, "Wrote inline #" + i + ": " + mList.get(i));
-                }
-                i++;
-            }
-            if (i < itemCount) {
-                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 " + itemCount);
-                        }
-                        while (i < itemCount && reply.dataSize() < MAX_IPC_SIZE) {
-                            reply.writeInt(1);
-
-                            final T parcelable = mList.get(i);
-                            reply.writeParcelable(parcelable, flags);
-
-                            if (DEBUG) {
-                                Log.d(TAG, "Wrote extra #" + i + ": " + mList.get(i));
-                            }
-                            i++;
-                        }
-                        if (i < itemCount) {
-                            if (DEBUG) {
-                                Log.d(TAG, "Breaking @" + i + " of " + itemCount);
-                            }
-                            reply.writeInt(0);
-                        }
-                        return true;
-                    }
-                };
-                if (DEBUG) {
-                    Log.d(TAG, "Breaking @" + i + " of " + itemCount + ": retriever=" + retriever);
-                }
-                dest.writeStrongBinder(retriever);
-            }
-        }
-    }
-
-    @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;
-    }
-
-    public static final Parcelable.Creator<MediaParceledListSlice> CREATOR =
-            new Parcelable.Creator<MediaParceledListSlice>() {
-        @Override
-        public MediaParceledListSlice createFromParcel(Parcel in) {
-            return new MediaParceledListSlice(in);
-        }
-
-        @Override
-        public MediaParceledListSlice[] newArray(int size) {
-            return new MediaParceledListSlice[size];
-        }
-    };
-}
diff --git a/packages/MediaComponents/apex/java/android/media/Rating.aidl b/packages/MediaComponents/apex/java/android/media/Rating.aidl
deleted file mode 100644
index 1dc336a..0000000
--- a/packages/MediaComponents/apex/java/android/media/Rating.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * 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;
-
-parcelable Rating;
diff --git a/packages/MediaComponents/apex/java/android/media/Rating.java b/packages/MediaComponents/apex/java/android/media/Rating.java
deleted file mode 100644
index 04d5364..0000000
--- a/packages/MediaComponents/apex/java/android/media/Rating.java
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * 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 final static 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 final static 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 final static int RATING_HEART = 1;
-
-    /**
-     * A rating style for "thumb up" vs "thumb down".
-     */
-    public final static int RATING_THUMB_UP_DOWN = 2;
-
-    /**
-     * A rating style with 0 to 3 stars.
-     */
-    public final static int RATING_3_STARS = 3;
-
-    /**
-     * A rating style with 0 to 4 stars.
-     */
-    public final static int RATING_4_STARS = 4;
-
-    /**
-     * A rating style with 0 to 5 stars.
-     */
-    public final static int RATING_5_STARS = 5;
-
-    /**
-     * A rating style expressed as a percentage.
-     */
-    public final static int RATING_PERCENTAGE = 6;
-
-    private final static 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 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)) {
-            Log.e(TAG, "Trying to set out of range star-based rating");
-            return null;
-        }
-        return new Rating(starRatingStyle, starRating);
-    }
-
-    /**
-     * 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)) {
-            Log.e(TAG, "Invalid percentage-based rating value");
-            return null;
-        } else {
-            return new Rating(RATING_PERCENTAGE, percent);
-        }
-    }
-
-    /**
-     * 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() {
-        switch (mRatingStyle) {
-            case RATING_3_STARS:
-            case RATING_4_STARS:
-            case RATING_5_STARS:
-                if (isRated()) {
-                    return mRatingValue;
-                }
-            default:
-                return -1.0f;
-        }
-    }
-
-    /**
-     * 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/packages/MediaComponents/apex/java/android/media/VolumeProvider.java b/packages/MediaComponents/apex/java/android/media/VolumeProvider.java
deleted file mode 100644
index 1c017c5..0000000
--- a/packages/MediaComponents/apex/java/android/media/VolumeProvider.java
+++ /dev/null
@@ -1,161 +0,0 @@
-/*
- * 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.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 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) {
-        mControlType = volumeControl;
-        mMaxVolume = maxVolume;
-        mCurrentVolume = currentVolume;
-    }
-
-    /**
-     * 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);
-        }
-    }
-
-    /**
-     * 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 static abstract class Callback {
-        public abstract void onVolumeChanged(VolumeProvider volumeProvider);
-    }
-}
diff --git a/packages/MediaComponents/apex/java/android/media/browse/MediaBrowser.aidl b/packages/MediaComponents/apex/java/android/media/browse/MediaBrowser.aidl
deleted file mode 100644
index 782e094..0000000
--- a/packages/MediaComponents/apex/java/android/media/browse/MediaBrowser.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 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;
-
-parcelable MediaBrowser.MediaItem;
\ No newline at end of file
diff --git a/packages/MediaComponents/apex/java/android/media/browse/MediaBrowser.java b/packages/MediaComponents/apex/java/android/media/browse/MediaBrowser.java
deleted file mode 100644
index b1b14c6..0000000
--- a/packages/MediaComponents/apex/java/android/media/browse/MediaBrowser.java
+++ /dev/null
@@ -1,1171 +0,0 @@
-/*
- * 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.media.MediaDescription;
-import android.media.MediaParceledListSlice;
-import android.media.session.MediaController;
-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);
-                } 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 sane 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 final 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 final 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 final void onLoadChildren(final IMediaBrowserServiceCallbacks callback,
-            final String parentId, final MediaParceledListSlice 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 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 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 static abstract 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 static abstract 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;
-
-        public 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, MediaParceledListSlice list) {
-            onLoadChildrenWithOptions(parentId, list, null);
-        }
-
-        @Override
-        public void onLoadChildrenWithOptions(String parentId, MediaParceledListSlice list,
-                final 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;
-
-        public 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/packages/MediaComponents/apex/java/android/media/browse/MediaBrowserUtils.java b/packages/MediaComponents/apex/java/android/media/browse/MediaBrowserUtils.java
deleted file mode 100644
index 2943e60..0000000
--- a/packages/MediaComponents/apex/java/android/media/browse/MediaBrowserUtils.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * 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 {
-    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);
-        }
-    }
-
-    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/packages/MediaComponents/apex/java/android/media/session/IActiveSessionsListener.aidl b/packages/MediaComponents/apex/java/android/media/session/IActiveSessionsListener.aidl
deleted file mode 100644
index 4b9e4bd..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/IActiveSessionsListener.aidl
+++ /dev/null
@@ -1,26 +0,0 @@
-/* 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.media.session.MediaSession;
-
-/**
- * Listens for changes to the list of active sessions.
- * @hide
- */
-oneway interface IActiveSessionsListener {
-    void onActiveSessionsChanged(in List<MediaSession.Token> sessions);
-}
diff --git a/packages/MediaComponents/apex/java/android/media/session/ICallback.aidl b/packages/MediaComponents/apex/java/android/media/session/ICallback.aidl
deleted file mode 100644
index 322bffa..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/ICallback.aidl
+++ /dev/null
@@ -1,35 +0,0 @@
-/* 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.session;
-
-import android.app.PendingIntent;
-import android.content.ComponentName;
-import android.media.session.MediaSession;
-import android.view.KeyEvent;
-
-/**
- * @hide
- */
-oneway interface ICallback {
-    void onMediaKeyEventDispatchedToMediaSession(in KeyEvent event,
-            in MediaSession.Token sessionToken);
-    void onMediaKeyEventDispatchedToMediaButtonReceiver(in KeyEvent event,
-            in ComponentName mediaButtonReceiver);
-
-    void onAddressedPlayerChangedToMediaSession(in MediaSession.Token sessionToken);
-    void onAddressedPlayerChangedToMediaButtonReceiver(in ComponentName mediaButtonReceiver);
-}
-
diff --git a/packages/MediaComponents/apex/java/android/media/session/IOnMediaKeyListener.aidl b/packages/MediaComponents/apex/java/android/media/session/IOnMediaKeyListener.aidl
deleted file mode 100644
index aa98ea3..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/IOnMediaKeyListener.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-/* 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.session;
-
-import android.os.ResultReceiver;
-import android.view.KeyEvent;
-
-/**
- * Listener to handle media key.
- * @hide
- */
-oneway interface IOnMediaKeyListener {
-    void onMediaKey(in KeyEvent event, in ResultReceiver result);
-}
-
diff --git a/packages/MediaComponents/apex/java/android/media/session/IOnVolumeKeyLongPressListener.aidl b/packages/MediaComponents/apex/java/android/media/session/IOnVolumeKeyLongPressListener.aidl
deleted file mode 100644
index 07b8347..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/IOnVolumeKeyLongPressListener.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-/* 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.session;
-
-import android.view.KeyEvent;
-
-/**
- * Listener to handle volume key long-press.
- * @hide
- */
-oneway interface IOnVolumeKeyLongPressListener {
-    void onVolumeKeyLongPress(in KeyEvent event);
-}
-
diff --git a/packages/MediaComponents/apex/java/android/media/session/ISession.aidl b/packages/MediaComponents/apex/java/android/media/session/ISession.aidl
deleted file mode 100644
index 14b1c64..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/ISession.aidl
+++ /dev/null
@@ -1,54 +0,0 @@
-/* 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.media.AudioAttributes;
-import android.media.MediaMetadata;
-import android.media.MediaParceledListSlice;
-import android.media.session.ISessionController;
-import android.media.session.PlaybackState;
-import android.media.session.MediaSession;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-
-/**
- * Interface to a MediaSession in the system.
- * @hide
- */
-interface ISession {
-    void sendEvent(String event, in Bundle data);
-    ISessionController getController();
-    void setFlags(int flags);
-    void setActive(boolean active);
-    void setMediaButtonReceiver(in PendingIntent mbr);
-    void setLaunchPendingIntent(in PendingIntent pi);
-    void destroy();
-
-    // These commands are for the TransportPerformer
-    void setMetadata(in MediaMetadata metadata, long duration, String metadataDescription);
-    void setPlaybackState(in PlaybackState state);
-    void setQueue(in MediaParceledListSlice queue);
-    void setQueueTitle(CharSequence title);
-    void setExtras(in Bundle extras);
-    void setRatingType(int type);
-
-    // These commands relate to volume handling
-    //TODO(b/119751592): Decide if AudioAttributes should be updated.
-    //void setPlaybackToLocal(in AudioAttributes attributes);
-    void setPlaybackToRemote(int control, int max);
-    void setCurrentVolume(int currentVolume);
-}
diff --git a/packages/MediaComponents/apex/java/android/media/session/ISessionCallback.aidl b/packages/MediaComponents/apex/java/android/media/session/ISessionCallback.aidl
deleted file mode 100644
index 626338d..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/ISessionCallback.aidl
+++ /dev/null
@@ -1,71 +0,0 @@
-/* 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.content.Intent;
-import android.media.Rating;
-import android.media.session.ISessionControllerCallback;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-
-/**
- * @hide
- */
-oneway interface ISessionCallback {
-    void onCommand(String packageName, int pid, int uid, ISessionControllerCallback caller,
-            String command, in Bundle args, in ResultReceiver cb);
-    void onMediaButton(String packageName, int pid, int uid, in Intent mediaButtonIntent,
-            int sequenceNumber, in ResultReceiver cb);
-    void onMediaButtonFromController(String packageName, int pid, int uid,
-            ISessionControllerCallback caller, in Intent mediaButtonIntent);
-
-    // These callbacks are for the TransportPerformer
-    void onPrepare(String packageName, int pid, int uid, ISessionControllerCallback caller);
-    void onPrepareFromMediaId(String packageName, int pid, int uid,
-            ISessionControllerCallback caller, String mediaId, in Bundle extras);
-    void onPrepareFromSearch(String packageName, int pid, int uid,
-            ISessionControllerCallback caller, String query, in Bundle extras);
-    void onPrepareFromUri(String packageName, int pid, int uid, ISessionControllerCallback caller,
-            in Uri uri, in Bundle extras);
-    void onPlay(String packageName, int pid, int uid, ISessionControllerCallback caller);
-    void onPlayFromMediaId(String packageName, int pid, int uid, ISessionControllerCallback caller,
-            String mediaId, in Bundle extras);
-    void onPlayFromSearch(String packageName, int pid, int uid, ISessionControllerCallback caller,
-            String query, in Bundle extras);
-    void onPlayFromUri(String packageName, int pid, int uid, ISessionControllerCallback caller,
-            in Uri uri, in Bundle extras);
-    void onSkipToTrack(String packageName, int pid, int uid, ISessionControllerCallback caller,
-            long id);
-    void onPause(String packageName, int pid, int uid, ISessionControllerCallback caller);
-    void onStop(String packageName, int pid, int uid, ISessionControllerCallback caller);
-    void onNext(String packageName, int pid, int uid, ISessionControllerCallback caller);
-    void onPrevious(String packageName, int pid, int uid, ISessionControllerCallback caller);
-    void onFastForward(String packageName, int pid, int uid, ISessionControllerCallback caller);
-    void onRewind(String packageName, int pid, int uid, ISessionControllerCallback caller);
-    void onSeekTo(String packageName, int pid, int uid, ISessionControllerCallback caller,
-            long pos);
-    void onRate(String packageName, int pid, int uid, ISessionControllerCallback caller,
-            in Rating rating);
-    void onCustomAction(String packageName, int pid, int uid, ISessionControllerCallback caller,
-            String action, in Bundle args);
-
-    // These callbacks are for volume handling
-    void onAdjustVolume(String packageName, int pid, int uid, ISessionControllerCallback caller,
-            int direction);
-    void onSetVolumeTo(String packageName, int pid, int uid,
-            ISessionControllerCallback caller, int value);
-}
diff --git a/packages/MediaComponents/apex/java/android/media/session/ISessionController.aidl b/packages/MediaComponents/apex/java/android/media/session/ISessionController.aidl
deleted file mode 100644
index 433b12f..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/ISessionController.aidl
+++ /dev/null
@@ -1,88 +0,0 @@
-/* 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.content.Intent;
-import android.media.MediaMetadata;
-import android.media.MediaParceledListSlice;
-import android.media.Rating;
-import android.media.session.ISessionControllerCallback;
-import android.media.session.MediaSession;
-import android.media.session.ParcelableVolumeInfo;
-import android.media.session.PlaybackState;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-import android.view.KeyEvent;
-
-import java.util.List;
-
-/**
- * Interface to MediaSessionRecord in the system.
- * @hide
- */
-interface ISessionController {
-    void sendCommand(String packageName, ISessionControllerCallback caller,
-            String command, in Bundle args, in ResultReceiver cb);
-    boolean sendMediaButton(String packageName, ISessionControllerCallback caller,
-            boolean asSystemService, in KeyEvent mediaButton);
-    void registerCallbackListener(String packageName, ISessionControllerCallback cb);
-    void unregisterCallbackListener(ISessionControllerCallback cb);
-    boolean isTransportControlEnabled();
-    String getPackageName();
-    String getTag();
-    PendingIntent getLaunchPendingIntent();
-    long getFlags();
-    ParcelableVolumeInfo getVolumeAttributes();
-    void adjustVolume(String packageName, String opPackageName, ISessionControllerCallback caller,
-            boolean asSystemService, int direction, int flags);
-    void setVolumeTo(String packageName, String opPackageName, ISessionControllerCallback caller,
-            int value, int flags);
-
-    // These commands are for the TransportControls
-    void prepare(String packageName, ISessionControllerCallback caller);
-    void prepareFromMediaId(String packageName, ISessionControllerCallback caller,
-            String mediaId, in Bundle extras);
-    void prepareFromSearch(String packageName, ISessionControllerCallback caller,
-            String string, in Bundle extras);
-    void prepareFromUri(String packageName, ISessionControllerCallback caller,
-            in Uri uri, in Bundle extras);
-    void play(String packageName, ISessionControllerCallback caller);
-    void playFromMediaId(String packageName, ISessionControllerCallback caller,
-            String mediaId, in Bundle extras);
-    void playFromSearch(String packageName, ISessionControllerCallback caller,
-            String string, in Bundle extras);
-    void playFromUri(String packageName, ISessionControllerCallback caller,
-            in Uri uri, in Bundle extras);
-    void skipToQueueItem(String packageName, ISessionControllerCallback caller, long id);
-    void pause(String packageName, ISessionControllerCallback caller);
-    void stop(String packageName, ISessionControllerCallback caller);
-    void next(String packageName, ISessionControllerCallback caller);
-    void previous(String packageName, ISessionControllerCallback caller);
-    void fastForward(String packageName, ISessionControllerCallback caller);
-    void rewind(String packageName, ISessionControllerCallback caller);
-    void seekTo(String packageName, ISessionControllerCallback caller, long pos);
-    void rate(String packageName, ISessionControllerCallback caller, in Rating rating);
-    void sendCustomAction(String packageName, ISessionControllerCallback caller,
-            String action, in Bundle args);
-    MediaMetadata getMetadata();
-    PlaybackState getPlaybackState();
-    MediaParceledListSlice getQueue();
-    CharSequence getQueueTitle();
-    Bundle getExtras();
-    int getRatingType();
-}
diff --git a/packages/MediaComponents/apex/java/android/media/session/ISessionControllerCallback.aidl b/packages/MediaComponents/apex/java/android/media/session/ISessionControllerCallback.aidl
deleted file mode 100644
index f5cc4f6..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/ISessionControllerCallback.aidl
+++ /dev/null
@@ -1,39 +0,0 @@
-/* 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.media.MediaMetadata;
-import android.media.MediaParceledListSlice;
-import android.media.session.ParcelableVolumeInfo;
-import android.media.session.PlaybackState;
-import android.media.session.MediaSession;
-import android.os.Bundle;
-
-/**
- * @hide
- */
-oneway interface ISessionControllerCallback {
-    void onEvent(String event, in Bundle extras);
-    void onSessionDestroyed();
-
-    // These callbacks are for the TransportController
-    void onPlaybackStateChanged(in PlaybackState state);
-    void onMetadataChanged(in MediaMetadata metadata);
-    void onQueueChanged(in MediaParceledListSlice queue);
-    void onQueueTitleChanged(CharSequence title);
-    void onExtrasChanged(in Bundle extras);
-    void onVolumeInfoChanged(in ParcelableVolumeInfo info);
-}
diff --git a/packages/MediaComponents/apex/java/android/media/session/ISessionManager.aidl b/packages/MediaComponents/apex/java/android/media/session/ISessionManager.aidl
deleted file mode 100644
index d6c226f..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/ISessionManager.aidl
+++ /dev/null
@@ -1,58 +0,0 @@
-/* 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.content.ComponentName;
-import android.media.IRemoteVolumeController;
-import android.media.session.IActiveSessionsListener;
-import android.media.session.ICallback;
-import android.media.session.IOnMediaKeyListener;
-import android.media.session.IOnVolumeKeyLongPressListener;
-import android.media.session.ISession;
-import android.media.session.ISessionCallback;
-import android.os.Bundle;
-import android.view.KeyEvent;
-
-/**
- * Interface to the MediaSessionManagerService
- * @hide
- */
-interface ISessionManager {
-    ISession createSession(String packageName, in ISessionCallback cb, String tag, int userId);
-    List<IBinder> getSessions(in ComponentName compName, int userId);
-    void dispatchMediaKeyEvent(String packageName, boolean asSystemService, in KeyEvent keyEvent,
-            boolean needWakeLock);
-    void dispatchVolumeKeyEvent(String packageName, String opPackageName, boolean asSystemService,
-            in KeyEvent keyEvent, int stream, boolean musicOnly);
-    void dispatchAdjustVolume(String packageName, String opPackageName, int suggestedStream,
-            int delta, int flags);
-    void addSessionsListener(in IActiveSessionsListener listener, in ComponentName compName,
-            int userId);
-    void removeSessionsListener(in IActiveSessionsListener listener);
-
-    // This is for the system volume UI only
-    void setRemoteVolumeController(in IRemoteVolumeController rvc);
-
-    // For PhoneWindowManager to precheck media keys
-    boolean isGlobalPriorityActive();
-
-    void setCallback(in ICallback callback);
-    void setOnVolumeKeyLongPressListener(in IOnVolumeKeyLongPressListener listener);
-    void setOnMediaKeyListener(in IOnMediaKeyListener listener);
-
-    // MediaSession2
-    boolean isTrusted(String controllerPackageName, int controllerPid, int controllerUid);
-}
diff --git a/packages/MediaComponents/apex/java/android/media/session/MediaController.java b/packages/MediaComponents/apex/java/android/media/session/MediaController.java
deleted file mode 100644
index 65682a8..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/MediaController.java
+++ /dev/null
@@ -1,1190 +0,0 @@
-/*
- * 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.NonNull;
-import android.annotation.Nullable;
-import android.annotation.UnsupportedAppUsage;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.media.AudioAttributes;
-import android.media.AudioManager;
-import android.media.MediaMetadata;
-import android.media.MediaParceledListSlice;
-import android.media.Rating;
-import android.media.VolumeProvider;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.text.TextUtils;
-import android.util.Log;
-import android.view.KeyEvent;
-
-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 final TransportControls mTransportControls;
-
-    /**
-     * Call for creating a MediaController directly from a binder. Should only
-     * be used by framework code.
-     *
-     * @hide
-     */
-    public MediaController(Context context, ISessionController sessionBinder) {
-        if (sessionBinder == null) {
-            throw new IllegalArgumentException("Session token cannot be null");
-        }
-        if (context == null) {
-            throw new IllegalArgumentException("Context cannot be null");
-        }
-        mSessionBinder = sessionBinder;
-        mTransportControls = new TransportControls();
-        mToken = new MediaSession.Token(sessionBinder);
-        mContext = context;
-    }
-
-    /**
-     * 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) {
-        this(context, token.getBinder());
-    }
-
-    /**
-     * 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) {
-        return dispatchMediaButtonEventInternal(false, keyEvent);
-    }
-
-    /**
-     * Dispatches the media button 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 media key event
-     * @return {@code true} if the event was sent to the session, {@code false} otherwise
-     * @hide
-     */
-    public boolean dispatchMediaButtonEventAsSystemService(@NonNull KeyEvent keyEvent) {
-        return dispatchMediaButtonEventInternal(true, keyEvent);
-    }
-
-    private boolean dispatchMediaButtonEventInternal(boolean asSystemService,
-            @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(), mCbStub,
-                    asSystemService, keyEvent);
-        } catch (RemoteException e) {
-            // System is dead. =(
-        }
-        return false;
-    }
-
-    /**
-     * Dispatches the volume button 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 volume key event
-     * @hide
-     */
-    public void dispatchVolumeButtonEventAsSystemService(@NonNull KeyEvent keyEvent) {
-        switch (keyEvent.getAction()) {
-            case KeyEvent.ACTION_DOWN: {
-                int direction = 0;
-                switch (keyEvent.getKeyCode()) {
-                    case KeyEvent.KEYCODE_VOLUME_UP:
-                        direction = AudioManager.ADJUST_RAISE;
-                        break;
-                    case KeyEvent.KEYCODE_VOLUME_DOWN:
-                        direction = AudioManager.ADJUST_LOWER;
-                        break;
-                    case KeyEvent.KEYCODE_VOLUME_MUTE:
-                        direction = AudioManager.ADJUST_TOGGLE_MUTE;
-                        break;
-                }
-                try {
-                    mSessionBinder.adjustVolume(mContext.getPackageName(),
-                            mContext.getOpPackageName(), mCbStub, true, direction,
-                            AudioManager.FLAG_SHOW_UI);
-                } catch (RemoteException e) {
-                    Log.wtf(TAG, "Error calling adjustVolumeBy", e);
-                }
-            }
-
-            case KeyEvent.ACTION_UP: {
-                final int flags = AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE
-                        | AudioManager.FLAG_FROM_KEY;
-                try {
-                    mSessionBinder.adjustVolume(mContext.getPackageName(),
-                            mContext.getOpPackageName(), mCbStub, true, 0, flags);
-                } catch (RemoteException e) {
-                    Log.wtf(TAG, "Error calling adjustVolumeBy", e);
-                }
-            }
-        }
-    }
-
-    /**
-     * 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 {
-            MediaParceledListSlice queue = mSessionBinder.getQueue();
-            if (queue != null) {
-                return queue.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 @MediaSession.SessionFlags 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 {
-            ParcelableVolumeInfo result = mSessionBinder.getVolumeAttributes();
-            return new PlaybackInfo(result.volumeType, result.audioAttrs, result.controlType,
-                    result.maxVolume, result.currentVolume);
-
-        } 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 {
-            mSessionBinder.setVolumeTo(mContext.getPackageName(), mContext.getOpPackageName(),
-                    mCbStub, 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 {
-            mSessionBinder.adjustVolume(mContext.getPackageName(), mContext.getOpPackageName(),
-                    mCbStub, false, 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(), mCbStub, 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;
-    }
-
-    /**
-     * Get the session's tag for debugging purposes.
-     *
-     * @return The session's tag.
-     * @hide
-     */
-    public String getTag() {
-        if (mTag == null) {
-            try {
-                mTag = mSessionBinder.getTag();
-            } catch (RemoteException e) {
-                Log.d(TAG, "Dead object in getTag.", e);
-            }
-        }
-        return mTag;
-    }
-
-    /*
-     * @hide
-     */
-    ISessionController getSessionBinder() {
-        return mSessionBinder;
-    }
-
-    /**
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public boolean controlsSameSession(MediaController other) {
-        if (other == null) return false;
-        return mSessionBinder.asBinder() == other.getSessionBinder().asBinder();
-    }
-
-    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.registerCallbackListener(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.unregisterCallbackListener(mCbStub);
-            } catch (RemoteException e) {
-                Log.e(TAG, "Dead object in removeCallbackLocked");
-            }
-            mCbRegistered = false;
-        }
-        return success;
-    }
-
-    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 final 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 static abstract 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(), mCbStub);
-            } 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(), mCbStub, 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(), mCbStub, 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(), mCbStub, 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(), mCbStub);
-            } 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(), mCbStub, 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(), mCbStub, 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(), mCbStub, 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(), mCbStub, 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(), mCbStub);
-            } 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(), mCbStub);
-            } 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(), mCbStub, 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(), mCbStub);
-            } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling fastForward.", e);
-            }
-        }
-
-        /**
-         * Skip to the next item.
-         */
-        public void skipToNext() {
-            try {
-                mSessionBinder.next(mContext.getPackageName(), mCbStub);
-            } 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(), mCbStub);
-            } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling rewind.", e);
-            }
-        }
-
-        /**
-         * Skip to the previous item.
-         */
-        public void skipToPrevious() {
-            try {
-                mSessionBinder.previous(mContext.getPackageName(), mCbStub);
-            } 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(), mCbStub, rating);
-            } catch (RemoteException e) {
-                Log.wtf(TAG, "Error calling rate.", 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(), mCbStub, 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 {
-        /**
-         * The session uses remote playback.
-         */
-        public static final int PLAYBACK_TYPE_REMOTE = 2;
-        /**
-         * The session uses local playback.
-         */
-        public static final int PLAYBACK_TYPE_LOCAL = 1;
-
-        private final int mVolumeType;
-        private final int mVolumeControl;
-        private final int mMaxVolume;
-        private final int mCurrentVolume;
-        private final AudioAttributes mAudioAttrs;
-
-        /**
-         * @hide
-         */
-        public PlaybackInfo(int type, AudioAttributes attrs, int control, int max, int current) {
-            mVolumeType = type;
-            mAudioAttrs = attrs;
-            mVolumeControl = control;
-            mMaxVolume = max;
-            mCurrentVolume = current;
-        }
-
-        /**
-         * 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 mVolumeType;
-        }
-
-        /**
-         * 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;
-        }
-
-        /**
-         * 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;
-        }
-    }
-
-    private final static class CallbackStub extends ISessionControllerCallback.Stub {
-        private final WeakReference<MediaController> mController;
-
-        public 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(MediaParceledListSlice parceledQueue) {
-            List<MediaSession.QueueItem> queue = parceledQueue == null ? null : parceledQueue
-                    .getList();
-            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(ParcelableVolumeInfo pvi) {
-            MediaController controller = mController.get();
-            if (controller != null) {
-                PlaybackInfo info = new PlaybackInfo(pvi.volumeType, pvi.audioAttrs,
-                        pvi.controlType, pvi.maxVolume, pvi.currentVolume);
-                controller.postMessage(MSG_UPDATE_VOLUME, info, null);
-            }
-        }
-
-    }
-
-    private final static class MessageHandler extends Handler {
-        private final MediaController.Callback mCallback;
-        private boolean mRegistered = false;
-
-        public 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((List<MediaSession.QueueItem>) msg.obj);
-                    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/packages/MediaComponents/apex/java/android/media/session/MediaSession.aidl b/packages/MediaComponents/apex/java/android/media/session/MediaSession.aidl
deleted file mode 100644
index f657cef..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/MediaSession.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/* Copyright 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;
-
-parcelable MediaSession.Token;
-parcelable MediaSession.QueueItem;
\ No newline at end of file
diff --git a/packages/MediaComponents/apex/java/android/media/session/MediaSession.java b/packages/MediaComponents/apex/java/android/media/session/MediaSession.java
deleted file mode 100644
index 3cbeff9..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/MediaSession.java
+++ /dev/null
@@ -1,1569 +0,0 @@
-/*
- * 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.UnsupportedAppUsage;
-import android.app.Activity;
-import android.app.PendingIntent;
-import android.content.Context;
-import android.content.Intent;
-import android.media.AudioAttributes;
-import android.media.MediaDescription;
-import android.media.MediaMetadata;
-import android.media.MediaParceledListSlice;
-import android.media.Rating;
-import android.media.VolumeProvider;
-import android.media.session.MediaSessionManager.RemoteUserInfo;
-import android.net.Uri;
-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.os.UserHandle;
-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 {
-    private 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.
-     *
-     * @hide
-     */
-    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 final int mMaxBitmapSize;
-
-    private final MediaSession.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.
-     *
-     * @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, UserHandle.myUserId());
-    }
-
-    /**
-     * Creates a new session as the specified user. To create a session as a
-     * user other than your own you must hold the
-     * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL}
-     * permission.
-     *
-     * @param context The context to use to create the session.
-     * @param tag A short name for debugging purposes.
-     * @param userId The user id to create the session as.
-     * @hide
-     */
-    public MediaSession(@NonNull Context context, @NonNull String tag, int userId) {
-        if (context == null) {
-            throw new IllegalArgumentException("context cannot be null.");
-        }
-        if (TextUtils.isEmpty(tag)) {
-            throw new IllegalArgumentException("tag cannot be null or empty");
-        }
-        mMaxBitmapSize = context.getResources().getDimensionPixelSize(
-                android.R.dimen.config_mediaMetadataBitmapMaxSize);
-        mCbStub = new CallbackStub(this);
-        MediaSessionManager manager = (MediaSessionManager) context
-                .getSystemService(Context.MEDIA_SESSION_SERVICE);
-        try {
-            //TODO(b/119749862): Resolve hidden API usage. MediaSessioManager#createSession
-            //mBinder = manager.createSession(mCbStub, tag, userId);
-            mBinder = null;  //TODO: remove this.
-            mSessionToken = new Token(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.
-     *
-     * @param mbr The {@link PendingIntent} to send the media button event to.
-     */
-    public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
-        try {
-            mBinder.setMediaButtonReceiver(mbr);
-        } catch (RemoteException e) {
-            Log.wtf(TAG, "Failure in setMediaButtonReceiver.", 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.");
-        }
-        //TODO(b/119751592): Decide if AudioAttributes should be updated.
-        /*
-        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());
-            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.destroy();
-        } 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, 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 {
-            mBinder.setQueue(queue == null ? null : new MediaParceledListSlice<QueueItem>(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;
-    }
-
-    private void dispatchPrepare(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE, null, null);
-    }
-
-    private void dispatchPrepareFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_MEDIA_ID, mediaId, extras);
-    }
-
-    private void dispatchPrepareFromSearch(RemoteUserInfo caller, String query, Bundle extras) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_SEARCH, query, extras);
-    }
-
-    private void dispatchPrepareFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_URI, uri, extras);
-    }
-
-    private void dispatchPlay(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PLAY, null, null);
-    }
-
-    private void dispatchPlayFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PLAY_MEDIA_ID, mediaId, extras);
-    }
-
-    private void dispatchPlayFromSearch(RemoteUserInfo caller, String query, Bundle extras) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras);
-    }
-
-    private void dispatchPlayFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PLAY_URI, uri, extras);
-    }
-
-    private void dispatchSkipToItem(RemoteUserInfo caller, long id) {
-        postToCallback(caller, CallbackMessageHandler.MSG_SKIP_TO_ITEM, id, null);
-    }
-
-    private void dispatchPause(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PAUSE, null, null);
-    }
-
-    private void dispatchStop(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_STOP, null, null);
-    }
-
-    private void dispatchNext(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_NEXT, null, null);
-    }
-
-    private void dispatchPrevious(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PREVIOUS, null, null);
-    }
-
-    private void dispatchFastForward(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_FAST_FORWARD, null, null);
-    }
-
-    private void dispatchRewind(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_REWIND, null, null);
-    }
-
-    private void dispatchSeekTo(RemoteUserInfo caller, long pos) {
-        postToCallback(caller, CallbackMessageHandler.MSG_SEEK_TO, pos, null);
-    }
-
-    private void dispatchRate(RemoteUserInfo caller, Rating rating) {
-        postToCallback(caller, CallbackMessageHandler.MSG_RATE, rating, null);
-    }
-
-    private void dispatchCustomAction(RemoteUserInfo caller, String action, Bundle args) {
-        postToCallback(caller, CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args);
-    }
-
-    private void dispatchMediaButton(RemoteUserInfo caller, Intent mediaButtonIntent) {
-        postToCallback(caller, CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent, null);
-    }
-
-    private void dispatchMediaButtonDelayed(RemoteUserInfo info, Intent mediaButtonIntent,
-            long delay) {
-        postToCallbackDelayed(info, CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT,
-                mediaButtonIntent, null, delay);
-    }
-
-    private void dispatchAdjustVolume(RemoteUserInfo caller, int direction) {
-        postToCallback(caller, CallbackMessageHandler.MSG_ADJUST_VOLUME, direction, null);
-    }
-
-    private void dispatchSetVolumeTo(RemoteUserInfo caller, int volume) {
-        postToCallback(caller, CallbackMessageHandler.MSG_SET_VOLUME, volume, null);
-    }
-
-    private void dispatchCommand(RemoteUserInfo caller, String command, Bundle args,
-            ResultReceiver resultCb) {
-        Command cmd = new Command(command, args, resultCb);
-        postToCallback(caller, CallbackMessageHandler.MSG_COMMAND, cmd, null);
-    }
-
-    private void postToCallback(RemoteUserInfo caller, int what, Object obj, Bundle data) {
-        postToCallbackDelayed(caller, what, obj, data, 0);
-    }
-
-    private void postToCallbackDelayed(RemoteUserInfo caller, int what, Object obj, Bundle data,
-            long delay) {
-        synchronized (mLock) {
-            if (mCallback != null) {
-                mCallback.post(caller, what, obj, data, delay);
-            }
-        }
-    }
-
-    /**
-     * Return true if this is considered an active playback state.
-     *
-     * @hide
-     */
-    public static boolean isActiveState(int state) {
-        switch (state) {
-            case PlaybackState.STATE_FAST_FORWARDING:
-            case PlaybackState.STATE_REWINDING:
-            case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
-            case PlaybackState.STATE_SKIPPING_TO_NEXT:
-            case PlaybackState.STATE_BUFFERING:
-            case PlaybackState.STATE_CONNECTING:
-            case PlaybackState.STATE_PLAYING:
-                return true;
-        }
-        return false;
-    }
-
-    /**
-     * 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 ISessionController mBinder;
-
-        /**
-         * @hide
-         */
-        public Token(ISessionController binder) {
-            mBinder = binder;
-        }
-
-        @Override
-        public int describeContents() {
-            return 0;
-        }
-
-        @Override
-        public void writeToParcel(Parcel dest, int flags) {
-            dest.writeStrongBinder(mBinder.asBinder());
-        }
-
-        @Override
-        public int hashCode() {
-            final int prime = 31;
-            int result = 1;
-            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 (mBinder == null) {
-                if (other.mBinder != null)
-                    return false;
-            } else if (!mBinder.asBinder().equals(other.mBinder.asBinder()))
-                return false;
-            return true;
-        }
-
-        ISessionController getBinder() {
-            return mBinder;
-        }
-
-        public static final Parcelable.Creator<Token> CREATOR
-                = new Parcelable.Creator<Token>() {
-            @Override
-            public Token createFromParcel(Parcel in) {
-                return new Token(ISessionController.Stub.asInterface(in.readStrongBinder()));
-            }
-
-            @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) {
-        }
-
-        /**
-         * 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,
-                ISessionControllerCallback caller) {
-            return new RemoteUserInfo(packageName, pid, uid);
-        }
-
-        @Override
-        public void onCommand(String packageName, int pid, int uid,
-                ISessionControllerCallback caller, String command, Bundle args, ResultReceiver cb) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchCommand(createRemoteUserInfo(packageName, pid, uid, caller),
-                        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, null),
-                            mediaButtonIntent);
-                }
-            } finally {
-                if (cb != null) {
-                    cb.send(sequenceNumber, null);
-                }
-            }
-        }
-
-        @Override
-        public void onMediaButtonFromController(String packageName, int pid, int uid,
-                ISessionControllerCallback caller, Intent mediaButtonIntent) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid, caller),
-                        mediaButtonIntent);
-            }
-        }
-
-        @Override
-        public void onPrepare(String packageName, int pid, int uid,
-                ISessionControllerCallback caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onPrepareFromMediaId(String packageName, int pid, int uid,
-                ISessionControllerCallback caller, String mediaId,
-                Bundle extras) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPrepareFromMediaId(
-                        createRemoteUserInfo(packageName, pid, uid, caller), mediaId, extras);
-            }
-        }
-
-        @Override
-        public void onPrepareFromSearch(String packageName, int pid, int uid,
-                ISessionControllerCallback caller, String query,
-                Bundle extras) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPrepareFromSearch(
-                        createRemoteUserInfo(packageName, pid, uid, caller), query, extras);
-            }
-        }
-
-        @Override
-        public void onPrepareFromUri(String packageName, int pid, int uid,
-                ISessionControllerCallback caller, Uri uri, Bundle extras) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPrepareFromUri(createRemoteUserInfo(packageName, pid, uid, caller),
-                        uri, extras);
-            }
-        }
-
-        @Override
-        public void onPlay(String packageName, int pid, int uid,
-                ISessionControllerCallback caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPlay(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onPlayFromMediaId(String packageName, int pid, int uid,
-                ISessionControllerCallback caller, String mediaId,
-                Bundle extras) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPlayFromMediaId(createRemoteUserInfo(packageName, pid, uid, caller),
-                        mediaId, extras);
-            }
-        }
-
-        @Override
-        public void onPlayFromSearch(String packageName, int pid, int uid,
-                ISessionControllerCallback caller, String query,
-                Bundle extras) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPlayFromSearch(createRemoteUserInfo(packageName, pid, uid, caller),
-                        query, extras);
-            }
-        }
-
-        @Override
-        public void onPlayFromUri(String packageName, int pid, int uid,
-                ISessionControllerCallback caller, Uri uri, Bundle extras) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPlayFromUri(createRemoteUserInfo(packageName, pid, uid, caller),
-                        uri, extras);
-            }
-        }
-
-        @Override
-        public void onSkipToTrack(String packageName, int pid, int uid,
-                ISessionControllerCallback caller, long id) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchSkipToItem(createRemoteUserInfo(packageName, pid, uid, caller), id);
-            }
-        }
-
-        @Override
-        public void onPause(String packageName, int pid, int uid,
-                ISessionControllerCallback caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPause(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onStop(String packageName, int pid, int uid,
-                ISessionControllerCallback caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchStop(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onNext(String packageName, int pid, int uid,
-                ISessionControllerCallback caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchNext(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onPrevious(String packageName, int pid, int uid,
-                ISessionControllerCallback caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onFastForward(String packageName, int pid, int uid,
-                ISessionControllerCallback caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchFastForward(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onRewind(String packageName, int pid, int uid,
-                ISessionControllerCallback caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchRewind(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onSeekTo(String packageName, int pid, int uid,
-                ISessionControllerCallback caller, long pos) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchSeekTo(createRemoteUserInfo(packageName, pid, uid, caller), pos);
-            }
-        }
-
-        @Override
-        public void onRate(String packageName, int pid, int uid, ISessionControllerCallback caller,
-                Rating rating) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchRate(createRemoteUserInfo(packageName, pid, uid, caller), rating);
-            }
-        }
-
-        @Override
-        public void onCustomAction(String packageName, int pid, int uid,
-                ISessionControllerCallback caller, String action, Bundle args) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchCustomAction(createRemoteUserInfo(packageName, pid, uid, caller),
-                        action, args);
-            }
-        }
-
-        @Override
-        public void onAdjustVolume(String packageName, int pid, int uid,
-                ISessionControllerCallback caller, int direction) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchAdjustVolume(createRemoteUserInfo(packageName, pid, uid, caller),
-                        direction);
-            }
-        }
-
-        @Override
-        public void onSetVolumeTo(String packageName, int pid, int uid,
-                ISessionControllerCallback caller, int value) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchSetVolumeTo(createRemoteUserInfo(packageName, pid, uid, caller),
-                        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
-        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 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;
-
-        public 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_CUSTOM_ACTION = 20;
-        private static final int MSG_ADJUST_VOLUME = 21;
-        private static final int MSG_SET_VOLUME = 22;
-        private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 23;
-
-        private MediaSession.Callback mCallback;
-        private RemoteUserInfo mCurrentControllerInfo;
-
-        public CallbackMessageHandler(Looper looper, MediaSession.Callback callback) {
-            super(looper);
-            mCallback = callback;
-            mCallback.mHandler = this;
-        }
-
-        public 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_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/packages/MediaComponents/apex/java/android/media/session/ParcelableVolumeInfo.aidl b/packages/MediaComponents/apex/java/android/media/session/ParcelableVolumeInfo.aidl
deleted file mode 100644
index c4250f0..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/ParcelableVolumeInfo.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 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;
-
-parcelable ParcelableVolumeInfo;
diff --git a/packages/MediaComponents/apex/java/android/media/session/ParcelableVolumeInfo.java b/packages/MediaComponents/apex/java/android/media/session/ParcelableVolumeInfo.java
deleted file mode 100644
index f59c975..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/ParcelableVolumeInfo.java
+++ /dev/null
@@ -1,80 +0,0 @@
-/* Copyright 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.media.AudioAttributes;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Convenience class for passing information about the audio configuration of a
- * session. The public implementation is {@link MediaController.PlaybackInfo}.
- *
- * @hide
- */
-public class ParcelableVolumeInfo implements Parcelable {
-    public int volumeType;
-    public AudioAttributes audioAttrs;
-    public int controlType;
-    public int maxVolume;
-    public int currentVolume;
-
-    public ParcelableVolumeInfo(int volumeType, AudioAttributes audioAttrs, int controlType,
-            int maxVolume,
-            int currentVolume) {
-        this.volumeType = volumeType;
-        this.audioAttrs = audioAttrs;
-        this.controlType = controlType;
-        this.maxVolume = maxVolume;
-        this.currentVolume = currentVolume;
-    }
-
-    public ParcelableVolumeInfo(Parcel from) {
-        volumeType = from.readInt();
-        controlType = from.readInt();
-        maxVolume = from.readInt();
-        currentVolume = from.readInt();
-        audioAttrs = AudioAttributes.CREATOR.createFromParcel(from);
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(volumeType);
-        dest.writeInt(controlType);
-        dest.writeInt(maxVolume);
-        dest.writeInt(currentVolume);
-        audioAttrs.writeToParcel(dest, flags);
-    }
-
-
-    public static final Parcelable.Creator<ParcelableVolumeInfo> CREATOR
-            = new Parcelable.Creator<ParcelableVolumeInfo>() {
-        @Override
-        public ParcelableVolumeInfo createFromParcel(Parcel in) {
-            return new ParcelableVolumeInfo(in);
-        }
-
-        @Override
-        public ParcelableVolumeInfo[] newArray(int size) {
-            return new ParcelableVolumeInfo[size];
-        }
-    };
-}
diff --git a/packages/MediaComponents/apex/java/android/media/session/PlaybackState.aidl b/packages/MediaComponents/apex/java/android/media/session/PlaybackState.aidl
deleted file mode 100644
index 0876ebd..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/PlaybackState.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 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;
-
-parcelable PlaybackState;
diff --git a/packages/MediaComponents/apex/java/android/media/session/PlaybackState.java b/packages/MediaComponents/apex/java/android/media/session/PlaybackState.java
deleted file mode 100644
index ed4f9af..0000000
--- a/packages/MediaComponents/apex/java/android/media/session/PlaybackState.java
+++ /dev/null
@@ -1,1081 +0,0 @@
-/*
- * 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.media.RemoteControlClient;
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.os.SystemClock;
-import android.text.TextUtils;
-import java.util.ArrayList;
-import java.util.List;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * 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})
-    @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;
-
-    /**
-     * @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 final static int STATE_NONE = 0;
-
-    /**
-     * State indicating this item is currently stopped.
-     *
-     * @see Builder#setState
-     */
-    public final static int STATE_STOPPED = 1;
-
-    /**
-     * State indicating this item is currently paused.
-     *
-     * @see Builder#setState
-     */
-    public final static int STATE_PAUSED = 2;
-
-    /**
-     * State indicating this item is currently playing.
-     *
-     * @see Builder#setState
-     */
-    public final static int STATE_PLAYING = 3;
-
-    /**
-     * State indicating this item is currently fast forwarding.
-     *
-     * @see Builder#setState
-     */
-    public final static int STATE_FAST_FORWARDING = 4;
-
-    /**
-     * State indicating this item is currently rewinding.
-     *
-     * @see Builder#setState
-     */
-    public final static int STATE_REWINDING = 5;
-
-    /**
-     * State indicating this item is currently buffering and will begin playing
-     * when enough data has buffered.
-     *
-     * @see Builder#setState
-     */
-    public final static 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 final static 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 final static int STATE_CONNECTING = 8;
-
-    /**
-     * State indicating the player is currently skipping to the previous item.
-     *
-     * @see Builder#setState
-     */
-    public final static int STATE_SKIPPING_TO_PREVIOUS = 9;
-
-    /**
-     * State indicating the player is currently skipping to the next item.
-     *
-     * @see Builder#setState
-     */
-    public final static int STATE_SKIPPING_TO_NEXT = 10;
-
-    /**
-     * State indicating the player is currently skipping to a specific item in
-     * the queue.
-     *
-     * @see Builder#setState
-     */
-    public final static int STATE_SKIPPING_TO_QUEUE_ITEM = 11;
-
-    /**
-     * Use this value for the position to indicate the position is not known.
-     */
-    public final static 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>
-     * </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;
-    }
-
-    /**
-     * 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}.
-     * @hide
-     */
-    public static int getStateFromRccState(int rccState) {
-        switch (rccState) {
-            case RemoteControlClient.PLAYSTATE_BUFFERING:
-                return STATE_BUFFERING;
-            case RemoteControlClient.PLAYSTATE_ERROR:
-                return STATE_ERROR;
-            case RemoteControlClient.PLAYSTATE_FAST_FORWARDING:
-                return STATE_FAST_FORWARDING;
-            //RemoteControlClient.PLAYSTATE_NONE is hidden
-            case 0:  //RemoteControlClient.PLAYSTATE_NONE:
-                return STATE_NONE;
-            case RemoteControlClient.PLAYSTATE_PAUSED:
-                return STATE_PAUSED;
-            case RemoteControlClient.PLAYSTATE_PLAYING:
-                return STATE_PLAYING;
-            case RemoteControlClient.PLAYSTATE_REWINDING:
-                return STATE_REWINDING;
-            case RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS:
-                return STATE_SKIPPING_TO_PREVIOUS;
-            case RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS:
-                return STATE_SKIPPING_TO_NEXT;
-            case RemoteControlClient.PLAYSTATE_STOPPED:
-                return 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}.
-     * @hide
-     */
-    public static int getRccStateFromState(int state) {
-        switch (state) {
-            case STATE_BUFFERING:
-                return RemoteControlClient.PLAYSTATE_BUFFERING;
-            case STATE_ERROR:
-                return RemoteControlClient.PLAYSTATE_ERROR;
-            case STATE_FAST_FORWARDING:
-                return RemoteControlClient.PLAYSTATE_FAST_FORWARDING;
-            case STATE_NONE:
-                //RemoteControlClient.PLAYSTATE_NONE is hidden
-                return 0;  //RemoteControlClient.PLAYSTATE_NONE;
-            case STATE_PAUSED:
-                return RemoteControlClient.PLAYSTATE_PAUSED;
-            case STATE_PLAYING:
-                return RemoteControlClient.PLAYSTATE_PLAYING;
-            case STATE_REWINDING:
-                return RemoteControlClient.PLAYSTATE_REWINDING;
-            case STATE_SKIPPING_TO_PREVIOUS:
-                return RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS;
-            case STATE_SKIPPING_TO_NEXT:
-                return RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS;
-            case STATE_STOPPED:
-                return RemoteControlClient.PLAYSTATE_STOPPED;
-            default:
-                return -1;
-        }
-    }
-
-    /**
-     * @hide
-     */
-    public 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;
-    }
-
-    /**
-     * @hide
-     */
-    public 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 RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS:
-                return ACTION_SKIP_TO_PREVIOUS;
-            case RemoteControlClient.FLAG_KEY_MEDIA_REWIND:
-                return ACTION_REWIND;
-            case RemoteControlClient.FLAG_KEY_MEDIA_PLAY:
-                return ACTION_PLAY;
-            case RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE:
-                return ACTION_PLAY_PAUSE;
-            case RemoteControlClient.FLAG_KEY_MEDIA_PAUSE:
-                return ACTION_PAUSE;
-            case RemoteControlClient.FLAG_KEY_MEDIA_STOP:
-                return ACTION_STOP;
-            case RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD:
-                return ACTION_FAST_FORWARD;
-            case RemoteControlClient.FLAG_KEY_MEDIA_NEXT:
-                return ACTION_SKIP_TO_NEXT;
-            case RemoteControlClient.FLAG_KEY_MEDIA_POSITION_UPDATE:
-                return ACTION_SEEK_TO;
-            case RemoteControlClient.FLAG_KEY_MEDIA_RATING:
-                return 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) ACTION_SKIP_TO_PREVIOUS:
-                return RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS;
-            case (int) ACTION_REWIND:
-                return RemoteControlClient.FLAG_KEY_MEDIA_REWIND;
-            case (int) ACTION_PLAY:
-                return RemoteControlClient.FLAG_KEY_MEDIA_PLAY;
-            case (int) ACTION_PLAY_PAUSE:
-                return RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE;
-            case (int) ACTION_PAUSE:
-                return RemoteControlClient.FLAG_KEY_MEDIA_PAUSE;
-            case (int) ACTION_STOP:
-                return RemoteControlClient.FLAG_KEY_MEDIA_STOP;
-            case (int) ACTION_FAST_FORWARD:
-                return RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD;
-            case (int) ACTION_SKIP_TO_NEXT:
-                return RemoteControlClient.FLAG_KEY_MEDIA_NEXT;
-            case (int) ACTION_SEEK_TO:
-                return RemoteControlClient.FLAG_KEY_MEDIA_POSITION_UPDATE;
-            case (int) ACTION_SET_RATING:
-                return RemoteControlClient.FLAG_KEY_MEDIA_RATING;
-        }
-        return 0;
-    }
-
-    public static final 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 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>
-         * </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/packages/MediaComponents/apex/java/android/service/media/IMediaBrowserService.aidl b/packages/MediaComponents/apex/java/android/service/media/IMediaBrowserService.aidl
deleted file mode 100644
index 84f41f6..0000000
--- a/packages/MediaComponents/apex/java/android/service/media/IMediaBrowserService.aidl
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2014 Google Inc. All Rights Reserved.
-
-package android.service.media;
-
-import android.content.res.Configuration;
-import android.service.media.IMediaBrowserServiceCallbacks;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.ResultReceiver;
-
-/**
- * Media API allows clients to browse through hierarchy of a user’s media collection,
- * playback a specific media entry and interact with the now playing queue.
- * @hide
- */
-oneway interface IMediaBrowserService {
-    void connect(String pkg, in Bundle rootHints, IMediaBrowserServiceCallbacks callbacks);
-    void disconnect(IMediaBrowserServiceCallbacks callbacks);
-
-    void addSubscriptionDeprecated(String uri, IMediaBrowserServiceCallbacks callbacks);
-    void removeSubscriptionDeprecated(String uri, IMediaBrowserServiceCallbacks callbacks);
-
-    void getMediaItem(String uri, in ResultReceiver cb, IMediaBrowserServiceCallbacks callbacks);
-    void addSubscription(String uri, in IBinder token, in Bundle options,
-            IMediaBrowserServiceCallbacks callbacks);
-    void removeSubscription(String uri, in IBinder token, IMediaBrowserServiceCallbacks callbacks);
-}
diff --git a/packages/MediaComponents/apex/java/android/service/media/IMediaBrowserServiceCallbacks.aidl b/packages/MediaComponents/apex/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
deleted file mode 100644
index 8dc480d..0000000
--- a/packages/MediaComponents/apex/java/android/service/media/IMediaBrowserServiceCallbacks.aidl
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2014 Google Inc. All Rights Reserved.
-
-package android.service.media;
-
-import android.graphics.Bitmap;
-import android.media.MediaParceledListSlice;
-import android.media.session.MediaSession;
-import android.os.Bundle;
-
-/**
- * Media API allows clients to browse through hierarchy of a user’s media collection,
- * playback a specific media entry and interact with the now playing queue.
- * @hide
- */
-oneway interface IMediaBrowserServiceCallbacks {
-    /**
-     * Invoked when the connected has been established.
-     * @param root The root media id for browsing.
-     * @param session The {@link MediaSession.Token media session token} that can be used to control
-     *         the playback of the media app.
-     * @param extra Extras returned by the media service.
-     */
-    void onConnect(String root, in MediaSession.Token session, in Bundle extras);
-    void onConnectFailed();
-    void onLoadChildren(String mediaId, in MediaParceledListSlice list);
-    void onLoadChildrenWithOptions(String mediaId, in MediaParceledListSlice list,
-            in Bundle options);
-}
diff --git a/packages/MediaComponents/apex/java/android/service/media/MediaBrowserService.java b/packages/MediaComponents/apex/java/android/service/media/MediaBrowserService.java
deleted file mode 100644
index 76c99b9..0000000
--- a/packages/MediaComponents/apex/java/android/service/media/MediaBrowserService.java
+++ /dev/null
@@ -1,856 +0,0 @@
-/*
- * 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.service.media;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SdkConstant;
-import android.annotation.SdkConstant.SdkConstantType;
-import android.annotation.UnsupportedAppUsage;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.PackageManager;
-import android.media.MediaParceledListSlice;
-import android.media.browse.MediaBrowser;
-import android.media.browse.MediaBrowserUtils;
-import android.media.session.MediaSession;
-import android.os.Binder;
-import android.os.Bundle;
-import android.os.Handler;
-import android.media.session.MediaSessionManager;
-import android.media.session.MediaSessionManager.RemoteUserInfo;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.os.ResultReceiver;
-import android.service.media.IMediaBrowserService;
-import android.service.media.IMediaBrowserServiceCallbacks;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.util.Log;
-import android.util.Pair;
-
-import java.io.FileDescriptor;
-import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-
-/**
- * Base class for media browser services.
- * <p>
- * Media browser services enable applications to browse media content provided by an application
- * and ask the application to start playing it. They may also be used to control content that
- * is already playing by way of a {@link MediaSession}.
- * </p>
- *
- * To extend this class, you must declare the service in your manifest file with
- * an intent filter with the {@link #SERVICE_INTERFACE} action.
- *
- * For example:
- * </p><pre>
- * &lt;service android:name=".MyMediaBrowserService"
- *          android:label="&#64;string/service_name" >
- *     &lt;intent-filter>
- *         &lt;action android:name="android.media.browse.MediaBrowserService" />
- *     &lt;/intent-filter>
- * &lt;/service>
- * </pre>
- *
- */
-public abstract class MediaBrowserService extends Service {
-    private static final String TAG = "MediaBrowserService";
-    private static final boolean DBG = false;
-
-    /**
-     * The {@link Intent} that must be declared as handled by the service.
-     */
-    @SdkConstant(SdkConstantType.SERVICE_ACTION)
-    public static final String SERVICE_INTERFACE = "android.media.browse.MediaBrowserService";
-
-    /**
-     * A key for passing the MediaItem to the ResultReceiver in getItem.
-     * @hide
-     */
-    @UnsupportedAppUsage
-    public static final String KEY_MEDIA_ITEM = "media_item";
-
-    private static final int RESULT_FLAG_OPTION_NOT_HANDLED = 1 << 0;
-    private static final int RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED = 1 << 1;
-
-    private static final int RESULT_ERROR = -1;
-    private static final int RESULT_OK = 0;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(flag=true, value = { RESULT_FLAG_OPTION_NOT_HANDLED,
-            RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED })
-    private @interface ResultFlags { }
-
-    private final ArrayMap<IBinder, ConnectionRecord> mConnections = new ArrayMap<>();
-    private ConnectionRecord mCurConnection;
-    private final Handler mHandler = new Handler();
-    private ServiceBinder mBinder;
-    MediaSession.Token mSession;
-
-    /**
-     * All the info about a connection.
-     */
-    private class ConnectionRecord implements IBinder.DeathRecipient {
-        String pkg;
-        int uid;
-        int pid;
-        Bundle rootHints;
-        IMediaBrowserServiceCallbacks callbacks;
-        BrowserRoot root;
-        HashMap<String, List<Pair<IBinder, Bundle>>> subscriptions = new HashMap<>();
-
-        @Override
-        public void binderDied() {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mConnections.remove(callbacks.asBinder());
-                }
-            });
-        }
-    }
-
-    /**
-     * Completion handler for asynchronous callback methods in {@link MediaBrowserService}.
-     * <p>
-     * Each of the methods that takes one of these to send the result must call
-     * {@link #sendResult} to respond to the caller with the given results. If those
-     * functions return without calling {@link #sendResult}, they must instead call
-     * {@link #detach} before returning, and then may call {@link #sendResult} when
-     * they are done. If more than one of those methods is called, an exception will
-     * be thrown.
-     *
-     * @see #onLoadChildren
-     * @see #onLoadItem
-     */
-    public class Result<T> {
-        private Object mDebug;
-        private boolean mDetachCalled;
-        private boolean mSendResultCalled;
-        @UnsupportedAppUsage
-        private int mFlags;
-
-        Result(Object debug) {
-            mDebug = debug;
-        }
-
-        /**
-         * Send the result back to the caller.
-         */
-        public void sendResult(T result) {
-            if (mSendResultCalled) {
-                throw new IllegalStateException("sendResult() called twice for: " + mDebug);
-            }
-            mSendResultCalled = true;
-            onResultSent(result, mFlags);
-        }
-
-        /**
-         * Detach this message from the current thread and allow the {@link #sendResult}
-         * call to happen later.
-         */
-        public void detach() {
-            if (mDetachCalled) {
-                throw new IllegalStateException("detach() called when detach() had already"
-                        + " been called for: " + mDebug);
-            }
-            if (mSendResultCalled) {
-                throw new IllegalStateException("detach() called when sendResult() had already"
-                        + " been called for: " + mDebug);
-            }
-            mDetachCalled = true;
-        }
-
-        boolean isDone() {
-            return mDetachCalled || mSendResultCalled;
-        }
-
-        void setFlags(@ResultFlags int flags) {
-            mFlags = flags;
-        }
-
-        /**
-         * Called when the result is sent, after assertions about not being called twice
-         * have happened.
-         */
-        void onResultSent(T result, @ResultFlags int flags) {
-        }
-    }
-
-    private class ServiceBinder extends IMediaBrowserService.Stub {
-        @Override
-        public void connect(final String pkg, final Bundle rootHints,
-                final IMediaBrowserServiceCallbacks callbacks) {
-
-            final int pid = Binder.getCallingPid();
-            final int uid = Binder.getCallingUid();
-            if (!isValidPackage(pkg, uid)) {
-                throw new IllegalArgumentException("Package/uid mismatch: uid=" + uid
-                        + " package=" + pkg);
-            }
-
-            mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        final IBinder b = callbacks.asBinder();
-
-                        // Clear out the old subscriptions. We are getting new ones.
-                        mConnections.remove(b);
-
-                        final ConnectionRecord connection = new ConnectionRecord();
-                        connection.pkg = pkg;
-                        connection.pid = pid;
-                        connection.uid = uid;
-                        connection.rootHints = rootHints;
-                        connection.callbacks = callbacks;
-
-                        mCurConnection = connection;
-                        connection.root = MediaBrowserService.this.onGetRoot(pkg, uid, rootHints);
-                        mCurConnection = null;
-
-                        // If they didn't return something, don't allow this client.
-                        if (connection.root == null) {
-                            Log.i(TAG, "No root for client " + pkg + " from service "
-                                    + getClass().getName());
-                            try {
-                                callbacks.onConnectFailed();
-                            } catch (RemoteException ex) {
-                                Log.w(TAG, "Calling onConnectFailed() failed. Ignoring. "
-                                        + "pkg=" + pkg);
-                            }
-                        } else {
-                            try {
-                                mConnections.put(b, connection);
-                                b.linkToDeath(connection, 0);
-                                if (mSession != null) {
-                                    callbacks.onConnect(connection.root.getRootId(),
-                                            mSession, connection.root.getExtras());
-                                }
-                            } catch (RemoteException ex) {
-                                Log.w(TAG, "Calling onConnect() failed. Dropping client. "
-                                        + "pkg=" + pkg);
-                                mConnections.remove(b);
-                            }
-                        }
-                    }
-                });
-        }
-
-        @Override
-        public void disconnect(final IMediaBrowserServiceCallbacks callbacks) {
-            mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        final IBinder b = callbacks.asBinder();
-
-                        // Clear out the old subscriptions. We are getting new ones.
-                        final ConnectionRecord old = mConnections.remove(b);
-                        if (old != null) {
-                            // TODO
-                            old.callbacks.asBinder().unlinkToDeath(old, 0);
-                        }
-                    }
-                });
-        }
-
-        @Override
-        public void addSubscriptionDeprecated(String id, IMediaBrowserServiceCallbacks callbacks) {
-            // do-nothing
-        }
-
-        @Override
-        public void addSubscription(final String id, final IBinder token, final Bundle options,
-                final IMediaBrowserServiceCallbacks callbacks) {
-            mHandler.post(new Runnable() {
-                    @Override
-                    public void run() {
-                        final IBinder b = callbacks.asBinder();
-
-                        // Get the record for the connection
-                        final ConnectionRecord connection = mConnections.get(b);
-                        if (connection == null) {
-                            Log.w(TAG, "addSubscription for callback that isn't registered id="
-                                + id);
-                            return;
-                        }
-
-                        MediaBrowserService.this.addSubscription(id, connection, token, options);
-                    }
-                });
-        }
-
-        @Override
-        public void removeSubscriptionDeprecated(String id, IMediaBrowserServiceCallbacks callbacks) {
-            // do-nothing
-        }
-
-        @Override
-        public void removeSubscription(final String id, final IBinder token,
-                final IMediaBrowserServiceCallbacks callbacks) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    final IBinder b = callbacks.asBinder();
-
-                    ConnectionRecord connection = mConnections.get(b);
-                    if (connection == null) {
-                        Log.w(TAG, "removeSubscription for callback that isn't registered id="
-                                + id);
-                        return;
-                    }
-                    if (!MediaBrowserService.this.removeSubscription(id, connection, token)) {
-                        Log.w(TAG, "removeSubscription called for " + id
-                                + " which is not subscribed");
-                    }
-                }
-            });
-        }
-
-        @Override
-        public void getMediaItem(final String mediaId, final ResultReceiver receiver,
-                final IMediaBrowserServiceCallbacks callbacks) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    final IBinder b = callbacks.asBinder();
-                    ConnectionRecord connection = mConnections.get(b);
-                    if (connection == null) {
-                        Log.w(TAG, "getMediaItem for callback that isn't registered id=" + mediaId);
-                        return;
-                    }
-                    performLoadItem(mediaId, connection, receiver);
-                }
-            });
-        }
-    }
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        mBinder = new ServiceBinder();
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        if (SERVICE_INTERFACE.equals(intent.getAction())) {
-            return mBinder;
-        }
-        return null;
-    }
-
-    @Override
-    public void dump(FileDescriptor fd, PrintWriter writer, String[] args) {
-    }
-
-    /**
-     * Called to get the root information for browsing by a particular client.
-     * <p>
-     * The implementation should verify that the client package has permission
-     * to access browse media information before returning the root id; it
-     * should return null if the client is not allowed to access this
-     * information.
-     * </p>
-     *
-     * @param clientPackageName The package name of the application which is
-     *            requesting access to browse media.
-     * @param clientUid The uid of the application which is requesting access to
-     *            browse media.
-     * @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.
-     * @return The {@link BrowserRoot} for accessing this app's content or null.
-     * @see BrowserRoot#EXTRA_RECENT
-     * @see BrowserRoot#EXTRA_OFFLINE
-     * @see BrowserRoot#EXTRA_SUGGESTED
-     */
-    public abstract @Nullable BrowserRoot onGetRoot(@NonNull String clientPackageName,
-            int clientUid, @Nullable Bundle rootHints);
-
-    /**
-     * Called to get information about the children of a media item.
-     * <p>
-     * Implementations must call {@link Result#sendResult result.sendResult}
-     * with the list of children. If loading the children will be an expensive
-     * operation that should be performed on another thread,
-     * {@link Result#detach result.detach} may be called before returning from
-     * this function, and then {@link Result#sendResult result.sendResult}
-     * called when the loading is complete.
-     * </p><p>
-     * In case the media item does not have any children, call {@link Result#sendResult}
-     * with an empty list. When the given {@code parentId} is invalid, implementations must
-     * call {@link Result#sendResult result.sendResult} with {@code null}, which will invoke
-     * {@link MediaBrowser.SubscriptionCallback#onError}.
-     * </p>
-     *
-     * @param parentId The id of the parent media item whose children are to be
-     *            queried.
-     * @param result The Result to send the list of children to.
-     */
-    public abstract void onLoadChildren(@NonNull String parentId,
-            @NonNull Result<List<MediaBrowser.MediaItem>> result);
-
-    /**
-     * Called to get information about the children of a media item.
-     * <p>
-     * Implementations must call {@link Result#sendResult result.sendResult}
-     * with the list of children. If loading the children will be an expensive
-     * operation that should be performed on another thread,
-     * {@link Result#detach result.detach} may be called before returning from
-     * this function, and then {@link Result#sendResult result.sendResult}
-     * called when the loading is complete.
-     * </p><p>
-     * In case the media item does not have any children, call {@link Result#sendResult}
-     * with an empty list. When the given {@code parentId} is invalid, implementations must
-     * call {@link Result#sendResult result.sendResult} with {@code null}, which will invoke
-     * {@link MediaBrowser.SubscriptionCallback#onError}.
-     * </p>
-     *
-     * @param parentId The id of the parent media item whose children are to be
-     *            queried.
-     * @param result The Result to send the list of children to.
-     * @param options The bundle of service-specific arguments sent from the media
-     *            browser. The information returned through the result should be
-     *            affected by the contents of this bundle.
-     */
-    public void onLoadChildren(@NonNull String parentId,
-            @NonNull Result<List<MediaBrowser.MediaItem>> result, @NonNull Bundle options) {
-        // To support backward compatibility, when the implementation of MediaBrowserService doesn't
-        // override onLoadChildren() with options, onLoadChildren() without options will be used
-        // instead, and the options will be applied in the implementation of result.onResultSent().
-        result.setFlags(RESULT_FLAG_OPTION_NOT_HANDLED);
-        onLoadChildren(parentId, result);
-    }
-
-    /**
-     * Called to get information about a specific media item.
-     * <p>
-     * Implementations must call {@link Result#sendResult result.sendResult}. If
-     * loading the item will be an expensive operation {@link Result#detach
-     * result.detach} may be called before returning from this function, and
-     * then {@link Result#sendResult result.sendResult} called when the item has
-     * been loaded.
-     * </p><p>
-     * When the given {@code itemId} is invalid, implementations must call
-     * {@link Result#sendResult result.sendResult} with {@code null}.
-     * </p><p>
-     * The default implementation will invoke {@link MediaBrowser.ItemCallback#onError}.
-     * </p>
-     *
-     * @param itemId The id for the specific
-     *            {@link android.media.browse.MediaBrowser.MediaItem}.
-     * @param result The Result to send the item to.
-     */
-    public void onLoadItem(String itemId, Result<MediaBrowser.MediaItem> result) {
-        result.setFlags(RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED);
-        result.sendResult(null);
-    }
-
-    /**
-     * Call to set the media session.
-     * <p>
-     * This should be called as soon as possible during the service's startup.
-     * It may only be called once.
-     *
-     * @param token The token for the service's {@link MediaSession}.
-     */
-    public void setSessionToken(final MediaSession.Token token) {
-        if (token == null) {
-            throw new IllegalArgumentException("Session token may not be null.");
-        }
-        if (mSession != null) {
-            throw new IllegalStateException("The session token has already been set.");
-        }
-        mSession = token;
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                Iterator<ConnectionRecord> iter = mConnections.values().iterator();
-                while (iter.hasNext()){
-                    ConnectionRecord connection = iter.next();
-                    try {
-                        connection.callbacks.onConnect(connection.root.getRootId(), token,
-                                connection.root.getExtras());
-                    } catch (RemoteException e) {
-                        Log.w(TAG, "Connection for " + connection.pkg + " is no longer valid.");
-                        iter.remove();
-                    }
-                }
-            }
-        });
-    }
-
-    /**
-     * Gets the session token, or null if it has not yet been created
-     * or if it has been destroyed.
-     */
-    public @Nullable MediaSession.Token getSessionToken() {
-        return mSession;
-    }
-
-    /**
-     * Gets the root hints sent from the currently connected {@link MediaBrowser}.
-     * The root hints are service-specific arguments included in an optional bundle sent 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.
-     *
-     * @throws IllegalStateException If this method is called outside of {@link #onGetRoot} or
-     *             {@link #onLoadChildren} or {@link #onLoadItem}.
-     * @see MediaBrowserService.BrowserRoot#EXTRA_RECENT
-     * @see MediaBrowserService.BrowserRoot#EXTRA_OFFLINE
-     * @see MediaBrowserService.BrowserRoot#EXTRA_SUGGESTED
-     */
-    public final Bundle getBrowserRootHints() {
-        if (mCurConnection == null) {
-            throw new IllegalStateException("This should be called inside of onGetRoot or"
-                    + " onLoadChildren or onLoadItem methods");
-        }
-        return mCurConnection.rootHints == null ? null : new Bundle(mCurConnection.rootHints);
-    }
-
-    /**
-     * Gets the browser information who sent the current request.
-     *
-     * @throws IllegalStateException If this method is called outside of {@link #onGetRoot} or
-     *             {@link #onLoadChildren} or {@link #onLoadItem}.
-     * @see MediaSessionManager#isTrustedForMediaControl(RemoteUserInfo)
-     */
-    public final RemoteUserInfo getCurrentBrowserInfo() {
-        if (mCurConnection == null) {
-            throw new IllegalStateException("This should be called inside of onGetRoot or"
-                    + " onLoadChildren or onLoadItem methods");
-        }
-        return new RemoteUserInfo(mCurConnection.pkg, mCurConnection.pid, mCurConnection.uid);
-    }
-
-    /**
-     * Notifies all connected media browsers that the children of
-     * the specified parent id have changed in some way.
-     * This will cause browsers to fetch subscribed content again.
-     *
-     * @param parentId The id of the parent media item whose
-     * children changed.
-     */
-    public void notifyChildrenChanged(@NonNull String parentId) {
-        notifyChildrenChangedInternal(parentId, null);
-    }
-
-    /**
-     * Notifies all connected media browsers that the children of
-     * the specified parent id have changed in some way.
-     * This will cause browsers to fetch subscribed content again.
-     *
-     * @param parentId The id of the parent media item whose
-     *            children changed.
-     * @param options The bundle of service-specific arguments to send
-     *            to the media browser. The contents of this bundle may
-     *            contain the information about the change.
-     */
-    public void notifyChildrenChanged(@NonNull String parentId, @NonNull Bundle options) {
-        if (options == null) {
-            throw new IllegalArgumentException("options cannot be null in notifyChildrenChanged");
-        }
-        notifyChildrenChangedInternal(parentId, options);
-    }
-
-    private void notifyChildrenChangedInternal(final String parentId, final Bundle options) {
-        if (parentId == null) {
-            throw new IllegalArgumentException("parentId cannot be null in notifyChildrenChanged");
-        }
-        mHandler.post(new Runnable() {
-            @Override
-            public void run() {
-                for (IBinder binder : mConnections.keySet()) {
-                    ConnectionRecord connection = mConnections.get(binder);
-                    List<Pair<IBinder, Bundle>> callbackList =
-                            connection.subscriptions.get(parentId);
-                    if (callbackList != null) {
-                        for (Pair<IBinder, Bundle> callback : callbackList) {
-                            if (MediaBrowserUtils.hasDuplicatedItems(options, callback.second)) {
-                                performLoadChildren(parentId, connection, callback.second);
-                            }
-                        }
-                    }
-                }
-            }
-        });
-    }
-
-    /**
-     * Return whether the given package is one of the ones that is owned by the uid.
-     */
-    private boolean isValidPackage(String pkg, int uid) {
-        if (pkg == null) {
-            return false;
-        }
-        final PackageManager pm = getPackageManager();
-        final String[] packages = pm.getPackagesForUid(uid);
-        final int N = packages.length;
-        for (int i=0; i<N; i++) {
-            if (packages[i].equals(pkg)) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Save the subscription and if it is a new subscription send the results.
-     */
-    private void addSubscription(String id, ConnectionRecord connection, IBinder token,
-            Bundle options) {
-        // Save the subscription
-        List<Pair<IBinder, Bundle>> callbackList = connection.subscriptions.get(id);
-        if (callbackList == null) {
-            callbackList = new ArrayList<>();
-        }
-        for (Pair<IBinder, Bundle> callback : callbackList) {
-            if (token == callback.first
-                    && MediaBrowserUtils.areSameOptions(options, callback.second)) {
-                return;
-            }
-        }
-        callbackList.add(new Pair<>(token, options));
-        connection.subscriptions.put(id, callbackList);
-        // send the results
-        performLoadChildren(id, connection, options);
-    }
-
-    /**
-     * Remove the subscription.
-     */
-    private boolean removeSubscription(String id, ConnectionRecord connection, IBinder token) {
-        if (token == null) {
-            return connection.subscriptions.remove(id) != null;
-        }
-        boolean removed = false;
-        List<Pair<IBinder, Bundle>> callbackList = connection.subscriptions.get(id);
-        if (callbackList != null) {
-            Iterator<Pair<IBinder, Bundle>> iter = callbackList.iterator();
-            while (iter.hasNext()){
-                if (token == iter.next().first) {
-                    removed = true;
-                    iter.remove();
-                }
-            }
-            if (callbackList.size() == 0) {
-                connection.subscriptions.remove(id);
-            }
-        }
-        return removed;
-    }
-
-    /**
-     * Call onLoadChildren and then send the results back to the connection.
-     * <p>
-     * Callers must make sure that this connection is still connected.
-     */
-    private void performLoadChildren(final String parentId, final ConnectionRecord connection,
-            final Bundle options) {
-        final Result<List<MediaBrowser.MediaItem>> result
-                = new Result<List<MediaBrowser.MediaItem>>(parentId) {
-            @Override
-            void onResultSent(List<MediaBrowser.MediaItem> list, @ResultFlags int flag) {
-                if (mConnections.get(connection.callbacks.asBinder()) != connection) {
-                    if (DBG) {
-                        Log.d(TAG, "Not sending onLoadChildren result for connection that has"
-                                + " been disconnected. pkg=" + connection.pkg + " id=" + parentId);
-                    }
-                    return;
-                }
-
-                List<MediaBrowser.MediaItem> filteredList =
-                        (flag & RESULT_FLAG_OPTION_NOT_HANDLED) != 0
-                        ? applyOptions(list, options) : list;
-                final MediaParceledListSlice<MediaBrowser.MediaItem> pls =
-                        filteredList == null ? null : new MediaParceledListSlice<>(filteredList);
-                try {
-                    connection.callbacks.onLoadChildrenWithOptions(parentId, pls, options);
-                } catch (RemoteException ex) {
-                    // The other side is in the process of crashing.
-                    Log.w(TAG, "Calling onLoadChildren() failed for id=" + parentId
-                            + " package=" + connection.pkg);
-                }
-            }
-        };
-
-        mCurConnection = connection;
-        if (options == null) {
-            onLoadChildren(parentId, result);
-        } else {
-            onLoadChildren(parentId, result, options);
-        }
-        mCurConnection = null;
-
-        if (!result.isDone()) {
-            throw new IllegalStateException("onLoadChildren must call detach() or sendResult()"
-                    + " before returning for package=" + connection.pkg + " id=" + parentId);
-        }
-    }
-
-    private List<MediaBrowser.MediaItem> applyOptions(List<MediaBrowser.MediaItem> list,
-            final Bundle options) {
-        if (list == null) {
-            return null;
-        }
-        int page = options.getInt(MediaBrowser.EXTRA_PAGE, -1);
-        int pageSize = options.getInt(MediaBrowser.EXTRA_PAGE_SIZE, -1);
-        if (page == -1 && pageSize == -1) {
-            return list;
-        }
-        int fromIndex = pageSize * page;
-        int toIndex = fromIndex + pageSize;
-        if (page < 0 || pageSize < 1 || fromIndex >= list.size()) {
-            return Collections.EMPTY_LIST;
-        }
-        if (toIndex > list.size()) {
-            toIndex = list.size();
-        }
-        return list.subList(fromIndex, toIndex);
-    }
-
-    private void performLoadItem(String itemId, final ConnectionRecord connection,
-            final ResultReceiver receiver) {
-        final Result<MediaBrowser.MediaItem> result =
-                new Result<MediaBrowser.MediaItem>(itemId) {
-            @Override
-            void onResultSent(MediaBrowser.MediaItem item, @ResultFlags int flag) {
-                if (mConnections.get(connection.callbacks.asBinder()) != connection) {
-                    if (DBG) {
-                        Log.d(TAG, "Not sending onLoadItem result for connection that has"
-                                + " been disconnected. pkg=" + connection.pkg + " id=" + itemId);
-                    }
-                    return;
-                }
-                if ((flag & RESULT_FLAG_ON_LOAD_ITEM_NOT_IMPLEMENTED) != 0) {
-                    receiver.send(RESULT_ERROR, null);
-                    return;
-                }
-                Bundle bundle = new Bundle();
-                bundle.putParcelable(KEY_MEDIA_ITEM, item);
-                receiver.send(RESULT_OK, bundle);
-            }
-        };
-
-        mCurConnection = connection;
-        onLoadItem(itemId, result);
-        mCurConnection = null;
-
-        if (!result.isDone()) {
-            throw new IllegalStateException("onLoadItem must call detach() or sendResult()"
-                    + " before returning for id=" + itemId);
-        }
-    }
-
-    /**
-     * Contains information that the browser service needs to send to the client
-     * when first connected.
-     */
-    public static final class BrowserRoot {
-        /**
-         * The lookup key for a boolean that indicates whether the browser service should return a
-         * browser root for recently played media items.
-         *
-         * <p>When creating a media browser for a given media browser service, this key can be
-         * supplied as a root hint for retrieving media items that are recently played.
-         * If the media browser service can provide such media items, the implementation must return
-         * the key in the root hint when {@link #onGetRoot(String, int, Bundle)} is called back.
-         *
-         * <p>The root hint may contain multiple keys.
-         *
-         * @see #EXTRA_OFFLINE
-         * @see #EXTRA_SUGGESTED
-         */
-        public static final String EXTRA_RECENT = "android.service.media.extra.RECENT";
-
-        /**
-         * The lookup key for a boolean that indicates whether the browser service should return a
-         * browser root for offline media items.
-         *
-         * <p>When creating a media browser for a given media browser service, this key can be
-         * supplied as a root hint for retrieving media items that are can be played without an
-         * internet connection.
-         * If the media browser service can provide such media items, the implementation must return
-         * the key in the root hint when {@link #onGetRoot(String, int, Bundle)} is called back.
-         *
-         * <p>The root hint may contain multiple keys.
-         *
-         * @see #EXTRA_RECENT
-         * @see #EXTRA_SUGGESTED
-         */
-        public static final String EXTRA_OFFLINE = "android.service.media.extra.OFFLINE";
-
-        /**
-         * The lookup key for a boolean that indicates whether the browser service should return a
-         * browser root for suggested media items.
-         *
-         * <p>When creating a media browser for a given media browser service, this key can be
-         * supplied as a root hint for retrieving the media items suggested by the media browser
-         * service. The list of media items passed in {@link android.media.browse.MediaBrowser.SubscriptionCallback#onChildrenLoaded(String, List)}
-         * is considered ordered by relevance, first being the top suggestion.
-         * If the media browser service can provide such media items, the implementation must return
-         * the key in the root hint when {@link #onGetRoot(String, int, Bundle)} is called back.
-         *
-         * <p>The root hint may contain multiple keys.
-         *
-         * @see #EXTRA_RECENT
-         * @see #EXTRA_OFFLINE
-         */
-        public static final String EXTRA_SUGGESTED = "android.service.media.extra.SUGGESTED";
-
-        final private String mRootId;
-        final private Bundle mExtras;
-
-        /**
-         * Constructs a browser root.
-         * @param rootId The root id for browsing.
-         * @param extras Any extras about the browser service.
-         */
-        public BrowserRoot(@NonNull String rootId, @Nullable Bundle extras) {
-            if (rootId == null) {
-                throw new IllegalArgumentException("The root id in BrowserRoot cannot be null. " +
-                        "Use null for BrowserRoot instead.");
-            }
-            mRootId = rootId;
-            mExtras = extras;
-        }
-
-        /**
-         * Gets the root id for browsing.
-         */
-        public String getRootId() {
-            return mRootId;
-        }
-
-        /**
-         * Gets any extras about the browser service.
-         */
-        public Bundle getExtras() {
-            return mExtras;
-        }
-    }
-}
diff --git a/packages/OWNERS b/packages/OWNERS
deleted file mode 100644
index 3b9fd2b..0000000
--- a/packages/OWNERS
+++ /dev/null
@@ -1,9 +0,0 @@
-akersten@google.com
-dwkang@google.com
-hdmoon@google.com
-insun@google.com
-jaewan@google.com
-jinpark@google.com
-marcone@google.com
-sungsoo@google.com
-wjia@google.com