Home | History | Annotate | Download | only in media
      1 /*
      2  * Copyright (C) 2013 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 package android.support.v7.media;
     17 
     18 import android.content.IntentFilter;
     19 import android.os.Bundle;
     20 import android.text.TextUtils;
     21 
     22 import java.util.ArrayList;
     23 import java.util.Arrays;
     24 import java.util.Collection;
     25 import java.util.Collections;
     26 import java.util.List;
     27 
     28 /**
     29  * Describes the properties of a route.
     30  * <p>
     31  * Each route is uniquely identified by an opaque id string.  This token
     32  * may take any form as long as it is unique within the media route provider.
     33  * </p><p>
     34  * This object is immutable once created using a {@link Builder} instance.
     35  * </p>
     36  */
     37 public final class MediaRouteDescriptor {
     38     private static final String KEY_ID = "id";
     39     private static final String KEY_NAME = "name";
     40     private static final String KEY_DESCRIPTION = "status";
     41     private static final String KEY_ENABLED = "enabled";
     42     private static final String KEY_CONNECTING = "connecting";
     43     private static final String KEY_CONTROL_FILTERS = "controlFilters";
     44     private static final String KEY_PLAYBACK_TYPE = "playbackType";
     45     private static final String KEY_PLAYBACK_STREAM = "playbackStream";
     46     private static final String KEY_VOLUME = "volume";
     47     private static final String KEY_VOLUME_MAX = "volumeMax";
     48     private static final String KEY_VOLUME_HANDLING = "volumeHandling";
     49     private static final String KEY_PRESENTATION_DISPLAY_ID = "presentationDisplayId";
     50     private static final String KEY_EXTRAS = "extras";
     51 
     52     private final Bundle mBundle;
     53     private List<IntentFilter> mControlFilters;
     54 
     55     private MediaRouteDescriptor(Bundle bundle, List<IntentFilter> controlFilters) {
     56         mBundle = bundle;
     57         mControlFilters = controlFilters;
     58     }
     59 
     60     /**
     61      * Gets the unique id of the route.
     62      * <p>
     63      * The route id associated with a route descriptor functions as a stable
     64      * identifier for the route and must be unique among all routes offered
     65      * by the provider.
     66      * </p>
     67      */
     68     public String getId() {
     69         return mBundle.getString(KEY_ID);
     70     }
     71 
     72     /**
     73      * Gets the user-visible name of the route.
     74      * <p>
     75      * The route name identifies the destination represented by the route.
     76      * It may be a user-supplied name, an alias, or device serial number.
     77      * </p>
     78      */
     79     public String getName() {
     80         return mBundle.getString(KEY_NAME);
     81     }
     82 
     83     /**
     84      * Gets the user-visible description of the route.
     85      * <p>
     86      * The route description describes the kind of destination represented by the route.
     87      * It may be a user-supplied string, a model number or brand of device.
     88      * </p>
     89      */
     90     public String getDescription() {
     91         return mBundle.getString(KEY_DESCRIPTION);
     92     }
     93 
     94     /**
     95      * Gets whether the route is enabled.
     96      */
     97     public boolean isEnabled() {
     98         return mBundle.getBoolean(KEY_ENABLED, true);
     99     }
    100 
    101     /**
    102      * Gets whether the route is connecting.
    103      */
    104     public boolean isConnecting() {
    105         return mBundle.getBoolean(KEY_CONNECTING, false);
    106     }
    107 
    108     /**
    109      * Gets the route's {@link MediaControlIntent media control intent} filters.
    110      */
    111     public List<IntentFilter> getControlFilters() {
    112         ensureControlFilters();
    113         return mControlFilters;
    114     }
    115 
    116     private void ensureControlFilters() {
    117         if (mControlFilters == null) {
    118             mControlFilters = mBundle.<IntentFilter>getParcelableArrayList(KEY_CONTROL_FILTERS);
    119             if (mControlFilters == null) {
    120                 mControlFilters = Collections.<IntentFilter>emptyList();
    121             }
    122         }
    123     }
    124 
    125     /**
    126      * Gets the route's playback type.
    127      */
    128     public int getPlaybackType() {
    129         return mBundle.getInt(KEY_PLAYBACK_TYPE, MediaRouter.RouteInfo.PLAYBACK_TYPE_REMOTE);
    130     }
    131 
    132     /**
    133      * Gets the route's playback stream.
    134      */
    135     public int getPlaybackStream() {
    136         return mBundle.getInt(KEY_PLAYBACK_STREAM, -1);
    137     }
    138 
    139     /**
    140      * Gets the route's current volume, or 0 if unknown.
    141      */
    142     public int getVolume() {
    143         return mBundle.getInt(KEY_VOLUME);
    144     }
    145 
    146     /**
    147      * Gets the route's maximum volume, or 0 if unknown.
    148      */
    149     public int getVolumeMax() {
    150         return mBundle.getInt(KEY_VOLUME_MAX);
    151     }
    152 
    153     /**
    154      * Gets the route's volume handling.
    155      */
    156     public int getVolumeHandling() {
    157         return mBundle.getInt(KEY_VOLUME_HANDLING,
    158                 MediaRouter.RouteInfo.PLAYBACK_VOLUME_FIXED);
    159     }
    160 
    161     /**
    162      * Gets the route's presentation display id, or -1 if none.
    163      */
    164     public int getPresentationDisplayId() {
    165         return mBundle.getInt(KEY_PRESENTATION_DISPLAY_ID, -1);
    166     }
    167 
    168     /**
    169      * Gets a bundle of extras for this route descriptor.
    170      * The extras will be ignored by the media router but they may be used
    171      * by applications.
    172      */
    173     public Bundle getExtras() {
    174         return mBundle.getBundle(KEY_EXTRAS);
    175     }
    176 
    177     /**
    178      * Returns true if the route descriptor has all of the required fields.
    179      */
    180     public boolean isValid() {
    181         ensureControlFilters();
    182         if (TextUtils.isEmpty(getId())
    183                 || TextUtils.isEmpty(getName())
    184                 || mControlFilters.contains(null)) {
    185             return false;
    186         }
    187         return true;
    188     }
    189 
    190     @Override
    191     public String toString() {
    192         StringBuilder result = new StringBuilder();
    193         result.append("MediaRouteDescriptor{ ");
    194         result.append("id=").append(getId());
    195         result.append(", name=").append(getName());
    196         result.append(", description=").append(getDescription());
    197         result.append(", isEnabled=").append(isEnabled());
    198         result.append(", isConnecting=").append(isConnecting());
    199         result.append(", controlFilters=").append(Arrays.toString(getControlFilters().toArray()));
    200         result.append(", playbackType=").append(getPlaybackType());
    201         result.append(", playbackStream=").append(getPlaybackStream());
    202         result.append(", volume=").append(getVolume());
    203         result.append(", volumeMax=").append(getVolumeMax());
    204         result.append(", volumeHandling=").append(getVolumeHandling());
    205         result.append(", presentationDisplayId=").append(getPresentationDisplayId());
    206         result.append(", extras=").append(getExtras());
    207         result.append(", isValid=").append(isValid());
    208         result.append(" }");
    209         return result.toString();
    210     }
    211 
    212     /**
    213      * Converts this object to a bundle for serialization.
    214      *
    215      * @return The contents of the object represented as a bundle.
    216      */
    217     public Bundle asBundle() {
    218         return mBundle;
    219     }
    220 
    221     /**
    222      * Creates an instance from a bundle.
    223      *
    224      * @param bundle The bundle, or null if none.
    225      * @return The new instance, or null if the bundle was null.
    226      */
    227     public static MediaRouteDescriptor fromBundle(Bundle bundle) {
    228         return bundle != null ? new MediaRouteDescriptor(bundle, null) : null;
    229     }
    230 
    231     /**
    232      * Builder for {@link MediaRouteDescriptor media route descriptors}.
    233      */
    234     public static final class Builder {
    235         private final Bundle mBundle;
    236         private ArrayList<IntentFilter> mControlFilters;
    237 
    238         /**
    239          * Creates a media route descriptor builder.
    240          *
    241          * @param id The unique id of the route.
    242          * @param name The user-visible name of the route.
    243          */
    244         public Builder(String id, String name) {
    245             mBundle = new Bundle();
    246             setId(id);
    247             setName(name);
    248         }
    249 
    250         /**
    251          * Creates a media route descriptor builder whose initial contents are
    252          * copied from an existing descriptor.
    253          */
    254         public Builder(MediaRouteDescriptor descriptor) {
    255             if (descriptor == null) {
    256                 throw new IllegalArgumentException("descriptor must not be null");
    257             }
    258 
    259             mBundle = new Bundle(descriptor.mBundle);
    260 
    261             descriptor.ensureControlFilters();
    262             if (!descriptor.mControlFilters.isEmpty()) {
    263                 mControlFilters = new ArrayList<IntentFilter>(descriptor.mControlFilters);
    264             }
    265         }
    266 
    267         /**
    268          * Sets the unique id of the route.
    269          * <p>
    270          * The route id associated with a route descriptor functions as a stable
    271          * identifier for the route and must be unique among all routes offered
    272          * by the provider.
    273          * </p>
    274          */
    275         public Builder setId(String id) {
    276             mBundle.putString(KEY_ID, id);
    277             return this;
    278         }
    279 
    280         /**
    281          * Sets the user-visible name of the route.
    282          * <p>
    283          * The route name identifies the destination represented by the route.
    284          * It may be a user-supplied name, an alias, or device serial number.
    285          * </p>
    286          */
    287         public Builder setName(String name) {
    288             mBundle.putString(KEY_NAME, name);
    289             return this;
    290         }
    291 
    292         /**
    293          * Sets the user-visible description of the route.
    294          * <p>
    295          * The route description describes the kind of destination represented by the route.
    296          * It may be a user-supplied string, a model number or brand of device.
    297          * </p>
    298          */
    299         public Builder setDescription(String description) {
    300             mBundle.putString(KEY_DESCRIPTION, description);
    301             return this;
    302         }
    303 
    304         /**
    305          * Sets whether the route is enabled.
    306          * <p>
    307          * Disabled routes represent routes that a route provider knows about, such as paired
    308          * Wifi Display receivers, but that are not currently available for use.
    309          * </p>
    310          */
    311         public Builder setEnabled(boolean enabled) {
    312             mBundle.putBoolean(KEY_ENABLED, enabled);
    313             return this;
    314         }
    315 
    316         /**
    317          * Sets whether the route is in the process of connecting and is not yet
    318          * ready for use.
    319          */
    320         public Builder setConnecting(boolean connecting) {
    321             mBundle.putBoolean(KEY_CONNECTING, connecting);
    322             return this;
    323         }
    324 
    325         /**
    326          * Adds a {@link MediaControlIntent media control intent} filter for the route.
    327          */
    328         public Builder addControlFilter(IntentFilter filter) {
    329             if (filter == null) {
    330                 throw new IllegalArgumentException("filter must not be null");
    331             }
    332 
    333             if (mControlFilters == null) {
    334                 mControlFilters = new ArrayList<IntentFilter>();
    335             }
    336             if (!mControlFilters.contains(filter)) {
    337                 mControlFilters.add(filter);
    338             }
    339             return this;
    340         }
    341 
    342         /**
    343          * Adds a list of {@link MediaControlIntent media control intent} filters for the route.
    344          */
    345         public Builder addControlFilters(Collection<IntentFilter> filters) {
    346             if (filters == null) {
    347                 throw new IllegalArgumentException("filters must not be null");
    348             }
    349 
    350             if (!filters.isEmpty()) {
    351                 for (IntentFilter filter : filters) {
    352                     addControlFilter(filter);
    353                 }
    354             }
    355             return this;
    356         }
    357 
    358         /**
    359          * Sets the route's playback type.
    360          */
    361         public Builder setPlaybackType(int playbackType) {
    362             mBundle.putInt(KEY_PLAYBACK_TYPE, playbackType);
    363             return this;
    364         }
    365 
    366         /**
    367          * Sets the route's playback stream.
    368          */
    369         public Builder setPlaybackStream(int playbackStream) {
    370             mBundle.putInt(KEY_PLAYBACK_STREAM, playbackStream);
    371             return this;
    372         }
    373 
    374         /**
    375          * Sets the route's current volume, or 0 if unknown.
    376          */
    377         public Builder setVolume(int volume) {
    378             mBundle.putInt(KEY_VOLUME, volume);
    379             return this;
    380         }
    381 
    382         /**
    383          * Sets the route's maximum volume, or 0 if unknown.
    384          */
    385         public Builder setVolumeMax(int volumeMax) {
    386             mBundle.putInt(KEY_VOLUME_MAX, volumeMax);
    387             return this;
    388         }
    389 
    390         /**
    391          * Sets the route's volume handling.
    392          */
    393         public Builder setVolumeHandling(int volumeHandling) {
    394             mBundle.putInt(KEY_VOLUME_HANDLING, volumeHandling);
    395             return this;
    396         }
    397 
    398         /**
    399          * Sets the route's presentation display id, or -1 if none.
    400          */
    401         public Builder setPresentationDisplayId(int presentationDisplayId) {
    402             mBundle.putInt(KEY_PRESENTATION_DISPLAY_ID, presentationDisplayId);
    403             return this;
    404         }
    405 
    406         /**
    407          * Sets a bundle of extras for this route descriptor.
    408          * The extras will be ignored by the media router but they may be used
    409          * by applications.
    410          */
    411         public Builder setExtras(Bundle extras) {
    412             mBundle.putBundle(KEY_EXTRAS, extras);
    413             return this;
    414         }
    415 
    416         /**
    417          * Builds the {@link MediaRouteDescriptor media route descriptor}.
    418          */
    419         public MediaRouteDescriptor build() {
    420             if (mControlFilters != null) {
    421                 mBundle.putParcelableArrayList(KEY_CONTROL_FILTERS, mControlFilters);
    422             }
    423             return new MediaRouteDescriptor(mBundle, mControlFilters);
    424         }
    425     }
    426 }