2803 lines
112 KiB
Java
2803 lines
112 KiB
Java
/*
|
||
* Copyright (C) 2014 The Android Open Source Project
|
||
*
|
||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
* you may not use this file except in compliance with the License.
|
||
* You may obtain a copy of the License at
|
||
*
|
||
* http://www.apache.org/licenses/LICENSE-2.0
|
||
*
|
||
* Unless required by applicable law or agreed to in writing, software
|
||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
* See the License for the specific language governing permissions and
|
||
* limitations under the License.
|
||
*/
|
||
|
||
package android.hardware.hdmi;
|
||
|
||
import android.annotation.CallbackExecutor;
|
||
import android.annotation.IntDef;
|
||
import android.annotation.NonNull;
|
||
import android.annotation.Nullable;
|
||
import android.annotation.RequiresFeature;
|
||
import android.annotation.RequiresPermission;
|
||
import android.annotation.SdkConstant;
|
||
import android.annotation.SdkConstant.SdkConstantType;
|
||
import android.annotation.StringDef;
|
||
import android.annotation.SuppressLint;
|
||
import android.annotation.SystemApi;
|
||
import android.annotation.SystemService;
|
||
import android.content.Context;
|
||
import android.content.pm.PackageManager;
|
||
import android.os.Binder;
|
||
import android.os.RemoteException;
|
||
import android.sysprop.HdmiProperties;
|
||
import android.util.ArrayMap;
|
||
import android.util.Log;
|
||
|
||
import com.android.internal.annotations.GuardedBy;
|
||
import com.android.internal.util.ConcurrentUtils;
|
||
|
||
import java.lang.annotation.Retention;
|
||
import java.lang.annotation.RetentionPolicy;
|
||
import java.util.ArrayList;
|
||
import java.util.Arrays;
|
||
import java.util.List;
|
||
import java.util.Objects;
|
||
import java.util.concurrent.Executor;
|
||
import java.util.stream.Collectors;
|
||
|
||
/**
|
||
* The {@link HdmiControlManager} class is used to send HDMI control messages
|
||
* to attached CEC devices. It also allows to control the eARC feature.
|
||
*
|
||
* <p>Provides various HDMI client instances that represent HDMI-CEC logical devices
|
||
* hosted in the system. {@link #getTvClient()}, for instance will return an
|
||
* {@link HdmiTvClient} object if the system is configured to host one. Android system
|
||
* can host more than one logical CEC devices. If multiple types are configured they
|
||
* all work as if they were independent logical devices running in the system.
|
||
*
|
||
* @hide
|
||
*/
|
||
@SystemApi
|
||
@SystemService(Context.HDMI_CONTROL_SERVICE)
|
||
@RequiresFeature(PackageManager.FEATURE_HDMI_CEC)
|
||
public final class HdmiControlManager {
|
||
private static final String TAG = "HdmiControlManager";
|
||
|
||
@Nullable private final IHdmiControlService mService;
|
||
|
||
private static final int INVALID_PHYSICAL_ADDRESS = 0xFFFF;
|
||
|
||
/**
|
||
* A cache of the current device's physical address. When device's HDMI out port
|
||
* is not connected to any device, it is set to {@link #INVALID_PHYSICAL_ADDRESS}.
|
||
*
|
||
* <p>Otherwise it is updated by the {@link ClientHotplugEventListener} registered
|
||
* with {@link com.android.server.hdmi.HdmiControlService} by the
|
||
* {@link #addHotplugEventListener(HotplugEventListener)} and the address is from
|
||
* {@link com.android.server.hdmi.HdmiControlService#getPortInfo()}
|
||
*/
|
||
@GuardedBy("mLock")
|
||
private int mLocalPhysicalAddress = INVALID_PHYSICAL_ADDRESS;
|
||
|
||
private void setLocalPhysicalAddress(int physicalAddress) {
|
||
synchronized (mLock) {
|
||
mLocalPhysicalAddress = physicalAddress;
|
||
}
|
||
}
|
||
|
||
private int getLocalPhysicalAddress() {
|
||
synchronized (mLock) {
|
||
return mLocalPhysicalAddress;
|
||
}
|
||
}
|
||
|
||
private final Object mLock = new Object();
|
||
|
||
/**
|
||
* Broadcast Action: Display OSD message.
|
||
* <p>Send when the service has a message to display on screen for events
|
||
* that need user's attention such as ARC status change.
|
||
* <p>Always contains the extra fields {@link #EXTRA_MESSAGE_ID}.
|
||
* <p>Requires {@link android.Manifest.permission#HDMI_CEC} to receive.
|
||
*/
|
||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||
public static final String ACTION_OSD_MESSAGE = "android.hardware.hdmi.action.OSD_MESSAGE";
|
||
|
||
// --- Messages for ACTION_OSD_MESSAGE ---
|
||
/**
|
||
* Message that ARC enabled device is connected to invalid port (non-ARC port).
|
||
*/
|
||
public static final int OSD_MESSAGE_ARC_CONNECTED_INVALID_PORT = 1;
|
||
|
||
/**
|
||
* Message used by TV to receive volume status from Audio Receiver. It should check volume value
|
||
* that is retrieved from extra value with the key {@link #EXTRA_MESSAGE_EXTRA_PARAM1}. If the
|
||
* value is in range of [0,100], it is current volume of Audio Receiver. And there is another
|
||
* value, {@link #AVR_VOLUME_MUTED}, which is used to inform volume mute.
|
||
*/
|
||
public static final int OSD_MESSAGE_AVR_VOLUME_CHANGED = 2;
|
||
|
||
/**
|
||
* Used as an extra field in the intent {@link #ACTION_OSD_MESSAGE}. Contains the ID of
|
||
* the message to display on screen.
|
||
*/
|
||
public static final String EXTRA_MESSAGE_ID = "android.hardware.hdmi.extra.MESSAGE_ID";
|
||
/**
|
||
* Used as an extra field in the intent {@link #ACTION_OSD_MESSAGE}. Contains the extra value
|
||
* of the message.
|
||
*/
|
||
public static final String EXTRA_MESSAGE_EXTRA_PARAM1 =
|
||
"android.hardware.hdmi.extra.MESSAGE_EXTRA_PARAM1";
|
||
|
||
/**
|
||
* Used as an extra field in the Set Menu Language intent. Contains the requested locale.
|
||
* @hide
|
||
*/
|
||
public static final String EXTRA_LOCALE = "android.hardware.hdmi.extra.LOCALE";
|
||
|
||
/**
|
||
* Broadcast Action: Active Source status was recovered by the device.
|
||
* <p>Send when device becomes the current active source such that the activity
|
||
* HdmiCecActiveSourceLostActivity can be finished and cleared from the screen.
|
||
* <p>Requires {@link android.Manifest.permission#HDMI_CEC} to receive.
|
||
* @hide
|
||
*/
|
||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||
public static final String ACTION_ON_ACTIVE_SOURCE_RECOVERED_DISMISS_UI =
|
||
"android.hardware.hdmi.action.ON_ACTIVE_SOURCE_RECOVERED_DISMISS_UI";
|
||
/**
|
||
* Volume value for mute state.
|
||
*/
|
||
public static final int AVR_VOLUME_MUTED = 101;
|
||
|
||
public static final int POWER_STATUS_UNKNOWN = -1;
|
||
public static final int POWER_STATUS_ON = 0;
|
||
public static final int POWER_STATUS_STANDBY = 1;
|
||
public static final int POWER_STATUS_TRANSIENT_TO_ON = 2;
|
||
public static final int POWER_STATUS_TRANSIENT_TO_STANDBY = 3;
|
||
|
||
/** @removed mistakenly exposed previously */
|
||
@IntDef ({
|
||
RESULT_SUCCESS,
|
||
RESULT_TIMEOUT,
|
||
RESULT_SOURCE_NOT_AVAILABLE,
|
||
RESULT_TARGET_NOT_AVAILABLE,
|
||
RESULT_ALREADY_IN_PROGRESS,
|
||
RESULT_EXCEPTION,
|
||
RESULT_INCORRECT_MODE,
|
||
RESULT_COMMUNICATION_FAILED,
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface ControlCallbackResult {}
|
||
|
||
/** Control operation is successfully handled by the framework. */
|
||
public static final int RESULT_SUCCESS = 0;
|
||
public static final int RESULT_TIMEOUT = 1;
|
||
/** Source device that the application is using is not available. */
|
||
public static final int RESULT_SOURCE_NOT_AVAILABLE = 2;
|
||
/** Target device that the application is controlling is not available. */
|
||
public static final int RESULT_TARGET_NOT_AVAILABLE = 3;
|
||
|
||
@Deprecated public static final int RESULT_ALREADY_IN_PROGRESS = 4;
|
||
public static final int RESULT_EXCEPTION = 5;
|
||
public static final int RESULT_INCORRECT_MODE = 6;
|
||
public static final int RESULT_COMMUNICATION_FAILED = 7;
|
||
|
||
public static final int DEVICE_EVENT_ADD_DEVICE = 1;
|
||
public static final int DEVICE_EVENT_REMOVE_DEVICE = 2;
|
||
public static final int DEVICE_EVENT_UPDATE_DEVICE = 3;
|
||
|
||
// --- One Touch Recording success result
|
||
/** Recording currently selected source. Indicates the status of a recording. */
|
||
public static final int ONE_TOUCH_RECORD_RECORDING_CURRENTLY_SELECTED_SOURCE = 0x01;
|
||
/** Recording Digital Service. Indicates the status of a recording. */
|
||
public static final int ONE_TOUCH_RECORD_RECORDING_DIGITAL_SERVICE = 0x02;
|
||
/** Recording Analogue Service. Indicates the status of a recording. */
|
||
public static final int ONE_TOUCH_RECORD_RECORDING_ANALOGUE_SERVICE = 0x03;
|
||
/** Recording External input. Indicates the status of a recording. */
|
||
public static final int ONE_TOUCH_RECORD_RECORDING_EXTERNAL_INPUT = 0x04;
|
||
|
||
// --- One Touch Record failure result
|
||
/** No recording – unable to record Digital Service. No suitable tuner. */
|
||
public static final int ONE_TOUCH_RECORD_UNABLE_DIGITAL_SERVICE = 0x05;
|
||
/** No recording – unable to record Analogue Service. No suitable tuner. */
|
||
public static final int ONE_TOUCH_RECORD_UNABLE_ANALOGUE_SERVICE = 0x06;
|
||
/**
|
||
* No recording – unable to select required service. as suitable tuner, but the requested
|
||
* parameters are invalid or out of range for that tuner.
|
||
*/
|
||
public static final int ONE_TOUCH_RECORD_UNABLE_SELECTED_SERVICE = 0x07;
|
||
/** No recording – invalid External plug number */
|
||
public static final int ONE_TOUCH_RECORD_INVALID_EXTERNAL_PLUG_NUMBER = 0x09;
|
||
/** No recording – invalid External Physical Address */
|
||
public static final int ONE_TOUCH_RECORD_INVALID_EXTERNAL_PHYSICAL_ADDRESS = 0x0A;
|
||
/** No recording – CA system not supported */
|
||
public static final int ONE_TOUCH_RECORD_UNSUPPORTED_CA = 0x0B;
|
||
/** No Recording – No or Insufficient CA Entitlements” */
|
||
public static final int ONE_TOUCH_RECORD_NO_OR_INSUFFICIENT_CA_ENTITLEMENTS = 0x0C;
|
||
/** No recording – Not allowed to copy source. Source is “copy never”. */
|
||
public static final int ONE_TOUCH_RECORD_DISALLOW_TO_COPY = 0x0D;
|
||
/** No recording – No further copies allowed */
|
||
public static final int ONE_TOUCH_RECORD_DISALLOW_TO_FUTHER_COPIES = 0x0E;
|
||
/** No recording – No media */
|
||
public static final int ONE_TOUCH_RECORD_NO_MEDIA = 0x10;
|
||
/** No recording – playing */
|
||
public static final int ONE_TOUCH_RECORD_PLAYING = 0x11;
|
||
/** No recording – already recording */
|
||
public static final int ONE_TOUCH_RECORD_ALREADY_RECORDING = 0x12;
|
||
/** No recording – media protected */
|
||
public static final int ONE_TOUCH_RECORD_MEDIA_PROTECTED = 0x13;
|
||
/** No recording – no source signal */
|
||
public static final int ONE_TOUCH_RECORD_NO_SOURCE_SIGNAL = 0x14;
|
||
/** No recording – media problem */
|
||
public static final int ONE_TOUCH_RECORD_MEDIA_PROBLEM = 0x15;
|
||
/** No recording – not enough space available */
|
||
public static final int ONE_TOUCH_RECORD_NOT_ENOUGH_SPACE = 0x16;
|
||
/** No recording – Parental Lock On */
|
||
public static final int ONE_TOUCH_RECORD_PARENT_LOCK_ON = 0x17;
|
||
/** Recording terminated normally */
|
||
public static final int ONE_TOUCH_RECORD_RECORDING_TERMINATED_NORMALLY = 0x1A;
|
||
/** Recording has already terminated */
|
||
public static final int ONE_TOUCH_RECORD_RECORDING_ALREADY_TERMINATED = 0x1B;
|
||
/** No recording – other reason */
|
||
public static final int ONE_TOUCH_RECORD_OTHER_REASON = 0x1F;
|
||
// From here extra message for recording that is not mentioned in CEC spec
|
||
/** No recording. Previous recording request in progress. */
|
||
public static final int ONE_TOUCH_RECORD_PREVIOUS_RECORDING_IN_PROGRESS = 0x30;
|
||
/** No recording. Please check recorder and connection. */
|
||
public static final int ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION = 0x31;
|
||
/** Cannot record currently displayed source. */
|
||
public static final int ONE_TOUCH_RECORD_FAIL_TO_RECORD_DISPLAYED_SCREEN = 0x32;
|
||
/** CEC is disabled. */
|
||
public static final int ONE_TOUCH_RECORD_CEC_DISABLED = 0x33;
|
||
|
||
// --- Types for timer recording
|
||
/** Timer recording type for digital service source. */
|
||
public static final int TIMER_RECORDING_TYPE_DIGITAL = 1;
|
||
/** Timer recording type for analogue service source. */
|
||
public static final int TIMER_RECORDING_TYPE_ANALOGUE = 2;
|
||
/** Timer recording type for external source. */
|
||
public static final int TIMER_RECORDING_TYPE_EXTERNAL = 3;
|
||
|
||
// --- Timer Status Data
|
||
/** [Timer Status Data/Media Info] - Media present and not protected. */
|
||
public static final int TIMER_STATUS_MEDIA_INFO_PRESENT_NOT_PROTECTED = 0x0;
|
||
/** [Timer Status Data/Media Info] - Media present, but protected. */
|
||
public static final int TIMER_STATUS_MEDIA_INFO_PRESENT_PROTECTED = 0x1;
|
||
/** [Timer Status Data/Media Info] - Media not present. */
|
||
public static final int TIMER_STATUS_MEDIA_INFO_NOT_PRESENT = 0x2;
|
||
|
||
/** [Timer Status Data/Programmed Info] - Enough space available for recording. */
|
||
public static final int TIMER_STATUS_PROGRAMMED_INFO_ENOUGH_SPACE = 0x8;
|
||
/** [Timer Status Data/Programmed Info] - Not enough space available for recording. */
|
||
public static final int TIMER_STATUS_PROGRAMMED_INFO_NOT_ENOUGH_SPACE = 0x9;
|
||
/** [Timer Status Data/Programmed Info] - Might not enough space available for recording. */
|
||
public static final int TIMER_STATUS_PROGRAMMED_INFO_MIGHT_NOT_ENOUGH_SPACE = 0xB;
|
||
/** [Timer Status Data/Programmed Info] - No media info available. */
|
||
public static final int TIMER_STATUS_PROGRAMMED_INFO_NO_MEDIA_INFO = 0xA;
|
||
|
||
/** [Timer Status Data/Not Programmed Error Info] - No free timer available. */
|
||
public static final int TIMER_STATUS_NOT_PROGRAMMED_NO_FREE_TIME = 0x1;
|
||
/** [Timer Status Data/Not Programmed Error Info] - Date out of range. */
|
||
public static final int TIMER_STATUS_NOT_PROGRAMMED_DATE_OUT_OF_RANGE = 0x2;
|
||
/** [Timer Status Data/Not Programmed Error Info] - Recording Sequence error. */
|
||
public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_SEQUENCE = 0x3;
|
||
/** [Timer Status Data/Not Programmed Error Info] - Invalid External Plug Number. */
|
||
public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PLUG_NUMBER = 0x4;
|
||
/** [Timer Status Data/Not Programmed Error Info] - Invalid External Physical Address. */
|
||
public static final int TIMER_STATUS_NOT_PROGRAMMED_INVALID_EXTERNAL_PHYSICAL_NUMBER = 0x5;
|
||
/** [Timer Status Data/Not Programmed Error Info] - CA system not supported. */
|
||
public static final int TIMER_STATUS_NOT_PROGRAMMED_CA_NOT_SUPPORTED = 0x6;
|
||
/** [Timer Status Data/Not Programmed Error Info] - No or insufficient CA Entitlements. */
|
||
public static final int TIMER_STATUS_NOT_PROGRAMMED_NO_CA_ENTITLEMENTS = 0x7;
|
||
/** [Timer Status Data/Not Programmed Error Info] - Does not support resolution. */
|
||
public static final int TIMER_STATUS_NOT_PROGRAMMED_UNSUPPORTED_RESOLUTION = 0x8;
|
||
/** [Timer Status Data/Not Programmed Error Info] - Parental Lock On. */
|
||
public static final int TIMER_STATUS_NOT_PROGRAMMED_PARENTAL_LOCK_ON= 0x9;
|
||
/** [Timer Status Data/Not Programmed Error Info] - Clock Failure. */
|
||
public static final int TIMER_STATUS_NOT_PROGRAMMED_CLOCK_FAILURE = 0xA;
|
||
/** [Timer Status Data/Not Programmed Error Info] - Duplicate: already programmed. */
|
||
public static final int TIMER_STATUS_NOT_PROGRAMMED_DUPLICATED = 0xE;
|
||
|
||
// --- Extra result value for timer recording.
|
||
/** No extra error. */
|
||
public static final int TIMER_RECORDING_RESULT_EXTRA_NO_ERROR = 0x00;
|
||
/** No timer recording - check recorder and connection. */
|
||
public static final int TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION = 0x01;
|
||
/** No timer recording - cannot record selected source. */
|
||
public static final int TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE = 0x02;
|
||
/** CEC is disabled. */
|
||
public static final int TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED = 0x03;
|
||
|
||
// -- Timer cleared status data code used for result of onClearTimerRecordingResult.
|
||
/** Timer not cleared – recording. */
|
||
public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_RECORDING = 0x00;
|
||
/** Timer not cleared – no matching. */
|
||
public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_MATCHING = 0x01;
|
||
/** Timer not cleared – no info available. */
|
||
public static final int CLEAR_TIMER_STATUS_TIMER_NOT_CLEARED_NO_INFO_AVAILABLE = 0x02;
|
||
/** Timer cleared. */
|
||
public static final int CLEAR_TIMER_STATUS_TIMER_CLEARED = 0x80;
|
||
/** Clear timer error - check recorder and connection. */
|
||
public static final int CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION = 0xA0;
|
||
/** Clear timer error - cannot clear timer for selected source. */
|
||
public static final int CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE = 0xA1;
|
||
/** Clear timer error - CEC is disabled. */
|
||
public static final int CLEAR_TIMER_STATUS_CEC_DISABLE = 0xA2;
|
||
|
||
/** The HdmiControlService is started. */
|
||
public static final int CONTROL_STATE_CHANGED_REASON_START = 0;
|
||
/** The state of HdmiControlService is changed by changing of settings. */
|
||
public static final int CONTROL_STATE_CHANGED_REASON_SETTING = 1;
|
||
/** The HdmiControlService is enabled to wake up. */
|
||
public static final int CONTROL_STATE_CHANGED_REASON_WAKEUP = 2;
|
||
/** The HdmiControlService will be disabled to standby. */
|
||
public static final int CONTROL_STATE_CHANGED_REASON_STANDBY = 3;
|
||
|
||
// -- Whether the HDMI CEC is enabled or disabled.
|
||
/**
|
||
* HDMI CEC enabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_ENABLED
|
||
*/
|
||
public static final int HDMI_CEC_CONTROL_ENABLED = 1;
|
||
/**
|
||
* HDMI CEC disabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_ENABLED
|
||
*/
|
||
public static final int HDMI_CEC_CONTROL_DISABLED = 0;
|
||
/**
|
||
* @hide
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_ENABLED
|
||
*/
|
||
@IntDef(prefix = { "HDMI_CEC_CONTROL_" }, value = {
|
||
HDMI_CEC_CONTROL_ENABLED,
|
||
HDMI_CEC_CONTROL_DISABLED
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface HdmiCecControl {}
|
||
|
||
// -- Supported HDMI-CEC versions.
|
||
/**
|
||
* Version constant for HDMI-CEC v1.4b.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_VERSION
|
||
*/
|
||
public static final int HDMI_CEC_VERSION_1_4_B = 0x05;
|
||
/**
|
||
* Version constant for HDMI-CEC v2.0.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_VERSION
|
||
*/
|
||
public static final int HDMI_CEC_VERSION_2_0 = 0x06;
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_VERSION
|
||
* @hide
|
||
*/
|
||
@IntDef(prefix = { "HDMI_CEC_VERSION_" }, value = {
|
||
HDMI_CEC_VERSION_1_4_B,
|
||
HDMI_CEC_VERSION_2_0
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface HdmiCecVersion {}
|
||
|
||
// -- Whether the Routing Control feature is enabled or disabled.
|
||
/**
|
||
* Routing Control feature enabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_ROUTING_CONTROL
|
||
*/
|
||
public static final int ROUTING_CONTROL_ENABLED = 1;
|
||
/**
|
||
* Routing Control feature disabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_ROUTING_CONTROL
|
||
*/
|
||
public static final int ROUTING_CONTROL_DISABLED = 0;
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_ROUTING_CONTROL
|
||
* @hide
|
||
*/
|
||
@IntDef(prefix = { "ROUTING_CONTROL_" }, value = {
|
||
ROUTING_CONTROL_ENABLED,
|
||
ROUTING_CONTROL_DISABLED
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface RoutingControl {}
|
||
|
||
// -- Whether the Soundbar mode feature is enabled or disabled.
|
||
/**
|
||
* Soundbar mode feature enabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SOUNDBAR_MODE
|
||
*/
|
||
public static final int SOUNDBAR_MODE_ENABLED = 1;
|
||
/**
|
||
* Soundbar mode feature disabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SOUNDBAR_MODE
|
||
*/
|
||
public static final int SOUNDBAR_MODE_DISABLED = 0;
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SOUNDBAR_MODE
|
||
* @hide
|
||
*/
|
||
@IntDef(prefix = { "SOUNDBAR_MODE" }, value = {
|
||
SOUNDBAR_MODE_ENABLED,
|
||
SOUNDBAR_MODE_DISABLED
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface SoundbarMode {}
|
||
|
||
// -- Scope of CEC power control messages sent by a playback device.
|
||
/**
|
||
* Send CEC power control messages to TV only:
|
||
* Upon going to sleep, send {@code <Standby>} to TV only.
|
||
* Upon waking up, attempt to turn on the TV via {@code <One Touch Play>} but do not turn on the
|
||
* Audio system via {@code <System Audio Mode Request>}.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE
|
||
*/
|
||
public static final String POWER_CONTROL_MODE_TV = "to_tv";
|
||
/**
|
||
* Send CEC power control messages to TV and Audio System:
|
||
* Upon going to sleep, send {@code <Standby>} to TV and Audio system.
|
||
* Upon waking up, attempt to turn on the TV via {@code <One Touch Play>} and attempt to turn on
|
||
* the Audio system via {@code <System Audio Mode Request>}.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE
|
||
*/
|
||
public static final String POWER_CONTROL_MODE_TV_AND_AUDIO_SYSTEM = "to_tv_and_audio_system";
|
||
/**
|
||
* Broadcast CEC power control messages to all devices in the network:
|
||
* Upon going to sleep, send {@code <Standby>} to all devices in the network.
|
||
* Upon waking up, attempt to turn on the TV via {@code <One Touch Play>} and attempt to turn on
|
||
* the Audio system via {@code <System Audio Mode Request>}.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE
|
||
*/
|
||
public static final String POWER_CONTROL_MODE_BROADCAST = "broadcast";
|
||
/**
|
||
* Don't send any CEC power control messages:
|
||
* Upon going to sleep, do not send any {@code <Standby>} message.
|
||
* Upon waking up, do not turn on the TV via {@code <One Touch Play>} and do not turn on the
|
||
* Audio system via {@code <System Audio Mode Request>}.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE
|
||
*/
|
||
public static final String POWER_CONTROL_MODE_NONE = "none";
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE
|
||
* @hide
|
||
*/
|
||
@StringDef(prefix = { "POWER_CONTROL_MODE_" }, value = {
|
||
POWER_CONTROL_MODE_TV,
|
||
POWER_CONTROL_MODE_TV_AND_AUDIO_SYSTEM,
|
||
POWER_CONTROL_MODE_BROADCAST,
|
||
POWER_CONTROL_MODE_NONE
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface PowerControlMode {}
|
||
|
||
// -- Which power state action should be taken when Active Source is lost.
|
||
/**
|
||
* No action to be taken.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST
|
||
*/
|
||
public static final String POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE = "none";
|
||
/**
|
||
* Go to standby immediately.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST
|
||
*/
|
||
public static final String POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW = "standby_now";
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST
|
||
* @hide
|
||
*/
|
||
@StringDef(prefix = { "POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_" }, value = {
|
||
POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_NONE,
|
||
POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST_STANDBY_NOW
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface ActiveSourceLostBehavior {}
|
||
|
||
// -- Whether System Audio Control is enabled or disabled.
|
||
/**
|
||
* System Audio Control enabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL
|
||
*/
|
||
public static final int SYSTEM_AUDIO_CONTROL_ENABLED = 1;
|
||
/**
|
||
* System Audio Control disabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL
|
||
*/
|
||
public static final int SYSTEM_AUDIO_CONTROL_DISABLED = 0;
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL
|
||
* @hide
|
||
*/
|
||
@IntDef(prefix = { "SYSTEM_AUDIO_CONTROL_" }, value = {
|
||
SYSTEM_AUDIO_CONTROL_ENABLED,
|
||
SYSTEM_AUDIO_CONTROL_DISABLED
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface SystemAudioControl {}
|
||
|
||
// -- Whether System Audio Mode muting is enabled or disabled.
|
||
/**
|
||
* System Audio Mode muting enabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING
|
||
*/
|
||
public static final int SYSTEM_AUDIO_MODE_MUTING_ENABLED = 1;
|
||
/**
|
||
* System Audio Mode muting disabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING
|
||
*/
|
||
public static final int SYSTEM_AUDIO_MODE_MUTING_DISABLED = 0;
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING
|
||
* @hide
|
||
*/
|
||
@IntDef(prefix = { "SYSTEM_AUDIO_MODE_MUTING_" }, value = {
|
||
SYSTEM_AUDIO_MODE_MUTING_ENABLED,
|
||
SYSTEM_AUDIO_MODE_MUTING_DISABLED
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface SystemAudioModeMuting {}
|
||
|
||
// -- Whether the HDMI CEC volume control is enabled or disabled.
|
||
/**
|
||
* HDMI CEC enabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE
|
||
*/
|
||
public static final int VOLUME_CONTROL_ENABLED = 1;
|
||
/**
|
||
* HDMI CEC disabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE
|
||
*/
|
||
public static final int VOLUME_CONTROL_DISABLED = 0;
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE
|
||
* @hide
|
||
*/
|
||
@IntDef(prefix = { "VOLUME_CONTROL_" }, value = {
|
||
VOLUME_CONTROL_ENABLED,
|
||
VOLUME_CONTROL_DISABLED
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface VolumeControl {}
|
||
|
||
// -- Whether TV Wake on One Touch Play is enabled or disabled.
|
||
/**
|
||
* TV Wake on One Touch Play enabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY
|
||
*/
|
||
public static final int TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED = 1;
|
||
/**
|
||
* TV Wake on One Touch Play disabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY
|
||
*/
|
||
public static final int TV_WAKE_ON_ONE_TOUCH_PLAY_DISABLED = 0;
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY
|
||
* @hide
|
||
*/
|
||
@IntDef(prefix = { "TV_WAKE_ON_ONE_TOUCH_PLAY_" }, value = {
|
||
TV_WAKE_ON_ONE_TOUCH_PLAY_ENABLED,
|
||
TV_WAKE_ON_ONE_TOUCH_PLAY_DISABLED
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface TvWakeOnOneTouchPlay {}
|
||
|
||
// -- Whether TV should send <Standby> on sleep.
|
||
/**
|
||
* Sending <Standby> on sleep.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP
|
||
*/
|
||
public static final int TV_SEND_STANDBY_ON_SLEEP_ENABLED = 1;
|
||
/**
|
||
* Not sending <Standby> on sleep.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP
|
||
*/
|
||
public static final int TV_SEND_STANDBY_ON_SLEEP_DISABLED = 0;
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP
|
||
* @hide
|
||
*/
|
||
@IntDef(prefix = { "TV_SEND_STANDBY_ON_SLEEP_" }, value = {
|
||
TV_SEND_STANDBY_ON_SLEEP_ENABLED,
|
||
TV_SEND_STANDBY_ON_SLEEP_DISABLED
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface TvSendStandbyOnSleep {}
|
||
|
||
// -- Whether a playback device should act on an incoming {@code <Set Menu Language>} message.
|
||
/**
|
||
* Confirmation dialog should be shown upon receiving the CEC message.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SET_MENU_LANGUAGE
|
||
* @hide
|
||
*/
|
||
public static final int SET_MENU_LANGUAGE_ENABLED = 1;
|
||
/**
|
||
* The message should be ignored.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SET_MENU_LANGUAGE
|
||
* @hide
|
||
*/
|
||
public static final int SET_MENU_LANGUAGE_DISABLED = 0;
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SET_MENU_LANGUAGE
|
||
* @hide
|
||
*/
|
||
@IntDef(prefix = { "SET_MENU_LANGUAGE_" }, value = {
|
||
SET_MENU_LANGUAGE_ENABLED,
|
||
SET_MENU_LANGUAGE_DISABLED
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface SetMenuLanguage {}
|
||
|
||
// -- The RC profile of a TV panel.
|
||
/**
|
||
* RC profile none.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_TV
|
||
* @hide
|
||
*/
|
||
public static final int RC_PROFILE_TV_NONE = 0x0;
|
||
/**
|
||
* RC profile 1.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_TV
|
||
* @hide
|
||
*/
|
||
public static final int RC_PROFILE_TV_ONE = 0x2;
|
||
/**
|
||
* RC profile 2.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_TV
|
||
* @hide
|
||
*/
|
||
public static final int RC_PROFILE_TV_TWO = 0x6;
|
||
/**
|
||
* RC profile 3.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_TV
|
||
* @hide
|
||
*/
|
||
public static final int RC_PROFILE_TV_THREE = 0xA;
|
||
/**
|
||
* RC profile 4.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_TV
|
||
* @hide
|
||
*/
|
||
public static final int RC_PROFILE_TV_FOUR = 0xE;
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_TV
|
||
* @hide
|
||
*/
|
||
@IntDef(prefix = { "RC_PROFILE_TV_" }, value = {
|
||
RC_PROFILE_TV_NONE,
|
||
RC_PROFILE_TV_ONE,
|
||
RC_PROFILE_TV_TWO,
|
||
RC_PROFILE_TV_THREE,
|
||
RC_PROFILE_TV_FOUR
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface RcProfileTv {}
|
||
|
||
// -- RC profile parameter defining if a source handles a specific menu.
|
||
/**
|
||
* Handles the menu.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_ROOT_MENU
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_SETUP_MENU
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_TOP_MENU
|
||
* @see HdmiControlManager#
|
||
* CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU
|
||
* @hide
|
||
*/
|
||
public static final int RC_PROFILE_SOURCE_MENU_HANDLED = 1;
|
||
/**
|
||
* Doesn't handle the menu.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_ROOT_MENU
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_SETUP_MENU
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_TOP_MENU
|
||
* @see HdmiControlManager#
|
||
* CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU
|
||
* @hide
|
||
*/
|
||
public static final int RC_PROFILE_SOURCE_MENU_NOT_HANDLED = 0;
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_ROOT_MENU
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_SETUP_MENU
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_TOP_MENU
|
||
* @see HdmiControlManager#
|
||
* CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU
|
||
* @hide
|
||
*/
|
||
@IntDef(prefix = { "RC_PROFILE_SOURCE_MENU_" }, value = {
|
||
RC_PROFILE_SOURCE_MENU_HANDLED,
|
||
RC_PROFILE_SOURCE_MENU_NOT_HANDLED
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface RcProfileSourceHandlesMenu {}
|
||
|
||
// -- Whether the Short Audio Descriptor (SAD) for a specific codec should be queried or not.
|
||
/**
|
||
* Query the SAD.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_LPCM
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DD
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MPEG1
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MP3
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MPEG2
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_AAC
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DTS
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_ATRAC
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DDP
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DTSHD
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_TRUEHD
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DST
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_WMAPRO
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MAX
|
||
*/
|
||
public static final int QUERY_SAD_ENABLED = 1;
|
||
/**
|
||
* Don't query the SAD.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_LPCM
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DD
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MPEG1
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MP3
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MPEG2
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_AAC
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DTS
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_ATRAC
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DDP
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DTSHD
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_TRUEHD
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DST
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_WMAPRO
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MAX
|
||
*/
|
||
public static final int QUERY_SAD_DISABLED = 0;
|
||
/**
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_LPCM
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DD
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MPEG1
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MP3
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MPEG2
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_AAC
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DTS
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_ATRAC
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DDP
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DTSHD
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_TRUEHD
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_DST
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_WMAPRO
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_QUERY_SAD_MAX
|
||
* @hide
|
||
*/
|
||
@IntDef(prefix = { "QUERY_SAD_" }, value = {
|
||
QUERY_SAD_ENABLED,
|
||
QUERY_SAD_DISABLED
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface SadPresenceInQuery {}
|
||
|
||
// -- Whether eARC is enabled or disabled.
|
||
/**
|
||
* eARC enabled.
|
||
*
|
||
* @see HdmiControlManager#SETTING_NAME_EARC_ENABLED
|
||
*/
|
||
public static final int EARC_FEATURE_ENABLED = 1;
|
||
/**
|
||
* eARC disabled.
|
||
*
|
||
* @see HdmiControlManager#SETTING_NAME_EARC_ENABLED
|
||
*/
|
||
public static final int EARC_FEATURE_DISABLED = 0;
|
||
/**
|
||
* @hide
|
||
*
|
||
* @see HdmiControlManager#SETTING_NAME_EARC_ENABLED
|
||
*/
|
||
@IntDef(prefix = { "EARC_FEATURE" }, value = {
|
||
EARC_FEATURE_ENABLED,
|
||
EARC_FEATURE_DISABLED
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface EarcFeature {}
|
||
|
||
// -- Settings available in the CEC Configuration.
|
||
/**
|
||
* Name of a setting deciding whether the CEC is enabled.
|
||
*
|
||
* @see HdmiControlManager#setHdmiCecEnabled(int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_HDMI_CEC_ENABLED = "hdmi_cec_enabled";
|
||
/**
|
||
* Name of a setting controlling the version of HDMI-CEC used.
|
||
*
|
||
* @see HdmiControlManager#setHdmiCecVersion(int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_HDMI_CEC_VERSION = "hdmi_cec_version";
|
||
/**
|
||
* Name of a setting deciding whether the Routing Control feature is enabled.
|
||
*
|
||
* @see HdmiControlManager#setRoutingControl(int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_ROUTING_CONTROL = "routing_control";
|
||
/**
|
||
* Name of a setting deciding whether the Soundbar mode feature is enabled.
|
||
* Before exposing this setting make sure the hardware supports it, otherwise, you may
|
||
* experience multiple issues.
|
||
*
|
||
* @see HdmiControlManager#setSoundbarMode(int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_SOUNDBAR_MODE = "soundbar_mode";
|
||
/**
|
||
* Name of a setting deciding on the power control mode.
|
||
*
|
||
* @see HdmiControlManager#setPowerControlMode(String)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_POWER_CONTROL_MODE = "power_control_mode";
|
||
/**
|
||
* Name of a setting deciding on power state action when losing Active Source.
|
||
*
|
||
* @see HdmiControlManager#setPowerStateChangeOnActiveSourceLost(String)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST =
|
||
"power_state_change_on_active_source_lost";
|
||
/**
|
||
* Name of a setting deciding whether System Audio Control is enabled.
|
||
*
|
||
* @see HdmiControlManager#setSystemAudioControl(int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL =
|
||
"system_audio_control";
|
||
/**
|
||
* Name of a setting deciding whether System Audio Muting is allowed.
|
||
*
|
||
* @see HdmiControlManager#setSystemAudioModeMuting(int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING =
|
||
"system_audio_mode_muting";
|
||
/**
|
||
* Controls whether volume control commands via HDMI CEC are enabled.
|
||
*
|
||
* <p>Effects on different device types:
|
||
* <table>
|
||
* <tr><th>HDMI CEC device type</th><th>0: disabled</th><th>1: enabled</th></tr>
|
||
* <tr>
|
||
* <td>TV (type: 0)</td>
|
||
* <td>Per CEC specification.</td>
|
||
* <td>TV changes system volume. TV no longer reacts to incoming volume changes
|
||
* via {@code <User Control Pressed>}. TV no longer handles {@code <Report Audio
|
||
* Status>}.</td>
|
||
* </tr>
|
||
* <tr>
|
||
* <td>Playback device (type: 4)</td>
|
||
* <td>Device sends volume commands to TV/Audio system via {@code <User Control
|
||
* Pressed>}</td>
|
||
* <td>Device does not send volume commands via {@code <User Control Pressed>}.</td>
|
||
* </tr>
|
||
* <tr>
|
||
* <td>Audio device (type: 5)</td>
|
||
* <td>Full "System Audio Control" capabilities.</td>
|
||
* <td>Audio device no longer reacts to incoming {@code <User Control Pressed>}
|
||
* volume commands. Audio device no longer reports volume changes via {@code
|
||
* <Report Audio Status>}.</td>
|
||
* </tr>
|
||
* </table>
|
||
*
|
||
* <p> Due to the resulting behavior, usage on TV and Audio devices is discouraged.
|
||
*
|
||
* @see HdmiControlManager#setHdmiCecVolumeControlEnabled(int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_VOLUME_CONTROL_MODE =
|
||
"volume_control_enabled";
|
||
/**
|
||
* Name of a setting deciding whether the TV will automatically turn on upon reception
|
||
* of the CEC command <Text View On> or <Image View On>.
|
||
*
|
||
* @see HdmiControlManager#setTvWakeOnOneTouchPlay(int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY =
|
||
"tv_wake_on_one_touch_play";
|
||
/**
|
||
* Name of a setting deciding whether the TV will also turn off other CEC devices
|
||
* when it goes to standby mode.
|
||
*
|
||
* @see HdmiControlManager#setTvSendStandbyOnSleep(int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP =
|
||
"tv_send_standby_on_sleep";
|
||
/**
|
||
* Name of a setting deciding whether {@code <Set Menu Language>} message should be
|
||
* handled by the framework or ignored.
|
||
*
|
||
* @hide
|
||
*/
|
||
public static final String CEC_SETTING_NAME_SET_MENU_LANGUAGE = "set_menu_language";
|
||
/**
|
||
* Name of a setting representing the RC profile of a TV panel.
|
||
*
|
||
* @hide
|
||
*/
|
||
public static final String CEC_SETTING_NAME_RC_PROFILE_TV =
|
||
"rc_profile_tv";
|
||
/**
|
||
* Name of a setting representing the RC profile parameter defining if a source handles the root
|
||
* menu.
|
||
*
|
||
* @hide
|
||
*/
|
||
public static final String CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_ROOT_MENU =
|
||
"rc_profile_source_handles_root_menu";
|
||
/**
|
||
* Name of a setting representing the RC profile parameter defining if a source handles the
|
||
* setup menu.
|
||
*
|
||
* @hide
|
||
*/
|
||
public static final String CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_SETUP_MENU =
|
||
"rc_profile_source_handles_setup_menu";
|
||
/**
|
||
* Name of a setting representing the RC profile parameter defining if a source handles the
|
||
* contents menu.
|
||
*
|
||
* @hide
|
||
*/
|
||
public static final String CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU =
|
||
"rc_profile_source_handles_contents_menu";
|
||
/**
|
||
* Name of a setting representing the RC profile parameter defining if a source handles the top
|
||
* menu.
|
||
*
|
||
* @hide
|
||
*/
|
||
public static final String CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_TOP_MENU =
|
||
"rc_profile_source_handles_top_menu";
|
||
/**
|
||
* Name of a setting representing the RC profile parameter defining if a source handles the
|
||
* media context sensitive menu.
|
||
*
|
||
* @hide
|
||
*/
|
||
public static final String
|
||
CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU =
|
||
"rc_profile_source_handles_media_context_sensitive_menu";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the LPCM codec
|
||
* (0x1) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_LPCM = "query_sad_lpcm";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the DD codec
|
||
* (0x2) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_DD = "query_sad_dd";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the MPEG1 codec
|
||
* (0x3) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_MPEG1 = "query_sad_mpeg1";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the MP3 codec
|
||
* (0x4) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_MP3 = "query_sad_mp3";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the MPEG2 codec
|
||
* (0x5) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_MPEG2 = "query_sad_mpeg2";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the AAC codec
|
||
* (0x6) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_AAC = "query_sad_aac";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the DTS codec
|
||
* (0x7) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_DTS = "query_sad_dts";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the ATRAC codec
|
||
* (0x8) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_ATRAC = "query_sad_atrac";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the ONEBITAUDIO
|
||
* codec (0x9) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO = "query_sad_onebitaudio";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the DDP codec
|
||
* (0xA) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_DDP = "query_sad_ddp";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the DTSHD codec
|
||
* (0xB) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_DTSHD = "query_sad_dtshd";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the TRUEHD codec
|
||
* (0xC) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_TRUEHD = "query_sad_truehd";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the DST codec
|
||
* (0xD) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_DST = "query_sad_dst";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the WMAPRO codec
|
||
* (0xE) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_WMAPRO = "query_sad_wmapro";
|
||
/**
|
||
* Name of a setting representing whether the Short Audio Descriptor (SAD) for the MAX codec
|
||
* (0xF) should be queried or not.
|
||
*
|
||
* @see HdmiControlManager#setSadPresenceInQuery(String, int)
|
||
*/
|
||
public static final String CEC_SETTING_NAME_QUERY_SAD_MAX = "query_sad_max";
|
||
/**
|
||
* Name of a setting representing whether eARC is enabled or not.
|
||
*
|
||
* @see HdmiControlManager#setEarcEnabled(int)
|
||
*/
|
||
public static final String SETTING_NAME_EARC_ENABLED = "earc_enabled";
|
||
/**
|
||
* @hide
|
||
*/
|
||
// TODO(b/240379115): change names of CEC settings so that their prefix matches with the other
|
||
// HDMI control settings.
|
||
@StringDef(value = {
|
||
CEC_SETTING_NAME_HDMI_CEC_ENABLED,
|
||
CEC_SETTING_NAME_HDMI_CEC_VERSION,
|
||
CEC_SETTING_NAME_ROUTING_CONTROL,
|
||
CEC_SETTING_NAME_SOUNDBAR_MODE,
|
||
CEC_SETTING_NAME_POWER_CONTROL_MODE,
|
||
CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST,
|
||
CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL,
|
||
CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING,
|
||
CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
|
||
CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY,
|
||
CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP,
|
||
CEC_SETTING_NAME_SET_MENU_LANGUAGE,
|
||
CEC_SETTING_NAME_RC_PROFILE_TV,
|
||
CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_ROOT_MENU,
|
||
CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_SETUP_MENU,
|
||
CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_CONTENTS_MENU,
|
||
CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_TOP_MENU,
|
||
CEC_SETTING_NAME_RC_PROFILE_SOURCE_HANDLES_MEDIA_CONTEXT_SENSITIVE_MENU,
|
||
CEC_SETTING_NAME_QUERY_SAD_LPCM,
|
||
CEC_SETTING_NAME_QUERY_SAD_DD,
|
||
CEC_SETTING_NAME_QUERY_SAD_MPEG1,
|
||
CEC_SETTING_NAME_QUERY_SAD_MP3,
|
||
CEC_SETTING_NAME_QUERY_SAD_MPEG2,
|
||
CEC_SETTING_NAME_QUERY_SAD_AAC,
|
||
CEC_SETTING_NAME_QUERY_SAD_DTS,
|
||
CEC_SETTING_NAME_QUERY_SAD_ATRAC,
|
||
CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO,
|
||
CEC_SETTING_NAME_QUERY_SAD_DDP,
|
||
CEC_SETTING_NAME_QUERY_SAD_DTSHD,
|
||
CEC_SETTING_NAME_QUERY_SAD_TRUEHD,
|
||
CEC_SETTING_NAME_QUERY_SAD_DST,
|
||
CEC_SETTING_NAME_QUERY_SAD_WMAPRO,
|
||
CEC_SETTING_NAME_QUERY_SAD_MAX,
|
||
SETTING_NAME_EARC_ENABLED,
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface SettingName {}
|
||
|
||
/**
|
||
* @hide
|
||
*/
|
||
@StringDef(prefix = { "CEC_SETTING_NAME_QUERY_SAD_" }, value = {
|
||
CEC_SETTING_NAME_QUERY_SAD_LPCM,
|
||
CEC_SETTING_NAME_QUERY_SAD_DD,
|
||
CEC_SETTING_NAME_QUERY_SAD_MPEG1,
|
||
CEC_SETTING_NAME_QUERY_SAD_MP3,
|
||
CEC_SETTING_NAME_QUERY_SAD_MPEG2,
|
||
CEC_SETTING_NAME_QUERY_SAD_AAC,
|
||
CEC_SETTING_NAME_QUERY_SAD_DTS,
|
||
CEC_SETTING_NAME_QUERY_SAD_ATRAC,
|
||
CEC_SETTING_NAME_QUERY_SAD_ONEBITAUDIO,
|
||
CEC_SETTING_NAME_QUERY_SAD_DDP,
|
||
CEC_SETTING_NAME_QUERY_SAD_DTSHD,
|
||
CEC_SETTING_NAME_QUERY_SAD_TRUEHD,
|
||
CEC_SETTING_NAME_QUERY_SAD_DST,
|
||
CEC_SETTING_NAME_QUERY_SAD_WMAPRO,
|
||
CEC_SETTING_NAME_QUERY_SAD_MAX,
|
||
})
|
||
@Retention(RetentionPolicy.SOURCE)
|
||
public @interface CecSettingSad {}
|
||
|
||
// True if we have a logical device of type playback hosted in the system.
|
||
private final boolean mHasPlaybackDevice;
|
||
// True if we have a logical device of type TV hosted in the system.
|
||
private final boolean mHasTvDevice;
|
||
// True if we have a logical device of type audio system hosted in the system.
|
||
private final boolean mHasAudioSystemDevice;
|
||
// True if we have a logical device of type audio system hosted in the system.
|
||
private final boolean mHasSwitchDevice;
|
||
// True if it's a switch device.
|
||
private final boolean mIsSwitchDevice;
|
||
|
||
/**
|
||
* {@hide} - hide this constructor because it has a parameter of type IHdmiControlService,
|
||
* which is a system private class. The right way to create an instance of this class is
|
||
* using the factory Context.getSystemService.
|
||
*/
|
||
public HdmiControlManager(IHdmiControlService service) {
|
||
mService = service;
|
||
int[] types = null;
|
||
if (mService != null) {
|
||
try {
|
||
types = mService.getSupportedTypes();
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
mHasTvDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_TV);
|
||
mHasPlaybackDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_PLAYBACK);
|
||
mHasAudioSystemDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||
mHasSwitchDevice = hasDeviceType(types, HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH);
|
||
mIsSwitchDevice = HdmiProperties.is_switch().orElse(false);
|
||
addHotplugEventListener(new ClientHotplugEventListener());
|
||
}
|
||
|
||
private final class ClientHotplugEventListener implements HotplugEventListener {
|
||
|
||
@Override
|
||
public void onReceived(HdmiHotplugEvent event) {
|
||
List<HdmiPortInfo> ports = new ArrayList<>();
|
||
try {
|
||
ports = mService.getPortInfo();
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
if (ports.isEmpty()) {
|
||
Log.e(TAG, "Can't find port info, not updating connected status. "
|
||
+ "Hotplug event:" + event);
|
||
return;
|
||
}
|
||
// If the HDMI OUT port is plugged or unplugged, update the mLocalPhysicalAddress
|
||
for (HdmiPortInfo port : ports) {
|
||
if (port.getId() == event.getPort()) {
|
||
if (port.getType() == HdmiPortInfo.PORT_OUTPUT) {
|
||
setLocalPhysicalAddress(
|
||
event.isConnected()
|
||
? port.getAddress()
|
||
: INVALID_PHYSICAL_ADDRESS);
|
||
}
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
private static boolean hasDeviceType(int[] types, int type) {
|
||
if (types == null) {
|
||
return false;
|
||
}
|
||
for (int t : types) {
|
||
if (t == type) {
|
||
return true;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* Gets an object that represents an HDMI-CEC logical device of a specified type.
|
||
*
|
||
* @param type CEC device type
|
||
* @return {@link HdmiClient} instance. {@code null} on failure.
|
||
* See {@link HdmiDeviceInfo#DEVICE_PLAYBACK}
|
||
* See {@link HdmiDeviceInfo#DEVICE_TV}
|
||
* See {@link HdmiDeviceInfo#DEVICE_AUDIO_SYSTEM}
|
||
*/
|
||
@Nullable
|
||
@SuppressLint("RequiresPermission")
|
||
public HdmiClient getClient(int type) {
|
||
if (mService == null) {
|
||
return null;
|
||
}
|
||
switch (type) {
|
||
case HdmiDeviceInfo.DEVICE_TV:
|
||
return mHasTvDevice ? new HdmiTvClient(mService) : null;
|
||
case HdmiDeviceInfo.DEVICE_PLAYBACK:
|
||
return mHasPlaybackDevice ? new HdmiPlaybackClient(mService) : null;
|
||
case HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM:
|
||
try {
|
||
if ((mService.getCecSettingIntValue(CEC_SETTING_NAME_SOUNDBAR_MODE)
|
||
== SOUNDBAR_MODE_ENABLED && mHasPlaybackDevice)
|
||
|| mHasAudioSystemDevice) {
|
||
return new HdmiAudioSystemClient(mService);
|
||
}
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
return null;
|
||
case HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH:
|
||
return (mHasSwitchDevice || mIsSwitchDevice)
|
||
? new HdmiSwitchClient(mService) : null;
|
||
default:
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Gets an object that represents an HDMI-CEC logical device of type playback on the system.
|
||
*
|
||
* <p>Used to send HDMI control messages to other devices like TV or audio amplifier through
|
||
* HDMI bus. It is also possible to communicate with other logical devices hosted in the same
|
||
* system if the system is configured to host more than one type of HDMI-CEC logical devices.
|
||
*
|
||
* @return {@link HdmiPlaybackClient} instance. {@code null} on failure.
|
||
*/
|
||
@Nullable
|
||
@SuppressLint("RequiresPermission")
|
||
public HdmiPlaybackClient getPlaybackClient() {
|
||
return (HdmiPlaybackClient) getClient(HdmiDeviceInfo.DEVICE_PLAYBACK);
|
||
}
|
||
|
||
/**
|
||
* Gets an object that represents an HDMI-CEC logical device of type TV on the system.
|
||
*
|
||
* <p>Used to send HDMI control messages to other devices and manage them through
|
||
* HDMI bus. It is also possible to communicate with other logical devices hosted in the same
|
||
* system if the system is configured to host more than one type of HDMI-CEC logical devices.
|
||
*
|
||
* @return {@link HdmiTvClient} instance. {@code null} on failure.
|
||
*/
|
||
@Nullable
|
||
@SuppressLint("RequiresPermission")
|
||
public HdmiTvClient getTvClient() {
|
||
return (HdmiTvClient) getClient(HdmiDeviceInfo.DEVICE_TV);
|
||
}
|
||
|
||
/**
|
||
* Gets an object that represents an HDMI-CEC logical device of type audio system on the system.
|
||
*
|
||
* <p>Used to send HDMI control messages to other devices like TV through HDMI bus. It is also
|
||
* possible to communicate with other logical devices hosted in the same system if the system is
|
||
* configured to host more than one type of HDMI-CEC logical devices.
|
||
*
|
||
* @return {@link HdmiAudioSystemClient} instance. {@code null} on failure.
|
||
*
|
||
* @hide
|
||
*/
|
||
@Nullable
|
||
@SuppressLint("RequiresPermission")
|
||
public HdmiAudioSystemClient getAudioSystemClient() {
|
||
return (HdmiAudioSystemClient) getClient(HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||
}
|
||
|
||
/**
|
||
* Gets an object that represents an HDMI-CEC logical device of type switch on the system.
|
||
*
|
||
* <p>Used to send HDMI control messages to other devices (e.g. TVs) through HDMI bus.
|
||
* It is also possible to communicate with other logical devices hosted in the same
|
||
* system if the system is configured to host more than one type of HDMI-CEC logical device.
|
||
*
|
||
* @return {@link HdmiSwitchClient} instance. {@code null} on failure.
|
||
*/
|
||
@Nullable
|
||
@SuppressLint("RequiresPermission")
|
||
public HdmiSwitchClient getSwitchClient() {
|
||
return (HdmiSwitchClient) getClient(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH);
|
||
}
|
||
|
||
/**
|
||
* Get a snapshot of the real-time status of the devices on the CEC bus.
|
||
*
|
||
* @return a list of {@link HdmiDeviceInfo} of the connected CEC devices on the CEC bus. An
|
||
* empty list will be returned if there is none.
|
||
*/
|
||
@NonNull
|
||
public List<HdmiDeviceInfo> getConnectedDevices() {
|
||
try {
|
||
return mService.getDeviceList();
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @removed
|
||
* @deprecated Please use {@link #getConnectedDevices()} instead.
|
||
*/
|
||
@Deprecated
|
||
public List<HdmiDeviceInfo> getConnectedDevicesList() {
|
||
try {
|
||
return mService.getDeviceList();
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get the list of the HDMI ports configuration.
|
||
*
|
||
* <p>This returns an empty list when the current device does not have HDMI ports.
|
||
*
|
||
* @return a list of {@link HdmiPortInfo}
|
||
*/
|
||
@NonNull
|
||
public List<HdmiPortInfo> getPortInfo() {
|
||
try {
|
||
return mService.getPortInfo();
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Power off the target device by sending CEC commands. Note that this device can't be the
|
||
* current device itself.
|
||
*
|
||
* <p>The target device info can be obtained by calling {@link #getConnectedDevicesList()}.
|
||
*
|
||
* @param deviceInfo {@link HdmiDeviceInfo} of the device to be powered off.
|
||
*/
|
||
public void powerOffDevice(@NonNull HdmiDeviceInfo deviceInfo) {
|
||
Objects.requireNonNull(deviceInfo);
|
||
try {
|
||
mService.powerOffRemoteDevice(
|
||
deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus());
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @removed
|
||
* @deprecated Please use {@link #powerOffDevice(deviceInfo)} instead.
|
||
*/
|
||
@Deprecated
|
||
public void powerOffRemoteDevice(@NonNull HdmiDeviceInfo deviceInfo) {
|
||
Objects.requireNonNull(deviceInfo);
|
||
try {
|
||
mService.powerOffRemoteDevice(
|
||
deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus());
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Power on the target device by sending CEC commands. Note that this device can't be the
|
||
* current device itself.
|
||
*
|
||
* <p>The target device info can be obtained by calling {@link #getConnectedDevicesList()}.
|
||
*
|
||
* @param deviceInfo {@link HdmiDeviceInfo} of the device to be powered on.
|
||
*
|
||
* @hide
|
||
*/
|
||
public void powerOnDevice(HdmiDeviceInfo deviceInfo) {
|
||
Objects.requireNonNull(deviceInfo);
|
||
try {
|
||
mService.powerOnRemoteDevice(
|
||
deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus());
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @removed
|
||
* @deprecated Please use {@link #powerOnDevice(deviceInfo)} instead.
|
||
*/
|
||
@Deprecated
|
||
public void powerOnRemoteDevice(HdmiDeviceInfo deviceInfo) {
|
||
Objects.requireNonNull(deviceInfo);
|
||
try {
|
||
mService.powerOnRemoteDevice(
|
||
deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus());
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Request the target device to be the new Active Source by sending CEC commands. Note that
|
||
* this device can't be the current device itself.
|
||
*
|
||
* <p>The target device info can be obtained by calling {@link #getConnectedDevicesList()}.
|
||
*
|
||
* <p>If the target device responds to the command, the users should see the target device
|
||
* streaming on their TVs.
|
||
*
|
||
* @param deviceInfo HdmiDeviceInfo of the target device
|
||
*/
|
||
public void setActiveSource(@NonNull HdmiDeviceInfo deviceInfo) {
|
||
Objects.requireNonNull(deviceInfo);
|
||
try {
|
||
mService.askRemoteDeviceToBecomeActiveSource(deviceInfo.getPhysicalAddress());
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @removed
|
||
* @deprecated Please use {@link #setActiveSource(deviceInfo)} instead.
|
||
*/
|
||
@Deprecated
|
||
public void requestRemoteDeviceToBecomeActiveSource(@NonNull HdmiDeviceInfo deviceInfo) {
|
||
Objects.requireNonNull(deviceInfo);
|
||
try {
|
||
mService.askRemoteDeviceToBecomeActiveSource(deviceInfo.getPhysicalAddress());
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Controls standby mode of the system. It will also try to turn on/off the connected devices if
|
||
* necessary.
|
||
*
|
||
* @param isStandbyModeOn target status of the system's standby mode
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setStandbyMode(boolean isStandbyModeOn) {
|
||
try {
|
||
mService.setStandbyMode(isStandbyModeOn);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* For CEC source devices (OTT/STB/Audio system): toggle the power status of the HDMI-connected
|
||
* display and follow the display's new power status.
|
||
* For all other devices: no functionality.
|
||
*
|
||
* @hide
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void toggleAndFollowTvPower() {
|
||
try {
|
||
mService.toggleAndFollowTvPower();
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Determines whether the HDMI CEC stack should handle KEYCODE_TV_POWER.
|
||
*
|
||
* @hide
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public boolean shouldHandleTvPowerKey() {
|
||
try {
|
||
return mService.shouldHandleTvPowerKey();
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Controls whether volume control commands via HDMI CEC are enabled.
|
||
*
|
||
* <p>When disabled:
|
||
* <ul>
|
||
* <li>the device will not send any HDMI CEC audio messages
|
||
* <li>received HDMI CEC audio messages are responded to with {@code <Feature Abort>}
|
||
* </ul>
|
||
*
|
||
* <p>Effects on different device types:
|
||
* <table>
|
||
* <tr><th>HDMI CEC device type</th><th>enabled</th><th>disabled</th></tr>
|
||
* <tr>
|
||
* <td>TV (type: 0)</td>
|
||
* <td>Per CEC specification.</td>
|
||
* <td>TV changes system volume. TV no longer reacts to incoming volume changes via
|
||
* {@code <User Control Pressed>}. TV no longer handles {@code <Report Audio Status>}
|
||
* .</td>
|
||
* </tr>
|
||
* <tr>
|
||
* <td>Playback device (type: 4)</td>
|
||
* <td>Device sends volume commands to TV/Audio system via {@code <User Control
|
||
* Pressed>}</td><td>Device does not send volume commands via {@code <User Control
|
||
* Pressed>}.</td>
|
||
* </tr>
|
||
* <tr>
|
||
* <td>Audio device (type: 5)</td>
|
||
* <td>Full "System Audio Control" capabilities.</td>
|
||
* <td>Audio device no longer reacts to incoming {@code <User Control Pressed>}
|
||
* volume commands. Audio device no longer reports volume changes via {@code <Report
|
||
* Audio Status>}.</td>
|
||
* </tr>
|
||
* </table>
|
||
*
|
||
* <p> Due to the resulting behavior, usage on TV and Audio devices is discouraged.
|
||
*
|
||
* @param hdmiCecVolumeControlEnabled target state of HDMI CEC volume control.
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setHdmiCecVolumeControlEnabled(
|
||
@VolumeControl int hdmiCecVolumeControlEnabled) {
|
||
try {
|
||
mService.setCecSettingIntValue(CEC_SETTING_NAME_VOLUME_CONTROL_MODE,
|
||
hdmiCecVolumeControlEnabled);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Returns whether volume changes via HDMI CEC are enabled.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_VOLUME_CONTROL_MODE
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
@VolumeControl
|
||
public int getHdmiCecVolumeControlEnabled() {
|
||
try {
|
||
return mService.getCecSettingIntValue(CEC_SETTING_NAME_VOLUME_CONTROL_MODE);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Gets whether the system is in system audio mode.
|
||
*
|
||
* @hide
|
||
*/
|
||
public boolean getSystemAudioMode() {
|
||
try {
|
||
return mService.getSystemAudioMode();
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get the physical address of the device.
|
||
*
|
||
* <p>Physical address needs to be automatically adjusted when devices are phyiscally or
|
||
* electrically added or removed from the device tree. Please see HDMI Specification Version
|
||
* 1.4b 8.7 Physical Address for more details on the address discovery proccess.
|
||
*/
|
||
public int getPhysicalAddress() {
|
||
return getLocalPhysicalAddress();
|
||
}
|
||
|
||
/**
|
||
* Check if the target device is connected to the current device.
|
||
*
|
||
* <p>The API also returns true if the current device is the target.
|
||
*
|
||
* @param targetDevice {@link HdmiDeviceInfo} of the target device.
|
||
* @return true if {@code targetDevice} is directly or indirectly
|
||
* connected to the current device.
|
||
*/
|
||
public boolean isDeviceConnected(@NonNull HdmiDeviceInfo targetDevice) {
|
||
Objects.requireNonNull(targetDevice);
|
||
int physicalAddress = getLocalPhysicalAddress();
|
||
if (physicalAddress == INVALID_PHYSICAL_ADDRESS) {
|
||
return false;
|
||
}
|
||
int targetPhysicalAddress = targetDevice.getPhysicalAddress();
|
||
if (targetPhysicalAddress == INVALID_PHYSICAL_ADDRESS) {
|
||
return false;
|
||
}
|
||
return HdmiUtils.getLocalPortFromPhysicalAddress(targetPhysicalAddress, physicalAddress)
|
||
!= HdmiUtils.TARGET_NOT_UNDER_LOCAL_DEVICE;
|
||
}
|
||
|
||
/**
|
||
* @removed
|
||
* @deprecated Please use {@link #isDeviceConnected(targetDevice)} instead.
|
||
*/
|
||
@Deprecated
|
||
public boolean isRemoteDeviceConnected(@NonNull HdmiDeviceInfo targetDevice) {
|
||
Objects.requireNonNull(targetDevice);
|
||
int physicalAddress = getLocalPhysicalAddress();
|
||
if (physicalAddress == INVALID_PHYSICAL_ADDRESS) {
|
||
return false;
|
||
}
|
||
int targetPhysicalAddress = targetDevice.getPhysicalAddress();
|
||
if (targetPhysicalAddress == INVALID_PHYSICAL_ADDRESS) {
|
||
return false;
|
||
}
|
||
return HdmiUtils.getLocalPortFromPhysicalAddress(targetPhysicalAddress, physicalAddress)
|
||
!= HdmiUtils.TARGET_NOT_UNDER_LOCAL_DEVICE;
|
||
}
|
||
|
||
/**
|
||
* Listener used to get hotplug event from HDMI port.
|
||
*/
|
||
public interface HotplugEventListener {
|
||
void onReceived(HdmiHotplugEvent event);
|
||
}
|
||
|
||
private final ArrayMap<HotplugEventListener, IHdmiHotplugEventListener>
|
||
mHotplugEventListeners = new ArrayMap<>();
|
||
|
||
/**
|
||
* Listener used to get HDMI Control (CEC) status (enabled/disabled) and the connected display
|
||
* status.
|
||
* @hide
|
||
*/
|
||
public interface HdmiControlStatusChangeListener {
|
||
/**
|
||
* Called when HDMI Control (CEC) is enabled/disabled.
|
||
*
|
||
* @param isCecEnabled status of HDMI Control
|
||
* {@link android.hardware.hdmi.HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_ENABLED}:
|
||
* {@code HDMI_CEC_CONTROL_ENABLED} if enabled.
|
||
* @param isCecAvailable status of CEC support of the connected display (the TV).
|
||
* {@code true} if supported.
|
||
*
|
||
* Note: Value of isCecAvailable is only valid when isCecEnabled is true.
|
||
**/
|
||
void onStatusChange(@HdmiControlManager.HdmiCecControl int isCecEnabled,
|
||
boolean isCecAvailable);
|
||
}
|
||
|
||
private final ArrayMap<HdmiControlStatusChangeListener, IHdmiControlStatusChangeListener>
|
||
mHdmiControlStatusChangeListeners = new ArrayMap<>();
|
||
|
||
/**
|
||
* Listener used to get the status of the HDMI CEC volume control feature (enabled/disabled).
|
||
* @hide
|
||
*/
|
||
public interface HdmiCecVolumeControlFeatureListener {
|
||
/**
|
||
* Called when the HDMI Control (CEC) volume control feature is enabled/disabled.
|
||
*
|
||
* @param hdmiCecVolumeControl status of HDMI CEC volume control feature
|
||
* @see {@link HdmiControlManager#setHdmiCecVolumeControlEnabled(int)} ()}
|
||
**/
|
||
void onHdmiCecVolumeControlFeature(@VolumeControl int hdmiCecVolumeControl);
|
||
}
|
||
|
||
private final ArrayMap<HdmiCecVolumeControlFeatureListener,
|
||
IHdmiCecVolumeControlFeatureListener>
|
||
mHdmiCecVolumeControlFeatureListeners = new ArrayMap<>();
|
||
|
||
/**
|
||
* Listener used to get vendor-specific commands.
|
||
*/
|
||
public interface VendorCommandListener {
|
||
/**
|
||
* Called when a vendor command is received.
|
||
*
|
||
* @param srcAddress source logical address
|
||
* @param destAddress destination logical address
|
||
* @param params vendor-specific parameters
|
||
* @param hasVendorId {@code true} if the command is <Vendor Command
|
||
* With ID>. The first 3 bytes of params is vendor id.
|
||
*/
|
||
void onReceived(int srcAddress, int destAddress, byte[] params, boolean hasVendorId);
|
||
|
||
/**
|
||
* The callback is called:
|
||
* <ul>
|
||
* <li> before HdmiControlService is disabled.
|
||
* <li> after HdmiControlService is enabled and the local address is assigned.
|
||
* </ul>
|
||
* The client shouldn't hold the thread too long since this is a blocking call.
|
||
*
|
||
* @param enabled {@code true} if HdmiControlService is enabled.
|
||
* @param reason the reason code why the state of HdmiControlService is changed.
|
||
* @see #CONTROL_STATE_CHANGED_REASON_START
|
||
* @see #CONTROL_STATE_CHANGED_REASON_SETTING
|
||
* @see #CONTROL_STATE_CHANGED_REASON_WAKEUP
|
||
* @see #CONTROL_STATE_CHANGED_REASON_STANDBY
|
||
*/
|
||
void onControlStateChanged(boolean enabled, int reason);
|
||
}
|
||
|
||
/**
|
||
* Adds a listener to get informed of {@link HdmiHotplugEvent}.
|
||
*
|
||
* <p>To stop getting the notification,
|
||
* use {@link #removeHotplugEventListener(HotplugEventListener)}.
|
||
*
|
||
* Note that each invocation of the callback will be executed on an arbitrary
|
||
* Binder thread. This means that all callback implementations must be
|
||
* thread safe. To specify the execution thread, use
|
||
* {@link addHotplugEventListener(Executor, HotplugEventListener)}.
|
||
*
|
||
* @param listener {@link HotplugEventListener} instance
|
||
* @see HdmiControlManager#removeHotplugEventListener(HotplugEventListener)
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void addHotplugEventListener(HotplugEventListener listener) {
|
||
addHotplugEventListener(ConcurrentUtils.DIRECT_EXECUTOR, listener);
|
||
}
|
||
|
||
/**
|
||
* Adds a listener to get informed of {@link HdmiHotplugEvent}.
|
||
*
|
||
* <p>To stop getting the notification,
|
||
* use {@link #removeHotplugEventListener(HotplugEventListener)}.
|
||
*
|
||
* @param listener {@link HotplugEventListener} instance
|
||
* @see HdmiControlManager#removeHotplugEventListener(HotplugEventListener)
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void addHotplugEventListener(@NonNull @CallbackExecutor Executor executor,
|
||
@NonNull HotplugEventListener listener) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "addHotplugEventListener: HdmiControlService is not available");
|
||
return;
|
||
}
|
||
if (mHotplugEventListeners.containsKey(listener)) {
|
||
Log.e(TAG, "listener is already registered");
|
||
return;
|
||
}
|
||
IHdmiHotplugEventListener wrappedListener =
|
||
getHotplugEventListenerWrapper(executor, listener);
|
||
mHotplugEventListeners.put(listener, wrappedListener);
|
||
try {
|
||
mService.addHotplugEventListener(wrappedListener);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Removes a listener to stop getting informed of {@link HdmiHotplugEvent}.
|
||
*
|
||
* @param listener {@link HotplugEventListener} instance to be removed
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void removeHotplugEventListener(HotplugEventListener listener) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "removeHotplugEventListener: HdmiControlService is not available");
|
||
return;
|
||
}
|
||
IHdmiHotplugEventListener wrappedListener = mHotplugEventListeners.remove(listener);
|
||
if (wrappedListener == null) {
|
||
Log.e(TAG, "tried to remove not-registered listener");
|
||
return;
|
||
}
|
||
try {
|
||
mService.removeHotplugEventListener(wrappedListener);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
private IHdmiHotplugEventListener getHotplugEventListenerWrapper(
|
||
Executor executor, final HotplugEventListener listener) {
|
||
return new IHdmiHotplugEventListener.Stub() {
|
||
@Override
|
||
public void onReceived(HdmiHotplugEvent event) {
|
||
final long token = Binder.clearCallingIdentity();
|
||
try {
|
||
executor.execute(() -> listener.onReceived(event));
|
||
} finally {
|
||
Binder.restoreCallingIdentity(token);
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Adds a listener to get informed of {@link HdmiControlStatusChange}.
|
||
*
|
||
* <p>To stop getting the notification,
|
||
* use {@link #removeHdmiControlStatusChangeListener(HdmiControlStatusChangeListener)}.
|
||
*
|
||
* Note that each invocation of the callback will be executed on an arbitrary
|
||
* Binder thread. This means that all callback implementations must be
|
||
* thread safe. To specify the execution thread, use
|
||
* {@link addHdmiControlStatusChangeListener(Executor, HdmiControlStatusChangeListener)}.
|
||
*
|
||
* @param listener {@link HdmiControlStatusChangeListener} instance
|
||
* @see HdmiControlManager#removeHdmiControlStatusChangeListener(
|
||
* HdmiControlStatusChangeListener)
|
||
*
|
||
* @hide
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void addHdmiControlStatusChangeListener(HdmiControlStatusChangeListener listener) {
|
||
addHdmiControlStatusChangeListener(ConcurrentUtils.DIRECT_EXECUTOR, listener);
|
||
}
|
||
|
||
/**
|
||
* Adds a listener to get informed of {@link HdmiControlStatusChange}.
|
||
*
|
||
* <p>To stop getting the notification,
|
||
* use {@link #removeHdmiControlStatusChangeListener(HdmiControlStatusChangeListener)}.
|
||
*
|
||
* @param listener {@link HdmiControlStatusChangeListener} instance
|
||
* @see HdmiControlManager#removeHdmiControlStatusChangeListener(
|
||
* HdmiControlStatusChangeListener)
|
||
*
|
||
* @hide
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void addHdmiControlStatusChangeListener(@NonNull @CallbackExecutor Executor executor,
|
||
@NonNull HdmiControlStatusChangeListener listener) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "addHdmiControlStatusChangeListener: HdmiControlService is not available");
|
||
return;
|
||
}
|
||
if (mHdmiControlStatusChangeListeners.containsKey(listener)) {
|
||
Log.e(TAG, "listener is already registered");
|
||
return;
|
||
}
|
||
IHdmiControlStatusChangeListener wrappedListener =
|
||
getHdmiControlStatusChangeListenerWrapper(executor, listener);
|
||
mHdmiControlStatusChangeListeners.put(listener, wrappedListener);
|
||
try {
|
||
mService.addHdmiControlStatusChangeListener(wrappedListener);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Removes a listener to stop getting informed of {@link HdmiControlStatusChange}.
|
||
*
|
||
* @param listener {@link HdmiControlStatusChangeListener} instance to be removed
|
||
*
|
||
* @hide
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void removeHdmiControlStatusChangeListener(HdmiControlStatusChangeListener listener) {
|
||
if (mService == null) {
|
||
Log.e(TAG,
|
||
"removeHdmiControlStatusChangeListener: HdmiControlService is not available");
|
||
return;
|
||
}
|
||
IHdmiControlStatusChangeListener wrappedListener =
|
||
mHdmiControlStatusChangeListeners.remove(listener);
|
||
if (wrappedListener == null) {
|
||
Log.e(TAG, "tried to remove not-registered listener");
|
||
return;
|
||
}
|
||
try {
|
||
mService.removeHdmiControlStatusChangeListener(wrappedListener);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
private IHdmiControlStatusChangeListener getHdmiControlStatusChangeListenerWrapper(
|
||
Executor executor, final HdmiControlStatusChangeListener listener) {
|
||
return new IHdmiControlStatusChangeListener.Stub() {
|
||
@Override
|
||
public void onStatusChange(@HdmiCecControl int isCecEnabled, boolean isCecAvailable) {
|
||
final long token = Binder.clearCallingIdentity();
|
||
try {
|
||
executor.execute(() -> listener.onStatusChange(isCecEnabled, isCecAvailable));
|
||
} finally {
|
||
Binder.restoreCallingIdentity(token);
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Adds a listener to get informed of changes to the state of the HDMI CEC volume control
|
||
* feature.
|
||
*
|
||
* Upon adding a listener, the current state of the HDMI CEC volume control feature will be
|
||
* sent immediately.
|
||
*
|
||
* <p>To stop getting the notification,
|
||
* use {@link #removeHdmiCecVolumeControlFeatureListener(HdmiCecVolumeControlFeatureListener)}.
|
||
*
|
||
* @param listener {@link HdmiCecVolumeControlFeatureListener} instance
|
||
* @hide
|
||
* @see #removeHdmiCecVolumeControlFeatureListener(HdmiCecVolumeControlFeatureListener)
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void addHdmiCecVolumeControlFeatureListener(@NonNull @CallbackExecutor Executor executor,
|
||
@NonNull HdmiCecVolumeControlFeatureListener listener) {
|
||
if (mService == null) {
|
||
Log.e(TAG,
|
||
"addHdmiCecVolumeControlFeatureListener: HdmiControlService is not available");
|
||
return;
|
||
}
|
||
if (mHdmiCecVolumeControlFeatureListeners.containsKey(listener)) {
|
||
Log.e(TAG, "listener is already registered");
|
||
return;
|
||
}
|
||
IHdmiCecVolumeControlFeatureListener wrappedListener =
|
||
createHdmiCecVolumeControlFeatureListenerWrapper(executor, listener);
|
||
mHdmiCecVolumeControlFeatureListeners.put(listener, wrappedListener);
|
||
try {
|
||
mService.addHdmiCecVolumeControlFeatureListener(wrappedListener);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Removes a listener to stop getting informed of changes to the state of the HDMI CEC volume
|
||
* control feature.
|
||
*
|
||
* @param listener {@link HdmiCecVolumeControlFeatureListener} instance to be removed
|
||
* @hide
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void removeHdmiCecVolumeControlFeatureListener(
|
||
HdmiCecVolumeControlFeatureListener listener) {
|
||
if (mService == null) {
|
||
Log.e(TAG,
|
||
"removeHdmiCecVolumeControlFeatureListener: HdmiControlService is not "
|
||
+ "available");
|
||
return;
|
||
}
|
||
IHdmiCecVolumeControlFeatureListener wrappedListener =
|
||
mHdmiCecVolumeControlFeatureListeners.remove(listener);
|
||
if (wrappedListener == null) {
|
||
Log.e(TAG, "tried to remove not-registered listener");
|
||
return;
|
||
}
|
||
try {
|
||
mService.removeHdmiCecVolumeControlFeatureListener(wrappedListener);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
private IHdmiCecVolumeControlFeatureListener createHdmiCecVolumeControlFeatureListenerWrapper(
|
||
Executor executor, final HdmiCecVolumeControlFeatureListener listener) {
|
||
return new android.hardware.hdmi.IHdmiCecVolumeControlFeatureListener.Stub() {
|
||
@Override
|
||
public void onHdmiCecVolumeControlFeature(int enabled) {
|
||
final long token = Binder.clearCallingIdentity();
|
||
try {
|
||
executor.execute(() -> listener.onHdmiCecVolumeControlFeature(enabled));
|
||
} finally {
|
||
Binder.restoreCallingIdentity(token);
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Listener used to get setting change notification.
|
||
*/
|
||
public interface CecSettingChangeListener {
|
||
/**
|
||
* Called when value of a setting changes.
|
||
*
|
||
* @param setting name of a CEC setting that changed
|
||
*/
|
||
void onChange(@NonNull @SettingName String setting);
|
||
}
|
||
|
||
private final ArrayMap<String,
|
||
ArrayMap<CecSettingChangeListener, IHdmiCecSettingChangeListener>>
|
||
mCecSettingChangeListeners = new ArrayMap<>();
|
||
|
||
private void addCecSettingChangeListener(
|
||
@NonNull @SettingName String setting,
|
||
@NonNull @CallbackExecutor Executor executor,
|
||
@NonNull CecSettingChangeListener listener) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "addCecSettingChangeListener: HdmiControlService is not available");
|
||
return;
|
||
}
|
||
if (mCecSettingChangeListeners.containsKey(setting)
|
||
&& mCecSettingChangeListeners.get(setting).containsKey(listener)) {
|
||
Log.e(TAG, "listener is already registered");
|
||
return;
|
||
}
|
||
IHdmiCecSettingChangeListener wrappedListener =
|
||
getCecSettingChangeListenerWrapper(executor, listener);
|
||
if (!mCecSettingChangeListeners.containsKey(setting)) {
|
||
mCecSettingChangeListeners.put(setting, new ArrayMap<>());
|
||
}
|
||
mCecSettingChangeListeners.get(setting).put(listener, wrappedListener);
|
||
try {
|
||
mService.addCecSettingChangeListener(setting, wrappedListener);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
private void removeCecSettingChangeListener(
|
||
@NonNull @SettingName String setting,
|
||
@NonNull CecSettingChangeListener listener) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "removeCecSettingChangeListener: HdmiControlService is not available");
|
||
return;
|
||
}
|
||
IHdmiCecSettingChangeListener wrappedListener =
|
||
!mCecSettingChangeListeners.containsKey(setting) ? null :
|
||
mCecSettingChangeListeners.get(setting).remove(listener);
|
||
if (wrappedListener == null) {
|
||
Log.e(TAG, "tried to remove not-registered listener");
|
||
return;
|
||
}
|
||
try {
|
||
mService.removeCecSettingChangeListener(setting, wrappedListener);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
private IHdmiCecSettingChangeListener getCecSettingChangeListenerWrapper(
|
||
Executor executor, final CecSettingChangeListener listener) {
|
||
return new IHdmiCecSettingChangeListener.Stub() {
|
||
@Override
|
||
public void onChange(String setting) {
|
||
final long token = Binder.clearCallingIdentity();
|
||
try {
|
||
executor.execute(() -> listener.onChange(setting));
|
||
} finally {
|
||
Binder.restoreCallingIdentity(token);
|
||
}
|
||
}
|
||
};
|
||
}
|
||
|
||
/**
|
||
* Get a set of user-modifiable HDMI control settings.
|
||
* This applies to CEC settings and eARC settings.
|
||
*
|
||
* @return a set of user-modifiable settings.
|
||
* @throws RuntimeException when the HdmiControlService is not available.
|
||
*/
|
||
// TODO(b/240379115): rename this API to represent that this applies to all HDMI control
|
||
// settings and not just CEC settings.
|
||
@NonNull
|
||
@SettingName
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public List<String> getUserCecSettings() {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getUserCecSettings: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getUserCecSettings();
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get a set of allowed values for an HDMI control setting (string value-type).
|
||
* This applies to CEC settings and eARC settings.
|
||
*
|
||
*
|
||
* @param name name of the setting
|
||
* @return a set of allowed values for a settings. {@code null} on failure.
|
||
* @throws IllegalArgumentException when setting {@code name} does not exist.
|
||
* @throws IllegalArgumentException when setting {@code name} value type is invalid.
|
||
* @throws RuntimeException when the HdmiControlService is not available.
|
||
*/
|
||
// TODO(b/240379115): rename this API to represent that this applies to all HDMI control
|
||
// settings and not just CEC settings.
|
||
@NonNull
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public List<String> getAllowedCecSettingStringValues(@NonNull @SettingName String name) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getAllowedCecSettingStringValues: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getAllowedCecSettingStringValues(name);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get a set of allowed values for an HDMI control setting (int value-type).
|
||
* This applies to CEC settings and eARC settings.
|
||
*
|
||
* @param name name of the setting
|
||
* @return a set of allowed values for a settings. {@code null} on failure.
|
||
* @throws IllegalArgumentException when setting {@code name} does not exist.
|
||
* @throws IllegalArgumentException when setting {@code name} value type is invalid.
|
||
* @throws RuntimeException when the HdmiControlService is not available.
|
||
*/
|
||
// TODO(b/240379115): rename this API to represent that this applies to all HDMI control
|
||
// settings and not just CEC settings.
|
||
@NonNull
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public List<Integer> getAllowedCecSettingIntValues(@NonNull @SettingName String name) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getAllowedCecSettingIntValues: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
int[] allowedValues = mService.getAllowedCecSettingIntValues(name);
|
||
return Arrays.stream(allowedValues).boxed().collect(Collectors.toList());
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set the global status of HDMI CEC.
|
||
*
|
||
* <p>This allows to enable/disable HDMI CEC on the device.
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setHdmiCecEnabled(@NonNull @HdmiCecControl int value) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "setHdmiCecEnabled: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
mService.setCecSettingIntValue(CEC_SETTING_NAME_HDMI_CEC_ENABLED, value);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get the current global status of HDMI CEC.
|
||
*
|
||
* <p>Reflects whether HDMI CEC is currently enabled on the device.
|
||
*/
|
||
@NonNull
|
||
@HdmiCecControl
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public int getHdmiCecEnabled() {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getHdmiCecEnabled: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getCecSettingIntValue(CEC_SETTING_NAME_HDMI_CEC_ENABLED);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Add change listener for global status of HDMI CEC.
|
||
*
|
||
* <p>To stop getting the notification,
|
||
* use {@link #removeHdmiCecEnabledChangeListener(CecSettingChangeListener)}.
|
||
*
|
||
* Note that each invocation of the callback will be executed on an arbitrary
|
||
* Binder thread. This means that all callback implementations must be
|
||
* thread safe. To specify the execution thread, use
|
||
* {@link addHdmiCecEnabledChangeListener(Executor, CecSettingChangeListener)}.
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void addHdmiCecEnabledChangeListener(@NonNull CecSettingChangeListener listener) {
|
||
addHdmiCecEnabledChangeListener(ConcurrentUtils.DIRECT_EXECUTOR, listener);
|
||
}
|
||
|
||
/**
|
||
* Add change listener for global status of HDMI CEC.
|
||
*
|
||
* <p>To stop getting the notification,
|
||
* use {@link #removeHdmiCecEnabledChangeListener(CecSettingChangeListener)}.
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void addHdmiCecEnabledChangeListener(
|
||
@NonNull @CallbackExecutor Executor executor,
|
||
@NonNull CecSettingChangeListener listener) {
|
||
addCecSettingChangeListener(CEC_SETTING_NAME_HDMI_CEC_ENABLED, executor, listener);
|
||
}
|
||
|
||
/**
|
||
* Remove change listener for global status of HDMI CEC.
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void removeHdmiCecEnabledChangeListener(
|
||
@NonNull CecSettingChangeListener listener) {
|
||
removeCecSettingChangeListener(CEC_SETTING_NAME_HDMI_CEC_ENABLED, listener);
|
||
}
|
||
|
||
/**
|
||
* Set the version of the HDMI CEC specification currently used.
|
||
*
|
||
* <p>Allows to select either CEC 1.4b or 2.0 to be used by the device.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_VERSION
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setHdmiCecVersion(@NonNull @HdmiCecVersion int value) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "setHdmiCecVersion: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
mService.setCecSettingIntValue(CEC_SETTING_NAME_HDMI_CEC_VERSION, value);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get the version of the HDMI CEC specification currently used.
|
||
*
|
||
* <p>Reflects which CEC version 1.4b or 2.0 is currently used by the device.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_HDMI_CEC_VERSION
|
||
*/
|
||
@NonNull
|
||
@HdmiCecVersion
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public int getHdmiCecVersion() {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getHdmiCecVersion: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getCecSettingIntValue(CEC_SETTING_NAME_HDMI_CEC_VERSION);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set the status of Routing Control feature.
|
||
*
|
||
* <p>This allows to enable/disable Routing Control on the device.
|
||
* If enabled, the switch device will route to the correct input source on
|
||
* receiving Routing Control related messages. If disabled, you can only
|
||
* switch the input via controls on this device.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_ROUTING_CONTROL
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setRoutingControl(@NonNull @RoutingControl int value) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "setRoutingControl: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
mService.setCecSettingIntValue(CEC_SETTING_NAME_ROUTING_CONTROL, value);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get the current status of Routing Control feature.
|
||
*
|
||
* <p>Reflects whether Routing Control is currently enabled on the device.
|
||
* If enabled, the switch device will route to the correct input source on
|
||
* receiving Routing Control related messages. If disabled, you can only
|
||
* switch the input via controls on this device.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_ROUTING_CONTROL
|
||
*/
|
||
@NonNull
|
||
@RoutingControl
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public int getRoutingControl() {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getRoutingControl: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getCecSettingIntValue(CEC_SETTING_NAME_ROUTING_CONTROL);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set the status of Soundbar mode feature.
|
||
*
|
||
* <p>This allows to enable/disable Soundbar mode on the playback device.
|
||
* The setting's effect will be available on devices where the hardware supports this feature.
|
||
* If enabled, an audio system local device will be allocated and try to establish an ARC
|
||
* connection with the TV. If disabled, the ARC connection will be terminated and the audio
|
||
* system local device will be removed from the network.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SOUNDBAR_MODE
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setSoundbarMode(@SoundbarMode int value) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "setSoundbarMode: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
mService.setCecSettingIntValue(CEC_SETTING_NAME_SOUNDBAR_MODE, value);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get the current status of Soundbar mode feature.
|
||
*
|
||
* <p>Reflects whether Soundbar mode is currently enabled on the playback device.
|
||
* If enabled, an audio system local device will be allocated and try to establish an ARC
|
||
* connection with the TV. If disabled, the ARC connection will be terminated and the audio
|
||
* system local device will be removed from the network.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SOUNDBAR_MODE
|
||
*/
|
||
@SoundbarMode
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public int getSoundbarMode() {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getSoundbarMode: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getCecSettingIntValue(CEC_SETTING_NAME_SOUNDBAR_MODE);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set the status of Power Control.
|
||
*
|
||
* <p>Specifies to which devices Power Control messages should be sent:
|
||
* only to the TV, broadcast to all devices, no power control messages.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setPowerControlMode(@NonNull @PowerControlMode String value) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "setPowerControlMode: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
mService.setCecSettingStringValue(CEC_SETTING_NAME_POWER_CONTROL_MODE, value);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get the status of Power Control.
|
||
*
|
||
* <p>Reflects to which devices Power Control messages should be sent:
|
||
* only to the TV, broadcast to all devices, no power control messages.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_POWER_CONTROL_MODE
|
||
*/
|
||
@NonNull
|
||
@PowerControlMode
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public String getPowerControlMode() {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getPowerControlMode: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getCecSettingStringValue(CEC_SETTING_NAME_POWER_CONTROL_MODE);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set the current power state behaviour when Active Source is lost.
|
||
*
|
||
* <p>Sets the action taken: do nothing or go to sleep immediately.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setPowerStateChangeOnActiveSourceLost(
|
||
@NonNull @ActiveSourceLostBehavior String value) {
|
||
if (mService == null) {
|
||
Log.e(TAG,
|
||
"setPowerStateChangeOnActiveSourceLost: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
mService.setCecSettingStringValue(
|
||
CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST, value);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get the current power state behaviour when Active Source is lost.
|
||
*
|
||
* <p>Reflects the action taken: do nothing or go to sleep immediately.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST
|
||
*/
|
||
@NonNull
|
||
@ActiveSourceLostBehavior
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public String getPowerStateChangeOnActiveSourceLost() {
|
||
if (mService == null) {
|
||
Log.e(TAG,
|
||
"getPowerStateChangeOnActiveSourceLost: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getCecSettingStringValue(
|
||
CEC_SETTING_NAME_POWER_STATE_CHANGE_ON_ACTIVE_SOURCE_LOST);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set the current status of System Audio Control.
|
||
*
|
||
* <p>Sets whether HDMI System Audio Control feature is enabled. If enabled,
|
||
* TV or Audio System will try to turn on the System Audio Mode if there's a
|
||
* connected CEC-enabled AV Receiver. Then an audio stream will be played on
|
||
* the AVR instead of TV speaker or Audio System speakers. If disabled, the
|
||
* System Audio Mode will never be activated.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setSystemAudioControl(@NonNull @SystemAudioControl int value) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "setSystemAudioControl: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
mService.setCecSettingIntValue(CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL, value);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get the current status of System Audio Control.
|
||
*
|
||
* <p>Reflects whether HDMI System Audio Control feature is enabled. If enabled,
|
||
* TV or Audio System will try to turn on the System Audio Mode if there's a
|
||
* connected CEC-enabled AV Receiver. Then an audio stream will be played on
|
||
* the AVR instead of TV speaker or Audio System speakers. If disabled, the
|
||
* System Audio Mode will never be activated.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL
|
||
*/
|
||
@NonNull
|
||
@SystemAudioControl
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public int getSystemAudioControl() {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getSystemAudioControl: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getCecSettingIntValue(CEC_SETTING_NAME_SYSTEM_AUDIO_CONTROL);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set the current status of System Audio Mode muting.
|
||
*
|
||
* <p>Sets whether the device should be muted when System Audio Mode is turned off.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setSystemAudioModeMuting(@NonNull @SystemAudioModeMuting int value) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "setSystemAudioModeMuting: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
mService.setCecSettingIntValue(CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING, value);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get the current status of System Audio Mode muting.
|
||
*
|
||
* <p>Reflects whether the device should be muted when System Audio Mode is turned off.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING
|
||
*/
|
||
@NonNull
|
||
@SystemAudioModeMuting
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public int getSystemAudioModeMuting() {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getSystemAudioModeMuting: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getCecSettingIntValue(CEC_SETTING_NAME_SYSTEM_AUDIO_MODE_MUTING);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set the current status of TV Wake on One Touch Play.
|
||
*
|
||
* <p>Sets whether the TV should wake up upon reception of <Text View On>
|
||
* or <Image View On>.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setTvWakeOnOneTouchPlay(@NonNull @TvWakeOnOneTouchPlay int value) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "setTvWakeOnOneTouchPlay: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
mService.setCecSettingIntValue(CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY, value);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get the current status of TV Wake on One Touch Play.
|
||
*
|
||
* <p>Reflects whether the TV should wake up upon reception of <Text View On>
|
||
* or <Image View On>.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY
|
||
*/
|
||
@NonNull
|
||
@TvWakeOnOneTouchPlay
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public int getTvWakeOnOneTouchPlay() {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getTvWakeOnOneTouchPlay: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getCecSettingIntValue(CEC_SETTING_NAME_TV_WAKE_ON_ONE_TOUCH_PLAY);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set the current status of TV send <Standby> on Sleep.
|
||
*
|
||
* <p>Sets whether the device will also turn off other CEC devices
|
||
* when it goes to standby mode.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setTvSendStandbyOnSleep(@NonNull @TvSendStandbyOnSleep int value) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "setTvSendStandbyOnSleep: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
mService.setCecSettingIntValue(CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP, value);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get the current status of TV send <Standby> on Sleep.
|
||
*
|
||
* <p>Reflects whether the device will also turn off other CEC devices
|
||
* when it goes to standby mode.
|
||
*
|
||
* @see HdmiControlManager#CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP
|
||
*/
|
||
@NonNull
|
||
@TvSendStandbyOnSleep
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public int getTvSendStandbyOnSleep() {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getTvSendStandbyOnSleep: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getCecSettingIntValue(CEC_SETTING_NAME_TV_SEND_STANDBY_ON_SLEEP);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set presence of one Short Audio Descriptor (SAD) in the query.
|
||
*
|
||
* <p>Allows the caller to specify whether the SAD for a specific audio codec should be
|
||
* present in the <Request Short Audio Descriptor> query. Each <Request Short Audio
|
||
* Descriptor> message can carry at most 4 SADs at a time. This method allows the caller to
|
||
* limit the amount of SADs queried and therefore limit the amount of CEC messages on the bus.
|
||
*
|
||
* <p>When an ARC connection is established, the TV sends a
|
||
* <Request Short Audio Descriptor> query to the Audio System that it's connected to. If
|
||
* an SAD is queried and the Audio System reports that it supports that SAD, the TV can send
|
||
* audio in that format to be output on the Audio System via ARC.
|
||
* If a codec is not queried, the TV doesn't know if the connected Audio System supports this
|
||
* SAD and doesn't send audio in that format to the Audio System.
|
||
*
|
||
* @param setting SAD to set.
|
||
* @param value Presence to set the SAD to.
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setSadPresenceInQuery(@NonNull @CecSettingSad String setting,
|
||
@SadPresenceInQuery int value) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "setSadPresenceInQuery: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
mService.setCecSettingIntValue(setting, value);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set presence of multiple Short Audio Descriptors (SADs) in the query.
|
||
*
|
||
* <p>Allows the caller to specify whether the SADs for specific audio codecs should be present
|
||
* in the <Request Short Audio Descriptor> query. For audio codecs that are not specified,
|
||
* the SAD's presence remains at its previous value. Each <Request Short Audio Descriptor>
|
||
* message can carry at most 4 SADs at a time. This method allows the caller to limit the amount
|
||
* of SADs queried and therefore limit the amount of CEC messages on the bus.
|
||
*
|
||
* <p>When an ARC connection is established, the TV sends a
|
||
* <Request Short Audio Descriptor> query to the Audio System that it's connected to. If
|
||
* an SAD is queried and the Audio System reports that it supports that SAD, the TV can send
|
||
* audio in that format to be output on the Audio System via ARC.
|
||
* If a codec is not queried, the TV doesn't know if the connected Audio System supports this
|
||
* SAD and doesn't send audio in that format to the Audio System.
|
||
*
|
||
*
|
||
* @param settings SADs to set.
|
||
* @param value Presence to set all specified SADs to.
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setSadsPresenceInQuery(@NonNull @CecSettingSad List<String> settings,
|
||
@SadPresenceInQuery int value) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "setSadsPresenceInQuery: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
for (String sad : settings) {
|
||
mService.setCecSettingIntValue(sad, value);
|
||
}
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get presence of one Short Audio Descriptor (SAD) in the query.
|
||
*
|
||
* <p>Reflects whether the SAD for a specific audio codec should be present in the
|
||
* <Request Short Audio Descriptor> query.
|
||
*
|
||
* <p>When an ARC connection is established, the TV sends a
|
||
* <Request Short Audio Descriptor> query to the Audio System that it's connected to. If
|
||
* an SAD is queried and the Audio System reports that it supports that SAD, the TV can send
|
||
* audio in that format to be output on the Audio System via ARC.
|
||
* If a codec is not queried, the TV doesn't know if the connected Audio System supports this
|
||
* SAD and doesn't send audio in that format to the Audio System.
|
||
*
|
||
* @param setting SAD to get.
|
||
* @return Current presence of the specified SAD.
|
||
*/
|
||
@SadPresenceInQuery
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public int getSadPresenceInQuery(@NonNull @CecSettingSad String setting) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getSadPresenceInQuery: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getCecSettingIntValue(setting);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Set the global status of eARC.
|
||
*
|
||
* <p>This allows to enable/disable the eARC feature on the device. If the feature is enabled
|
||
* and the hardware supports eARC as well, the device can attempt to establish an eARC
|
||
* connection.
|
||
*/
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public void setEarcEnabled(@NonNull @EarcFeature int value) {
|
||
if (mService == null) {
|
||
Log.e(TAG, "setEarcEnabled: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
mService.setCecSettingIntValue(SETTING_NAME_EARC_ENABLED, value);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Get the current global status of eARC.
|
||
*
|
||
* <p>Reflects whether the eARC feature is currently enabled on the device.
|
||
*/
|
||
@NonNull
|
||
@EarcFeature
|
||
@RequiresPermission(android.Manifest.permission.HDMI_CEC)
|
||
public int getEarcEnabled() {
|
||
if (mService == null) {
|
||
Log.e(TAG, "getEarcEnabled: HdmiControlService is not available");
|
||
throw new RuntimeException("HdmiControlService is not available");
|
||
}
|
||
try {
|
||
return mService.getCecSettingIntValue(SETTING_NAME_EARC_ENABLED);
|
||
} catch (RemoteException e) {
|
||
throw e.rethrowFromSystemServer();
|
||
}
|
||
}
|
||
}
|