1 /* 2 * Copyright (C) 2014 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 android.hardware.hdmi; 18 19 import android.annotation.CallbackExecutor; 20 import android.annotation.IntDef; 21 import android.annotation.NonNull; 22 import android.annotation.Nullable; 23 import android.annotation.RequiresFeature; 24 import android.annotation.RequiresPermission; 25 import android.annotation.SdkConstant; 26 import android.annotation.SdkConstant.SdkConstantType; 27 import android.annotation.StringDef; 28 import android.annotation.SuppressLint; 29 import android.annotation.SystemApi; 30 import android.annotation.SystemService; 31 import android.content.Context; 32 import android.content.pm.PackageManager; 33 import android.os.Binder; 34 import android.os.RemoteException; 35 import android.sysprop.HdmiProperties; 36 import android.util.ArrayMap; 37 import android.util.Log; 38 39 import com.android.internal.util.ConcurrentUtils; 40 41 import java.lang.annotation.Retention; 42 import java.lang.annotation.RetentionPolicy; 43 import java.util.Arrays; 44 import java.util.List; 45 import java.util.Objects; 46 import java.util.concurrent.Executor; 47 import java.util.stream.Collectors; 48 49 /** 50 * The {@link HdmiControlManager} class is used to send HDMI control messages 51 * to attached CEC devices. 52 * 53 * <p>Provides various HDMI client instances that represent HDMI-CEC logical devices 54 * hosted in the system. {@link #getTvClient()}, for instance will return an 55 * {@link HdmiTvClient} object if the system is configured to host one. Android system 56 * can host more than one logical CEC devices. If multiple types are configured they 57 * all work as if they were independent logical devices running in the system. 58 * 59 * @hide 60 */ 61 @SystemApi 62 @SystemService(Context.HDMI_CONTROL_SERVICE) 63 @RequiresFeature(PackageManager.FEATURE_HDMI_CEC) 64 public final class HdmiControlManager { 65 private static final String TAG = "HdmiControlManager"; 66 67 @Nullable private final IHdmiControlService mService; 68 69 private static final int INVALID_PHYSICAL_ADDRESS = 0xFFFF; 70 71 /** 72 * Broadcast Action: Display OSD message. 73 * <p>Send when the service has a message to display on screen for events 74 * that need user's attention such as ARC status change. 75 * <p>Always contains the extra fields {@link #EXTRA_MESSAGE_ID}. 76 * <p>Requires {@link android.Manifest.permission#HDMI_CEC} to receive. 77 */ 78 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 79 public static final String ACTION_OSD_MESSAGE = "android.hardware.hdmi.action.OSD_MESSAGE"; 80 81 // --- Messages for ACTION_OSD_MESSAGE --- 82 /** 83 * Message that ARC enabled device is connected to invalid port (non-ARC port). 84 */ 85 public static final int OSD_MESSAGE_ARC_CONNECTED_INVALID_PORT = 1; 86 87 /** 88 * Message used by TV to receive volume status from Audio Receiver. It should check volume value 89 * that is retrieved from extra value with the key {@link #EXTRA_MESSAGE_EXTRA_PARAM1}. If the 90 * value is in range of [0,100], it is current volume of Audio Receiver. And there is another 91 * value, {@link #AVR_VOLUME_MUTED}, which is used to inform volume mute. 92 */ 93 public static final int OSD_MESSAGE_AVR_VOLUME_CHANGED = 2; 94 95 /** 96 * Used as an extra field in the intent {@link #ACTION_OSD_MESSAGE}. Contains the ID of 97 * the message to display on screen. 98 */ 99 public static final String EXTRA_MESSAGE_ID = "android.hardware.hdmi.extra.MESSAGE_ID"; 100 /** 101 * Used as an extra field in the intent {@link #ACTION_OSD_MESSAGE}. Contains the extra value 102 * of the message. 103 */ 104 public static final String EXTRA_MESSAGE_EXTRA_PARAM1 = 105 "android.hardware.hdmi.extra.MESSAGE_EXTRA_PARAM1"; 106 107 /** 108 * Used as an extra field in the Set Menu Language intent. Contains the requested locale. 109 * @hide 110 */ 111 public static final String EXTRA_LOCALE = "android.hardware.hdmi.extra.LOCALE"; 112 113 /** 114 * Volume value for mute state. 115 */ 116 public static final int AVR_VOLUME_MUTED = 101; 117 118 public static final int POWER_STATUS_UNKNOWN = -1; 119 public static final int POWER_STATUS_ON = 0; 120 public static final int POWER_STATUS_STANDBY = 1; 121 public static final int POWER_STATUS_TRANSIENT_TO_ON = 2; 122 public static final int POWER_STATUS_TRANSIENT_TO_STANDBY = 3; 123 124 @IntDef ({ 125 RESULT_SUCCESS, 126 RESULT_TIMEOUT, 127 RESULT_SOURCE_NOT_AVAILABLE, 128 RESULT_TARGET_NOT_AVAILABLE, 129 RESULT_ALREADY_IN_PROGRESS, 130 RESULT_EXCEPTION, 131 RESULT_INCORRECT_MODE, 132 RESULT_COMMUNICATION_FAILED, 133 }) 134 public @interface ControlCallbackResult {} 135 136 /** Control operation is successfully handled by the framework. */ 137 public static final int RESULT_SUCCESS = 0; 138 public static final int RESULT_TIMEOUT = 1; 139 /** Source device that the application is using is not available. */ 140 public static final int RESULT_SOURCE_NOT_AVAILABLE = 2; 141 /** Target device that the application is controlling is not available. */ 142 public static final int RESULT_TARGET_NOT_AVAILABLE = 3; 143 144 @Deprecated public static final int RESULT_ALREADY_IN_PROGRESS = 4; 145 public static final int RESULT_EXCEPTION = 5; 146 public static final int RESULT_INCORRECT_MODE = 6; 147 public static final int RESULT_COMMUNICATION_FAILED = 7; 148 149 public static final int DEVICE_EVENT_ADD_DEVICE = 1; 150 public static final int DEVICE_EVENT_REMOVE_DEVICE = 2; 151 public static final int DEVICE_EVENT_UPDATE_DEVICE = 3; 152 153 // --- One Touch Recording success result 154 /** Recording currently selected source. Indicates the status of a recording. */ 155 public static final int ONE_TOUCH_RECORD_RECORDING_CURRENTLY_SELECTED_SOURCE = 0x01; 156 /** Recording Digital Service. Indicates the status of a recording. */ 157 public static final int ONE_TOUCH_RECORD_RECORDING_DIGITAL_SERVICE = 0x02; 158 /** Recording Analogue Service. Indicates the status of a recording. */ 159 public static final int ONE_TOUCH_RECORD_RECORDING_ANALOGUE_SERVICE = 0x03; 160 /** Recording External input. Indicates the status of a recording. */ 161 public static final int ONE_TOUCH_RECORD_RECORDING_EXTERNAL_INPUT = 0x04; 162 163 // --- One Touch Record failure result 164 /** No recording – unable to record Digital Service. No suitable tuner. */ 165 public static final int ONE_TOUCH_RECORD_UNABLE_DIGITAL_SERVICE = 0x05; 166 /** No recording – unable to record Analogue Service. No suitable tuner. */ 167 public static final int ONE_TOUCH_RECORD_UNABLE_ANALOGUE_SERVICE = 0x06; 168 /** 169 * No recording – unable to select required service. as suitable tuner, but the requested 170 * parameters are invalid or out of range for that tuner. 171 */ 172 public static final int ONE_TOUCH_RECORD_UNABLE_SELECTED_SERVICE = 0x07; 173 /** No recording – invalid External plug number */ 174 public static final int ONE_TOUCH_RECORD_INVALID_EXTERNAL_PLUG_NUMBER = 0x09; 175 /** No recording – invalid External Physical Address */ 176 public static final int ONE_TOUCH_RECORD_INVALID_EXTERNAL_PHYSICAL_ADDRESS = 0x0A; 177 /** No recording – CA system not supported */ 178 public static final int ONE_TOUCH_RECORD_UNSUPPORTED_CA = 0x0B; 179 /** No Recording – No or Insufficient CA Entitlements” */ 180 public static final int ONE_TOUCH_RECORD_NO_OR_INSUFFICIENT_CA_ENTITLEMENTS = 0x0C; 181 /** No recording – Not allowed to copy source. Source is “copy never”. */ 182 public static final int ONE_TOUCH_RECORD_DISALLOW_TO_COPY = 0x0D; 183 /** No recording – No further copies allowed */ 184 public static final int ONE_TOUCH_RECORD_DISALLOW_TO_FUTHER_COPIES = 0x0E; 185 /** No recording – No media */ 186 public static final int ONE_TOUCH_RECORD_NO_MEDIA = 0x10; 187 /** No recording – playing */ 188 public static final int ONE_TOUCH_RECORD_PLAYING = 0x11; 189 /** No recording – already recording */ 190 public static final int ONE_TOUCH_RECORD_ALREADY_RECORDING = 0x12; 191 /** No recording – media protected */ 192 public static final int ONE_TOUCH_RECORD_MEDIA_PROTECTED = 0x13; 193 /** No recording – no source signal */ 194 public static final int ONE_TOUCH_RECORD_NO_SOURCE_SIGNAL = 0x14; 195 /** No recording – media problem */ 196 public static final int ONE_TOUCH_RECORD_MEDIA_PROBLEM = 0x15; 197 /** No recording – not enough space available */ 198 public static final int ONE_TOUCH_RECORD_NOT_ENOUGH_SPACE = 0x16; 199 /** No recording – Parental Lock On */ 200 public static final int ONE_TOUCH_RECORD_PARENT_LOCK_ON = 0x17; 201 /** Recording terminated normally */ 202 public static final int ONE_TOUCH_RECORD_RECORDING_TERMINATED_NORMALLY = 0x1A; 203 /** Recording has already terminated */ 204 public static final int ONE_TOUCH_RECORD_RECORDING_ALREADY_TERMINATED = 0x1B; 205 /** No recording – other reason */ 206 public static final int ONE_TOUCH_RECORD_OTHER_REASON = 0x1F; 207 // From here extra message for recording that is not mentioned in CEC spec 208 /** No recording. Previous recording request in progress. */ 209 public static final int ONE_TOUCH_RECORD_PREVIOUS_RECORDING_IN_PROGRESS = 0x30; 210 /** No recording. Please check recorder and connection. */ 211 public static final int ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION = 0x31; 212 /** Cannot record currently displayed source. */ 213 public static final int ONE_TOUCH_RECORD_FAIL_TO_RECORD_DISPLAYED_SCREEN = 0x32; 214 /** CEC is disabled. */ 215 public static final int ONE_TOUCH_RECORD_CEC_DISABLED = 0x33; 216 217 // --- Types for timer recording 218 /** Timer recording type for digital service source. */ 219 public static final int TIMER_RECORDING_TYPE_DIGITAL = 1; 220 /** Timer recording type for analogue service source. */ 221 public static final int TIMER_RECORDING_TYPE_ANALOGUE = 2; 222 /** Timer recording type for external source. */ 223 public static final int TIMER_RECORDING_TYPE_EXTERNAL = 3; 224 225 // --- Timer Status Data 226 /** [Timer Status Data/Media Info] - Media present and not protected. */ 227 public static final int TIMER_STATUS_MEDIA_INFO_PRESENT_NOT_PROTECTED = 0x0; 228 /** [Timer Status Data/Media Info] - Media present, but protected. */ 229 public static final int TIMER_STATUS_MEDIA_INFO_PRESENT_PROTECTED = 0x1; 230 /** [Timer Status Data/Media Info] - Media not present. */ 231 public static final int TIMER_STATUS_MEDIA_INFO_NOT_PRESENT = 0x2; 232 233 /** [Timer Status Data/Programmed Info] - Enough space available for recording. */ 234 public static final int TIMER_STATUS_PROGRAMMED_INFO_ENOUGH_SPACE = 0x8; 235 /** [Timer Status Data/Programmed Info] - Not enough space available for recording. */ 236 public static final int TIMER_STATUS_PROGRAMMED_INFO_NOT_ENOUGH_SPACE = 0x9; 237 /** [Timer Status Data/Programmed Info] - Might not enough space available for recording. */ 238 public static final int TIMER_STATUS_PROGRAMMED_INFO_MIGHT_NOT_ENOUGH_SPACE = 0xB; 239 /** [Timer Status Data/Programmed Info] - No media info available. */ 240 public static final int TIMER_STATUS_PROGRAMMED_INFO_NO_MEDIA_INFO = 0xA; 241 242 /** [Timer Status Data/Not Programmed Error Info] - No free timer available. */ 243 public static final int TIMER_STATUS_NOT_PROGRAMMED_NO_FREE_TIME = 0x1; 244 /** [Timer Status Data/Not Programmed Error Info] - Date out of range. */ 245 public static final int TIMER_STATUS_NOT_PROGRAMMED_DATE_OUT_OF_RANGE = 0x2; 246 /** [Timer Status Data/Not Programmed Error Info] - Recording Sequence error. */ 247 public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_SEQUENCE = 0x3; 248 /** [Timer Status Data/Not Programmed Error Info] - Invalid External Plug Number. */ 249 public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PLUG_NUMBER = 0x4; 250 /** [Timer Status Data/Not Programmed Error Info] - Invalid External Physical Address. */ 251 public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PHYSICAL_NUMBER = 0x5; 252 /** [Timer Status Data/Not Programmed Error Info] - CA system not supported. */ 253 public static final int TIMER_STATUS_NOT_PROGRAMMED_CA_NOT_SUPPORTED = 0x6; 254 /** [Timer Status Data/Not Programmed Error Info] - No or insufficient CA Entitlements. */ 255 public static final int TIMER_STATUS_NOT_PROGRAMMED_NO_CA_ENTITLEMENTS = 0x7; 256 /** [Timer Status Data/Not Programmed Error Info] - Does not support resolution. */ 257 public static final int TIMER_STATUS_NOT_PROGRAMMED_UNSUPPORTED_RESOLUTION = 0x8; 258 /** [Timer Status Data/Not Programmed Error Info] - Parental Lock On. */ 259 public static final int TIMER_STATUS_NOT_PROGRAMMED_PARENTAL_LOCK_ON= 0x9; 260 /** [Timer Status Data/Not Programmed Error Info] - Clock Failure. */ 261 public static final int TIMER_STATUS_NOT_PROGRAMMED_CLOCK_FAILURE = 0xA; 262 /** [Timer Status Data/Not Programmed Error Info] - Duplicate: already programmed. */ 263 public static final int TIMER_STATUS_NOT_PROGRAMMED_DUPLICATED = 0xE; 264 265 // --- Extra result value for timer recording. 266 /** No extra error. */ 267 public static final int TIMER_RECORDING_RESULT_EXTRA_NO_ERROR = 0x00; 268 /** No timer recording - check recorder and connection. */ 269 public static final int TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION = 0x01; 270 /** No timer recording - cannot record selected source. */ 271 public static final int TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE = 0x02; 272 /** CEC is disabled. */ 273 public static final int TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED = 0x03; 274 275 // -- Timer cleared status data code used for result of onClearTimerRecordingResult. 276 /** Timer not cleared – recording. */ 277 public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_RECORDING = 0x00; 278 /** Timer not cleared – no matching. */ 279 public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_MATCHING = 0x01; 280 /** Timer not cleared – no info available. */ 281 public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_INFO_AVAILABLE = 0x02; 282 /** Timer cleared. */ 283 public static final int CLEAR_TIMER_STATUS_TIMER_CLEARED = 0x80; 284 /** Clear timer error - check recorder and connection. */ 285 public static final int CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION = 0xA0; 286 /** Clear timer error - cannot clear timer for selected source. */ 287 public static final int CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE = 0xA1; 288 /** Clear timer error - CEC is disabled. */ 289 public static final int CLEAR_TIMER_STATUS_CEC_DISABLE = 0xA2; 290 291 /** The HdmiControlService is started. */ 292 public static final int CONTROL_STATE_CHANGED_REASON_START = 0; 293 /** The state of HdmiControlService is changed by changing of settings. */ 294 public static final int CONTROL_STATE_CHANGED_REASON_SETTING = 1; 295 /** The HdmiControlService is enabled to wake up. */ 296 public static final int CONTROL_STATE_CHANGED_REASON_WAKEUP = 2; 297 /** The HdmiControlService will be disabled to standby. */ 298 public static final int CONTROL_STATE_CHANGED_REASON_STANDBY = 3; 299 300 // -- Whether the HDMI CEC is enabled or disabled. 301 /** 302 * HDMI CEC enabled. 303 * 304 * @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_ENABLED 305 */ 306 public static final int HDMI_CEC_CONTROL_ENABLED = 1; 307 /** 308 * HDMI CEC disabled. 309 * 310 * @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_ENABLED 311 */ 312 public static final int HDMI_CEC_CONTROL_DISABLED = 0; 313 /** 314 * @hide 315 * 316 * @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_ENABLED 317 */ 318 @IntDef(prefix = { "HDMI_CEC_CONTROL_" }, value = { 319 HDMI_CEC_CONTROL_ENABLED, 320 HDMI_CEC_CONTROL_DISABLED 321 }) 322 @Retention(RetentionPolicy.SOURCE) 323 public @interface HdmiCecControl {} 324 325 // -- Supported HDMI-CEC versions. 326 /** 327 * Version constant for HDMI-CEC v1.4b. 328 * 329 * @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_VERSION 330 */ 331 public static final int HDMI_CEC_VERSION_1_4_B = 0x05; 332 /** 333 * Version constant for HDMI-CEC v2.0. 334 * 335 * @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_VERSION 336 */ 337 public static final int HDMI_CEC_VERSION_2_0 = 0x06; 338 /** 339 * @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_VERSION 340 * @hide 341 */ 342 @IntDef(prefix = { "HDMI_CEC_VERSION_" }, value = { 343 HDMI_CEC_VERSION_1_4_B, 344 HDMI_CEC_VERSION_2_0 345 }) 346 @Retention(RetentionPolicy.SOURCE) 347 public @interface HdmiCecVersion {} 348 349 // -- Whether the Routing Control feature is enabled or disabled. 350 /** 351 * Routing Control feature enabled. 352 * 353 * @see HdmiControlManager#CEC_SETTING_NAME_ROUTING_CONTROL 354 */ 355 public static final int ROUTING_CONTROL_ENABLED = 1; 356 /** 357 * Routing Control feature disabled. 358 * 359 * @see HdmiControlManager#CEC_SETTING_NAME_ROUTING_CONTROL 360 */ 361 public static final int ROUTING_CONTROL_DISABLED = 0; 362 /** 363 * @see HdmiControlManager#CEC_SETTING_NAME_ROUTING_CONTROL 364 * @hide 365 */ 366 @IntDef(prefix = { "ROUTING_CONTROL_" }, value = { 367 ROUTING_CONTROL_ENABLED, 368 ROUTING_CONTROL_DISABLED 369 }) 370 @Retention(RetentionPolicy.SOURCE) 371 public @interface RoutingControl {} 372 373 // -- Scope of CEC power control messages sent by a playback device. 374 /** 375 * Send CEC power control messages to TV only: 376 * Upon going to sleep, send {@code <Standby>} to TV only. 377 * Upon waking up, attempt to turn on the TV via {@code <One Touch Play>} but do not turn on the 378 * Audio system via {@code <System Audio Mode Request>}. 379 * 380 * @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE 381 */ 382 public static final String POWER_CONTROL_MODE_TV = "to_tv"; 383 /** 384 * Send CEC power control messages to TV and Audio System: 385 * Upon going to sleep, send {@code <Standby>} to TV and Audio system. 386 * Upon waking up, attempt to turn on the TV via {@code <One Touch Play>} and attempt to turn on 387 * the Audio system via {@code <System Audio Mode Request>}. 388 * 389 * @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE 390 */ 391 public static final String POWER_CONTROL_MODE_TV_AND_AUDIO_SYSTEM = "to_tv_and_audio_system"; 392 /** 393 * Broadcast CEC power control messages to all devices in the network: 394 * Upon going to sleep, send {@code <Standby>} to all devices in the network. 395 * Upon waking up, attempt to turn on the TV via {@code <One Touch Play>} and attempt to turn on 396 * the Audio system via {@code <System Audio Mode Request>}. 397 * 398 * @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE 399 */ 400 public static final String POWER_CONTROL_MODE_BROADCAST = "broadcast"; 401 /** 402 * Don't send any CEC power control messages: 403 * Upon going to sleep, do not send any {@code <Standby>} message. 404 * Upon waking up, do not turn on the TV via {@code <One Touch Play>} and do not turn on the 405 * Audio system via {@code <System Audio Mode Request>}. 406 * 407 * @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE 408 */ 409 public static final String POWER_CONTROL_MODE_NONE = "none"; 410 /** 411 * @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE 412 * @hide 413 */ 414 @StringDef(prefix = { "POWER_CONTROL_MODE_" }, value = { 415 POWER_CONTROL_MODE_TV, 416 POWER_CONTROL_MODE_TV_AND_AUDIO_SYSTEM, 417 POWER_CONTROL_MODE_BROADCAST, 418 POWER_CONTROL_MODE_NONE 419 }) 420 @Retention(RetentionPolicy.SOURCE) 421 public @interface PowerControlMode {} 422 423 // -- Which power state action should be taken when Active Source is lost. 424 /** 425 * No action to be taken. 426 * 427 * @see HdmiControlManager#CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST 428 */ 429 public static final String POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE = "none"; 430 /** 431 * Go to standby immediately. 432 * 433 * @see HdmiControlManager#CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST 434 */ 435 public static final String POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW = "standby_now"; 436 /** 437 * @see HdmiControlManager#CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST 438 * @hide 439 */ 440 @StringDef(prefix = { "POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_" }, value = { 441 POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE, 442 POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW 443 }) 444 @Retention(RetentionPolicy.SOURCE) 445 public @interface ActiveSourceLostBehavior {} 446 447 // -- Whether System Audio Control is enabled or disabled. 448 /** 449 * System Audio Control enabled. 450 * 451 * @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL 452 */ 453 public static final int SYSTEM_AUDIO_CONTROL_ENABLED = 1; 454 /** 455 * System Audio Control disabled. 456 * 457 * @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL 458 */ 459 public static final int SYSTEM_AUDIO_CONTROL_DISABLED = 0; 460 /** 461 * @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL 462 * @hide 463 */ 464 @IntDef(prefix = { "SYSTEM_AUDIO_CONTROL_" }, value = { 465 SYSTEM_AUDIO_CONTROL_ENABLED, 466 SYSTEM_AUDIO_CONTROL_DISABLED 467 }) 468 @Retention(RetentionPolicy.SOURCE) 469 public @interface SystemAudioControl {} 470 471 // -- Whether System Audio Mode muting is enabled or disabled. 472 /** 473 * System Audio Mode muting enabled. 474 * 475 * @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING 476 */ 477 public static final int SYSTEM_AUDIO_MODE_MUTING_ENABLED = 1; 478 /** 479 * System Audio Mode muting disabled. 480 * 481 * @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING 482 */ 483 public static final int SYSTEM_AUDIO_MODE_MUTING_DISABLED = 0; 484 /** 485 * @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING 486 * @hide 487 */ 488 @IntDef(prefix = { "SYSTEM_AUDIO_MODE_MUTING_" }, value = { 489 SYSTEM_AUDIO_MODE_MUTING_ENABLED, 490 SYSTEM_AUDIO_MODE_MUTING_DISABLED 491 }) 492 @Retention(RetentionPolicy.SOURCE) 493 public @interface SystemAudioModeMuting {} 494 495 // -- Whether the HDMI CEC volume control is enabled or disabled. 496 /** 497 * HDMI CEC enabled. 498 * 499 * @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE 500 */ 501 public static final int VOLUME_CONTROL_ENABLED = 1; 502 /** 503 * HDMI CEC disabled. 504 * 505 * @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE 506 */ 507 public static final int VOLUME_CONTROL_DISABLED = 0; 508 /** 509 * @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE 510 * @hide 511 */ 512 @IntDef(prefix = { "VOLUME_CONTROL_" }, value = { 513 VOLUME_CONTROL_ENABLED, 514 VOLUME_CONTROL_DISABLED 515 }) 516 @Retention(RetentionPolicy.SOURCE) 517 public @interface VolumeControl {} 518 519 // -- Whether TV Wake on One Touch Play is enabled or disabled. 520 /** 521 * TV Wake on One Touch Play enabled. 522 * 523 * @see HdmiControlManager#CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY 524 */ 525 public static final int TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED = 1; 526 /** 527 * TV Wake on One Touch Play disabled. 528 * 529 * @see HdmiControlManager#CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY 530 */ 531 public static final int TV_WAKE_ON_ONE_TOUCH_PLAY_DISABLED = 0; 532 /** 533 * @see HdmiControlManager#CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY 534 * @hide 535 */ 536 @IntDef(prefix = { "TV_WAKE_ON_ONE_TOUCH_PLAY_" }, value = { 537 TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED, 538 TV_WAKE_ON_ONE_TOUCH_PLAY_DISABLED 539 }) 540 @Retention(RetentionPolicy.SOURCE) 541 public @interface TvWakeOnOneTouchPlay {} 542 543 // -- Whether TV should send <Standby> on sleep. 544 /** 545 * Sending <Standby> on sleep. 546 * 547 * @see HdmiControlManager#CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP 548 */ 549 public static final int TV_SEND_STANDBY_ON_SLEEP_ENABLED = 1; 550 /** 551 * Not sending <Standby> on sleep. 552 * 553 * @see HdmiControlManager#CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP 554 */ 555 public static final int TV_SEND_STANDBY_ON_SLEEP_DISABLED = 0; 556 /** 557 * @see HdmiControlManager#CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP 558 * @hide 559 */ 560 @IntDef(prefix = { "TV_SEND_STANDBY_ON_SLEEP_" }, value = { 561 TV_SEND_STANDBY_ON_SLEEP_ENABLED, 562 TV_SEND_STANDBY_ON_SLEEP_DISABLED 563 }) 564 @Retention(RetentionPolicy.SOURCE) 565 public @interface TvSendStandbyOnSleep {} 566 567 // -- Whether a playback device should act on an incoming {@code <Set Menu Language>} message. 568 /** 569 * Confirmation dialog should be shown upon receiving the CEC message. 570 * 571 * @see HdmiControlManager#CEC_SETTING_NAME_SET_MENU_LANGUAGE 572 * @hide 573 */ 574 public static final int SET_MENU_LANGUAGE_ENABLED = 1; 575 /** 576 * The message should be ignored. 577 * 578 * @see HdmiControlManager#CEC_SETTING_NAME_SET_MENU_LANGUAGE 579 * @hide 580 */ 581 public static final int SET_MENU_LANGUAGE_DISABLED = 0; 582 /** 583 * @see HdmiControlManager#CEC_SETTING_NAME_SET_MENU_LANGUAGE 584 * @hide 585 */ 586 @IntDef(prefix = { "SET_MENU_LANGUAGE_" }, value = { 587 SET_MENU_LANGUAGE_ENABLED, 588 SET_MENU_LANGUAGE_DISABLED 589 }) 590 @Retention(RetentionPolicy.SOURCE) 591 public @interface SetMenuLanguage {} 592 593 // -- The RC profile of a TV panel. 594 /** 595 * RC profile none. 596 * 597 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_TV 598 * @hide 599 */ 600 public static final int RC_PROFILE_TV_NONE = 0x0; 601 /** 602 * RC profile 1. 603 * 604 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_TV 605 * @hide 606 */ 607 public static final int RC_PROFILE_TV_ONE = 0x2; 608 /** 609 * RC profile 2. 610 * 611 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_TV 612 * @hide 613 */ 614 public static final int RC_PROFILE_TV_TWO = 0x6; 615 /** 616 * RC profile 3. 617 * 618 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_TV 619 * @hide 620 */ 621 public static final int RC_PROFILE_TV_THREE = 0xA; 622 /** 623 * RC profile 4. 624 * 625 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_TV 626 * @hide 627 */ 628 public static final int RC_PROFILE_TV_FOUR = 0xE; 629 /** 630 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_TV 631 * @hide 632 */ 633 @IntDef(prefix = { "RC_PROFILE_TV_" }, value = { 634 RC_PROFILE_TV_NONE, 635 RC_PROFILE_TV_ONE, 636 RC_PROFILE_TV_TWO, 637 RC_PROFILE_TV_THREE, 638 RC_PROFILE_TV_FOUR 639 }) 640 @Retention(RetentionPolicy.SOURCE) 641 public @interface RcProfileTv {} 642 643 // -- RC profile parameter defining if a source handles a specific menu. 644 /** 645 * Handles the menu. 646 * 647 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_ROOT_MENU 648 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_SETUP_MENU 649 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU 650 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_TOP_MENU 651 * @see HdmiControlManager# 652 * CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU 653 * @hide 654 */ 655 public static final int RC_PROFILE_SOURCE_MENU_HANDLED = 1; 656 /** 657 * Doesn't handle the menu. 658 * 659 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_ROOT_MENU 660 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_SETUP_MENU 661 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU 662 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_TOP_MENU 663 * @see HdmiControlManager# 664 * CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU 665 * @hide 666 */ 667 public static final int RC_PROFILE_SOURCE_MENU_NOT_HANDLED = 0; 668 /** 669 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_ROOT_MENU 670 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_SETUP_MENU 671 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU 672 * @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_TOP_MENU 673 * @see HdmiControlManager# 674 * CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU 675 * @hide 676 */ 677 @IntDef(prefix = { "RC_PROFILE_SOURCE_MENU_" }, value = { 678 RC_PROFILE_SOURCE_MENU_HANDLED, 679 RC_PROFILE_SOURCE_MENU_NOT_HANDLED 680 }) 681 @Retention(RetentionPolicy.SOURCE) 682 public @interface RcProfileSourceHandlesMenu {} 683 684 // -- Whether the Short Audio Descriptor (SAD) for a specific codec should be queried or not. 685 /** 686 * Query the SAD. 687 * 688 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_LPCM 689 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DD 690 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MPEG1 691 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MP3 692 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MPEG2 693 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_AAC 694 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DTS 695 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_ATRAC 696 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO 697 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DDP 698 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DTSHD 699 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_TRUEHD 700 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DST 701 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_WMAPRO 702 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MAX 703 */ 704 public static final int QUERY_SAD_ENABLED = 1; 705 /** 706 * Don't query the SAD. 707 * 708 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_LPCM 709 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DD 710 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MPEG1 711 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MP3 712 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MPEG2 713 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_AAC 714 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DTS 715 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_ATRAC 716 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO 717 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DDP 718 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DTSHD 719 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_TRUEHD 720 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DST 721 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_WMAPRO 722 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MAX 723 */ 724 public static final int QUERY_SAD_DISABLED = 0; 725 /** 726 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_LPCM 727 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DD 728 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MPEG1 729 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MP3 730 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MPEG2 731 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_AAC 732 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DTS 733 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_ATRAC 734 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO 735 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DDP 736 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DTSHD 737 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_TRUEHD 738 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DST 739 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_WMAPRO 740 * @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MAX 741 * @hide 742 */ 743 @IntDef(prefix = { "QUERY_SAD_" }, value = { 744 QUERY_SAD_ENABLED, 745 QUERY_SAD_DISABLED 746 }) 747 @Retention(RetentionPolicy.SOURCE) 748 public @interface SadPresenceInQuery {} 749 750 // -- Settings available in the CEC Configuration. 751 /** 752 * Name of a setting deciding whether the CEC is enabled. 753 * 754 * @see HdmiControlManager#setHdmiCecEnabled(int) 755 */ 756 public static final String CEC_SETTING_NAME_HDMI_CEC_ENABLED = "hdmi_cec_enabled"; 757 /** 758 * Name of a setting controlling the version of HDMI-CEC used. 759 * 760 * @see HdmiControlManager#setHdmiCecVersion(int) 761 */ 762 public static final String CEC_SETTING_NAME_HDMI_CEC_VERSION = "hdmi_cec_version"; 763 /** 764 * Name of a setting deciding whether the Routing Control feature is enabled. 765 * 766 * @see HdmiControlManager#setRoutingControl(int) 767 */ 768 public static final String CEC_SETTING_NAME_ROUTING_CONTROL = "routing_control"; 769 /** 770 * Name of a setting deciding on the power control mode. 771 * 772 * @see HdmiControlManager#setPowerControlMode(String) 773 */ 774 public static final String CEC_SETTING_NAME_POWER_CONTROL_MODE = "power_control_mode"; 775 /** 776 * Name of a setting deciding on power state action when losing Active Source. 777 * 778 * @see HdmiControlManager#setPowerStateChangeOnActiveSourceLost(String) 779 */ 780 public static final String CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST = 781 "power_state_change_on_active_source_lost"; 782 /** 783 * Name of a setting deciding whether System Audio Control is enabled. 784 * 785 * @see HdmiControlManager#setSystemAudioControl(int) 786 */ 787 public static final String CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL = 788 "system_audio_control"; 789 /** 790 * Name of a setting deciding whether System Audio Muting is allowed. 791 * 792 * @see HdmiControlManager#setSystemAudioModeMuting(int) 793 */ 794 public static final String CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING = 795 "system_audio_mode_muting"; 796 /** 797 * Controls whether volume control commands via HDMI CEC are enabled. 798 * 799 * <p>Effects on different device types: 800 * <table> 801 * <tr><th>HDMI CEC device type</th><th>0: disabled</th><th>1: enabled</th></tr> 802 * <tr> 803 * <td>TV (type: 0)</td> 804 * <td>Per CEC specification.</td> 805 * <td>TV changes system volume. TV no longer reacts to incoming volume changes 806 * via {@code <User Control Pressed>}. TV no longer handles {@code <Report Audio 807 * Status>}.</td> 808 * </tr> 809 * <tr> 810 * <td>Playback device (type: 4)</td> 811 * <td>Device sends volume commands to TV/Audio system via {@code <User Control 812 * Pressed>}</td> 813 * <td>Device does not send volume commands via {@code <User Control Pressed>}.</td> 814 * </tr> 815 * <tr> 816 * <td>Audio device (type: 5)</td> 817 * <td>Full "System Audio Control" capabilities.</td> 818 * <td>Audio device no longer reacts to incoming {@code <User Control Pressed>} 819 * volume commands. Audio device no longer reports volume changes via {@code 820 * <Report Audio Status>}.</td> 821 * </tr> 822 * </table> 823 * 824 * <p> Due to the resulting behavior, usage on TV and Audio devices is discouraged. 825 * 826 * @see HdmiControlManager#setHdmiCecVolumeControlEnabled(int) 827 */ 828 public static final String CEC_SETTING_NAME_VOLUME_CONTROL_MODE = 829 "volume_control_enabled"; 830 /** 831 * Name of a setting deciding whether the TV will automatically turn on upon reception 832 * of the CEC command <Text View On> or <Image View On>. 833 * 834 * @see HdmiControlManager#setTvWakeOnOneTouchPlay(int) 835 */ 836 public static final String CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY = 837 "tv_wake_on_one_touch_play"; 838 /** 839 * Name of a setting deciding whether the TV will also turn off other CEC devices 840 * when it goes to standby mode. 841 * 842 * @see HdmiControlManager#setTvSendStandbyOnSleep(int) 843 */ 844 public static final String CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP = 845 "tv_send_standby_on_sleep"; 846 /** 847 * Name of a setting deciding whether {@code <Set Menu Language>} message should be 848 * handled by the framework or ignored. 849 * 850 * @hide 851 */ 852 public static final String CEC_SETTING_NAME_SET_MENU_LANGUAGE = "set_menu_language"; 853 /** 854 * Name of a setting representing the RC profile of a TV panel. 855 * 856 * @hide 857 */ 858 public static final String CEC_SETTING_NAME_RC_PROFILE_TV = 859 "rc_profile_tv"; 860 /** 861 * Name of a setting representing the RC profile parameter defining if a source handles the root 862 * menu. 863 * 864 * @hide 865 */ 866 public static final String CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_ROOT_MENU = 867 "rc_profile_source_handles_root_menu"; 868 /** 869 * Name of a setting representing the RC profile parameter defining if a source handles the 870 * setup menu. 871 * 872 * @hide 873 */ 874 public static final String CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_SETUP_MENU = 875 "rc_profile_source_handles_setup_menu"; 876 /** 877 * Name of a setting representing the RC profile parameter defining if a source handles the 878 * contents menu. 879 * 880 * @hide 881 */ 882 public static final String CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU = 883 "rc_profile_source_handles_contents_menu"; 884 /** 885 * Name of a setting representing the RC profile parameter defining if a source handles the top 886 * menu. 887 * 888 * @hide 889 */ 890 public static final String CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_TOP_MENU = 891 "rc_profile_source_handles_top_menu"; 892 /** 893 * Name of a setting representing the RC profile parameter defining if a source handles the 894 * media context sensitive menu. 895 * 896 * @hide 897 */ 898 public static final String 899 CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU = 900 "rc_profile_source_handles_media_context_sensitive_menu"; 901 /** 902 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the LPCM codec 903 * (0x1) should be queried or not. 904 * 905 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 906 */ 907 public static final String CEC_SETTING_NAME_QUERY_SAD_LPCM = "query_sad_lpcm"; 908 /** 909 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the DD codec 910 * (0x2) should be queried or not. 911 * 912 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 913 */ 914 public static final String CEC_SETTING_NAME_QUERY_SAD_DD = "query_sad_dd"; 915 /** 916 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the MPEG1 codec 917 * (0x3) should be queried or not. 918 * 919 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 920 */ 921 public static final String CEC_SETTING_NAME_QUERY_SAD_MPEG1 = "query_sad_mpeg1"; 922 /** 923 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the MP3 codec 924 * (0x4) should be queried or not. 925 * 926 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 927 */ 928 public static final String CEC_SETTING_NAME_QUERY_SAD_MP3 = "query_sad_mp3"; 929 /** 930 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the MPEG2 codec 931 * (0x5) should be queried or not. 932 * 933 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 934 */ 935 public static final String CEC_SETTING_NAME_QUERY_SAD_MPEG2 = "query_sad_mpeg2"; 936 /** 937 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the AAC codec 938 * (0x6) should be queried or not. 939 * 940 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 941 */ 942 public static final String CEC_SETTING_NAME_QUERY_SAD_AAC = "query_sad_aac"; 943 /** 944 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the DTS codec 945 * (0x7) should be queried or not. 946 * 947 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 948 */ 949 public static final String CEC_SETTING_NAME_QUERY_SAD_DTS = "query_sad_dts"; 950 /** 951 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the ATRAC codec 952 * (0x8) should be queried or not. 953 * 954 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 955 */ 956 public static final String CEC_SETTING_NAME_QUERY_SAD_ATRAC = "query_sad_atrac"; 957 /** 958 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the ONEBITAUDIO 959 * codec (0x9) should be queried or not. 960 * 961 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 962 */ 963 public static final String CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO = "query_sad_onebitaudio"; 964 /** 965 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the DDP codec 966 * (0xA) should be queried or not. 967 * 968 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 969 */ 970 public static final String CEC_SETTING_NAME_QUERY_SAD_DDP = "query_sad_ddp"; 971 /** 972 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the DTSHD codec 973 * (0xB) should be queried or not. 974 * 975 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 976 */ 977 public static final String CEC_SETTING_NAME_QUERY_SAD_DTSHD = "query_sad_dtshd"; 978 /** 979 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the TRUEHD codec 980 * (0xC) should be queried or not. 981 * 982 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 983 */ 984 public static final String CEC_SETTING_NAME_QUERY_SAD_TRUEHD = "query_sad_truehd"; 985 /** 986 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the DST codec 987 * (0xD) should be queried or not. 988 * 989 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 990 */ 991 public static final String CEC_SETTING_NAME_QUERY_SAD_DST = "query_sad_dst"; 992 /** 993 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the WMAPRO codec 994 * (0xE) should be queried or not. 995 * 996 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 997 */ 998 public static final String CEC_SETTING_NAME_QUERY_SAD_WMAPRO = "query_sad_wmapro"; 999 /** 1000 * Name of a setting representing whether the Short Audio Descriptor (SAD) for the MAX codec 1001 * (0xF) should be queried or not. 1002 * 1003 * @see HdmiControlManager#setSadPresenceInQuery(String, int) 1004 */ 1005 public static final String CEC_SETTING_NAME_QUERY_SAD_MAX = "query_sad_max"; 1006 /** 1007 * @hide 1008 */ 1009 @StringDef(prefix = { "CEC_SETTING_NAME_" }, value = { 1010 CEC_SETTING_NAME_HDMI_CEC_ENABLED, 1011 CEC_SETTING_NAME_HDMI_CEC_VERSION, 1012 CEC_SETTING_NAME_POWER_CONTROL_MODE, 1013 CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, 1014 CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL, 1015 CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING, 1016 CEC_SETTING_NAME_VOLUME_CONTROL_MODE, 1017 CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY, 1018 CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP, 1019 CEC_SETTING_NAME_SET_MENU_LANGUAGE, 1020 CEC_SETTING_NAME_RC_PROFILE_TV, 1021 CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_ROOT_MENU, 1022 CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_SETUP_MENU, 1023 CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU, 1024 CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_TOP_MENU, 1025 CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU, 1026 CEC_SETTING_NAME_QUERY_SAD_LPCM, 1027 CEC_SETTING_NAME_QUERY_SAD_DD, 1028 CEC_SETTING_NAME_QUERY_SAD_MPEG1, 1029 CEC_SETTING_NAME_QUERY_SAD_MP3, 1030 CEC_SETTING_NAME_QUERY_SAD_MPEG2, 1031 CEC_SETTING_NAME_QUERY_SAD_AAC, 1032 CEC_SETTING_NAME_QUERY_SAD_DTS, 1033 CEC_SETTING_NAME_QUERY_SAD_ATRAC, 1034 CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO, 1035 CEC_SETTING_NAME_QUERY_SAD_DDP, 1036 CEC_SETTING_NAME_QUERY_SAD_DTSHD, 1037 CEC_SETTING_NAME_QUERY_SAD_TRUEHD, 1038 CEC_SETTING_NAME_QUERY_SAD_DST, 1039 CEC_SETTING_NAME_QUERY_SAD_WMAPRO, 1040 CEC_SETTING_NAME_QUERY_SAD_MAX, 1041 }) 1042 public @interface CecSettingName {} 1043 1044 /** 1045 * @hide 1046 */ 1047 @StringDef(prefix = { "CEC_SETTING_NAME_QUERY_SAD_" }, value = { 1048 CEC_SETTING_NAME_QUERY_SAD_LPCM, 1049 CEC_SETTING_NAME_QUERY_SAD_DD, 1050 CEC_SETTING_NAME_QUERY_SAD_MPEG1, 1051 CEC_SETTING_NAME_QUERY_SAD_MP3, 1052 CEC_SETTING_NAME_QUERY_SAD_MPEG2, 1053 CEC_SETTING_NAME_QUERY_SAD_AAC, 1054 CEC_SETTING_NAME_QUERY_SAD_DTS, 1055 CEC_SETTING_NAME_QUERY_SAD_ATRAC, 1056 CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO, 1057 CEC_SETTING_NAME_QUERY_SAD_DDP, 1058 CEC_SETTING_NAME_QUERY_SAD_DTSHD, 1059 CEC_SETTING_NAME_QUERY_SAD_TRUEHD, 1060 CEC_SETTING_NAME_QUERY_SAD_DST, 1061 CEC_SETTING_NAME_QUERY_SAD_WMAPRO, 1062 CEC_SETTING_NAME_QUERY_SAD_MAX, 1063 }) 1064 public @interface CecSettingSad {} 1065 1066 // True if we have a logical device of type playback hosted in the system. 1067 private final boolean mHasPlaybackDevice; 1068 // True if we have a logical device of type TV hosted in the system. 1069 private final boolean mHasTvDevice; 1070 // True if we have a logical device of type audio system hosted in the system. 1071 private final boolean mHasAudioSystemDevice; 1072 // True if we have a logical device of type audio system hosted in the system. 1073 private final boolean mHasSwitchDevice; 1074 // True if it's a switch device. 1075 private final boolean mIsSwitchDevice; 1076 1077 /** 1078 * {@hide} - hide this constructor because it has a parameter of type IHdmiControlService, 1079 * which is a system private class. The right way to create an instance of this class is 1080 * using the factory Context.getSystemService. 1081 */ HdmiControlManager(IHdmiControlService service)1082 public HdmiControlManager(IHdmiControlService service) { 1083 mService = service; 1084 int[] types = null; 1085 if (mService != null) { 1086 try { 1087 types = mService.getSupportedTypes(); 1088 } catch (RemoteException e) { 1089 throw e.rethrowFromSystemServer(); 1090 } 1091 } 1092 mHasTvDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_TV); 1093 mHasPlaybackDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_PLAYBACK); 1094 mHasAudioSystemDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1095 mHasSwitchDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH); 1096 mIsSwitchDevice = HdmiProperties.is_switch().orElse(false); 1097 } 1098 hasDeviceType(int[] types, int type)1099 private static boolean hasDeviceType(int[] types, int type) { 1100 if (types == null) { 1101 return false; 1102 } 1103 for (int t : types) { 1104 if (t == type) { 1105 return true; 1106 } 1107 } 1108 return false; 1109 } 1110 1111 /** 1112 * Gets an object that represents an HDMI-CEC logical device of a specified type. 1113 * 1114 * @param type CEC device type 1115 * @return {@link HdmiClient} instance. {@code null} on failure. 1116 * See {@link HdmiDeviceInfo#DEVICE_PLAYBACK} 1117 * See {@link HdmiDeviceInfo#DEVICE_TV} 1118 * See {@link HdmiDeviceInfo#DEVICE_AUDIO_SYSTEM} 1119 */ 1120 @Nullable 1121 @SuppressLint("RequiresPermission") getClient(int type)1122 public HdmiClient getClient(int type) { 1123 if (mService == null) { 1124 return null; 1125 } 1126 switch (type) { 1127 case HdmiDeviceInfo.DEVICE_TV: 1128 return mHasTvDevice ? new HdmiTvClient(mService) : null; 1129 case HdmiDeviceInfo.DEVICE_PLAYBACK: 1130 return mHasPlaybackDevice ? new HdmiPlaybackClient(mService) : null; 1131 case HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM: 1132 return mHasAudioSystemDevice ? new HdmiAudioSystemClient(mService) : null; 1133 case HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH: 1134 return (mHasSwitchDevice || mIsSwitchDevice) 1135 ? new HdmiSwitchClient(mService) : null; 1136 default: 1137 return null; 1138 } 1139 } 1140 1141 /** 1142 * Gets an object that represents an HDMI-CEC logical device of type playback on the system. 1143 * 1144 * <p>Used to send HDMI control messages to other devices like TV or audio amplifier through 1145 * HDMI bus. It is also possible to communicate with other logical devices hosted in the same 1146 * system if the system is configured to host more than one type of HDMI-CEC logical devices. 1147 * 1148 * @return {@link HdmiPlaybackClient} instance. {@code null} on failure. 1149 */ 1150 @Nullable 1151 @SuppressLint("RequiresPermission") getPlaybackClient()1152 public HdmiPlaybackClient getPlaybackClient() { 1153 return (HdmiPlaybackClient) getClient(HdmiDeviceInfo.DEVICE_PLAYBACK); 1154 } 1155 1156 /** 1157 * Gets an object that represents an HDMI-CEC logical device of type TV on the system. 1158 * 1159 * <p>Used to send HDMI control messages to other devices and manage them through 1160 * HDMI bus. It is also possible to communicate with other logical devices hosted in the same 1161 * system if the system is configured to host more than one type of HDMI-CEC logical devices. 1162 * 1163 * @return {@link HdmiTvClient} instance. {@code null} on failure. 1164 */ 1165 @Nullable 1166 @SuppressLint("RequiresPermission") getTvClient()1167 public HdmiTvClient getTvClient() { 1168 return (HdmiTvClient) getClient(HdmiDeviceInfo.DEVICE_TV); 1169 } 1170 1171 /** 1172 * Gets an object that represents an HDMI-CEC logical device of type audio system on the system. 1173 * 1174 * <p>Used to send HDMI control messages to other devices like TV through HDMI bus. It is also 1175 * possible to communicate with other logical devices hosted in the same system if the system is 1176 * configured to host more than one type of HDMI-CEC logical devices. 1177 * 1178 * @return {@link HdmiAudioSystemClient} instance. {@code null} on failure. 1179 * 1180 * @hide 1181 */ 1182 @Nullable 1183 @SuppressLint("RequiresPermission") getAudioSystemClient()1184 public HdmiAudioSystemClient getAudioSystemClient() { 1185 return (HdmiAudioSystemClient) getClient(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM); 1186 } 1187 1188 /** 1189 * Gets an object that represents an HDMI-CEC logical device of type switch on the system. 1190 * 1191 * <p>Used to send HDMI control messages to other devices (e.g. TVs) through HDMI bus. 1192 * It is also possible to communicate with other logical devices hosted in the same 1193 * system if the system is configured to host more than one type of HDMI-CEC logical device. 1194 * 1195 * @return {@link HdmiSwitchClient} instance. {@code null} on failure. 1196 */ 1197 @Nullable 1198 @SuppressLint("RequiresPermission") getSwitchClient()1199 public HdmiSwitchClient getSwitchClient() { 1200 return (HdmiSwitchClient) getClient(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH); 1201 } 1202 1203 /** 1204 * Get a snapshot of the real-time status of the devices on the CEC bus. 1205 * 1206 * <p>This only applies to devices with switch functionality, which are devices with one 1207 * or more than one HDMI inputs. 1208 * 1209 * @return a list of {@link HdmiDeviceInfo} of the connected CEC devices on the CEC bus. An 1210 * empty list will be returned if there is none. 1211 */ 1212 @NonNull getConnectedDevices()1213 public List<HdmiDeviceInfo> getConnectedDevices() { 1214 try { 1215 return mService.getDeviceList(); 1216 } catch (RemoteException e) { 1217 throw e.rethrowFromSystemServer(); 1218 } 1219 } 1220 1221 /** 1222 * @removed 1223 * @deprecated Please use {@link #getConnectedDevices()} instead. 1224 */ 1225 @Deprecated getConnectedDevicesList()1226 public List<HdmiDeviceInfo> getConnectedDevicesList() { 1227 try { 1228 return mService.getDeviceList(); 1229 } catch (RemoteException e) { 1230 throw e.rethrowFromSystemServer(); 1231 } 1232 } 1233 1234 /** 1235 * Power off the target device by sending CEC commands. Note that this device can't be the 1236 * current device itself. 1237 * 1238 * <p>The target device info can be obtained by calling {@link #getConnectedDevicesList()}. 1239 * 1240 * @param deviceInfo {@link HdmiDeviceInfo} of the device to be powered off. 1241 */ powerOffDevice(@onNull HdmiDeviceInfo deviceInfo)1242 public void powerOffDevice(@NonNull HdmiDeviceInfo deviceInfo) { 1243 Objects.requireNonNull(deviceInfo); 1244 try { 1245 mService.powerOffRemoteDevice( 1246 deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus()); 1247 } catch (RemoteException e) { 1248 throw e.rethrowFromSystemServer(); 1249 } 1250 } 1251 1252 /** 1253 * @removed 1254 * @deprecated Please use {@link #powerOffDevice(deviceInfo)} instead. 1255 */ 1256 @Deprecated powerOffRemoteDevice(@onNull HdmiDeviceInfo deviceInfo)1257 public void powerOffRemoteDevice(@NonNull HdmiDeviceInfo deviceInfo) { 1258 Objects.requireNonNull(deviceInfo); 1259 try { 1260 mService.powerOffRemoteDevice( 1261 deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus()); 1262 } catch (RemoteException e) { 1263 throw e.rethrowFromSystemServer(); 1264 } 1265 } 1266 1267 /** 1268 * Power on the target device by sending CEC commands. Note that this device can't be the 1269 * current device itself. 1270 * 1271 * <p>The target device info can be obtained by calling {@link #getConnectedDevicesList()}. 1272 * 1273 * @param deviceInfo {@link HdmiDeviceInfo} of the device to be powered on. 1274 * 1275 * @hide 1276 */ powerOnDevice(HdmiDeviceInfo deviceInfo)1277 public void powerOnDevice(HdmiDeviceInfo deviceInfo) { 1278 Objects.requireNonNull(deviceInfo); 1279 try { 1280 mService.powerOnRemoteDevice( 1281 deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus()); 1282 } catch (RemoteException e) { 1283 throw e.rethrowFromSystemServer(); 1284 } 1285 } 1286 1287 /** 1288 * @removed 1289 * @deprecated Please use {@link #powerOnDevice(deviceInfo)} instead. 1290 */ 1291 @Deprecated powerOnRemoteDevice(HdmiDeviceInfo deviceInfo)1292 public void powerOnRemoteDevice(HdmiDeviceInfo deviceInfo) { 1293 Objects.requireNonNull(deviceInfo); 1294 try { 1295 mService.powerOnRemoteDevice( 1296 deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus()); 1297 } catch (RemoteException e) { 1298 throw e.rethrowFromSystemServer(); 1299 } 1300 } 1301 1302 /** 1303 * Request the target device to be the new Active Source by sending CEC commands. Note that 1304 * this device can't be the current device itself. 1305 * 1306 * <p>The target device info can be obtained by calling {@link #getConnectedDevicesList()}. 1307 * 1308 * <p>If the target device responds to the command, the users should see the target device 1309 * streaming on their TVs. 1310 * 1311 * @param deviceInfo HdmiDeviceInfo of the target device 1312 */ setActiveSource(@onNull HdmiDeviceInfo deviceInfo)1313 public void setActiveSource(@NonNull HdmiDeviceInfo deviceInfo) { 1314 Objects.requireNonNull(deviceInfo); 1315 try { 1316 mService.askRemoteDeviceToBecomeActiveSource(deviceInfo.getPhysicalAddress()); 1317 } catch (RemoteException e) { 1318 throw e.rethrowFromSystemServer(); 1319 } 1320 } 1321 1322 /** 1323 * @removed 1324 * @deprecated Please use {@link #setActiveSource(deviceInfo)} instead. 1325 */ 1326 @Deprecated requestRemoteDeviceToBecomeActiveSource(@onNull HdmiDeviceInfo deviceInfo)1327 public void requestRemoteDeviceToBecomeActiveSource(@NonNull HdmiDeviceInfo deviceInfo) { 1328 Objects.requireNonNull(deviceInfo); 1329 try { 1330 mService.askRemoteDeviceToBecomeActiveSource(deviceInfo.getPhysicalAddress()); 1331 } catch (RemoteException e) { 1332 throw e.rethrowFromSystemServer(); 1333 } 1334 } 1335 1336 /** 1337 * Controls standby mode of the system. It will also try to turn on/off the connected devices if 1338 * necessary. 1339 * 1340 * @param isStandbyModeOn target status of the system's standby mode 1341 */ 1342 @RequiresPermission(android.Manifest.permission.HDMI_CEC) setStandbyMode(boolean isStandbyModeOn)1343 public void setStandbyMode(boolean isStandbyModeOn) { 1344 try { 1345 mService.setStandbyMode(isStandbyModeOn); 1346 } catch (RemoteException e) { 1347 throw e.rethrowFromSystemServer(); 1348 } 1349 } 1350 1351 /** 1352 * For CEC source devices (OTT/STB/Audio system): toggle the power status of the HDMI-connected 1353 * display and follow the display's new power status. 1354 * For all other devices: no functionality. 1355 * 1356 * @hide 1357 */ 1358 @RequiresPermission(android.Manifest.permission.HDMI_CEC) toggleAndFollowTvPower()1359 public void toggleAndFollowTvPower() { 1360 try { 1361 mService.toggleAndFollowTvPower(); 1362 } catch (RemoteException e) { 1363 throw e.rethrowFromSystemServer(); 1364 } 1365 } 1366 1367 /** 1368 * Determines whether the HDMI CEC stack should handle KEYCODE_TV_POWER. 1369 * 1370 * @hide 1371 */ 1372 @RequiresPermission(android.Manifest.permission.HDMI_CEC) shouldHandleTvPowerKey()1373 public boolean shouldHandleTvPowerKey() { 1374 try { 1375 return mService.shouldHandleTvPowerKey(); 1376 } catch (RemoteException e) { 1377 throw e.rethrowFromSystemServer(); 1378 } 1379 } 1380 1381 /** 1382 * Controls whether volume control commands via HDMI CEC are enabled. 1383 * 1384 * <p>When disabled: 1385 * <ul> 1386 * <li>the device will not send any HDMI CEC audio messages 1387 * <li>received HDMI CEC audio messages are responded to with {@code <Feature Abort>} 1388 * </ul> 1389 * 1390 * <p>Effects on different device types: 1391 * <table> 1392 * <tr><th>HDMI CEC device type</th><th>enabled</th><th>disabled</th></tr> 1393 * <tr> 1394 * <td>TV (type: 0)</td> 1395 * <td>Per CEC specification.</td> 1396 * <td>TV changes system volume. TV no longer reacts to incoming volume changes via 1397 * {@code <User Control Pressed>}. TV no longer handles {@code <Report Audio Status>} 1398 * .</td> 1399 * </tr> 1400 * <tr> 1401 * <td>Playback device (type: 4)</td> 1402 * <td>Device sends volume commands to TV/Audio system via {@code <User Control 1403 * Pressed>}</td><td>Device does not send volume commands via {@code <User Control 1404 * Pressed>}.</td> 1405 * </tr> 1406 * <tr> 1407 * <td>Audio device (type: 5)</td> 1408 * <td>Full "System Audio Control" capabilities.</td> 1409 * <td>Audio device no longer reacts to incoming {@code <User Control Pressed>} 1410 * volume commands. Audio device no longer reports volume changes via {@code <Report 1411 * Audio Status>}.</td> 1412 * </tr> 1413 * </table> 1414 * 1415 * <p> Due to the resulting behavior, usage on TV and Audio devices is discouraged. 1416 * 1417 * @param hdmiCecVolumeControlEnabled target state of HDMI CEC volume control. 1418 * @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE 1419 */ 1420 @RequiresPermission(android.Manifest.permission.HDMI_CEC) setHdmiCecVolumeControlEnabled( @olumeControl int hdmiCecVolumeControlEnabled)1421 public void setHdmiCecVolumeControlEnabled( 1422 @VolumeControl int hdmiCecVolumeControlEnabled) { 1423 try { 1424 mService.setCecSettingIntValue(CEC_SETTING_NAME_VOLUME_CONTROL_MODE, 1425 hdmiCecVolumeControlEnabled); 1426 } catch (RemoteException e) { 1427 throw e.rethrowFromSystemServer(); 1428 } 1429 } 1430 1431 /** 1432 * Returns whether volume changes via HDMI CEC are enabled. 1433 * 1434 * @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE 1435 */ 1436 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 1437 @VolumeControl getHdmiCecVolumeControlEnabled()1438 public int getHdmiCecVolumeControlEnabled() { 1439 try { 1440 return mService.getCecSettingIntValue(CEC_SETTING_NAME_VOLUME_CONTROL_MODE); 1441 } catch (RemoteException e) { 1442 throw e.rethrowFromSystemServer(); 1443 } 1444 } 1445 1446 /** 1447 * Gets whether the system is in system audio mode. 1448 * 1449 * @hide 1450 */ getSystemAudioMode()1451 public boolean getSystemAudioMode() { 1452 try { 1453 return mService.getSystemAudioMode(); 1454 } catch (RemoteException e) { 1455 throw e.rethrowFromSystemServer(); 1456 } 1457 } 1458 1459 /** 1460 * Get the physical address of the device. 1461 * 1462 * <p>Physical address needs to be automatically adjusted when devices are phyiscally or 1463 * electrically added or removed from the device tree. Please see HDMI Specification Version 1464 * 1.4b 8.7 Physical Address for more details on the address discovery proccess. 1465 */ getPhysicalAddress()1466 public int getPhysicalAddress() { 1467 try { 1468 return mService.getPhysicalAddress(); 1469 } catch (RemoteException e) { 1470 return INVALID_PHYSICAL_ADDRESS; 1471 } 1472 } 1473 1474 /** 1475 * Check if the target device is connected to the current device. 1476 * 1477 * <p>The API also returns true if the current device is the target. 1478 * 1479 * @param targetDevice {@link HdmiDeviceInfo} of the target device. 1480 * @return true if {@code targetDevice} is directly or indirectly 1481 * connected to the current device. 1482 */ isDeviceConnected(@onNull HdmiDeviceInfo targetDevice)1483 public boolean isDeviceConnected(@NonNull HdmiDeviceInfo targetDevice) { 1484 Objects.requireNonNull(targetDevice); 1485 int physicalAddress = getPhysicalAddress(); 1486 if (physicalAddress == INVALID_PHYSICAL_ADDRESS) { 1487 return false; 1488 } 1489 int targetPhysicalAddress = targetDevice.getPhysicalAddress(); 1490 if (targetPhysicalAddress == INVALID_PHYSICAL_ADDRESS) { 1491 return false; 1492 } 1493 return HdmiUtils.getLocalPortFromPhysicalAddress(targetPhysicalAddress, physicalAddress) 1494 != HdmiUtils.TARGET_NOT_UNDER_LOCAL_DEVICE; 1495 } 1496 1497 /** 1498 * @removed 1499 * @deprecated Please use {@link #isDeviceConnected(targetDevice)} instead. 1500 */ 1501 @Deprecated isRemoteDeviceConnected(@onNull HdmiDeviceInfo targetDevice)1502 public boolean isRemoteDeviceConnected(@NonNull HdmiDeviceInfo targetDevice) { 1503 Objects.requireNonNull(targetDevice); 1504 int physicalAddress = getPhysicalAddress(); 1505 if (physicalAddress == INVALID_PHYSICAL_ADDRESS) { 1506 return false; 1507 } 1508 int targetPhysicalAddress = targetDevice.getPhysicalAddress(); 1509 if (targetPhysicalAddress == INVALID_PHYSICAL_ADDRESS) { 1510 return false; 1511 } 1512 return HdmiUtils.getLocalPortFromPhysicalAddress(targetPhysicalAddress, physicalAddress) 1513 != HdmiUtils.TARGET_NOT_UNDER_LOCAL_DEVICE; 1514 } 1515 1516 /** 1517 * Listener used to get hotplug event from HDMI port. 1518 */ 1519 public interface HotplugEventListener { onReceived(HdmiHotplugEvent event)1520 void onReceived(HdmiHotplugEvent event); 1521 } 1522 1523 private final ArrayMap<HotplugEventListener, IHdmiHotplugEventListener> 1524 mHotplugEventListeners = new ArrayMap<>(); 1525 1526 /** 1527 * Listener used to get HDMI Control (CEC) status (enabled/disabled) and the connected display 1528 * status. 1529 * @hide 1530 */ 1531 public interface HdmiControlStatusChangeListener { 1532 /** 1533 * Called when HDMI Control (CEC) is enabled/disabled. 1534 * 1535 * @param isCecEnabled status of HDMI Control 1536 * {@link android.hardware.hdmi.HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_ENABLED}: 1537 * {@code HDMI_CEC_CONTROL_ENABLED} if enabled. 1538 * @param isCecAvailable status of CEC support of the connected display (the TV). 1539 * {@code true} if supported. 1540 * 1541 * Note: Value of isCecAvailable is only valid when isCecEnabled is true. 1542 **/ onStatusChange(@dmiControlManager.HdmiCecControl int isCecEnabled, boolean isCecAvailable)1543 void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled, 1544 boolean isCecAvailable); 1545 } 1546 1547 private final ArrayMap<HdmiControlStatusChangeListener, IHdmiControlStatusChangeListener> 1548 mHdmiControlStatusChangeListeners = new ArrayMap<>(); 1549 1550 /** 1551 * Listener used to get the status of the HDMI CEC volume control feature (enabled/disabled). 1552 * @hide 1553 */ 1554 public interface HdmiCecVolumeControlFeatureListener { 1555 /** 1556 * Called when the HDMI Control (CEC) volume control feature is enabled/disabled. 1557 * 1558 * @param hdmiCecVolumeControl status of HDMI CEC volume control feature 1559 * @see {@link HdmiControlManager#setHdmiCecVolumeControlEnabled(int)} ()} 1560 **/ onHdmiCecVolumeControlFeature(@olumeControl int hdmiCecVolumeControl)1561 void onHdmiCecVolumeControlFeature(@VolumeControl int hdmiCecVolumeControl); 1562 } 1563 1564 private final ArrayMap<HdmiCecVolumeControlFeatureListener, 1565 IHdmiCecVolumeControlFeatureListener> 1566 mHdmiCecVolumeControlFeatureListeners = new ArrayMap<>(); 1567 1568 /** 1569 * Listener used to get vendor-specific commands. 1570 */ 1571 public interface VendorCommandListener { 1572 /** 1573 * Called when a vendor command is received. 1574 * 1575 * @param srcAddress source logical address 1576 * @param destAddress destination logical address 1577 * @param params vendor-specific parameters 1578 * @param hasVendorId {@code true} if the command is <Vendor Command 1579 * With ID>. The first 3 bytes of params is vendor id. 1580 */ onReceived(int srcAddress, int destAddress, byte[] params, boolean hasVendorId)1581 void onReceived(int srcAddress, int destAddress, byte[] params, boolean hasVendorId); 1582 1583 /** 1584 * The callback is called: 1585 * <ul> 1586 * <li> before HdmiControlService is disabled. 1587 * <li> after HdmiControlService is enabled and the local address is assigned. 1588 * </ul> 1589 * The client shouldn't hold the thread too long since this is a blocking call. 1590 * 1591 * @param enabled {@code true} if HdmiControlService is enabled. 1592 * @param reason the reason code why the state of HdmiControlService is changed. 1593 * @see #CONTROL_STATE_CHANGED_REASON_START 1594 * @see #CONTROL_STATE_CHANGED_REASON_SETTING 1595 * @see #CONTROL_STATE_CHANGED_REASON_WAKEUP 1596 * @see #CONTROL_STATE_CHANGED_REASON_STANDBY 1597 */ onControlStateChanged(boolean enabled, int reason)1598 void onControlStateChanged(boolean enabled, int reason); 1599 } 1600 1601 /** 1602 * Adds a listener to get informed of {@link HdmiHotplugEvent}. 1603 * 1604 * <p>To stop getting the notification, 1605 * use {@link #removeHotplugEventListener(HotplugEventListener)}. 1606 * 1607 * Note that each invocation of the callback will be executed on an arbitrary 1608 * Binder thread. This means that all callback implementations must be 1609 * thread safe. To specify the execution thread, use 1610 * {@link addHotplugEventListener(Executor, HotplugEventListener)}. 1611 * 1612 * @param listener {@link HotplugEventListener} instance 1613 * @see HdmiControlManager#removeHotplugEventListener(HotplugEventListener) 1614 */ 1615 @RequiresPermission(android.Manifest.permission.HDMI_CEC) addHotplugEventListener(HotplugEventListener listener)1616 public void addHotplugEventListener(HotplugEventListener listener) { 1617 addHotplugEventListener(ConcurrentUtils.DIRECT_EXECUTOR, listener); 1618 } 1619 1620 /** 1621 * Adds a listener to get informed of {@link HdmiHotplugEvent}. 1622 * 1623 * <p>To stop getting the notification, 1624 * use {@link #removeHotplugEventListener(HotplugEventListener)}. 1625 * 1626 * @param listener {@link HotplugEventListener} instance 1627 * @see HdmiControlManager#removeHotplugEventListener(HotplugEventListener) 1628 */ 1629 @RequiresPermission(android.Manifest.permission.HDMI_CEC) addHotplugEventListener(@onNull @allbackExecutor Executor executor, @NonNull HotplugEventListener listener)1630 public void addHotplugEventListener(@NonNull @CallbackExecutor Executor executor, 1631 @NonNull HotplugEventListener listener) { 1632 if (mService == null) { 1633 Log.e(TAG, "HdmiControlService is not available"); 1634 return; 1635 } 1636 if (mHotplugEventListeners.containsKey(listener)) { 1637 Log.e(TAG, "listener is already registered"); 1638 return; 1639 } 1640 IHdmiHotplugEventListener wrappedListener = 1641 getHotplugEventListenerWrapper(executor, listener); 1642 mHotplugEventListeners.put(listener, wrappedListener); 1643 try { 1644 mService.addHotplugEventListener(wrappedListener); 1645 } catch (RemoteException e) { 1646 throw e.rethrowFromSystemServer(); 1647 } 1648 } 1649 1650 /** 1651 * Removes a listener to stop getting informed of {@link HdmiHotplugEvent}. 1652 * 1653 * @param listener {@link HotplugEventListener} instance to be removed 1654 */ 1655 @RequiresPermission(android.Manifest.permission.HDMI_CEC) removeHotplugEventListener(HotplugEventListener listener)1656 public void removeHotplugEventListener(HotplugEventListener listener) { 1657 if (mService == null) { 1658 Log.e(TAG, "HdmiControlService is not available"); 1659 return; 1660 } 1661 IHdmiHotplugEventListener wrappedListener = mHotplugEventListeners.remove(listener); 1662 if (wrappedListener == null) { 1663 Log.e(TAG, "tried to remove not-registered listener"); 1664 return; 1665 } 1666 try { 1667 mService.removeHotplugEventListener(wrappedListener); 1668 } catch (RemoteException e) { 1669 throw e.rethrowFromSystemServer(); 1670 } 1671 } 1672 getHotplugEventListenerWrapper( Executor executor, final HotplugEventListener listener)1673 private IHdmiHotplugEventListener getHotplugEventListenerWrapper( 1674 Executor executor, final HotplugEventListener listener) { 1675 return new IHdmiHotplugEventListener.Stub() { 1676 @Override 1677 public void onReceived(HdmiHotplugEvent event) { 1678 final long token = Binder.clearCallingIdentity(); 1679 try { 1680 executor.execute(() -> listener.onReceived(event)); 1681 } finally { 1682 Binder.restoreCallingIdentity(token); 1683 } 1684 } 1685 }; 1686 } 1687 1688 /** 1689 * Adds a listener to get informed of {@link HdmiControlStatusChange}. 1690 * 1691 * <p>To stop getting the notification, 1692 * use {@link #removeHdmiControlStatusChangeListener(HdmiControlStatusChangeListener)}. 1693 * 1694 * Note that each invocation of the callback will be executed on an arbitrary 1695 * Binder thread. This means that all callback implementations must be 1696 * thread safe. To specify the execution thread, use 1697 * {@link addHdmiControlStatusChangeListener(Executor, HdmiControlStatusChangeListener)}. 1698 * 1699 * @param listener {@link HdmiControlStatusChangeListener} instance 1700 * @see HdmiControlManager#removeHdmiControlStatusChangeListener( 1701 * HdmiControlStatusChangeListener) 1702 * 1703 * @hide 1704 */ 1705 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 1706 public void addHdmiControlStatusChangeListener(HdmiControlStatusChangeListener listener) { 1707 addHdmiControlStatusChangeListener(ConcurrentUtils.DIRECT_EXECUTOR, listener); 1708 } 1709 1710 /** 1711 * Adds a listener to get informed of {@link HdmiControlStatusChange}. 1712 * 1713 * <p>To stop getting the notification, 1714 * use {@link #removeHdmiControlStatusChangeListener(HdmiControlStatusChangeListener)}. 1715 * 1716 * @param listener {@link HdmiControlStatusChangeListener} instance 1717 * @see HdmiControlManager#removeHdmiControlStatusChangeListener( 1718 * HdmiControlStatusChangeListener) 1719 * 1720 * @hide 1721 */ 1722 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 1723 public void addHdmiControlStatusChangeListener(@NonNull @CallbackExecutor Executor executor, 1724 @NonNull HdmiControlStatusChangeListener listener) { 1725 if (mService == null) { 1726 Log.e(TAG, "HdmiControlService is not available"); 1727 return; 1728 } 1729 if (mHdmiControlStatusChangeListeners.containsKey(listener)) { 1730 Log.e(TAG, "listener is already registered"); 1731 return; 1732 } 1733 IHdmiControlStatusChangeListener wrappedListener = 1734 getHdmiControlStatusChangeListenerWrapper(executor, listener); 1735 mHdmiControlStatusChangeListeners.put(listener, wrappedListener); 1736 try { 1737 mService.addHdmiControlStatusChangeListener(wrappedListener); 1738 } catch (RemoteException e) { 1739 throw e.rethrowFromSystemServer(); 1740 } 1741 } 1742 1743 /** 1744 * Removes a listener to stop getting informed of {@link HdmiControlStatusChange}. 1745 * 1746 * @param listener {@link HdmiControlStatusChangeListener} instance to be removed 1747 * 1748 * @hide 1749 */ 1750 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 1751 public void removeHdmiControlStatusChangeListener(HdmiControlStatusChangeListener listener) { 1752 if (mService == null) { 1753 Log.e(TAG, "HdmiControlService is not available"); 1754 return; 1755 } 1756 IHdmiControlStatusChangeListener wrappedListener = 1757 mHdmiControlStatusChangeListeners.remove(listener); 1758 if (wrappedListener == null) { 1759 Log.e(TAG, "tried to remove not-registered listener"); 1760 return; 1761 } 1762 try { 1763 mService.removeHdmiControlStatusChangeListener(wrappedListener); 1764 } catch (RemoteException e) { 1765 throw e.rethrowFromSystemServer(); 1766 } 1767 } 1768 1769 private IHdmiControlStatusChangeListener getHdmiControlStatusChangeListenerWrapper( 1770 Executor executor, final HdmiControlStatusChangeListener listener) { 1771 return new IHdmiControlStatusChangeListener.Stub() { 1772 @Override 1773 public void onStatusChange(@HdmiCecControl int isCecEnabled, boolean isCecAvailable) { 1774 final long token = Binder.clearCallingIdentity(); 1775 try { 1776 executor.execute(() -> listener.onStatusChange(isCecEnabled, isCecAvailable)); 1777 } finally { 1778 Binder.restoreCallingIdentity(token); 1779 } 1780 } 1781 }; 1782 } 1783 1784 /** 1785 * Adds a listener to get informed of changes to the state of the HDMI CEC volume control 1786 * feature. 1787 * 1788 * Upon adding a listener, the current state of the HDMI CEC volume control feature will be 1789 * sent immediately. 1790 * 1791 * <p>To stop getting the notification, 1792 * use {@link #removeHdmiCecVolumeControlFeatureListener(HdmiCecVolumeControlFeatureListener)}. 1793 * 1794 * @param listener {@link HdmiCecVolumeControlFeatureListener} instance 1795 * @hide 1796 * @see #removeHdmiCecVolumeControlFeatureListener(HdmiCecVolumeControlFeatureListener) 1797 */ 1798 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 1799 public void addHdmiCecVolumeControlFeatureListener(@NonNull @CallbackExecutor Executor executor, 1800 @NonNull HdmiCecVolumeControlFeatureListener listener) { 1801 if (mService == null) { 1802 Log.e(TAG, "HdmiControlService is not available"); 1803 return; 1804 } 1805 if (mHdmiCecVolumeControlFeatureListeners.containsKey(listener)) { 1806 Log.e(TAG, "listener is already registered"); 1807 return; 1808 } 1809 IHdmiCecVolumeControlFeatureListener wrappedListener = 1810 createHdmiCecVolumeControlFeatureListenerWrapper(executor, listener); 1811 mHdmiCecVolumeControlFeatureListeners.put(listener, wrappedListener); 1812 try { 1813 mService.addHdmiCecVolumeControlFeatureListener(wrappedListener); 1814 } catch (RemoteException e) { 1815 throw e.rethrowFromSystemServer(); 1816 } 1817 } 1818 1819 /** 1820 * Removes a listener to stop getting informed of changes to the state of the HDMI CEC volume 1821 * control feature. 1822 * 1823 * @param listener {@link HdmiCecVolumeControlFeatureListener} instance to be removed 1824 * @hide 1825 */ 1826 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 1827 public void removeHdmiCecVolumeControlFeatureListener( 1828 HdmiCecVolumeControlFeatureListener listener) { 1829 if (mService == null) { 1830 Log.e(TAG, "HdmiControlService is not available"); 1831 return; 1832 } 1833 IHdmiCecVolumeControlFeatureListener wrappedListener = 1834 mHdmiCecVolumeControlFeatureListeners.remove(listener); 1835 if (wrappedListener == null) { 1836 Log.e(TAG, "tried to remove not-registered listener"); 1837 return; 1838 } 1839 try { 1840 mService.removeHdmiCecVolumeControlFeatureListener(wrappedListener); 1841 } catch (RemoteException e) { 1842 throw e.rethrowFromSystemServer(); 1843 } 1844 } 1845 1846 private IHdmiCecVolumeControlFeatureListener createHdmiCecVolumeControlFeatureListenerWrapper( 1847 Executor executor, final HdmiCecVolumeControlFeatureListener listener) { 1848 return new android.hardware.hdmi.IHdmiCecVolumeControlFeatureListener.Stub() { 1849 @Override 1850 public void onHdmiCecVolumeControlFeature(int enabled) { 1851 final long token = Binder.clearCallingIdentity(); 1852 try { 1853 executor.execute(() -> listener.onHdmiCecVolumeControlFeature(enabled)); 1854 } finally { 1855 Binder.restoreCallingIdentity(token); 1856 } 1857 } 1858 }; 1859 } 1860 1861 /** 1862 * Listener used to get setting change notification. 1863 */ 1864 public interface CecSettingChangeListener { 1865 /** 1866 * Called when value of a setting changes. 1867 * 1868 * @param setting name of a CEC setting that changed 1869 */ 1870 void onChange(@NonNull @CecSettingName String setting); 1871 } 1872 1873 private final ArrayMap<String, 1874 ArrayMap<CecSettingChangeListener, IHdmiCecSettingChangeListener>> 1875 mCecSettingChangeListeners = new ArrayMap<>(); 1876 1877 private void addCecSettingChangeListener( 1878 @NonNull @CecSettingName String setting, 1879 @NonNull @CallbackExecutor Executor executor, 1880 @NonNull CecSettingChangeListener listener) { 1881 if (mService == null) { 1882 Log.e(TAG, "HdmiControlService is not available"); 1883 return; 1884 } 1885 if (mCecSettingChangeListeners.containsKey(setting) 1886 && mCecSettingChangeListeners.get(setting).containsKey(listener)) { 1887 Log.e(TAG, "listener is already registered"); 1888 return; 1889 } 1890 IHdmiCecSettingChangeListener wrappedListener = 1891 getCecSettingChangeListenerWrapper(executor, listener); 1892 if (!mCecSettingChangeListeners.containsKey(setting)) { 1893 mCecSettingChangeListeners.put(setting, new ArrayMap<>()); 1894 } 1895 mCecSettingChangeListeners.get(setting).put(listener, wrappedListener); 1896 try { 1897 mService.addCecSettingChangeListener(setting, wrappedListener); 1898 } catch (RemoteException e) { 1899 throw e.rethrowFromSystemServer(); 1900 } 1901 } 1902 1903 private void removeCecSettingChangeListener( 1904 @NonNull @CecSettingName String setting, 1905 @NonNull CecSettingChangeListener listener) { 1906 if (mService == null) { 1907 Log.e(TAG, "HdmiControlService is not available"); 1908 return; 1909 } 1910 IHdmiCecSettingChangeListener wrappedListener = 1911 !mCecSettingChangeListeners.containsKey(setting) ? null : 1912 mCecSettingChangeListeners.get(setting).remove(listener); 1913 if (wrappedListener == null) { 1914 Log.e(TAG, "tried to remove not-registered listener"); 1915 return; 1916 } 1917 try { 1918 mService.removeCecSettingChangeListener(setting, wrappedListener); 1919 } catch (RemoteException e) { 1920 throw e.rethrowFromSystemServer(); 1921 } 1922 } 1923 1924 private IHdmiCecSettingChangeListener getCecSettingChangeListenerWrapper( 1925 Executor executor, final CecSettingChangeListener listener) { 1926 return new IHdmiCecSettingChangeListener.Stub() { 1927 @Override 1928 public void onChange(String setting) { 1929 final long token = Binder.clearCallingIdentity(); 1930 try { 1931 executor.execute(() -> listener.onChange(setting)); 1932 } finally { 1933 Binder.restoreCallingIdentity(token); 1934 } 1935 } 1936 }; 1937 } 1938 1939 /** 1940 * Get a set of user-modifiable settings. 1941 * 1942 * @return a set of user-modifiable settings. 1943 * @throws RuntimeException when the HdmiControlService is not available. 1944 */ 1945 @NonNull 1946 @CecSettingName 1947 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 1948 public List<String> getUserCecSettings() { 1949 if (mService == null) { 1950 Log.e(TAG, "HdmiControlService is not available"); 1951 throw new RuntimeException("HdmiControlService is not available"); 1952 } 1953 try { 1954 return mService.getUserCecSettings(); 1955 } catch (RemoteException e) { 1956 throw e.rethrowFromSystemServer(); 1957 } 1958 } 1959 1960 /** 1961 * Get a set of allowed values for a setting (string value-type). 1962 * 1963 * @param name name of the setting 1964 * @return a set of allowed values for a settings. {@code null} on failure. 1965 * @throws IllegalArgumentException when setting {@code name} does not exist. 1966 * @throws IllegalArgumentException when setting {@code name} value type is invalid. 1967 * @throws RuntimeException when the HdmiControlService is not available. 1968 */ 1969 @NonNull 1970 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 1971 public List<String> getAllowedCecSettingStringValues(@NonNull @CecSettingName String name) { 1972 if (mService == null) { 1973 Log.e(TAG, "HdmiControlService is not available"); 1974 throw new RuntimeException("HdmiControlService is not available"); 1975 } 1976 try { 1977 return mService.getAllowedCecSettingStringValues(name); 1978 } catch (RemoteException e) { 1979 throw e.rethrowFromSystemServer(); 1980 } 1981 } 1982 1983 /** 1984 * Get a set of allowed values for a setting (int value-type). 1985 * 1986 * @param name name of the setting 1987 * @return a set of allowed values for a settings. {@code null} on failure. 1988 * @throws IllegalArgumentException when setting {@code name} does not exist. 1989 * @throws IllegalArgumentException when setting {@code name} value type is invalid. 1990 * @throws RuntimeException when the HdmiControlService is not available. 1991 */ 1992 @NonNull 1993 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 1994 public List<Integer> getAllowedCecSettingIntValues(@NonNull @CecSettingName String name) { 1995 if (mService == null) { 1996 Log.e(TAG, "HdmiControlService is not available"); 1997 throw new RuntimeException("HdmiControlService is not available"); 1998 } 1999 try { 2000 int[] allowedValues = mService.getAllowedCecSettingIntValues(name); 2001 return Arrays.stream(allowedValues).boxed().collect(Collectors.toList()); 2002 } catch (RemoteException e) { 2003 throw e.rethrowFromSystemServer(); 2004 } 2005 } 2006 2007 /** 2008 * Set the global status of HDMI CEC. 2009 * 2010 * <p>This allows to enable/disable HDMI CEC on the device. 2011 */ 2012 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2013 public void setHdmiCecEnabled(@NonNull @HdmiCecControl int value) { 2014 if (mService == null) { 2015 Log.e(TAG, "HdmiControlService is not available"); 2016 throw new RuntimeException("HdmiControlService is not available"); 2017 } 2018 try { 2019 mService.setCecSettingIntValue(CEC_SETTING_NAME_HDMI_CEC_ENABLED, value); 2020 } catch (RemoteException e) { 2021 throw e.rethrowFromSystemServer(); 2022 } 2023 } 2024 2025 /** 2026 * Get the current global status of HDMI CEC. 2027 * 2028 * <p>Reflects whether HDMI CEC is currently enabled on the device. 2029 */ 2030 @NonNull 2031 @HdmiCecControl 2032 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2033 public int getHdmiCecEnabled() { 2034 if (mService == null) { 2035 Log.e(TAG, "HdmiControlService is not available"); 2036 throw new RuntimeException("HdmiControlService is not available"); 2037 } 2038 try { 2039 return mService.getCecSettingIntValue(CEC_SETTING_NAME_HDMI_CEC_ENABLED); 2040 } catch (RemoteException e) { 2041 throw e.rethrowFromSystemServer(); 2042 } 2043 } 2044 2045 /** 2046 * Add change listener for global status of HDMI CEC. 2047 * 2048 * <p>To stop getting the notification, 2049 * use {@link #removeHdmiCecEnabledChangeListener(CecSettingChangeListener)}. 2050 * 2051 * Note that each invocation of the callback will be executed on an arbitrary 2052 * Binder thread. This means that all callback implementations must be 2053 * thread safe. To specify the execution thread, use 2054 * {@link addHdmiCecEnabledChangeListener(Executor, CecSettingChangeListener)}. 2055 */ 2056 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2057 public void addHdmiCecEnabledChangeListener(@NonNull CecSettingChangeListener listener) { 2058 addHdmiCecEnabledChangeListener(ConcurrentUtils.DIRECT_EXECUTOR, listener); 2059 } 2060 2061 /** 2062 * Add change listener for global status of HDMI CEC. 2063 * 2064 * <p>To stop getting the notification, 2065 * use {@link #removeHdmiCecEnabledChangeListener(CecSettingChangeListener)}. 2066 */ 2067 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2068 public void addHdmiCecEnabledChangeListener( 2069 @NonNull @CallbackExecutor Executor executor, 2070 @NonNull CecSettingChangeListener listener) { 2071 addCecSettingChangeListener(CEC_SETTING_NAME_HDMI_CEC_ENABLED, executor, listener); 2072 } 2073 2074 /** 2075 * Remove change listener for global status of HDMI CEC. 2076 */ 2077 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2078 public void removeHdmiCecEnabledChangeListener( 2079 @NonNull CecSettingChangeListener listener) { 2080 removeCecSettingChangeListener(CEC_SETTING_NAME_HDMI_CEC_ENABLED, listener); 2081 } 2082 2083 /** 2084 * Set the version of the HDMI CEC specification currently used. 2085 * 2086 * <p>Allows to select either CEC 1.4b or 2.0 to be used by the device. 2087 * 2088 * @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_VERSION 2089 */ 2090 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2091 public void setHdmiCecVersion(@NonNull @HdmiCecVersion int value) { 2092 if (mService == null) { 2093 Log.e(TAG, "HdmiControlService is not available"); 2094 throw new RuntimeException("HdmiControlService is not available"); 2095 } 2096 try { 2097 mService.setCecSettingIntValue(CEC_SETTING_NAME_HDMI_CEC_VERSION, value); 2098 } catch (RemoteException e) { 2099 throw e.rethrowFromSystemServer(); 2100 } 2101 } 2102 2103 /** 2104 * Get the version of the HDMI CEC specification currently used. 2105 * 2106 * <p>Reflects which CEC version 1.4b or 2.0 is currently used by the device. 2107 * 2108 * @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_VERSION 2109 */ 2110 @NonNull 2111 @HdmiCecVersion 2112 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2113 public int getHdmiCecVersion() { 2114 if (mService == null) { 2115 Log.e(TAG, "HdmiControlService is not available"); 2116 throw new RuntimeException("HdmiControlService is not available"); 2117 } 2118 try { 2119 return mService.getCecSettingIntValue(CEC_SETTING_NAME_HDMI_CEC_VERSION); 2120 } catch (RemoteException e) { 2121 throw e.rethrowFromSystemServer(); 2122 } 2123 } 2124 2125 /** 2126 * Set the status of Routing Control feature. 2127 * 2128 * <p>This allows to enable/disable Routing Control on the device. 2129 * If enabled, the switch device will route to the correct input source on 2130 * receiving Routing Control related messages. If disabled, you can only 2131 * switch the input via controls on this device. 2132 * 2133 * @see HdmiControlManager#CEC_SETTING_NAME_ROUTING_CONTROL 2134 */ 2135 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2136 public void setRoutingControl(@NonNull @RoutingControl int value) { 2137 if (mService == null) { 2138 Log.e(TAG, "HdmiControlService is not available"); 2139 throw new RuntimeException("HdmiControlService is not available"); 2140 } 2141 try { 2142 mService.setCecSettingIntValue(CEC_SETTING_NAME_ROUTING_CONTROL, value); 2143 } catch (RemoteException e) { 2144 throw e.rethrowFromSystemServer(); 2145 } 2146 } 2147 2148 /** 2149 * Get the current status of Routing Control feature. 2150 * 2151 * <p>Reflects whether Routing Control is currently enabled on the device. 2152 * If enabled, the switch device will route to the correct input source on 2153 * receiving Routing Control related messages. If disabled, you can only 2154 * switch the input via controls on this device. 2155 * 2156 * @see HdmiControlManager#CEC_SETTING_NAME_ROUTING_CONTROL 2157 */ 2158 @NonNull 2159 @RoutingControl 2160 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2161 public int getRoutingControl() { 2162 if (mService == null) { 2163 Log.e(TAG, "HdmiControlService is not available"); 2164 throw new RuntimeException("HdmiControlService is not available"); 2165 } 2166 try { 2167 return mService.getCecSettingIntValue(CEC_SETTING_NAME_ROUTING_CONTROL); 2168 } catch (RemoteException e) { 2169 throw e.rethrowFromSystemServer(); 2170 } 2171 } 2172 2173 /** 2174 * Set the status of Power Control. 2175 * 2176 * <p>Specifies to which devices Power Control messages should be sent: 2177 * only to the TV, broadcast to all devices, no power control messages. 2178 * 2179 * @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE 2180 */ 2181 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2182 public void setPowerControlMode(@NonNull @PowerControlMode String value) { 2183 if (mService == null) { 2184 Log.e(TAG, "HdmiControlService is not available"); 2185 throw new RuntimeException("HdmiControlService is not available"); 2186 } 2187 try { 2188 mService.setCecSettingStringValue(CEC_SETTING_NAME_POWER_CONTROL_MODE, value); 2189 } catch (RemoteException e) { 2190 throw e.rethrowFromSystemServer(); 2191 } 2192 } 2193 2194 /** 2195 * Get the status of Power Control. 2196 * 2197 * <p>Reflects to which devices Power Control messages should be sent: 2198 * only to the TV, broadcast to all devices, no power control messages. 2199 * 2200 * @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE 2201 */ 2202 @NonNull 2203 @PowerControlMode 2204 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2205 public String getPowerControlMode() { 2206 if (mService == null) { 2207 Log.e(TAG, "HdmiControlService is not available"); 2208 throw new RuntimeException("HdmiControlService is not available"); 2209 } 2210 try { 2211 return mService.getCecSettingStringValue(CEC_SETTING_NAME_POWER_CONTROL_MODE); 2212 } catch (RemoteException e) { 2213 throw e.rethrowFromSystemServer(); 2214 } 2215 } 2216 2217 /** 2218 * Set the current power state behaviour when Active Source is lost. 2219 * 2220 * <p>Sets the action taken: do nothing or go to sleep immediately. 2221 * 2222 * @see HdmiControlManager#CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST 2223 */ 2224 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2225 public void setPowerStateChangeOnActiveSourceLost( 2226 @NonNull @ActiveSourceLostBehavior String value) { 2227 if (mService == null) { 2228 Log.e(TAG, "HdmiControlService is not available"); 2229 throw new RuntimeException("HdmiControlService is not available"); 2230 } 2231 try { 2232 mService.setCecSettingStringValue( 2233 CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, value); 2234 } catch (RemoteException e) { 2235 throw e.rethrowFromSystemServer(); 2236 } 2237 } 2238 2239 /** 2240 * Get the current power state behaviour when Active Source is lost. 2241 * 2242 * <p>Reflects the action taken: do nothing or go to sleep immediately. 2243 * 2244 * @see HdmiControlManager#CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST 2245 */ 2246 @NonNull 2247 @ActiveSourceLostBehavior 2248 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2249 public String getPowerStateChangeOnActiveSourceLost() { 2250 if (mService == null) { 2251 Log.e(TAG, "HdmiControlService is not available"); 2252 throw new RuntimeException("HdmiControlService is not available"); 2253 } 2254 try { 2255 return mService.getCecSettingStringValue( 2256 CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST); 2257 } catch (RemoteException e) { 2258 throw e.rethrowFromSystemServer(); 2259 } 2260 } 2261 2262 /** 2263 * Set the current status of System Audio Control. 2264 * 2265 * <p>Sets whether HDMI System Audio Control feature is enabled. If enabled, 2266 * TV or Audio System will try to turn on the System Audio Mode if there's a 2267 * connected CEC-enabled AV Receiver. Then an audio stream will be played on 2268 * the AVR instead of TV speaker or Audio System speakers. If disabled, the 2269 * System Audio Mode will never be activated. 2270 * 2271 * @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL 2272 */ 2273 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2274 public void setSystemAudioControl(@NonNull @SystemAudioControl int value) { 2275 if (mService == null) { 2276 Log.e(TAG, "HdmiControlService is not available"); 2277 throw new RuntimeException("HdmiControlService is not available"); 2278 } 2279 try { 2280 mService.setCecSettingIntValue(CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL, value); 2281 } catch (RemoteException e) { 2282 throw e.rethrowFromSystemServer(); 2283 } 2284 } 2285 2286 /** 2287 * Get the current status of System Audio Control. 2288 * 2289 * <p>Reflects whether HDMI System Audio Control feature is enabled. If enabled, 2290 * TV or Audio System will try to turn on the System Audio Mode if there's a 2291 * connected CEC-enabled AV Receiver. Then an audio stream will be played on 2292 * the AVR instead of TV speaker or Audio System speakers. If disabled, the 2293 * System Audio Mode will never be activated. 2294 * 2295 * @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL 2296 */ 2297 @NonNull 2298 @SystemAudioControl 2299 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2300 public int getSystemAudioControl() { 2301 if (mService == null) { 2302 Log.e(TAG, "HdmiControlService is not available"); 2303 throw new RuntimeException("HdmiControlService is not available"); 2304 } 2305 try { 2306 return mService.getCecSettingIntValue(CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL); 2307 } catch (RemoteException e) { 2308 throw e.rethrowFromSystemServer(); 2309 } 2310 } 2311 2312 /** 2313 * Set the current status of System Audio Mode muting. 2314 * 2315 * <p>Sets whether the device should be muted when System Audio Mode is turned off. 2316 * 2317 * @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING 2318 */ 2319 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2320 public void setSystemAudioModeMuting(@NonNull @SystemAudioModeMuting int value) { 2321 if (mService == null) { 2322 Log.e(TAG, "HdmiControlService is not available"); 2323 throw new RuntimeException("HdmiControlService is not available"); 2324 } 2325 try { 2326 mService.setCecSettingIntValue(CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING, value); 2327 } catch (RemoteException e) { 2328 throw e.rethrowFromSystemServer(); 2329 } 2330 } 2331 2332 /** 2333 * Get the current status of System Audio Mode muting. 2334 * 2335 * <p>Reflects whether the device should be muted when System Audio Mode is turned off. 2336 * 2337 * @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING 2338 */ 2339 @NonNull 2340 @SystemAudioModeMuting 2341 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2342 public int getSystemAudioModeMuting() { 2343 if (mService == null) { 2344 Log.e(TAG, "HdmiControlService is not available"); 2345 throw new RuntimeException("HdmiControlService is not available"); 2346 } 2347 try { 2348 return mService.getCecSettingIntValue(CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING); 2349 } catch (RemoteException e) { 2350 throw e.rethrowFromSystemServer(); 2351 } 2352 } 2353 2354 /** 2355 * Set the current status of TV Wake on One Touch Play. 2356 * 2357 * <p>Sets whether the TV should wake up upon reception of <Text View On> 2358 * or <Image View On>. 2359 * 2360 * @see HdmiControlManager#CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY 2361 */ 2362 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2363 public void setTvWakeOnOneTouchPlay(@NonNull @TvWakeOnOneTouchPlay int value) { 2364 if (mService == null) { 2365 Log.e(TAG, "HdmiControlService is not available"); 2366 throw new RuntimeException("HdmiControlService is not available"); 2367 } 2368 try { 2369 mService.setCecSettingIntValue(CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY, value); 2370 } catch (RemoteException e) { 2371 throw e.rethrowFromSystemServer(); 2372 } 2373 } 2374 2375 /** 2376 * Get the current status of TV Wake on One Touch Play. 2377 * 2378 * <p>Reflects whether the TV should wake up upon reception of <Text View On> 2379 * or <Image View On>. 2380 * 2381 * @see HdmiControlManager#CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY 2382 */ 2383 @NonNull 2384 @TvWakeOnOneTouchPlay 2385 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2386 public int getTvWakeOnOneTouchPlay() { 2387 if (mService == null) { 2388 Log.e(TAG, "HdmiControlService is not available"); 2389 throw new RuntimeException("HdmiControlService is not available"); 2390 } 2391 try { 2392 return mService.getCecSettingIntValue(CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY); 2393 } catch (RemoteException e) { 2394 throw e.rethrowFromSystemServer(); 2395 } 2396 } 2397 2398 /** 2399 * Set the current status of TV send <Standby> on Sleep. 2400 * 2401 * <p>Sets whether the device will also turn off other CEC devices 2402 * when it goes to standby mode. 2403 * 2404 * @see HdmiControlManager#CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP 2405 */ 2406 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2407 public void setTvSendStandbyOnSleep(@NonNull @TvSendStandbyOnSleep int value) { 2408 if (mService == null) { 2409 Log.e(TAG, "HdmiControlService is not available"); 2410 throw new RuntimeException("HdmiControlService is not available"); 2411 } 2412 try { 2413 mService.setCecSettingIntValue(CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP, value); 2414 } catch (RemoteException e) { 2415 throw e.rethrowFromSystemServer(); 2416 } 2417 } 2418 2419 /** 2420 * Get the current status of TV send <Standby> on Sleep. 2421 * 2422 * <p>Reflects whether the device will also turn off other CEC devices 2423 * when it goes to standby mode. 2424 * 2425 * @see HdmiControlManager#CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP 2426 */ 2427 @NonNull 2428 @TvSendStandbyOnSleep 2429 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2430 public int getTvSendStandbyOnSleep() { 2431 if (mService == null) { 2432 Log.e(TAG, "HdmiControlService is not available"); 2433 throw new RuntimeException("HdmiControlService is not available"); 2434 } 2435 try { 2436 return mService.getCecSettingIntValue(CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP); 2437 } catch (RemoteException e) { 2438 throw e.rethrowFromSystemServer(); 2439 } 2440 } 2441 2442 /** 2443 * Set presence of one Short Audio Descriptor (SAD) in the query. 2444 * 2445 * <p>Allows the caller to specify whether the SAD for a specific audio codec should be 2446 * present in the <Request Short Audio Descriptor> query. Each <Request Short Audio 2447 * Descriptor> message can carry at most 4 SADs at a time. This method allows the caller to 2448 * limit the amount of SADs queried and therefore limit the amount of CEC messages on the bus. 2449 * 2450 * <p>When an ARC connection is established, the TV sends a 2451 * <Request Short Audio Descriptor> query to the Audio System that it's connected to. If 2452 * an SAD is queried and the Audio System reports that it supports that SAD, the TV can send 2453 * audio in that format to be output on the Audio System via ARC. 2454 * If a codec is not queried, the TV doesn't know if the connected Audio System supports this 2455 * SAD and doesn't send audio in that format to the Audio System. 2456 * 2457 * @param setting SAD to set. 2458 * @param value Presence to set the SAD to. 2459 */ 2460 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2461 public void setSadPresenceInQuery(@NonNull @CecSettingSad String setting, 2462 @SadPresenceInQuery int value) { 2463 if (mService == null) { 2464 Log.e(TAG, "HdmiControlService is not available"); 2465 throw new RuntimeException("HdmiControlService is not available"); 2466 } 2467 try { 2468 mService.setCecSettingIntValue(setting, value); 2469 } catch (RemoteException e) { 2470 throw e.rethrowFromSystemServer(); 2471 } 2472 } 2473 2474 /** 2475 * Set presence of multiple Short Audio Descriptors (SADs) in the query. 2476 * 2477 * <p>Allows the caller to specify whether the SADs for specific audio codecs should be present 2478 * in the <Request Short Audio Descriptor> query. For audio codecs that are not specified, 2479 * the SAD's presence remains at its previous value. Each <Request Short Audio Descriptor> 2480 * message can carry at most 4 SADs at a time. This method allows the caller to limit the amount 2481 * of SADs queried and therefore limit the amount of CEC messages on the bus. 2482 * 2483 * <p>When an ARC connection is established, the TV sends a 2484 * <Request Short Audio Descriptor> query to the Audio System that it's connected to. If 2485 * an SAD is queried and the Audio System reports that it supports that SAD, the TV can send 2486 * audio in that format to be output on the Audio System via ARC. 2487 * If a codec is not queried, the TV doesn't know if the connected Audio System supports this 2488 * SAD and doesn't send audio in that format to the Audio System. 2489 * 2490 * 2491 * @param settings SADs to set. 2492 * @param value Presence to set all specified SADs to. 2493 */ 2494 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2495 public void setSadsPresenceInQuery(@NonNull @CecSettingSad List<String> settings, 2496 @SadPresenceInQuery int value) { 2497 if (mService == null) { 2498 Log.e(TAG, "HdmiControlService is not available"); 2499 throw new RuntimeException("HdmiControlService is not available"); 2500 } 2501 try { 2502 for (String sad : settings) { 2503 mService.setCecSettingIntValue(sad, value); 2504 } 2505 } catch (RemoteException e) { 2506 throw e.rethrowFromSystemServer(); 2507 } 2508 } 2509 2510 /** 2511 * Get presence of one Short Audio Descriptor (SAD) in the query. 2512 * 2513 * <p>Reflects whether the SAD for a specific audio codec should be present in the 2514 * <Request Short Audio Descriptor> query. 2515 * 2516 * <p>When an ARC connection is established, the TV sends a 2517 * <Request Short Audio Descriptor> query to the Audio System that it's connected to. If 2518 * an SAD is queried and the Audio System reports that it supports that SAD, the TV can send 2519 * audio in that format to be output on the Audio System via ARC. 2520 * If a codec is not queried, the TV doesn't know if the connected Audio System supports this 2521 * SAD and doesn't send audio in that format to the Audio System. 2522 * 2523 * @param setting SAD to get. 2524 * @return Current presence of the specified SAD. 2525 */ 2526 @SadPresenceInQuery 2527 @RequiresPermission(android.Manifest.permission.HDMI_CEC) 2528 public int getSadPresenceInQuery(@NonNull @CecSettingSad String setting) { 2529 if (mService == null) { 2530 Log.e(TAG, "HdmiControlService is not available"); 2531 throw new RuntimeException("HdmiControlService is not available"); 2532 } 2533 try { 2534 return mService.getCecSettingIntValue(setting); 2535 } catch (RemoteException e) { 2536 throw e.rethrowFromSystemServer(); 2537 } 2538 } 2539 } 2540