Methods Summary |
---|
final void | addCecDevice(android.hardware.hdmi.HdmiDeviceInfo info)Called when a device is newly added or a new device is detected or
existing device is updated.
assertRunOnServiceThread();
HdmiDeviceInfo old = addDeviceInfo(info);
if (info.getLogicalAddress() == mAddress) {
// The addition of TV device itself should not be notified.
return;
}
if (old == null) {
invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_ADD_DEVICE);
} else if (!old.equals(info)) {
invokeDeviceEventListener(old, HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE);
invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_ADD_DEVICE);
}
|
private android.hardware.hdmi.HdmiDeviceInfo | addDeviceInfo(android.hardware.hdmi.HdmiDeviceInfo deviceInfo)Add a new {@link HdmiDeviceInfo}. It returns old device info which has the same
logical address as new device info's.
Declared as package-private. accessed by {@link HdmiControlService} only.
assertRunOnServiceThread();
HdmiDeviceInfo oldDeviceInfo = getCecDeviceInfo(deviceInfo.getLogicalAddress());
if (oldDeviceInfo != null) {
removeDeviceInfo(deviceInfo.getId());
}
mDeviceInfos.append(deviceInfo.getId(), deviceInfo);
updateSafeDeviceInfoList();
return oldDeviceInfo;
|
private void | addTvInput(java.lang.String inputId, int deviceId)
assertRunOnServiceThread();
mTvInputs.put(inputId, deviceId);
|
void | announceClearTimerRecordingResult(int recorderAddress, int result)
mService.invokeClearTimerRecordingResult(recorderAddress, result);
|
void | announceOneTouchRecordResult(int recorderAddress, int result)
mService.invokeOneTouchRecordResult(recorderAddress, result);
|
void | announceTimerRecordingResult(int recorderAddress, int result)
mService.invokeTimerRecordingResult(recorderAddress, result);
|
boolean | broadcastMenuLanguage(java.lang.String language)
assertRunOnServiceThread();
HdmiCecMessage command = HdmiCecMessageBuilder.buildSetMenuLanguageCommand(
mAddress, language);
if (command != null) {
mService.sendCecCommand(command);
return true;
}
return false;
|
private boolean | canStartArcUpdateAction(int avrAddress, boolean shouldCheckArcFeatureEnabled)
HdmiDeviceInfo avr = getAvrDeviceInfo();
if (avr != null
&& (avrAddress == avr.getLogicalAddress())
&& isConnectedToArcPort(avr.getPhysicalAddress())
&& isDirectConnectAddress(avr.getPhysicalAddress())) {
if (shouldCheckArcFeatureEnabled) {
return isArcFeatureEnabled();
} else {
return true;
}
} else {
return false;
}
|
void | changeArcFeatureEnabled(boolean enabled)
assertRunOnServiceThread();
if (mArcFeatureEnabled != enabled) {
mArcFeatureEnabled = enabled;
if (enabled) {
if (!mArcEstablished) {
startArcAction(true);
}
} else {
if (mArcEstablished) {
startArcAction(false);
}
}
}
|
void | changeMute(boolean mute)
assertRunOnServiceThread();
HdmiLogger.debug("[A]:Change mute:%b", mute);
synchronized (mLock) {
if (mSystemAudioMute == mute) {
HdmiLogger.debug("No need to change mute.");
return;
}
}
if (!isSystemAudioActivated()) {
HdmiLogger.debug("[A]:System audio is not activated.");
return;
}
// Remove existing volume action.
removeAction(VolumeControlAction.class);
sendUserControlPressedAndReleased(getAvrDeviceInfo().getLogicalAddress(),
mute ? HdmiCecKeycode.CEC_KEYCODE_MUTE_FUNCTION :
HdmiCecKeycode.CEC_KEYCODE_RESTORE_VOLUME_FUNCTION);
|
void | changeSystemAudioMode(boolean enabled, android.hardware.hdmi.IHdmiControlCallback callback)
assertRunOnServiceThread();
if (!mService.isControlEnabled() || hasAction(DeviceDiscoveryAction.class)) {
setSystemAudioMode(false, true);
invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
return;
}
HdmiDeviceInfo avr = getAvrDeviceInfo();
if (avr == null) {
setSystemAudioMode(false, true);
invokeCallback(callback, HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
return;
}
addAndStartAction(
new SystemAudioActionFromTv(this, avr.getLogicalAddress(), enabled, callback));
|
void | changeVolume(int curVolume, int delta, int maxVolume)
assertRunOnServiceThread();
if (delta == 0 || !isSystemAudioActivated()) {
return;
}
int targetVolume = curVolume + delta;
int cecVolume = VolumeControlAction.scaleToCecVolume(targetVolume, maxVolume);
synchronized (mLock) {
// If new volume is the same as current system audio volume, just ignore it.
// Note that UNKNOWN_VOLUME is not in range of cec volume scale.
if (cecVolume == mSystemAudioVolume) {
// Update tv volume with system volume value.
mService.setAudioStatus(false,
VolumeControlAction.scaleToCustomVolume(mSystemAudioVolume, maxVolume));
return;
}
}
List<VolumeControlAction> actions = getActions(VolumeControlAction.class);
if (actions.isEmpty()) {
addAndStartAction(new VolumeControlAction(this,
getAvrDeviceInfo().getLogicalAddress(), delta > 0));
} else {
actions.get(0).handleVolumeChange(delta > 0);
}
|
private boolean | checkRecordSource(byte[] recordSource)
return (recordSource != null) && HdmiRecordSources.checkRecordSource(recordSource);
|
private boolean | checkRecorder(int recorderAddress)
HdmiDeviceInfo device = getCecDeviceInfo(recorderAddress);
return (device != null)
&& (HdmiUtils.getTypeFromAddress(recorderAddress)
== HdmiDeviceInfo.DEVICE_RECORDER);
|
private boolean | checkTimerRecordingSource(int sourceType, byte[] recordSource)
return (recordSource != null)
&& HdmiTimerRecordSources.checkTimerRecordSource(sourceType, recordSource);
|
private void | clearDeviceInfoList()
assertRunOnServiceThread();
for (HdmiDeviceInfo info : mSafeExternalInputs) {
invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE);
}
mDeviceInfos.clear();
updateSafeDeviceInfoList();
|
void | clearTimerRecording(int recorderAddress, int sourceType, byte[] recordSource)
assertRunOnServiceThread();
if (!mService.isControlEnabled()) {
Slog.w(TAG, "Can not start one touch record. CEC control is disabled.");
announceClearTimerRecordingResult(recorderAddress, CLEAR_TIMER_STATUS_CEC_DISABLE);
return;
}
if (!checkRecorder(recorderAddress)) {
Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
announceClearTimerRecordingResult(recorderAddress,
CLEAR_TIMER_STATUS_CHECK_RECORDER_CONNECTION);
return;
}
if (!checkTimerRecordingSource(sourceType, recordSource)) {
Slog.w(TAG, "Invalid record source." + Arrays.toString(recordSource));
announceClearTimerRecordingResult(recorderAddress,
CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
return;
}
sendClearTimerMessage(recorderAddress, sourceType, recordSource);
|
void | deviceSelect(int id, android.hardware.hdmi.IHdmiControlCallback callback)Performs the action 'device select', or 'one touch play' initiated by TV.
assertRunOnServiceThread();
HdmiDeviceInfo targetDevice = mDeviceInfos.get(id);
if (targetDevice == null) {
invokeCallback(callback, HdmiControlManager.RESULT_TARGET_NOT_AVAILABLE);
return;
}
int targetAddress = targetDevice.getLogicalAddress();
ActiveSource active = getActiveSource();
if (active.isValid() && targetAddress == active.logicalAddress) {
invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS);
return;
}
if (targetAddress == Constants.ADDR_INTERNAL) {
handleSelectInternalSource();
// Switching to internal source is always successful even when CEC control is disabled.
setActiveSource(targetAddress, mService.getPhysicalAddress());
setActivePath(mService.getPhysicalAddress());
invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS);
return;
}
if (!mService.isControlEnabled()) {
setActiveSource(targetDevice);
invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
return;
}
removeAction(DeviceSelectAction.class);
addAndStartAction(new DeviceSelectAction(this, targetDevice, callback));
|
private void | disableArcIfExist()
assertRunOnServiceThread();
HdmiDeviceInfo avr = getAvrDeviceInfo();
if (avr == null) {
return;
}
// Seq #44.
removeAction(RequestArcInitiationAction.class);
if (!hasAction(RequestArcTerminationAction.class) && isArcEstabilished()) {
addAndStartAction(new RequestArcTerminationAction(this, avr.getLogicalAddress()));
}
|
protected void | disableDevice(boolean initiatedByCec, PendingActionClearedCallback callback)
super.disableDevice(initiatedByCec, callback);
assertRunOnServiceThread();
mService.unregisterTvInputCallback(mTvInputCallback);
// Remove any repeated working actions.
// HotplugDetectionAction will be reinstated during the wake up process.
// HdmiControlService.onWakeUp() -> initializeLocalDevices() ->
// LocalDeviceTv.onAddressAllocated() -> launchDeviceDiscovery().
removeAction(DeviceDiscoveryAction.class);
removeAction(HotplugDetectionAction.class);
removeAction(PowerStatusMonitorAction.class);
// Remove recording actions.
removeAction(OneTouchRecordAction.class);
removeAction(TimerRecordingAction.class);
disableSystemAudioIfExist();
disableArcIfExist();
clearDeviceInfoList();
checkIfPendingActionsCleared();
|
private void | disableSystemAudioIfExist()
assertRunOnServiceThread();
if (getAvrDeviceInfo() == null) {
return;
}
// Seq #31.
removeAction(SystemAudioActionFromAvr.class);
removeAction(SystemAudioActionFromTv.class);
removeAction(SystemAudioAutoInitiationAction.class);
removeAction(SystemAudioStatusAction.class);
removeAction(VolumeControlAction.class);
// Turn off the mode but do not write it the settings, so that the next time TV powers on
// the system audio mode setting can be restored automatically.
setSystemAudioMode(false, false);
|
boolean | dispatchMessage(HdmiCecMessage message)
assertRunOnServiceThread();
if (mService.isPowerStandby() && mStandbyHandler.handleCommand(message)) {
return true;
}
return super.onMessage(message);
|
void | displayOsd(int messageId)
assertRunOnServiceThread();
mService.displayOsd(messageId);
|
void | displayOsd(int messageId, int extra)
assertRunOnServiceThread();
mService.displayOsd(messageId, extra);
|
void | doManualPortSwitching(int portId, android.hardware.hdmi.IHdmiControlCallback callback)
assertRunOnServiceThread();
// Seq #20
if (!mService.isValidPortId(portId)) {
invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
return;
}
if (portId == getActivePortId()) {
invokeCallback(callback, HdmiControlManager.RESULT_SUCCESS);
return;
}
mActiveSource.invalidate();
if (!mService.isControlEnabled()) {
setActivePortId(portId);
invokeCallback(callback, HdmiControlManager.RESULT_INCORRECT_MODE);
return;
}
int oldPath = getActivePortId() != Constants.INVALID_PORT_ID
? mService.portIdToPath(getActivePortId()) : getDeviceInfo().getPhysicalAddress();
setActivePath(oldPath);
if (mSkipRoutingControl) {
mSkipRoutingControl = false;
return;
}
int newPath = mService.portIdToPath(portId);
startRoutingControl(oldPath, newPath, true, callback);
|
protected void | dump(com.android.internal.util.IndentingPrintWriter pw)
super.dump(pw);
pw.println("mArcEstablished: " + mArcEstablished);
pw.println("mArcFeatureEnabled: " + mArcFeatureEnabled);
pw.println("mSystemAudioActivated: " + mSystemAudioActivated);
pw.println("mSystemAudioMute: " + mSystemAudioMute);
pw.println("mAutoDeviceOff: " + mAutoDeviceOff);
pw.println("mAutoWakeup: " + mAutoWakeup);
pw.println("mSkipRoutingControl: " + mSkipRoutingControl);
pw.println("mPrevPortId: " + mPrevPortId);
pw.println("CEC devices:");
pw.increaseIndent();
for (HdmiDeviceInfo info : mSafeAllDeviceInfos) {
pw.println(info);
}
pw.decreaseIndent();
|
private int | findKeyReceiverAddress()
if (getActiveSource().isValid()) {
return getActiveSource().logicalAddress;
}
HdmiDeviceInfo info = getDeviceInfoByPath(getActivePath());
if (info != null) {
return info.getLogicalAddress();
}
return Constants.ADDR_INVALID;
|
boolean | getAutoWakeup()
assertRunOnServiceThread();
return mAutoWakeup;
|
android.hardware.hdmi.HdmiDeviceInfo | getAvrDeviceInfo()
assertRunOnServiceThread();
return getCecDeviceInfo(Constants.ADDR_AUDIO_SYSTEM);
|
android.hardware.hdmi.HdmiDeviceInfo | getCecDeviceInfo(int logicalAddress)Return a {@link HdmiDeviceInfo} corresponding to the given {@code logicalAddress}.
This is not thread-safe. For thread safety, call {@link #getSafeCecDeviceInfo(int)}.
assertRunOnServiceThread();
return mDeviceInfos.get(HdmiDeviceInfo.idForCecDevice(logicalAddress));
|
final android.hardware.hdmi.HdmiDeviceInfo | getDeviceInfoByPath(int path)Returns the {@link HdmiDeviceInfo} instance whose physical address matches
the given routing path. CEC devices use routing path for its physical address to
describe the hierarchy of the devices in the network.
assertRunOnServiceThread();
for (HdmiDeviceInfo info : getDeviceInfoList(false)) {
if (info.getPhysicalAddress() == path) {
return info;
}
}
return null;
|
java.util.List | getDeviceInfoList(boolean includeLocalDevice)Return a list of all {@link HdmiDeviceInfo}.
Declared as package-private. accessed by {@link HdmiControlService} only.
This is not thread-safe. For thread safety, call {@link #getSafeExternalInputsLocked} which
does not include local device.
assertRunOnServiceThread();
if (includeLocalDevice) {
return HdmiUtils.sparseArrayToList(mDeviceInfos);
} else {
ArrayList<HdmiDeviceInfo> infoList = new ArrayList<>();
for (int i = 0; i < mDeviceInfos.size(); ++i) {
HdmiDeviceInfo info = mDeviceInfos.valueAt(i);
if (!isLocalDeviceAddress(info.getLogicalAddress())) {
infoList.add(info);
}
}
return infoList;
}
|
private java.util.List | getInputDevices()Return a list of external cec input (source) devices.
Note that this effectively excludes non-source devices like system audio,
secondary TV.
ArrayList<HdmiDeviceInfo> infoList = new ArrayList<>();
for (int i = 0; i < mDeviceInfos.size(); ++i) {
HdmiDeviceInfo info = mDeviceInfos.valueAt(i);
if (isLocalDeviceAddress(info.getLogicalAddress())) {
continue;
}
if (info.isSourceType() && !hideDevicesBehindLegacySwitch(info)) {
infoList.add(info);
}
}
return infoList;
|
int | getPortId(int physicalAddress)
return mService.pathToPortId(physicalAddress);
|
int | getPowerStatus()
assertRunOnServiceThread();
return mService.getPowerStatus();
|
protected int | getPreferredAddress()
return Constants.ADDR_TV;
|
int | getPrevPortId()Returns the previous port id kept to handle input switching on .
synchronized (mLock) {
return mPrevPortId;
}
|
android.hardware.hdmi.HdmiDeviceInfo | getSafeAvrDeviceInfo()
return getSafeCecDeviceInfo(Constants.ADDR_AUDIO_SYSTEM);
|
android.hardware.hdmi.HdmiDeviceInfo | getSafeCecDeviceInfo(int logicalAddress)Thread safe version of {@link #getCecDeviceInfo(int)}.
synchronized (mLock) {
for (HdmiDeviceInfo info : mSafeAllDeviceInfos) {
if (info.isCecDevice() && info.getLogicalAddress() == logicalAddress) {
return info;
}
}
return null;
}
|
java.util.List | getSafeCecDevicesLocked()
ArrayList<HdmiDeviceInfo> infoList = new ArrayList<>();
for (HdmiDeviceInfo info : mSafeAllDeviceInfos) {
if (isLocalDeviceAddress(info.getLogicalAddress())) {
continue;
}
infoList.add(info);
}
return infoList;
|
android.hardware.hdmi.HdmiDeviceInfo | getSafeDeviceInfoByPath(int path)Returns the {@link HdmiDeviceInfo} instance whose physical address matches
the given routing path. This is the version accessible safely from threads
other than service thread.
synchronized (mLock) {
for (HdmiDeviceInfo info : mSafeAllDeviceInfos) {
if (info.getPhysicalAddress() == path) {
return info;
}
}
return null;
}
|
java.util.List | getSafeExternalInputsLocked()Return external input devices.
return mSafeExternalInputs;
|
boolean | getSystemAudioModeSetting()
return mService.readBooleanSetting(Global.HDMI_SYSTEM_AUDIO_ENABLED, false);
|
protected boolean | handleActiveSource(HdmiCecMessage message)
assertRunOnServiceThread();
int logicalAddress = message.getSource();
int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
HdmiDeviceInfo info = getCecDeviceInfo(logicalAddress);
if (info == null) {
if (!handleNewDeviceAtTheTailOfActivePath(physicalAddress)) {
HdmiLogger.debug("Device info %X not found; buffering the command", logicalAddress);
mDelayedMessageBuffer.add(message);
}
} else if (!isInputReady(info.getId())) {
HdmiLogger.debug("Input not ready for device: %X; buffering the command", info.getId());
mDelayedMessageBuffer.add(message);
} else {
ActiveSource activeSource = ActiveSource.of(logicalAddress, physicalAddress);
ActiveSourceHandler.create(this, null).process(activeSource, info.getDeviceType());
}
return true;
|
protected boolean | handleGetMenuLanguage(HdmiCecMessage message)
assertRunOnServiceThread();
if (!broadcastMenuLanguage(mService.getLanguage())) {
Slog.w(TAG, "Failed to respond to <Get Menu Language>: " + message.toString());
}
return true;
|
protected boolean | handleImageViewOn(HdmiCecMessage message)
assertRunOnServiceThread();
// Currently, it's the same as <Text View On>.
return handleTextViewOn(message);
|
protected boolean | handleInactiveSource(HdmiCecMessage message)
assertRunOnServiceThread();
// Seq #10
// Ignore <Inactive Source> from non-active source device.
if (getActiveSource().logicalAddress != message.getSource()) {
return true;
}
if (isProhibitMode()) {
return true;
}
int portId = getPrevPortId();
if (portId != Constants.INVALID_PORT_ID) {
// TODO: Do this only if TV is not showing multiview like PIP/PAP.
HdmiDeviceInfo inactiveSource = getCecDeviceInfo(message.getSource());
if (inactiveSource == null) {
return true;
}
if (mService.pathToPortId(inactiveSource.getPhysicalAddress()) == portId) {
return true;
}
// TODO: Switch the TV freeze mode off
doManualPortSwitching(portId, null);
setPrevPortId(Constants.INVALID_PORT_ID);
} else {
// No HDMI port to switch to was found. Notify the input change listers to
// switch to the lastly shown internal input.
mActiveSource.invalidate();
setActivePath(Constants.INVALID_PHYSICAL_ADDRESS);
mService.invokeInputChangeListener(HdmiDeviceInfo.INACTIVE_DEVICE);
}
return true;
|
protected boolean | handleInitiateArc(HdmiCecMessage message)
assertRunOnServiceThread();
if (!canStartArcUpdateAction(message.getSource(), true)) {
if (getAvrDeviceInfo() == null) {
// AVR may not have been discovered yet. Delay the message processing.
mDelayedMessageBuffer.add(message);
return true;
}
mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
if (!isConnectedToArcPort(message.getSource())) {
displayOsd(OSD_MESSAGE_ARC_CONNECTED_INVALID_PORT);
}
return true;
}
// In case where <Initiate Arc> is started by <Request ARC Initiation>
// need to clean up RequestArcInitiationAction.
removeAction(RequestArcInitiationAction.class);
SetArcTransmissionStateAction action = new SetArcTransmissionStateAction(this,
message.getSource(), true);
addAndStartAction(action);
return true;
|
protected boolean | handleMenuStatus(HdmiCecMessage message)
// Do nothing and just return true not to prevent from responding <Feature Abort>.
return true;
|
private boolean | handleNewDeviceAtTheTailOfActivePath(int path)
// Seq #22
if (isTailOfActivePath(path, getActivePath())) {
int newPath = mService.portIdToPath(getActivePortId());
setActivePath(newPath);
startRoutingControl(getActivePath(), newPath, false, null);
return true;
}
return false;
|
protected boolean | handleRecordStatus(HdmiCecMessage message)
// Do nothing.
return true;
|
protected boolean | handleRecordTvScreen(HdmiCecMessage message)
List<OneTouchRecordAction> actions = getActions(OneTouchRecordAction.class);
if (!actions.isEmpty()) {
// Assumes only one OneTouchRecordAction.
OneTouchRecordAction action = actions.get(0);
if (action.getRecorderAddress() != message.getSource()) {
announceOneTouchRecordResult(
message.getSource(),
HdmiControlManager.ONE_TOUCH_RECORD_PREVIOUS_RECORDING_IN_PROGRESS);
}
return super.handleRecordTvScreen(message);
}
int recorderAddress = message.getSource();
byte[] recordSource = mService.invokeRecordRequestListener(recorderAddress);
int reason = startOneTouchRecord(recorderAddress, recordSource);
if (reason != Constants.ABORT_NO_ERROR) {
mService.maySendFeatureAbortCommand(message, reason);
}
return true;
|
void | handleRemoveActiveRoutingPath(int path)
assertRunOnServiceThread();
// Seq #23
if (isTailOfActivePath(path, getActivePath())) {
int newPath = mService.portIdToPath(getActivePortId());
startRoutingControl(getActivePath(), newPath, true, null);
}
|
protected boolean | handleReportAudioStatus(HdmiCecMessage message)
assertRunOnServiceThread();
byte params[] = message.getParams();
int mute = params[0] & 0x80;
int volume = params[0] & 0x7F;
setAudioStatus(mute == 0x80, volume);
return true;
|
protected boolean | handleReportPhysicalAddress(HdmiCecMessage message)
assertRunOnServiceThread();
int path = HdmiUtils.twoBytesToInt(message.getParams());
int address = message.getSource();
int type = message.getParams()[2];
if (updateCecSwitchInfo(address, type, path)) return true;
// Ignore if [Device Discovery Action] is going on.
if (hasAction(DeviceDiscoveryAction.class)) {
Slog.i(TAG, "Ignored while Device Discovery Action is in progress: " + message);
return true;
}
if (!isInDeviceList(address, path)) {
handleNewDeviceAtTheTailOfActivePath(path);
}
// Add the device ahead with default information to handle <Active Source>
// promptly, rather than waiting till the new device action is finished.
HdmiDeviceInfo deviceInfo = new HdmiDeviceInfo(address, path, getPortId(path), type,
Constants.UNKNOWN_VENDOR_ID, HdmiUtils.getDefaultDeviceName(address));
addCecDevice(deviceInfo);
startNewDeviceAction(ActiveSource.of(address, path), type);
return true;
|
protected boolean | handleReportPowerStatus(HdmiCecMessage command)
int newStatus = command.getParams()[0] & 0xFF;
updateDevicePowerStatus(command.getSource(), newStatus);
return true;
|
protected boolean | handleRequestActiveSource(HdmiCecMessage message)
assertRunOnServiceThread();
// Seq #19
if (mAddress == getActiveSource().logicalAddress) {
mService.sendCecCommand(
HdmiCecMessageBuilder.buildActiveSource(mAddress, getActivePath()));
}
return true;
|
protected boolean | handleRoutingChange(HdmiCecMessage message)
assertRunOnServiceThread();
// Seq #21
byte[] params = message.getParams();
int currentPath = HdmiUtils.twoBytesToInt(params);
if (HdmiUtils.isAffectingActiveRoutingPath(getActivePath(), currentPath)) {
mActiveSource.invalidate();
removeAction(RoutingControlAction.class);
int newPath = HdmiUtils.twoBytesToInt(params, 2);
addAndStartAction(new RoutingControlAction(this, newPath, true, null));
}
return true;
|
private void | handleSelectInternalSource()
assertRunOnServiceThread();
// Seq #18
if (mService.isControlEnabled() && mActiveSource.logicalAddress != mAddress) {
updateActiveSource(mAddress, mService.getPhysicalAddress());
if (mSkipRoutingControl) {
mSkipRoutingControl = false;
return;
}
HdmiCecMessage activeSource = HdmiCecMessageBuilder.buildActiveSource(
mAddress, mService.getPhysicalAddress());
mService.sendCecCommand(activeSource);
}
|
protected boolean | handleSetOsdName(HdmiCecMessage message)
int source = message.getSource();
HdmiDeviceInfo deviceInfo = getCecDeviceInfo(source);
// If the device is not in device list, ignore it.
if (deviceInfo == null) {
Slog.e(TAG, "No source device info for <Set Osd Name>." + message);
return true;
}
String osdName = null;
try {
osdName = new String(message.getParams(), "US-ASCII");
} catch (UnsupportedEncodingException e) {
Slog.e(TAG, "Invalid <Set Osd Name> request:" + message, e);
return true;
}
if (deviceInfo.getDisplayName().equals(osdName)) {
Slog.i(TAG, "Ignore incoming <Set Osd Name> having same osd name:" + message);
return true;
}
addCecDevice(new HdmiDeviceInfo(deviceInfo.getLogicalAddress(),
deviceInfo.getPhysicalAddress(), deviceInfo.getPortId(),
deviceInfo.getDeviceType(), deviceInfo.getVendorId(), osdName));
return true;
|
protected boolean | handleSetSystemAudioMode(HdmiCecMessage message)
assertRunOnServiceThread();
if (!isMessageForSystemAudio(message)) {
if (getAvrDeviceInfo() == null) {
// AVR may not have been discovered yet. Delay the message processing.
mDelayedMessageBuffer.add(message);
return true;
}
HdmiLogger.warning("Invalid <Set System Audio Mode> message:" + message);
mService.maySendFeatureAbortCommand(message, Constants.ABORT_REFUSED);
return true;
}
SystemAudioActionFromAvr action = new SystemAudioActionFromAvr(this,
message.getSource(), HdmiUtils.parseCommandParamSystemAudioStatus(message), null);
addAndStartAction(action);
return true;
|
protected boolean | handleSystemAudioModeStatus(HdmiCecMessage message)
assertRunOnServiceThread();
if (!isMessageForSystemAudio(message)) {
HdmiLogger.warning("Invalid <System Audio Mode Status> message:" + message);
// Ignore this message.
return true;
}
setSystemAudioMode(HdmiUtils.parseCommandParamSystemAudioStatus(message), true);
return true;
|
protected boolean | handleTerminateArc(HdmiCecMessage message)
assertRunOnServiceThread();
// In cast of termination, do not check ARC configuration in that AVR device
// might be removed already.
// In case where <Terminate Arc> is started by <Request ARC Termination>
// need to clean up RequestArcInitiationAction.
removeAction(RequestArcTerminationAction.class);
SetArcTransmissionStateAction action = new SetArcTransmissionStateAction(this,
message.getSource(), false);
addAndStartAction(action);
return true;
|
protected boolean | handleTextViewOn(HdmiCecMessage message)
assertRunOnServiceThread();
if (mService.isPowerStandbyOrTransient() && mAutoWakeup) {
mService.wakeUp();
}
return true;
|
protected boolean | handleTimerClearedStatus(HdmiCecMessage message)
byte[] params = message.getParams();
int timerClearedStatusData = params[0] & 0xFF;
announceTimerRecordingResult(message.getSource(), timerClearedStatusData);
return true;
|
protected boolean | handleTimerStatus(HdmiCecMessage message)
// Do nothing.
return true;
|
boolean | hasSystemAudioDevice()
return getSafeAvrDeviceInfo() != null;
|
private boolean | hideDevicesBehindLegacySwitch(android.hardware.hdmi.HdmiDeviceInfo info)
return HdmiConfig.HIDE_DEVICES_BEHIND_LEGACY_SWITCH
&& !isConnectedToCecSwitch(info.getPhysicalAddress(), mCecSwitches);
|
private java.util.List | initLocalDeviceAddresses()
assertRunOnServiceThread();
List<Integer> addresses = new ArrayList<>();
for (HdmiCecLocalDevice device : mService.getAllLocalDevices()) {
addresses.add(device.getDeviceInfo().getLogicalAddress());
}
return Collections.unmodifiableList(addresses);
|
private static void | invokeCallback(android.hardware.hdmi.IHdmiControlCallback callback, int result)
if (callback == null) {
return;
}
try {
callback.onComplete(result);
} catch (RemoteException e) {
Slog.e(TAG, "Invoking callback failed:" + e);
}
|
private void | invokeDeviceEventListener(android.hardware.hdmi.HdmiDeviceInfo info, int status)
if (!hideDevicesBehindLegacySwitch(info)) {
mService.invokeDeviceEventListeners(info, status);
}
|
boolean | isArcEstabilished()Returns whether ARC is enabled or not.
assertRunOnServiceThread();
return mArcFeatureEnabled && mArcEstablished;
|
boolean | isArcFeatureEnabled()
assertRunOnServiceThread();
return mArcFeatureEnabled;
|
private static boolean | isConnectedToCecSwitch(int path, java.util.Collection switches)
for (int switchPath : switches) {
if (isParentPath(switchPath, path)) {
return true;
}
}
return false;
|
private boolean | isDirectConnectAddress(int physicalAddress)
return (physicalAddress & Constants.ROUTING_PATH_TOP_MASK) == physicalAddress;
|
boolean | isInDeviceList(int logicalAddress, int physicalAddress)Whether a device of the specified physical address and logical address exists
in a device info list. However, both are minimal condition and it could
be different device from the original one.
assertRunOnServiceThread();
HdmiDeviceInfo device = getCecDeviceInfo(logicalAddress);
if (device == null) {
return false;
}
return device.getPhysicalAddress() == physicalAddress;
|
protected boolean | isInputReady(int deviceId)
assertRunOnServiceThread();
return mTvInputs.containsValue(deviceId);
|
private boolean | isLocalDeviceAddress(int address)
return mLocalDeviceAddresses.contains(address);
|
private boolean | isMessageForSystemAudio(HdmiCecMessage message)
return mService.isControlEnabled()
&& message.getSource() == Constants.ADDR_AUDIO_SYSTEM
&& (message.getDestination() == Constants.ADDR_TV
|| message.getDestination() == Constants.ADDR_BROADCAST)
&& getAvrDeviceInfo() != null;
|
private static boolean | isParentPath(int parentPath, int childPath)
// (A000, AB00) (AB00, ABC0), (ABC0, ABCD)
// If child's last non-zero nibble is removed, the result equals to the parent.
for (int i = 0; i <= 12; i += 4) {
int nibble = (childPath >> i) & 0xF;
if (nibble != 0) {
int parentNibble = (parentPath >> i) & 0xF;
return parentNibble == 0 && (childPath >> i+4) == (parentPath >> i+4);
}
}
return false;
|
boolean | isPowerStandbyOrTransient()
return mService.isPowerStandbyOrTransient();
|
boolean | isProhibitMode()
return mService.isProhibitMode();
|
boolean | isSystemAudioActivated()
if (!hasSystemAudioDevice()) {
return false;
}
synchronized (mLock) {
return mSystemAudioActivated;
}
|
static boolean | isTailOfActivePath(int path, int activePath)Whether the given path is located in the tail of current active path.
// If active routing path is internal source, return false.
if (activePath == 0) {
return false;
}
for (int i = 12; i >= 0; i -= 4) {
int curActivePath = (activePath >> i) & 0xF;
if (curActivePath == 0) {
return true;
} else {
int curPath = (path >> i) & 0xF;
if (curPath != curActivePath) {
return false;
}
}
}
return false;
|
private void | launchDeviceDiscovery()
assertRunOnServiceThread();
clearDeviceInfoList();
DeviceDiscoveryAction action = new DeviceDiscoveryAction(this,
new DeviceDiscoveryCallback() {
@Override
public void onDeviceDiscoveryDone(List<HdmiDeviceInfo> deviceInfos) {
for (HdmiDeviceInfo info : deviceInfos) {
addCecDevice(info);
}
// Since we removed all devices when it's start and
// device discovery action does not poll local devices,
// we should put device info of local device manually here
for (HdmiCecLocalDevice device : mService.getAllLocalDevices()) {
addCecDevice(device.getDeviceInfo());
}
addAndStartAction(new HotplugDetectionAction(HdmiCecLocalDeviceTv.this));
addAndStartAction(new PowerStatusMonitorAction(HdmiCecLocalDeviceTv.this));
// If there is AVR, initiate System Audio Auto initiation action,
// which turns on and off system audio according to last system
// audio setting.
HdmiDeviceInfo avr = getAvrDeviceInfo();
if (avr != null) {
onNewAvrAdded(avr);
}
}
});
addAndStartAction(action);
|
void | launchRoutingControl(boolean routingForBootup)Launch routing control process.
assertRunOnServiceThread();
// Seq #24
if (getActivePortId() != Constants.INVALID_PORT_ID) {
if (!routingForBootup && !isProhibitMode()) {
int newPath = mService.portIdToPath(getActivePortId());
setActivePath(newPath);
startRoutingControl(getActivePath(), newPath, routingForBootup, null);
}
} else {
int activePath = mService.getPhysicalAddress();
setActivePath(activePath);
if (!routingForBootup
&& !mDelayedMessageBuffer.isBuffered(Constants.MESSAGE_ACTIVE_SOURCE)) {
mService.sendCecCommand(HdmiCecMessageBuilder.buildActiveSource(mAddress,
activePath));
}
}
|
private void | notifyArcStatusToAudioService(boolean enabled)
// Note that we don't set any name to ARC.
mService.getAudioManager().setWiredDeviceConnectionState(
AudioSystem.DEVICE_OUT_HDMI_ARC,
enabled ? 1 : 0, "");
|
protected void | onAddressAllocated(int logicalAddress, int reason)
assertRunOnServiceThread();
mService.registerTvInputCallback(mTvInputCallback);
mService.sendCecCommand(HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
mAddress, mService.getPhysicalAddress(), mDeviceType));
mService.sendCecCommand(HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
mAddress, mService.getVendorId()));
mCecSwitches.add(mService.getPhysicalAddress()); // TV is a CEC switch too.
mTvInputs.clear();
mSkipRoutingControl = (reason == HdmiControlService.INITIATED_BY_WAKE_UP_MESSAGE);
launchRoutingControl(reason != HdmiControlService.INITIATED_BY_ENABLE_CEC &&
reason != HdmiControlService.INITIATED_BY_BOOT_UP);
mLocalDeviceAddresses = initLocalDeviceAddresses();
launchDeviceDiscovery();
startQueuedActions();
|
void | onHotplug(int portId, boolean connected)
assertRunOnServiceThread();
if (!connected) {
removeCecSwitches(portId);
}
// Tv device will have permanent HotplugDetectionAction.
List<HotplugDetectionAction> hotplugActions = getActions(HotplugDetectionAction.class);
if (!hotplugActions.isEmpty()) {
// Note that hotplug action is single action running on a machine.
// "pollAllDevicesNow" cleans up timer and start poll action immediately.
// It covers seq #40, #43.
hotplugActions.get(0).pollAllDevicesNow();
}
updateArcFeatureStatus(portId, connected);
|
void | onNewAvrAdded(android.hardware.hdmi.HdmiDeviceInfo avr)
assertRunOnServiceThread();
if (getSystemAudioModeSetting() && !isSystemAudioActivated()) {
addAndStartAction(new SystemAudioAutoInitiationAction(this, avr.getLogicalAddress()));
}
if (isArcFeatureEnabled() && !hasAction(SetArcTransmissionStateAction.class)) {
startArcAction(true);
}
|
protected void | onStandby(boolean initiatedByCec)
assertRunOnServiceThread();
// Seq #11
if (!mService.isControlEnabled()) {
return;
}
if (!initiatedByCec && mAutoDeviceOff) {
mService.sendCecCommand(HdmiCecMessageBuilder.buildStandby(
mAddress, Constants.ADDR_BROADCAST));
}
|
void | processAllDelayedMessages()
assertRunOnServiceThread();
mDelayedMessageBuffer.processAllMessages();
|
void | processDelayedActiveSource(int address)
assertRunOnServiceThread();
mDelayedMessageBuffer.processActiveSource(address);
|
void | processDelayedMessages(int address)
assertRunOnServiceThread();
mDelayedMessageBuffer.processMessagesForDevice(address);
|
final void | removeCecDevice(int address)Called when a device is removed or removal of device is detected.
assertRunOnServiceThread();
HdmiDeviceInfo info = removeDeviceInfo(HdmiDeviceInfo.idForCecDevice(address));
mCecMessageCache.flushMessagesFrom(address);
invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE);
|
private void | removeCecSwitches(int portId)
Iterator<Integer> it = mCecSwitches.iterator();
while (!it.hasNext()) {
int path = it.next();
if (pathToPortId(path) == portId) {
it.remove();
}
}
|
private android.hardware.hdmi.HdmiDeviceInfo | removeDeviceInfo(int id)Remove a device info corresponding to the given {@code logicalAddress}.
It returns removed {@link HdmiDeviceInfo} if exists.
Declared as package-private. accessed by {@link HdmiControlService} only.
assertRunOnServiceThread();
HdmiDeviceInfo deviceInfo = mDeviceInfos.get(id);
if (deviceInfo != null) {
mDeviceInfos.remove(id);
}
updateSafeDeviceInfoList();
return deviceInfo;
|
private void | removeTvInput(java.lang.String inputId)
assertRunOnServiceThread();
mTvInputs.remove(inputId);
|
private void | sendClearTimerMessage(int recorderAddress, int sourceType, byte[] recordSource)
HdmiCecMessage message = null;
switch (sourceType) {
case TIMER_RECORDING_TYPE_DIGITAL:
message = HdmiCecMessageBuilder.buildClearDigitalTimer(mAddress, recorderAddress,
recordSource);
break;
case TIMER_RECORDING_TYPE_ANALOGUE:
message = HdmiCecMessageBuilder.buildClearAnalogueTimer(mAddress, recorderAddress,
recordSource);
break;
case TIMER_RECORDING_TYPE_EXTERNAL:
message = HdmiCecMessageBuilder.buildClearExternalTimer(mAddress, recorderAddress,
recordSource);
break;
default:
Slog.w(TAG, "Invalid source type:" + recorderAddress);
announceClearTimerRecordingResult(recorderAddress,
CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
return;
}
mService.sendCecCommand(message, new SendMessageCallback() {
@Override
public void onSendCompleted(int error) {
if (error != Constants.SEND_RESULT_SUCCESS) {
announceClearTimerRecordingResult(recorderAddress,
CLEAR_TIMER_STATUS_FAIL_TO_CLEAR_SELECTED_SOURCE);
}
}
});
|
protected void | sendKeyEvent(int keyCode, boolean isPressed)Sends key to a target CEC device.
assertRunOnServiceThread();
if (!HdmiCecKeycode.isSupportedKeycode(keyCode)) {
Slog.w(TAG, "Unsupported key: " + keyCode);
return;
}
List<SendKeyAction> action = getActions(SendKeyAction.class);
int logicalAddress = findKeyReceiverAddress();
if (logicalAddress == mAddress) {
Slog.w(TAG, "Discard key event to itself :" + keyCode + " pressed:" + isPressed);
return;
}
if (!action.isEmpty()) {
action.get(0).processKeyEvent(keyCode, isPressed);
} else {
if (isPressed) {
if (logicalAddress != Constants.ADDR_INVALID) {
addAndStartAction(new SendKeyAction(this, logicalAddress, keyCode));
return;
}
}
Slog.w(TAG, "Discard key event: " + keyCode + " pressed:" + isPressed);
}
|
protected void | sendStandby(int deviceId)
HdmiDeviceInfo targetDevice = mDeviceInfos.get(deviceId);
if (targetDevice == null) {
return;
}
int targetAddress = targetDevice.getLogicalAddress();
mService.sendCecCommand(HdmiCecMessageBuilder.buildStandby(mAddress, targetAddress));
|
boolean | setArcStatus(boolean enabled)Change ARC status into the given {@code enabled} status.
assertRunOnServiceThread();
HdmiLogger.debug("Set Arc Status[old:%b new:%b]", mArcEstablished, enabled);
boolean oldStatus = mArcEstablished;
// 1. Enable/disable ARC circuit.
mService.setAudioReturnChannel(getAvrDeviceInfo().getPortId(), enabled);
// 2. Notify arc status to audio service.
notifyArcStatusToAudioService(enabled);
// 3. Update arc status;
mArcEstablished = enabled;
return oldStatus;
|
void | setAudioStatus(boolean mute, int volume)
synchronized (mLock) {
mSystemAudioMute = mute;
mSystemAudioVolume = volume;
int maxVolume = mService.getAudioManager().getStreamMaxVolume(
AudioManager.STREAM_MUSIC);
mService.setAudioStatus(mute,
VolumeControlAction.scaleToCustomVolume(volume, maxVolume));
displayOsd(HdmiControlManager.OSD_MESSAGE_AVR_VOLUME_CHANGED,
mute ? HdmiControlManager.AVR_VOLUME_MUTED : volume);
}
|
void | setAutoDeviceOff(boolean enabled)
assertRunOnServiceThread();
mAutoDeviceOff = enabled;
|
void | setAutoWakeup(boolean enabled)
assertRunOnServiceThread();
mAutoWakeup = enabled;
|
protected void | setPreferredAddress(int addr)
Slog.w(TAG, "Preferred addres will not be stored for TV");
|
void | setPrevPortId(int portId)Sets the previous port id. INVALID_PORT_ID invalidates it, hence no actions will be
taken for .
synchronized (mLock) {
mPrevPortId = portId;
}
|
void | setSystemAudioMode(boolean on, boolean updateSetting)
HdmiLogger.debug("System Audio Mode change[old:%b new:%b]", mSystemAudioActivated, on);
if (updateSetting) {
mService.writeBooleanSetting(Global.HDMI_SYSTEM_AUDIO_ENABLED, on);
}
updateAudioManagerForSystemAudio(on);
synchronized (mLock) {
if (mSystemAudioActivated != on) {
mSystemAudioActivated = on;
mService.announceSystemAudioModeChange(on);
}
}
|
void | startArcAction(boolean enabled)
assertRunOnServiceThread();
HdmiDeviceInfo info = getAvrDeviceInfo();
if (info == null) {
Slog.w(TAG, "Failed to start arc action; No AVR device.");
return;
}
if (!canStartArcUpdateAction(info.getLogicalAddress(), enabled)) {
Slog.w(TAG, "Failed to start arc action; ARC configuration check failed.");
if (enabled && !isConnectedToArcPort(info.getPhysicalAddress())) {
displayOsd(OSD_MESSAGE_ARC_CONNECTED_INVALID_PORT);
}
return;
}
// Terminate opposite action and start action if not exist.
if (enabled) {
removeAction(RequestArcTerminationAction.class);
if (!hasAction(RequestArcInitiationAction.class)) {
addAndStartAction(new RequestArcInitiationAction(this, info.getLogicalAddress()));
}
} else {
removeAction(RequestArcInitiationAction.class);
if (!hasAction(RequestArcTerminationAction.class)) {
addAndStartAction(new RequestArcTerminationAction(this, info.getLogicalAddress()));
}
}
|
void | startNewDeviceAction(ActiveSource activeSource, int deviceType)
for (NewDeviceAction action : getActions(NewDeviceAction.class)) {
// If there is new device action which has the same logical address and path
// ignore new request.
// NewDeviceAction is created whenever it receives <Report Physical Address>.
// And there is a chance starting NewDeviceAction for the same source.
// Usually, new device sends <Report Physical Address> when it's plugged
// in. However, TV can detect a new device from HotPlugDetectionAction,
// which sends <Give Physical Address> to the source for newly detected
// device.
if (action.isActionOf(activeSource)) {
return;
}
}
addAndStartAction(new NewDeviceAction(this, activeSource.logicalAddress,
activeSource.physicalAddress, deviceType));
|
int | startOneTouchRecord(int recorderAddress, byte[] recordSource)
assertRunOnServiceThread();
if (!mService.isControlEnabled()) {
Slog.w(TAG, "Can not start one touch record. CEC control is disabled.");
announceOneTouchRecordResult(recorderAddress, ONE_TOUCH_RECORD_CEC_DISABLED);
return Constants.ABORT_NOT_IN_CORRECT_MODE;
}
if (!checkRecorder(recorderAddress)) {
Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
announceOneTouchRecordResult(recorderAddress,
ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
return Constants.ABORT_NOT_IN_CORRECT_MODE;
}
if (!checkRecordSource(recordSource)) {
Slog.w(TAG, "Invalid record source." + Arrays.toString(recordSource));
announceOneTouchRecordResult(recorderAddress,
ONE_TOUCH_RECORD_FAIL_TO_RECORD_DISPLAYED_SCREEN);
return Constants.ABORT_CANNOT_PROVIDE_SOURCE;
}
addAndStartAction(new OneTouchRecordAction(this, recorderAddress, recordSource));
Slog.i(TAG, "Start new [One Touch Record]-Target:" + recorderAddress + ", recordSource:"
+ Arrays.toString(recordSource));
return Constants.ABORT_NO_ERROR;
|
void | startRoutingControl(int oldPath, int newPath, boolean queryDevicePowerStatus, android.hardware.hdmi.IHdmiControlCallback callback)
assertRunOnServiceThread();
if (oldPath == newPath) {
return;
}
HdmiCecMessage routingChange =
HdmiCecMessageBuilder.buildRoutingChange(mAddress, oldPath, newPath);
mService.sendCecCommand(routingChange);
removeAction(RoutingControlAction.class);
addAndStartAction(
new RoutingControlAction(this, newPath, queryDevicePowerStatus, callback));
|
void | startTimerRecording(int recorderAddress, int sourceType, byte[] recordSource)
assertRunOnServiceThread();
if (!mService.isControlEnabled()) {
Slog.w(TAG, "Can not start one touch record. CEC control is disabled.");
announceTimerRecordingResult(recorderAddress,
TIMER_RECORDING_RESULT_EXTRA_CEC_DISABLED);
return;
}
if (!checkRecorder(recorderAddress)) {
Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
announceTimerRecordingResult(recorderAddress,
TIMER_RECORDING_RESULT_EXTRA_CHECK_RECORDER_CONNECTION);
return;
}
if (!checkTimerRecordingSource(sourceType, recordSource)) {
Slog.w(TAG, "Invalid record source." + Arrays.toString(recordSource));
announceTimerRecordingResult(
recorderAddress,
TIMER_RECORDING_RESULT_EXTRA_FAIL_TO_RECORD_SELECTED_SOURCE);
return;
}
addAndStartAction(
new TimerRecordingAction(this, recorderAddress, sourceType, recordSource));
Slog.i(TAG, "Start [Timer Recording]-Target:" + recorderAddress + ", SourceType:"
+ sourceType + ", RecordSource:" + Arrays.toString(recordSource));
|
void | stopOneTouchRecord(int recorderAddress)
assertRunOnServiceThread();
if (!mService.isControlEnabled()) {
Slog.w(TAG, "Can not stop one touch record. CEC control is disabled.");
announceOneTouchRecordResult(recorderAddress, ONE_TOUCH_RECORD_CEC_DISABLED);
return;
}
if (!checkRecorder(recorderAddress)) {
Slog.w(TAG, "Invalid recorder address:" + recorderAddress);
announceOneTouchRecordResult(recorderAddress,
ONE_TOUCH_RECORD_CHECK_RECORDER_CONNECTION);
return;
}
// Remove one touch record action so that other one touch record can be started.
removeAction(OneTouchRecordAction.class);
mService.sendCecCommand(HdmiCecMessageBuilder.buildRecordOff(mAddress, recorderAddress));
Slog.i(TAG, "Stop [One Touch Record]-Target:" + recorderAddress);
|
void | updateActiveInput(int path, boolean notifyInputChange)
assertRunOnServiceThread();
// Seq #15
setPrevPortId(getActivePortId());
setActivePath(path);
// TODO: Handle PAP/PIP case.
// Show OSD port change banner
if (notifyInputChange) {
ActiveSource activeSource = getActiveSource();
HdmiDeviceInfo info = getCecDeviceInfo(activeSource.logicalAddress);
if (info == null) {
info = mService.getDeviceInfoByPort(getActivePortId());
if (info == null) {
// No CEC/MHL device is present at the port. Attempt to switch to
// the hardware port itself for non-CEC devices that may be connected.
info = new HdmiDeviceInfo(path, getActivePortId());
}
}
mService.invokeInputChangeListener(info);
}
|
void | updateActiveSource(int logicalAddress, int physicalAddress)
assertRunOnServiceThread();
updateActiveSource(ActiveSource.of(logicalAddress, physicalAddress));
|
void | updateActiveSource(ActiveSource newActive)
assertRunOnServiceThread();
// Seq #14
if (mActiveSource.equals(newActive)) {
return;
}
setActiveSource(newActive);
int logicalAddress = newActive.logicalAddress;
if (getCecDeviceInfo(logicalAddress) != null && logicalAddress != mAddress) {
if (mService.pathToPortId(newActive.physicalAddress) == getActivePortId()) {
setPrevPortId(getActivePortId());
}
// TODO: Show the OSD banner related to the new active source device.
} else {
// TODO: If displayed, remove the OSD banner related to the previous
// active source device.
}
|
private void | updateArcFeatureStatus(int portId, boolean isConnected)
assertRunOnServiceThread();
// HEAC 2.4, HEACT 5-15
// Should not activate ARC if +5V status is false.
HdmiPortInfo portInfo = mService.getPortInfo(portId);
if (portInfo.isArcSupported()) {
changeArcFeatureEnabled(isConnected);
}
|
private void | updateAudioManagerForSystemAudio(boolean on)
int device = mService.getAudioManager().setHdmiSystemAudioSupported(on);
HdmiLogger.debug("[A]UpdateSystemAudio mode[on=%b] output=[%X]", on, device);
|
boolean | updateCecSwitchInfo(int address, int type, int path)
if (address == Constants.ADDR_UNREGISTERED
&& type == HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH) {
mCecSwitches.add(path);
updateSafeDeviceInfoList();
return true; // Pure switch does not need further processing. Return here.
}
if (type == HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
mCecSwitches.add(path);
}
return false;
|
void | updateDevicePowerStatus(int logicalAddress, int newPowerStatus)
HdmiDeviceInfo info = getCecDeviceInfo(logicalAddress);
if (info == null) {
Slog.w(TAG, "Can not update power status of non-existing device:" + logicalAddress);
return;
}
if (info.getDevicePowerStatus() == newPowerStatus) {
return;
}
HdmiDeviceInfo newInfo = HdmiUtils.cloneHdmiDeviceInfo(info, newPowerStatus);
// addDeviceInfo replaces old device info with new one if exists.
addDeviceInfo(newInfo);
invokeDeviceEventListener(newInfo, HdmiControlManager.DEVICE_EVENT_UPDATE_DEVICE);
|
private void | updateSafeDeviceInfoList()
assertRunOnServiceThread();
List<HdmiDeviceInfo> copiedDevices = HdmiUtils.sparseArrayToList(mDeviceInfos);
List<HdmiDeviceInfo> externalInputs = getInputDevices();
synchronized (mLock) {
mSafeAllDeviceInfos = copiedDevices;
mSafeExternalInputs = externalInputs;
}
|