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