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}