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