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}