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