Home | History | Annotate | Download | only in media
      1 /*
      2  * Copyright 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.media;
     18 
     19 import static android.media.MediaItem2.FLAG_BROWSABLE;
     20 import static android.media.MediaItem2.FLAG_PLAYABLE;
     21 
     22 import android.annotation.NonNull;
     23 import android.annotation.Nullable;
     24 import android.media.DataSourceDesc;
     25 import android.media.MediaItem2;
     26 import android.media.MediaItem2.Builder;
     27 import android.media.MediaItem2.Flags;
     28 import android.media.MediaMetadata2;
     29 import android.media.update.MediaItem2Provider;
     30 import android.os.Bundle;
     31 import android.text.TextUtils;
     32 
     33 import java.util.UUID;
     34 
     35 public class MediaItem2Impl implements MediaItem2Provider {
     36     private static final String KEY_ID = "android.media.mediaitem2.id";
     37     private static final String KEY_FLAGS = "android.media.mediaitem2.flags";
     38     private static final String KEY_METADATA = "android.media.mediaitem2.metadata";
     39     private static final String KEY_UUID = "android.media.mediaitem2.uuid";
     40 
     41     private final MediaItem2 mInstance;
     42     private final String mId;
     43     private final int mFlags;
     44     private final UUID mUUID;
     45     private MediaMetadata2 mMetadata;
     46     private DataSourceDesc mDataSourceDesc;
     47 
     48     // From the public API
     49     public MediaItem2Impl(@NonNull String mediaId, @Nullable DataSourceDesc dsd,
     50             @Nullable MediaMetadata2 metadata, @Flags int flags) {
     51         this(mediaId, dsd, metadata, flags, null);
     52     }
     53 
     54     private MediaItem2Impl(@NonNull String mediaId, @Nullable DataSourceDesc dsd,
     55             @Nullable MediaMetadata2 metadata, @Flags int flags, @Nullable UUID uuid) {
     56         if (mediaId == null) {
     57             throw new IllegalArgumentException("mediaId shouldn't be null");
     58         }
     59         if (metadata != null && !TextUtils.equals(mediaId, metadata.getMediaId())) {
     60             throw new IllegalArgumentException("metadata's id should be matched with the mediaid");
     61         }
     62 
     63         mId = mediaId;
     64         mDataSourceDesc = dsd;
     65         mMetadata = metadata;
     66         mFlags = flags;
     67         mUUID = (uuid == null) ? UUID.randomUUID() : uuid;
     68 
     69         mInstance = new MediaItem2(this);
     70     }
     71 
     72     @Override
     73     public boolean equals_impl(Object obj) {
     74         if (!(obj instanceof MediaItem2)) {
     75             return false;
     76         }
     77         MediaItem2 other = (MediaItem2) obj;
     78         return mUUID.equals(((MediaItem2Impl) other.getProvider()).mUUID);
     79     }
     80 
     81     /**
     82      * Return this object as a bundle to share between processes.
     83      *
     84      * @return a new bundle instance
     85      */
     86     public Bundle toBundle_impl() {
     87         Bundle bundle = new Bundle();
     88         bundle.putString(KEY_ID, mId);
     89         bundle.putInt(KEY_FLAGS, mFlags);
     90         if (mMetadata != null) {
     91             bundle.putBundle(KEY_METADATA, mMetadata.toBundle());
     92         }
     93         bundle.putString(KEY_UUID, mUUID.toString());
     94         return bundle;
     95     }
     96 
     97     /**
     98      * Create a MediaItem2 from the {@link Bundle}.
     99      *
    100      * @param bundle The bundle which was published by {@link MediaItem2#toBundle()}.
    101      * @return The newly created MediaItem2
    102      */
    103     public static MediaItem2 fromBundle_impl(@NonNull Bundle bundle) {
    104         if (bundle == null) {
    105             return null;
    106         }
    107         final String uuidString = bundle.getString(KEY_UUID);
    108         return fromBundle(bundle, UUID.fromString(uuidString));
    109     }
    110 
    111     /**
    112      * Create a MediaItem2 from the {@link Bundle} with the specified {@link UUID}.
    113      * If {@link UUID}
    114      * can be null for creating new.
    115      *
    116      * @param bundle The bundle which was published by {@link MediaItem2#toBundle()}.
    117      * @param uuid A {@link UUID} to override. Can be {@link null} for override.
    118      * @return The newly created MediaItem2
    119      */
    120     static MediaItem2 fromBundle(@NonNull Bundle bundle, @Nullable UUID uuid) {
    121         if (bundle == null) {
    122             return null;
    123         }
    124         final String id = bundle.getString(KEY_ID);
    125         final Bundle metadataBundle = bundle.getBundle(KEY_METADATA);
    126         final MediaMetadata2 metadata = MediaMetadata2.fromBundle(metadataBundle);
    127         final int flags = bundle.getInt(KEY_FLAGS);
    128         return new MediaItem2Impl(id, null, metadata, flags, uuid).getInstance();
    129     }
    130 
    131     private MediaItem2 getInstance() {
    132         return mInstance;
    133     }
    134 
    135     @Override
    136     public String toString_impl() {
    137         final StringBuilder sb = new StringBuilder("MediaItem2{");
    138         sb.append("mFlags=").append(mFlags);
    139         sb.append(", mMetadata=").append(mMetadata);
    140         sb.append('}');
    141         return sb.toString();
    142     }
    143 
    144     @Override
    145     public @Flags int getFlags_impl() {
    146         return mFlags;
    147     }
    148 
    149     @Override
    150     public boolean isBrowsable_impl() {
    151         return (mFlags & FLAG_BROWSABLE) != 0;
    152     }
    153 
    154     @Override
    155     public boolean isPlayable_impl() {
    156         return (mFlags & FLAG_PLAYABLE) != 0;
    157     }
    158 
    159     @Override
    160     public void setMetadata_impl(@Nullable MediaMetadata2 metadata) {
    161         if (metadata != null && !TextUtils.equals(mId, metadata.getMediaId())) {
    162             throw new IllegalArgumentException("metadata's id should be matched with the mediaId");
    163         }
    164         mMetadata = metadata;
    165     }
    166 
    167     @Override
    168     public @Nullable MediaMetadata2 getMetadata_impl() {
    169         return mMetadata;
    170     }
    171 
    172     @Override
    173     public @NonNull String getMediaId_impl() {
    174         return mId;
    175     }
    176 
    177     @Override
    178     public @Nullable DataSourceDesc getDataSourceDesc_impl() {
    179         return mDataSourceDesc;
    180     }
    181 
    182     public static class BuilderImpl implements MediaItem2Provider.BuilderProvider {
    183         private Builder mInstance;
    184         private @Flags int mFlags;
    185         private String mMediaId;
    186         private MediaMetadata2 mMetadata;
    187         private DataSourceDesc mDataSourceDesc;
    188 
    189         public BuilderImpl(Builder instance, int flags) {
    190             mInstance = instance;
    191             mFlags = flags;
    192         }
    193 
    194         @Override
    195         public Builder setMediaId_impl(@Nullable String mediaId) {
    196             mMediaId = mediaId;
    197             return mInstance;
    198         }
    199 
    200         @Override
    201         public Builder setMetadata_impl(@Nullable MediaMetadata2 metadata) {
    202             mMetadata = metadata;
    203             return mInstance;
    204         }
    205 
    206         @Override
    207         public Builder setDataSourceDesc_impl(@Nullable DataSourceDesc dataSourceDesc) {
    208             mDataSourceDesc = dataSourceDesc;
    209             return mInstance;
    210         }
    211 
    212         @Override
    213         public MediaItem2 build_impl() {
    214             String id = (mMetadata != null)
    215                     ? mMetadata.getString(MediaMetadata2.METADATA_KEY_MEDIA_ID) : null;
    216             if (id == null) {
    217                 //  TODO(jaewan): Double check if its sufficient (e.g. Use UUID instead?)
    218                 id = (mMediaId != null) ? mMediaId : toString();
    219             }
    220             return new MediaItem2Impl(id, mDataSourceDesc, mMetadata, mFlags).getInstance();
    221         }
    222     }
    223 }
    224