Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 929400f6 authored by Amy's avatar Amy Committed by Amy Zhang
Browse files

Fix Detect TV System Audio Mode Support Action

Fix the following issues

1. The Action should not override the mState, otherwise the mState in
the parent class will be STATE_NONE forever and be treated as a not
started queue Action. This will cause duplicate Action start

2. If the TV responds FEATURE ABORT with reason NOT IN THE CORRECT MODE,
the Action should have retry logic to wait until the TV is ready

3. Added some HdmiUtils funtions to handle the feature abort message
parsing

Test: manual
Bug: 130293139
Change-Id: I06aea06d5c830e52f5aaa46426dbc35c86bfcd5e
(cherry picked from commit ae50376b23aeaf218acf9e45e5d174caecb56ab3)
parent 78dc908e
Loading
Loading
Loading
Loading
+88 −0
Original line number Diff line number Diff line
@@ -86,6 +86,82 @@ final class Constants {
    /** Logical address used to indicate the source comes from internal device. */
    public static final int ADDR_INTERNAL = HdmiDeviceInfo.ADDR_INTERNAL;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
        MESSAGE_FEATURE_ABORT,
        MESSAGE_IMAGE_VIEW_ON,
        MESSAGE_TUNER_STEP_INCREMENT,
        MESSAGE_TUNER_STEP_DECREMENT,
        MESSAGE_TUNER_DEVICE_STATUS,
        MESSAGE_GIVE_TUNER_DEVICE_STATUS,
        MESSAGE_RECORD_ON,
        MESSAGE_RECORD_STATUS,
        MESSAGE_RECORD_OFF,
        MESSAGE_TEXT_VIEW_ON,
        MESSAGE_RECORD_TV_SCREEN,
        MESSAGE_GIVE_DECK_STATUS,
        MESSAGE_DECK_STATUS,
        MESSAGE_SET_MENU_LANGUAGE,
        MESSAGE_CLEAR_ANALOG_TIMER,
        MESSAGE_SET_ANALOG_TIMER,
        MESSAGE_TIMER_STATUS,
        MESSAGE_STANDBY,
        MESSAGE_PLAY,
        MESSAGE_DECK_CONTROL,
        MESSAGE_TIMER_CLEARED_STATUS,
        MESSAGE_USER_CONTROL_PRESSED,
        MESSAGE_USER_CONTROL_RELEASED,
        MESSAGE_GIVE_OSD_NAME,
        MESSAGE_SET_OSD_NAME,
        MESSAGE_SET_OSD_STRING,
        MESSAGE_SET_TIMER_PROGRAM_TITLE,
        MESSAGE_SYSTEM_AUDIO_MODE_REQUEST,
        MESSAGE_GIVE_AUDIO_STATUS,
        MESSAGE_SET_SYSTEM_AUDIO_MODE,
        MESSAGE_REPORT_AUDIO_STATUS,
        MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS,
        MESSAGE_SYSTEM_AUDIO_MODE_STATUS,
        MESSAGE_ROUTING_CHANGE,
        MESSAGE_ROUTING_INFORMATION,
        MESSAGE_ACTIVE_SOURCE,
        MESSAGE_GIVE_PHYSICAL_ADDRESS,
        MESSAGE_REPORT_PHYSICAL_ADDRESS,
        MESSAGE_REQUEST_ACTIVE_SOURCE,
        MESSAGE_SET_STREAM_PATH,
        MESSAGE_DEVICE_VENDOR_ID,
        MESSAGE_VENDOR_COMMAND,
        MESSAGE_VENDOR_REMOTE_BUTTON_DOWN,
        MESSAGE_VENDOR_REMOTE_BUTTON_UP,
        MESSAGE_GIVE_DEVICE_VENDOR_ID,
        MESSAGE_MENU_REQUEST,
        MESSAGE_MENU_STATUS,
        MESSAGE_GIVE_DEVICE_POWER_STATUS,
        MESSAGE_REPORT_POWER_STATUS,
        MESSAGE_GET_MENU_LANGUAGE,
        MESSAGE_SELECT_ANALOG_SERVICE,
        MESSAGE_SELECT_DIGITAL_SERVICE,
        MESSAGE_SET_DIGITAL_TIMER,
        MESSAGE_CLEAR_DIGITAL_TIMER,
        MESSAGE_SET_AUDIO_RATE,
        MESSAGE_INACTIVE_SOURCE,
        MESSAGE_CEC_VERSION,
        MESSAGE_GET_CEC_VERSION,
        MESSAGE_VENDOR_COMMAND_WITH_ID,
        MESSAGE_CLEAR_EXTERNAL_TIMER,
        MESSAGE_SET_EXTERNAL_TIMER,
        MESSAGE_REPORT_SHORT_AUDIO_DESCRIPTOR,
        MESSAGE_REQUEST_SHORT_AUDIO_DESCRIPTOR,
        MESSAGE_INITIATE_ARC,
        MESSAGE_REPORT_ARC_INITIATED,
        MESSAGE_REPORT_ARC_TERMINATED,
        MESSAGE_REQUEST_ARC_INITIATION,
        MESSAGE_REQUEST_ARC_TERMINATION,
        MESSAGE_TERMINATE_ARC,
        MESSAGE_CDC_MESSAGE,
        MESSAGE_ABORT,
    })
    public @interface FeatureOpcode {}

    static final int MESSAGE_FEATURE_ABORT = 0x00;
    static final int MESSAGE_IMAGE_VIEW_ON = 0x04;
    static final int MESSAGE_TUNER_STEP_INCREMENT = 0x05;
@@ -163,6 +239,18 @@ final class Constants {
    static final int TRUE = 1;
    static final int FALSE = 0;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef({
        ABORT_NO_ERROR,
        ABORT_UNRECOGNIZED_OPCODE,
        ABORT_NOT_IN_CORRECT_MODE,
        ABORT_CANNOT_PROVIDE_SOURCE,
        ABORT_INVALID_OPERAND,
        ABORT_REFUSED,
        ABORT_UNABLE_TO_DETERMINE,
    })
    public @interface AbortReason {}

    // Internal abort error code. It's the same as success.
    static final int ABORT_NO_ERROR = -1;
    // Constants related to operands of HDMI CEC commands.
+22 −3
Original line number Diff line number Diff line
@@ -26,9 +26,11 @@ public class DetectTvSystemAudioModeSupportAction extends HdmiCecFeatureAction {

    // State that waits for <Active Source> once send <Request Active Source>.
    private static final int STATE_WAITING_FOR_FEATURE_ABORT = 1;
    private static final int STATE_WAITING_FOR_SET_SAM = 2;
    private int mSendSetSystemAudioModeRetryCount = 0;
    static final int MAX_RETRY_COUNT = 5;

    private TvSystemAudioModeSupportedCallback mCallback;
    private int mState;

    DetectTvSystemAudioModeSupportAction(HdmiCecLocalDevice source,
            TvSystemAudioModeSupportedCallback callback) {
@@ -50,8 +52,13 @@ public class DetectTvSystemAudioModeSupportAction extends HdmiCecFeatureAction {
            if (mState != STATE_WAITING_FOR_FEATURE_ABORT) {
                return false;
            }
            if ((cmd.getParams()[0] & 0xFF) == Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE) {
            if (HdmiUtils.getAbortFeatureOpcode(cmd) == Constants.MESSAGE_SET_SYSTEM_AUDIO_MODE) {
                if(HdmiUtils.getAbortReason(cmd) == Constants.ABORT_NOT_IN_CORRECT_MODE) {
                    mActionTimer.clearTimerMessage();
                    mState = STATE_WAITING_FOR_SET_SAM;
                } else {
                    finishAction(false);
                }
                return true;
            }
        }
@@ -68,6 +75,18 @@ public class DetectTvSystemAudioModeSupportAction extends HdmiCecFeatureAction {
            case STATE_WAITING_FOR_FEATURE_ABORT:
                finishAction(true);
                break;
            case STATE_WAITING_FOR_SET_SAM:
                mSendSetSystemAudioModeRetryCount++;
                if (mSendSetSystemAudioModeRetryCount < MAX_RETRY_COUNT) {
                    mState = STATE_WAITING_FOR_FEATURE_ABORT;
                    addTimer(mState, HdmiConfig.TIMEOUT_MS);
                    sendSetSystemAudioMode();
                } else {
                    finishAction(false);
                }
                break;
            default:
                return;
        }
    }

+25 −1
Original line number Diff line number Diff line
@@ -24,8 +24,10 @@ import android.util.Xml;

import com.android.internal.util.HexDump;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.hdmi.Constants.AudioCodec;

import com.android.server.hdmi.Constants.AbortReason;
import com.android.server.hdmi.Constants.AudioCodec;
import com.android.server.hdmi.Constants.FeatureOpcode;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

@@ -457,6 +459,28 @@ final class HdmiUtils {
        return port;
    }

    /**
     * Parse the Feature Abort CEC message parameter into a [Feature Opcode].
     *
     * @param cmd the CEC message to parse
     * @return the original opcode of the cec message that got aborted.
     */
    @FeatureOpcode
    static int getAbortFeatureOpcode(HdmiCecMessage cmd) {
        return cmd.getParams()[0] & 0xFF;
    }

    /**
     * Parse the Feature Abort CEC message parameter into an [Abort Reason].
     *
     * @param cmd the CEC message to parse
     * @return The reason to abort the feature.
     */
    @AbortReason
    static int getAbortReason(HdmiCecMessage cmd) {
        return cmd.getParams()[1];
    }

    public static class ShortAudioDescriptorXmlParser {
        // We don't use namespaces
        private static final String NS = null;