{"record":{"id":"58161e78c2a24015","repo":"google/ExoPlayer","slug":"missing-implementation-to-handle-command-adjust-de","errorCode":null,"errorMessage":"Missing implementation to handle COMMAND_ADJUST_DEVICE_VOLUME or COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS","messagePattern":"Missing implementation to handle COMMAND_ADJUST_DEVICE_VOLUME or COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"library/common/src/main/java/com/google/android/exoplayer2/SimpleBasePlayer.java","lineNumber":3090,"sourceCode":"    throw new IllegalStateException(\n        \"Missing implementation to handle COMMAND_SET_DEVICE_VOLUME or\"\n            + \" COMMAND_SET_DEVICE_VOLUME_WITH_FLAGS\");\n  }\n\n  /**\n   * Handles calls to {@link Player#increaseDeviceVolume()} and {@link\n   * Player#increaseDeviceVolume(int)}.\n   *\n   * <p>Will only be called if {@link Player#COMMAND_ADJUST_DEVICE_VOLUME} or {@link\n   * Player#COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS} is available.\n   *\n   * @param flags Either 0 or a bitwise combination of one or more {@link C.VolumeFlags}.\n   * @return A {@link ListenableFuture} indicating the completion of all immediate {@link State}\n   *     changes caused by this call.\n   */\n  @ForOverride\n  protected ListenableFuture<?> handleIncreaseDeviceVolume(@C.VolumeFlags int flags) {\n    throw new IllegalStateException(\n        \"Missing implementation to handle COMMAND_ADJUST_DEVICE_VOLUME or\"\n            + \" COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS\");\n  }\n\n  /**\n   * Handles calls to {@link Player#decreaseDeviceVolume()} and {@link\n   * Player#decreaseDeviceVolume(int)}.\n   *\n   * <p>Will only be called if {@link Player#COMMAND_ADJUST_DEVICE_VOLUME} or {@link\n   * Player#COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS} is available.\n   *\n   * @param flags Either 0 or a bitwise combination of one or more {@link C.VolumeFlags}.\n   * @return A {@link ListenableFuture} indicating the completion of all immediate {@link State}\n   *     changes caused by this call.\n   */\n  @ForOverride\n  protected ListenableFuture<?> handleDecreaseDeviceVolume(@C.VolumeFlags int flags) {\n    throw new IllegalStateException(","sourceCodeStart":3072,"sourceCodeEnd":3108,"githubUrl":"https://github.com/google/ExoPlayer/blob/dd430f7053a1a3958deea3ead6a0565150c06bfc/library/common/src/main/java/com/google/android/exoplayer2/SimpleBasePlayer.java#L3072-L3108","documentation":"SimpleBasePlayer forwards Player.increaseDeviceVolume() / increaseDeviceVolume(int) to handleIncreaseDeviceVolume(int flags). If the subclass lists Player.COMMAND_ADJUST_DEVICE_VOLUME (or the _WITH_FLAGS variant) in availableCommands but leaves the default handler, the call throws this IllegalStateException. The message intentionally names both command constants because either one routes here.","triggerScenarios":"Calling player.increaseDeviceVolume() on a custom SimpleBasePlayer whose State.availableCommands includes COMMAND_ADJUST_DEVICE_VOLUME or COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS without an override of handleIncreaseDeviceVolume.","commonSituations":"Forwarding UI volume-up key events to a custom player; enabling the full volume command group in a wrapper player around a cast or remote session while only implementing setDeviceVolume.","solutions":["Override handleIncreaseDeviceVolume(@C.VolumeFlags int flags) and raise the device volume (e.g. AudioManager.adjustStreamVolume(STREAM_MUSIC, RAISE, flags)), returning an immediate future.","Alternatively drop COMMAND_ADJUST_DEVICE_VOLUME(_WITH_FLAGS) from availableCommands so the increment call is ignored instead of throwing.","Implement the whole volume-handler family (set/increase/decrease/mute) together whenever you advertise any device-volume command."],"exampleFix":"// before\n// availableCommands includes COMMAND_ADJUST_DEVICE_VOLUME, no override:\n\n// after\n@Override\nprotected ListenableFuture<?> handleIncreaseDeviceVolume(@C.VolumeFlags int flags) {\n  audioManager.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_RAISE, flags);\n  return Futures.immediateVoidFuture();\n}","handlingStrategy":"validation","validationCode":"boolean canAdjust = player.isCommandAvailable(Player.COMMAND_ADJUST_DEVICE_VOLUME)\n    || player.isCommandAvailable(Player.COMMAND_ADJUST_DEVICE_VOLUME_WITH_FLAGS);\nif (canAdjust) checkOverrides(playerClass, \"handleIncreaseDeviceVolume\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember one ADJUST command gates increase, decrease and mute — implement all three handlers.","Route volume-key events through isCommandAvailable checks before calling player methods.","Keep a checklist mapping COMMAND_* -> handle* in the subclass's unit test."],"tags":["exoplayer","media3","player","device-volume","subclassing"],"backgroundTag":null,"analyzedSha":"dd430f7053a1a3958deea3ead6a0565150c06bfc","analyzedAt":"2026-08-14T12:22:02.982Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}