NewDeviceActionpublic final class NewDeviceAction extends HdmiCecFeatureAction Feature action that discovers the information of a newly found logical device.
This action is created when receiving <Report Physical Address>, a CEC command a newly
connected HDMI-CEC device broadcasts to announce its advent. Additional commands are issued in
this action to gather more information on the device such as OSD name and device vendor ID.
The result is made in the form of {@link HdmiDeviceInfo} object, and passed to service
for the management through its life cycle.
Package-private, accessed by {@link HdmiControlService} only. |
Fields Summary |
---|
private static final String | TAG | static final int | STATE_WAITING_FOR_SET_OSD_NAME | static final int | STATE_WAITING_FOR_DEVICE_VENDOR_ID | private final int | mDeviceLogicalAddress | private final int | mDevicePhysicalAddress | private final int | mDeviceType | private int | mVendorId | private String | mDisplayName | private int | mTimeoutRetry |
Constructors Summary |
---|
NewDeviceAction(HdmiCecLocalDevice source, int deviceLogicalAddress, int devicePhysicalAddress, int deviceType)Constructor.
super(source);
mDeviceLogicalAddress = deviceLogicalAddress;
mDevicePhysicalAddress = devicePhysicalAddress;
mDeviceType = deviceType;
mVendorId = Constants.UNKNOWN_VENDOR_ID;
|
Methods Summary |
---|
private void | addDeviceInfo()
// The device should be in the device list with default information.
if (!tv().isInDeviceList(mDeviceLogicalAddress, mDevicePhysicalAddress)) {
Slog.w(TAG, String.format("Device not found (%02x, %04x)",
mDeviceLogicalAddress, mDevicePhysicalAddress));
return;
}
if (mDisplayName == null) {
mDisplayName = HdmiUtils.getDefaultDeviceName(mDeviceLogicalAddress);
}
HdmiDeviceInfo deviceInfo = new HdmiDeviceInfo(
mDeviceLogicalAddress, mDevicePhysicalAddress,
tv().getPortId(mDevicePhysicalAddress),
mDeviceType, mVendorId, mDisplayName);
tv().addCecDevice(deviceInfo);
// Consume CEC messages we already got for this newly found device.
tv().processDelayedMessages(mDeviceLogicalAddress);
if (HdmiUtils.getTypeFromAddress(mDeviceLogicalAddress)
== HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM) {
tv().onNewAvrAdded(deviceInfo);
}
| public void | handleTimerEvent(int state)
if (mState == STATE_NONE || mState != state) {
return;
}
if (state == STATE_WAITING_FOR_SET_OSD_NAME) {
if (++mTimeoutRetry < HdmiConfig.TIMEOUT_RETRY) {
requestOsdName(false);
return;
}
// Osd name request timed out. Try vendor id
requestVendorId(true);
} else if (state == STATE_WAITING_FOR_DEVICE_VENDOR_ID) {
if (++mTimeoutRetry < HdmiConfig.TIMEOUT_RETRY) {
requestVendorId(false);
return;
}
// vendor id timed out. Go ahead creating the device info what we've got so far.
addDeviceInfo();
finish();
}
| boolean | isActionOf(com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource activeSource)
return (mDeviceLogicalAddress == activeSource.logicalAddress)
&& (mDevicePhysicalAddress == activeSource.physicalAddress);
| private boolean | mayProcessCommandIfCached(int destAddress, int opcode)
HdmiCecMessage message = getCecMessageCache().getMessage(destAddress, opcode);
if (message != null) {
return processCommand(message);
}
return false;
| public boolean | processCommand(HdmiCecMessage cmd)
// For the logical device in interest, we want two more pieces of information -
// osd name and vendor id. They are requested in sequence. In case we don't
// get the expected responses (either by timeout or by receiving <feature abort> command),
// set them to a default osd name and unknown vendor id respectively.
int opcode = cmd.getOpcode();
int src = cmd.getSource();
byte[] params = cmd.getParams();
if (mDeviceLogicalAddress != src) {
return false;
}
if (mState == STATE_WAITING_FOR_SET_OSD_NAME) {
if (opcode == Constants.MESSAGE_SET_OSD_NAME) {
try {
mDisplayName = new String(params, "US-ASCII");
} catch (UnsupportedEncodingException e) {
Slog.e(TAG, "Failed to get OSD name: " + e.getMessage());
}
requestVendorId(true);
return true;
} else if (opcode == Constants.MESSAGE_FEATURE_ABORT) {
int requestOpcode = params[0] & 0xFF;
if (requestOpcode == Constants.MESSAGE_GIVE_OSD_NAME) {
requestVendorId(true);
return true;
}
}
} else if (mState == STATE_WAITING_FOR_DEVICE_VENDOR_ID) {
if (opcode == Constants.MESSAGE_DEVICE_VENDOR_ID) {
mVendorId = HdmiUtils.threeBytesToInt(params);
addDeviceInfo();
finish();
return true;
} else if (opcode == Constants.MESSAGE_FEATURE_ABORT) {
int requestOpcode = params[0] & 0xFF;
if (requestOpcode == Constants.MESSAGE_GIVE_DEVICE_VENDOR_ID) {
addDeviceInfo();
finish();
return true;
}
}
}
return false;
| private void | requestOsdName(boolean firstTry)
if (firstTry) {
mTimeoutRetry = 0;
}
mState = STATE_WAITING_FOR_SET_OSD_NAME;
if (mayProcessCommandIfCached(mDeviceLogicalAddress, Constants.MESSAGE_SET_OSD_NAME)) {
return;
}
sendCommand(HdmiCecMessageBuilder.buildGiveOsdNameCommand(getSourceAddress(),
mDeviceLogicalAddress));
addTimer(mState, HdmiConfig.TIMEOUT_MS);
| private void | requestVendorId(boolean firstTry)
if (firstTry) {
mTimeoutRetry = 0;
}
// At first, transit to waiting status for <Device Vendor Id>.
mState = STATE_WAITING_FOR_DEVICE_VENDOR_ID;
// If the message is already in cache, process it.
if (mayProcessCommandIfCached(mDeviceLogicalAddress,
Constants.MESSAGE_DEVICE_VENDOR_ID)) {
return;
}
sendCommand(HdmiCecMessageBuilder.buildGiveDeviceVendorIdCommand(getSourceAddress(),
mDeviceLogicalAddress));
addTimer(mState, HdmiConfig.TIMEOUT_MS);
| public boolean | start()
requestOsdName(true);
return true;
|
|