FileDocCategorySizeDatePackage
NewDeviceAction.javaAPI DocAndroid 5.1 API8425Thu Mar 12 22:22:42 GMT 2015com.android.server.hdmi

NewDeviceAction

public 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.

param
source {@link HdmiCecLocalDevice} instance
param
deviceLogicalAddress logical address of the device in interest
param
devicePhysicalAddress physical address of the device in interest
param
deviceType type of the device


                                       
       
                
        super(source);
        mDeviceLogicalAddress = deviceLogicalAddress;
        mDevicePhysicalAddress = devicePhysicalAddress;
        mDeviceType = deviceType;
        mVendorId = Constants.UNKNOWN_VENDOR_ID;
    
Methods Summary
private voidaddDeviceInfo()

        // 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 voidhandleTimerEvent(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();
        }
    
booleanisActionOf(com.android.server.hdmi.HdmiCecLocalDevice.ActiveSource activeSource)

        return (mDeviceLogicalAddress == activeSource.logicalAddress)
                && (mDevicePhysicalAddress == activeSource.physicalAddress);
    
private booleanmayProcessCommandIfCached(int destAddress, int opcode)

        HdmiCecMessage message = getCecMessageCache().getMessage(destAddress, opcode);
        if (message != null) {
            return processCommand(message);
        }
        return false;
    
public booleanprocessCommand(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 voidrequestOsdName(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 voidrequestVendorId(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 booleanstart()

        requestOsdName(true);
        return true;