MediaSession2: Move MediaItem2 to updatable

Bug: 72627815
Test: Run all MediaComponents test once
Change-Id: Iced94541233145b928e480f3d062a64cc0814a26
diff --git a/media/java/android/media/MediaItem2.java b/media/java/android/media/MediaItem2.java
index f9711aa..2e9894b 100644
--- a/media/java/android/media/MediaItem2.java
+++ b/media/java/android/media/MediaItem2.java
@@ -20,6 +20,9 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SystemApi;
+import android.content.Context;
+import android.media.update.ApiLoader;
+import android.media.update.MediaItem2Provider;
 import android.os.Bundle;
 import android.text.TextUtils;
 
@@ -36,10 +39,6 @@
  * @hide
  */
 public class MediaItem2 {
-    private final int mFlags;
-    private MediaMetadata2 mMetadata;
-    private DataSourceDesc mDataSourceDesc;
-
     /** @hide */
     @Retention(RetentionPolicy.SOURCE)
     @IntDef(flag=true, value = { FLAG_BROWSABLE, FLAG_PLAYABLE })
@@ -58,17 +57,29 @@
      */
     public static final int FLAG_PLAYABLE = 1 << 1;
 
+    private final MediaItem2Provider mProvider;
+
     /**
      * Create a new media item.
      *
+     * @param mediaId id of this item. It must be unique whithin this app
      * @param metadata metadata with the media id.
      * @param flags The flags for this item.
      */
-    public MediaItem2(@Nullable MediaMetadata2 metadata,
-            @Nullable DataSourceDesc data, @Flags int flags) {
-        mFlags = flags;
-        mDataSourceDesc = data;
-        setMetadata(metadata);
+    public MediaItem2(@NonNull Context context, @NonNull String mediaId,
+            @NonNull DataSourceDesc dsd, @Nullable MediaMetadata2 metadata,
+            @Flags int flags) {
+        mProvider = ApiLoader.getProvider(context).createMediaItem2Provider(
+                context, this, mediaId, dsd, metadata, flags);
+    }
+
+    /**
+     * Create a new media item
+     * @hide
+     */
+    @SystemApi
+    public MediaItem2(MediaItem2Provider provider) {
+        mProvider = provider;
     }
 
     /**
@@ -78,22 +89,22 @@
      */
     public Bundle toBundle() {
         // TODO(jaewan): Fill here when we rebase.
-        return new Bundle();
+        return mProvider.toBundle_impl();
+    }
+
+    public static MediaItem2 fromBundle(Context context, Bundle bundle) {
+        return ApiLoader.getProvider(context).fromBundle_MediaItem2(context, bundle);
     }
 
     public String toString() {
-        final StringBuilder sb = new StringBuilder("MediaItem2{");
-        sb.append("mFlags=").append(mFlags);
-        sb.append(", mMetadata=").append(mMetadata);
-        sb.append('}');
-        return sb.toString();
+        return mProvider.toString_impl();
     }
 
     /**
      * Gets the flags of the item.
      */
     public @Flags int getFlags() {
-        return mFlags;
+        return mProvider.getFlags_impl();
     }
 
     /**
@@ -101,7 +112,7 @@
      * @see #FLAG_BROWSABLE
      */
     public boolean isBrowsable() {
-        return (mFlags & FLAG_BROWSABLE) != 0;
+        return mProvider.isBrowsable_impl();
     }
 
     /**
@@ -109,29 +120,24 @@
      * @see #FLAG_PLAYABLE
      */
     public boolean isPlayable() {
-        return (mFlags & FLAG_PLAYABLE) != 0;
+        return mProvider.isPlayable_impl();
     }
 
     /**
-     * Set a metadata. Metadata shouldn't be null and should have non-empty media id.
+     * Set a metadata. Metadata shouldn't be {@code null} and its id should be match
+     * with this instance's id.
      *
-     * @param metadata
+     * @param metadata metadata to update
      */
     public void setMetadata(@NonNull MediaMetadata2 metadata) {
-        if (metadata == null) {
-            throw new IllegalArgumentException("metadata cannot be null");
-        }
-        if (TextUtils.isEmpty(metadata.getMediaId())) {
-            throw new IllegalArgumentException("metadata must have a non-empty media id");
-        }
-        mMetadata = metadata;
+        mProvider.setMetadata_impl(metadata);
     }
 
     /**
      * Returns the metadata of the media.
      */
     public @NonNull MediaMetadata2 getMetadata() {
-        return mMetadata;
+        return mProvider.getMetadata_impl();
     }
 
     /**
@@ -139,10 +145,17 @@
      * @see MediaMetadata2#METADATA_KEY_MEDIA_ID
      */
     public @Nullable String getMediaId() {
-        return mMetadata.getMediaId();
+        return mProvider.getMediaId_impl();
     }
 
+    /**
+     * Return the {@link DataSourceDesc}
+     * <p>
+     * Can be {@code null} if the MediaItem2 came from another process and anonymized
+     *
+     * @return data source descriptor
+     */
     public @Nullable DataSourceDesc getDataSourceDesc() {
-        return mDataSourceDesc;
+        return mProvider.getDataSourceDesc_impl();
     }
 }
diff --git a/media/java/android/media/update/MediaItem2Provider.java b/media/java/android/media/update/MediaItem2Provider.java
new file mode 100644
index 0000000..2970f0e
--- /dev/null
+++ b/media/java/android/media/update/MediaItem2Provider.java
@@ -0,0 +1,37 @@
+/*
+ * 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.update;
+
+import android.media.DataSourceDesc;
+import android.media.MediaMetadata2;
+import android.os.Bundle;
+
+/**
+ * @hide
+ */
+// TODO(jaewan): SystemApi
+public interface MediaItem2Provider {
+    Bundle toBundle_impl();
+    String toString_impl();
+    int getFlags_impl();
+    boolean isBrowsable_impl();
+    boolean isPlayable_impl();
+    void setMetadata_impl(MediaMetadata2 metadata);
+    MediaMetadata2 getMetadata_impl();
+    String getMediaId_impl();
+    DataSourceDesc getDataSourceDesc_impl();
+}
diff --git a/media/java/android/media/update/StaticProvider.java b/media/java/android/media/update/StaticProvider.java
index 963bc74..2176795 100644
--- a/media/java/android/media/update/StaticProvider.java
+++ b/media/java/android/media/update/StaticProvider.java
@@ -19,13 +19,16 @@
 import android.annotation.Nullable;
 import android.app.PendingIntent;
 import android.content.Context;
+import android.media.DataSourceDesc;
 import android.media.MediaBrowser2;
 import android.media.MediaBrowser2.BrowserCallback;
 import android.media.MediaController2;
 import android.media.MediaController2.ControllerCallback;
+import android.media.MediaItem2;
 import android.media.MediaLibraryService2;
 import android.media.MediaLibraryService2.MediaLibrarySession;
 import android.media.MediaLibraryService2.MediaLibrarySessionCallback;
+import android.media.MediaMetadata2;
 import android.media.MediaPlayerInterface;
 import android.media.MediaSession2;
 import android.media.MediaSession2.SessionCallback;
@@ -79,4 +82,8 @@
     SessionToken2 SessionToken2_fromBundle(Context context, Bundle bundle);
 
     SessionPlayer2Provider createSessionPlayer2(Context context, SessionPlayer2 instance);
+
+    MediaItem2Provider createMediaItem2Provider(Context context, MediaItem2 mediaItem2,
+            String mediaId, DataSourceDesc dsd, MediaMetadata2 metadata, int flags);
+    MediaItem2 fromBundle_MediaItem2(Context context, Bundle bundle);
 }