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

SystemAudioAction

public abstract class SystemAudioAction extends HdmiCecFeatureAction
Base feature action class for SystemAudioActionFromTv and SystemAudioActionFromAvr.

Fields Summary
private static final String
TAG
private static final int
STATE_CHECK_ROUTING_IN_PRGRESS
private static final int
STATE_WAIT_FOR_SET_SYSTEM_AUDIO_MODE
private static final int
MAX_SEND_RETRY_COUNT
private static final int
ON_TIMEOUT_MS
private static final int
OFF_TIMEOUT_MS
protected final int
mAvrLogicalAddress
protected boolean
mTargetAudioStatus
private final android.hardware.hdmi.IHdmiControlCallback
mCallback
private int
mSendRetryCount
Constructors Summary
SystemAudioAction(HdmiCecLocalDevice source, int avrAddress, boolean targetStatus, android.hardware.hdmi.IHdmiControlCallback callback)
Constructor

param
source {@link HdmiCecLocalDevice} instance
param
avrAddress logical address of AVR device
param
targetStatus Whether to enable the system audio mode or not
param
callback callback interface to be notified when it's done
throw
IllegalArugmentException if device type of sourceAddress and avrAddress is invalid


                                                      
         
              
        super(source);
        HdmiUtils.verifyAddressType(avrAddress, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
        mAvrLogicalAddress = avrAddress;
        mTargetAudioStatus = targetStatus;
        mCallback = callback;
    
Methods Summary
protected voidfinishWithCallback(int returnCode)

        if (mCallback != null) {
            try {
                mCallback.onComplete(returnCode);
            } catch (RemoteException e) {
                Slog.e(TAG, "Failed to invoke callback.", e);
            }
        }
        finish();
    
private intgetSystemAudioModeRequestParam()

        // <System Audio Mode Request> takes the physical address of the source device
        // as a parameter. Get it from following candidates, in the order listed below:
        // 1) physical address of the active source
        // 2) active routing path
        // 3) physical address of TV
        if (tv().getActiveSource().isValid()) {
            return tv().getActiveSource().physicalAddress;
        }
        int param = tv().getActivePath();
        return param != Constants.INVALID_PHYSICAL_ADDRESS
                ? param : Constants.PATH_INTERNAL;
    
private voidhandleSendSystemAudioModeRequestTimeout()

        if (!mTargetAudioStatus  // Don't retry for Off case.
                || mSendRetryCount++ >= MAX_SEND_RETRY_COUNT) {
            HdmiLogger.debug("[T]:wait for <Set System Audio Mode>.");
            setSystemAudioMode(false);
            finishWithCallback(HdmiControlManager.RESULT_TIMEOUT);
            return;
        }
        sendSystemAudioModeRequest();
    
final voidhandleTimerEvent(int state)

        if (mState != state) {
            return;
        }
        switch (mState) {
            case STATE_WAIT_FOR_SET_SYSTEM_AUDIO_MODE:
                handleSendSystemAudioModeRequestTimeout();
                return;
        }
    
final booleanprocessCommand(HdmiCecMessage cmd)

        if (cmd.getSource() != mAvrLogicalAddress) {
            return false;
        }
        switch (mState) {
            case STATE_WAIT_FOR_SET_SYSTEM_AUDIO_MODE:
                if (cmd.getOpcode() == Constants.MESSAGE_FEATURE_ABORT
                        && (cmd.getParams()[0] & 0xFF)
                                == Constants.MESSAGE_SYSTEM_AUDIO_MODE_REQUEST) {
                    HdmiLogger.debug("Failed to start system audio mode request.");
                    setSystemAudioMode(false);
                    finishWithCallback(HdmiControlManager.RESULT_EXCEPTION);
                    return true;
                }
                if (cmd.getOpcode() != Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE
                        || !HdmiUtils.checkCommandSource(cmd, mAvrLogicalAddress, TAG)) {
                    return false;
                }
                boolean receivedStatus = HdmiUtils.parseCommandParamSystemAudioStatus(cmd);
                if (receivedStatus == mTargetAudioStatus) {
                    setSystemAudioMode(receivedStatus);
                    startAudioStatusAction();
                    return true;
                } else {
                    HdmiLogger.debug("Unexpected system audio mode request:" + receivedStatus);
                    // Unexpected response, consider the request is newly initiated by AVR.
                    // To return 'false' will initiate new SystemAudioActionFromAvr by the control
                    // service.
                    finishWithCallback(HdmiControlManager.RESULT_EXCEPTION);
                    return false;
                }
            default:
                return false;
        }
    
protected voidremoveSystemAudioActionInProgress()

        removeActionExcept(SystemAudioActionFromTv.class, this);
        removeActionExcept(SystemAudioActionFromAvr.class, this);
    
protected voidsendSystemAudioModeRequest()

        List<RoutingControlAction> routingActions = getActions(RoutingControlAction.class);
        if (!routingActions.isEmpty()) {
            mState = STATE_CHECK_ROUTING_IN_PRGRESS;
            // Should have only one Routing Control Action
            RoutingControlAction routingAction = routingActions.get(0);
            routingAction.addOnFinishedCallback(this, new Runnable() {
                @Override
                public void run() {
                    sendSystemAudioModeRequestInternal();
                }
            });
            return;
        }
        sendSystemAudioModeRequestInternal();
    
private voidsendSystemAudioModeRequestInternal()

        HdmiCecMessage command = HdmiCecMessageBuilder.buildSystemAudioModeRequest(
                getSourceAddress(),
                mAvrLogicalAddress, getSystemAudioModeRequestParam(), mTargetAudioStatus);
        sendCommand(command, new HdmiControlService.SendMessageCallback() {
            @Override
            public void onSendCompleted(int error) {
                if (error != Constants.SEND_RESULT_SUCCESS) {
                    HdmiLogger.debug("Failed to send <System Audio Mode Request>:" + error);
                    setSystemAudioMode(false);
                    finishWithCallback(HdmiControlManager.RESULT_COMMUNICATION_FAILED);
                }
            }
        });
        mState = STATE_WAIT_FOR_SET_SYSTEM_AUDIO_MODE;
        addTimer(mState, mTargetAudioStatus ? ON_TIMEOUT_MS : OFF_TIMEOUT_MS);
    
protected voidsetSystemAudioMode(boolean mode)

        tv().setSystemAudioMode(mode, true);
    
protected voidstartAudioStatusAction()

        addAndStartAction(new SystemAudioStatusAction(tv(), mAvrLogicalAddress, mCallback));
        finish();