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