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

DeviceSelectAction

public final class DeviceSelectAction extends HdmiCecFeatureAction
Handles an action that selects a logical device as a new active source. Triggered by {@link HdmiTvClient}, attempts to select the given target device for a new active source. It does its best to wake up the target in standby mode before issuing the command >Set Stream path<.

Fields Summary
private static final String
TAG
private static final int
TIMEOUT_TRANSIT_TO_STANDBY_MS
private static final int
TIMEOUT_POWER_ON_MS
private static final int
LOOP_COUNTER_MAX
private static final int
STATE_WAIT_FOR_REPORT_POWER_STATUS
private static final int
STATE_WAIT_FOR_DEVICE_TO_TRANSIT_TO_STANDBY
private static final int
STATE_WAIT_FOR_DEVICE_POWER_ON
private final android.hardware.hdmi.HdmiDeviceInfo
mTarget
private final android.hardware.hdmi.IHdmiControlCallback
mCallback
private final HdmiCecMessage
mGivePowerStatus
private int
mPowerStatusCounter
Constructors Summary
public DeviceSelectAction(HdmiCecLocalDeviceTv source, android.hardware.hdmi.HdmiDeviceInfo target, android.hardware.hdmi.IHdmiControlCallback callback)
Constructor.

param
source {@link HdmiCecLocalDevice} instance
param
target target logical device that will be a new active source
param
callback callback object


                               
      
                
        super(source);
        mCallback = callback;
        mTarget = target;
        mGivePowerStatus = HdmiCecMessageBuilder.buildGiveDevicePowerStatus(
                getSourceAddress(), getTargetAddress());
    
Methods Summary
intgetTargetAddress()

        return mTarget.getLogicalAddress();
    
private booleanhandleReportPowerStatus(int powerStatus)

        switch (powerStatus) {
            case HdmiControlManager.POWER_STATUS_ON:
                sendSetStreamPath();
                return true;
            case HdmiControlManager.POWER_STATUS_TRANSIENT_TO_STANDBY:
                if (mPowerStatusCounter < 4) {
                    mState = STATE_WAIT_FOR_DEVICE_TO_TRANSIT_TO_STANDBY;
                    addTimer(mState, TIMEOUT_TRANSIT_TO_STANDBY_MS);
                } else {
                    sendSetStreamPath();
                }
                return true;
            case HdmiControlManager.POWER_STATUS_STANDBY:
                if (mPowerStatusCounter == 0) {
                    turnOnDevice();
                } else {
                    sendSetStreamPath();
                }
                return true;
            case HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON:
                if (mPowerStatusCounter < LOOP_COUNTER_MAX) {
                    mState = STATE_WAIT_FOR_DEVICE_POWER_ON;
                    addTimer(mState, TIMEOUT_POWER_ON_MS);
                } else {
                    sendSetStreamPath();
                }
                return true;
        }
        return false;
    
public voidhandleTimerEvent(int timeoutState)

        if (mState != timeoutState) {
            Slog.w(TAG, "Timer in a wrong state. Ignored.");
            return;
        }
        switch (mState) {
            case STATE_WAIT_FOR_REPORT_POWER_STATUS:
                if (tv().isPowerStandbyOrTransient()) {
                    invokeCallback(HdmiControlManager.RESULT_INCORRECT_MODE);
                    finish();
                    return;
                }
                sendSetStreamPath();
                break;
            case STATE_WAIT_FOR_DEVICE_TO_TRANSIT_TO_STANDBY:
            case STATE_WAIT_FOR_DEVICE_POWER_ON:
                mPowerStatusCounter++;
                queryDevicePowerStatus();
                break;
        }
    
private voidinvokeCallback(int result)

        if (mCallback == null) {
            return;
        }
        try {
            mCallback.onComplete(result);
        } catch (RemoteException e) {
            Slog.e(TAG, "Callback failed:" + e);
        }
    
public booleanprocessCommand(HdmiCecMessage cmd)

        if (cmd.getSource() != getTargetAddress()) {
            return false;
        }
        int opcode = cmd.getOpcode();
        byte[] params = cmd.getParams();

        switch (mState) {
            case STATE_WAIT_FOR_REPORT_POWER_STATUS:
                if (opcode == Constants.MESSAGE_REPORT_POWER_STATUS) {
                    return handleReportPowerStatus(params[0]);
                }
                return false;
            default:
                break;
        }
        return false;
    
private voidqueryDevicePowerStatus()

        sendCommand(mGivePowerStatus, new SendMessageCallback() {
            @Override
            public void onSendCompleted(int error) {
                if (error != Constants.SEND_RESULT_SUCCESS) {
                    invokeCallback(HdmiControlManager.RESULT_COMMUNICATION_FAILED);
                    finish();
                    return;
                }
            }
        });
        mState = STATE_WAIT_FOR_REPORT_POWER_STATUS;
        addTimer(mState, HdmiConfig.TIMEOUT_MS);
    
private voidsendSetStreamPath()

        // Turn the active source invalidated, which remains so till <Active Source> comes from
        // the selected device.
        tv().getActiveSource().invalidate();
        tv().setActivePath(mTarget.getPhysicalAddress());
        sendCommand(HdmiCecMessageBuilder.buildSetStreamPath(
                getSourceAddress(), mTarget.getPhysicalAddress()));
        invokeCallback(HdmiControlManager.RESULT_SUCCESS);
        finish();
    
public booleanstart()

        // Seq #9
        queryDevicePowerStatus();
        return true;
    
private voidturnOnDevice()

        sendUserControlPressedAndReleased(mTarget.getLogicalAddress(),
                HdmiCecKeycode.CEC_KEYCODE_POWER);
        sendUserControlPressedAndReleased(mTarget.getLogicalAddress(),
                HdmiCecKeycode.CEC_KEYCODE_POWER_ON_FUNCTION);
        mState = STATE_WAIT_FOR_DEVICE_POWER_ON;
        addTimer(mState, TIMEOUT_POWER_ON_MS);