1 /* 2 * Copyright 2018 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 */ 16 17 package androidx.media; 18 19 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 20 21 import android.net.Uri; 22 import android.os.Bundle; 23 import android.text.TextUtils; 24 25 import androidx.annotation.NonNull; 26 import androidx.annotation.Nullable; 27 import androidx.annotation.RestrictTo; 28 import androidx.media.MediaSession2.ControllerInfo; 29 import androidx.media.MediaSession2.SessionCallback; 30 31 import java.util.List; 32 33 /** 34 * Define a command that a {@link MediaController2} can send to a {@link MediaSession2}. 35 * <p> 36 * If {@link #getCommandCode()} isn't {@link #COMMAND_CODE_CUSTOM}), it's predefined command. 37 * If {@link #getCommandCode()} is {@link #COMMAND_CODE_CUSTOM}), it's custom command and 38 * {@link #getCustomCommand()} shouldn't be {@code null}. 39 */ 40 public final class SessionCommand2 { 41 /** 42 * Command code for the custom command which can be defined by string action in the 43 * {@link SessionCommand2}. 44 */ 45 public static final int COMMAND_CODE_CUSTOM = 0; 46 47 /** 48 * Command code for {@link MediaController2#play()}. 49 * <p> 50 * Command would be sent directly to the player if the session doesn't reject the request 51 * through the {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, 52 * SessionCommand2)}. 53 */ 54 public static final int COMMAND_CODE_PLAYBACK_PLAY = 1; 55 56 /** 57 * Command code for {@link MediaController2#pause()}. 58 * <p> 59 * Command would be sent directly to the player if the session doesn't reject the request 60 * through the {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, 61 * SessionCommand2)}. 62 */ 63 public static final int COMMAND_CODE_PLAYBACK_PAUSE = 2; 64 65 /** 66 * Command code for {@link MediaController2#reset()}. 67 * <p> 68 * Command would be sent directly to the player if the session doesn't reject the request 69 * through the {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, 70 * SessionCommand2)}. 71 */ 72 public static final int COMMAND_CODE_PLAYBACK_RESET = 3; 73 74 /** 75 * Command code for {@link MediaController2#skipToNextItem()}. 76 * <p> 77 * Command would be sent directly to the playlist agent if the session doesn't reject the 78 * request through the {@link SessionCallback#onCommandRequest( 79 * MediaSession2, ControllerInfo, SessionCommand2)}. 80 */ 81 public static final int COMMAND_CODE_PLAYLIST_SKIP_TO_NEXT_ITEM = 4; 82 83 /** 84 * Command code for {@link MediaController2#skipToPreviousItem()}. 85 * <p> 86 * Command would be sent directly to the playlist agent if the session doesn't reject the 87 * request through the {@link SessionCallback#onCommandRequest( 88 * MediaSession2, ControllerInfo, SessionCommand2)}. 89 */ 90 public static final int COMMAND_CODE_PLAYLIST_SKIP_TO_PREV_ITEM = 5; 91 92 /** 93 * Command code for {@link MediaController2#prepare()}. 94 * <p> 95 * Command would be sent directly to the player if the session doesn't reject the request 96 * through the {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, 97 * SessionCommand2)}. 98 */ 99 public static final int COMMAND_CODE_PLAYBACK_PREPARE = 6; 100 101 /** 102 * Command code for {@link MediaController2#fastForward()}. 103 */ 104 public static final int COMMAND_CODE_SESSION_FAST_FORWARD = 7; 105 106 /** 107 * Command code for {@link MediaController2#rewind()}. 108 */ 109 public static final int COMMAND_CODE_SESSION_REWIND = 8; 110 111 /** 112 * Command code for {@link MediaController2#seekTo(long)}. 113 * <p> 114 * Command would be sent directly to the player if the session doesn't reject the request 115 * through the {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, 116 * SessionCommand2)}. 117 */ 118 public static final int COMMAND_CODE_PLAYBACK_SEEK_TO = 9; 119 120 /** 121 * Command code for both {@link MediaController2#setVolumeTo(int, int)}. 122 * <p> 123 * Command would set the device volume or send to the volume provider directly if the session 124 * doesn't reject the request through the 125 * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. 126 */ 127 public static final int COMMAND_CODE_VOLUME_SET_VOLUME = 10; 128 129 /** 130 * Command code for both {@link MediaController2#adjustVolume(int, int)}. 131 * <p> 132 * Command would adjust the device volume or send to the volume provider directly if the session 133 * doesn't reject the request through the 134 * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. 135 */ 136 public static final int COMMAND_CODE_VOLUME_ADJUST_VOLUME = 11; 137 138 /** 139 * Command code for {@link MediaController2#skipToPlaylistItem(MediaItem2)}. 140 * <p> 141 * Command would be sent directly to the playlist agent if the session doesn't reject the 142 * request through the 143 * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. 144 */ 145 public static final int COMMAND_CODE_PLAYLIST_SKIP_TO_PLAYLIST_ITEM = 12; 146 147 /** 148 * Command code for {@link MediaController2#setShuffleMode(int)}. 149 * <p> 150 * Command would be sent directly to the playlist agent if the session doesn't reject the 151 * request through the 152 * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. 153 */ 154 public static final int COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE = 13; 155 156 /** 157 * Command code for {@link MediaController2#setRepeatMode(int)}. 158 * <p> 159 * Command would be sent directly to the playlist agent if the session doesn't reject the 160 * request through the 161 * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. 162 */ 163 public static final int COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE = 14; 164 165 /** 166 * Command code for {@link MediaController2#addPlaylistItem(int, MediaItem2)}. 167 * <p> 168 * Command would be sent directly to the playlist agent if the session doesn't reject the 169 * request through the 170 * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. 171 */ 172 public static final int COMMAND_CODE_PLAYLIST_ADD_ITEM = 15; 173 174 /** 175 * Command code for {@link MediaController2#addPlaylistItem(int, MediaItem2)}. 176 * <p> 177 * Command would be sent directly to the playlist agent if the session doesn't reject the 178 * request through the 179 * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. 180 */ 181 public static final int COMMAND_CODE_PLAYLIST_REMOVE_ITEM = 16; 182 183 /** 184 * Command code for {@link MediaController2#replacePlaylistItem(int, MediaItem2)}. 185 * <p> 186 * Command would be sent directly to the playlist agent if the session doesn't reject the 187 * request through the 188 * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. 189 */ 190 public static final int COMMAND_CODE_PLAYLIST_REPLACE_ITEM = 17; 191 192 /** 193 * Command code for {@link MediaController2#getPlaylist()}. This will expose metadata 194 * information to the controller. 195 */ 196 public static final int COMMAND_CODE_PLAYLIST_GET_LIST = 18; 197 198 /** 199 * Command code for {@link MediaController2#setPlaylist(List, MediaMetadata2)}. 200 * <p> 201 * Command would be sent directly to the playlist agent if the session doesn't reject the 202 * request through the 203 * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. 204 */ 205 public static final int COMMAND_CODE_PLAYLIST_SET_LIST = 19; 206 207 /** 208 * Command code for {@link MediaController2#getPlaylistMetadata()}. This will expose 209 * metadata information to the controller. 210 */ 211 public static final int COMMAND_CODE_PLAYLIST_GET_LIST_METADATA = 20; 212 213 /** 214 * Command code for {@link MediaController2#updatePlaylistMetadata(MediaMetadata2)}. 215 * <p> 216 * Command would be sent directly to the playlist agent if the session doesn't reject the 217 * request through the 218 * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. 219 */ 220 public static final int COMMAND_CODE_PLAYLIST_SET_LIST_METADATA = 21; 221 222 /** 223 * Command code for {@link MediaController2#getCurrentMediaItem()}. This will expose 224 * metadata information to the controller. 225 */ 226 public static final int COMMAND_CODE_PLAYLIST_GET_CURRENT_MEDIA_ITEM = 20; 227 228 /** 229 * Command code for {@link MediaController2#playFromMediaId(String, Bundle)}. 230 */ 231 public static final int COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID = 22; 232 233 /** 234 * Command code for {@link MediaController2#playFromUri(Uri, Bundle)}. 235 */ 236 public static final int COMMAND_CODE_SESSION_PLAY_FROM_URI = 23; 237 238 /** 239 * Command code for {@link MediaController2#playFromSearch(String, Bundle)}. 240 */ 241 public static final int COMMAND_CODE_SESSION_PLAY_FROM_SEARCH = 24; 242 243 /** 244 * Command code for {@link MediaController2#prepareFromMediaId(String, Bundle)}. 245 */ 246 public static final int COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID = 25; 247 248 /** 249 * Command code for {@link MediaController2#prepareFromUri(Uri, Bundle)}. 250 */ 251 public static final int COMMAND_CODE_SESSION_PREPARE_FROM_URI = 26; 252 253 /** 254 * Command code for {@link MediaController2#prepareFromSearch(String, Bundle)}. 255 */ 256 public static final int COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH = 27; 257 258 /** 259 * Command code for {@link MediaController2#setRating(String, Rating2)}. 260 */ 261 public static final int COMMAND_CODE_SESSION_SET_RATING = 28; 262 263 /** 264 * Command code for {@link MediaController2#subscribeRoutesInfo()} 265 */ 266 public static final int COMMAND_CODE_SESSION_SUBSCRIBE_ROUTES_INFO = 36; 267 268 /** 269 * Command code for {@link MediaController2#unsubscribeRoutesInfo()} 270 */ 271 public static final int COMMAND_CODE_SESSION_UNSUBSCRIBE_ROUTES_INFO = 37; 272 273 /** 274 * Command code for {@link MediaController2#selectRoute(Bundle)}} 275 */ 276 public static final int COMMAND_CODE_SESSION_SELECT_ROUTE = 38; 277 278 /** 279 * Command code for {@link MediaBrowser2#getChildren(String, int, int, Bundle)}. 280 */ 281 public static final int COMMAND_CODE_LIBRARY_GET_CHILDREN = 29; 282 283 /** 284 * Command code for {@link MediaBrowser2#getItem(String)}. 285 */ 286 public static final int COMMAND_CODE_LIBRARY_GET_ITEM = 30; 287 288 /** 289 * Command code for {@link MediaBrowser2#getLibraryRoot(Bundle)}. 290 */ 291 public static final int COMMAND_CODE_LIBRARY_GET_LIBRARY_ROOT = 31; 292 293 /** 294 * Command code for {@link MediaBrowser2#getSearchResult(String, int, int, Bundle)}. 295 */ 296 public static final int COMMAND_CODE_LIBRARY_GET_SEARCH_RESULT = 32; 297 298 /** 299 * Command code for {@link MediaBrowser2#search(String, Bundle)}. 300 */ 301 public static final int COMMAND_CODE_LIBRARY_SEARCH = 33; 302 303 /** 304 * Command code for {@link MediaBrowser2#subscribe(String, Bundle)}. 305 */ 306 public static final int COMMAND_CODE_LIBRARY_SUBSCRIBE = 34; 307 308 /** 309 * Command code for {@link MediaBrowser2#unsubscribe(String)}. 310 */ 311 public static final int COMMAND_CODE_LIBRARY_UNSUBSCRIBE = 35; 312 313 /** 314 * Command code for {@link MediaController2#setPlaybackSpeed(float)}}. 315 * <p> 316 * Command would be sent directly to the player if the session doesn't reject the request 317 * through the {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, 318 * SessionCommand2)}. 319 */ 320 public static final int COMMAND_CODE_PLAYBACK_SET_SPEED = 39; 321 322 private static final String KEY_COMMAND_CODE = 323 "android.media.media_session2.command.command_code"; 324 private static final String KEY_COMMAND_CUSTOM_COMMAND = 325 "android.media.media_session2.command.custom_command"; 326 private static final String KEY_COMMAND_EXTRAS = 327 "android.media.media_session2.command.extras"; 328 329 private final int mCommandCode; 330 // Nonnull if it's custom command 331 private final String mCustomCommand; 332 private final Bundle mExtras; 333 334 /** 335 * Constructor for creating a predefined command. 336 * 337 * @param commandCode A command code for predefined command. 338 */ 339 public SessionCommand2(int commandCode) { 340 if (commandCode == COMMAND_CODE_CUSTOM) { 341 throw new IllegalArgumentException("commandCode shouldn't be COMMAND_CODE_CUSTOM"); 342 } 343 mCommandCode = commandCode; 344 mCustomCommand = null; 345 mExtras = null; 346 } 347 348 /** 349 * Constructor for creating a custom command. 350 * 351 * @param action The action of this custom command. 352 * @param extras An extra bundle for this custom command. 353 */ 354 public SessionCommand2(@NonNull String action, @Nullable Bundle extras) { 355 if (action == null) { 356 throw new IllegalArgumentException("action shouldn't be null"); 357 } 358 mCommandCode = COMMAND_CODE_CUSTOM; 359 mCustomCommand = action; 360 mExtras = extras; 361 } 362 363 /** 364 * Gets the command code of a predefined command. 365 * This will return {@link #COMMAND_CODE_CUSTOM} for a custom command. 366 */ 367 public int getCommandCode() { 368 return mCommandCode; 369 } 370 371 /** 372 * Gets the action of a custom command. 373 * This will return {@code null} for a predefined command. 374 */ 375 public @Nullable String getCustomCommand() { 376 return mCustomCommand; 377 } 378 379 /** 380 * Gets the extra bundle of a custom command. 381 * This will return {@code null} for a predefined command. 382 */ 383 public @Nullable Bundle getExtras() { 384 return mExtras; 385 } 386 387 /** 388 * @return a new {@link Bundle} instance from the command 389 * @hide 390 */ 391 @RestrictTo(LIBRARY_GROUP) 392 public Bundle toBundle() { 393 Bundle bundle = new Bundle(); 394 bundle.putInt(KEY_COMMAND_CODE, mCommandCode); 395 bundle.putString(KEY_COMMAND_CUSTOM_COMMAND, mCustomCommand); 396 bundle.putBundle(KEY_COMMAND_EXTRAS, mExtras); 397 return bundle; 398 } 399 400 /** 401 * @return a new {@link SessionCommand2} instance from the Bundle 402 * @hide 403 */ 404 @RestrictTo(LIBRARY_GROUP) 405 public static SessionCommand2 fromBundle(@NonNull Bundle command) { 406 if (command == null) { 407 throw new IllegalArgumentException("command shouldn't be null"); 408 } 409 int code = command.getInt(KEY_COMMAND_CODE); 410 if (code != COMMAND_CODE_CUSTOM) { 411 return new SessionCommand2(code); 412 } else { 413 String customCommand = command.getString(KEY_COMMAND_CUSTOM_COMMAND); 414 if (customCommand == null) { 415 return null; 416 } 417 return new SessionCommand2(customCommand, command.getBundle(KEY_COMMAND_EXTRAS)); 418 } 419 } 420 421 @Override 422 public boolean equals(Object obj) { 423 if (!(obj instanceof SessionCommand2)) { 424 return false; 425 } 426 SessionCommand2 other = (SessionCommand2) obj; 427 return mCommandCode == other.mCommandCode 428 && TextUtils.equals(mCustomCommand, other.mCustomCommand); 429 } 430 431 @Override 432 public int hashCode() { 433 final int prime = 31; 434 return ((mCustomCommand != null) ? mCustomCommand.hashCode() : 0) * prime + mCommandCode; 435 } 436 } 437