SystemAudioAutoInitiationAction.java revision 377dcbd53af4529c352d453424539b069909fce4
1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.hdmi;
18
19import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
20
21/**
22 * Action to initiate system audio once AVR is detected on Device discovery action.
23 */
24// Seq #27
25final class SystemAudioAutoInitiationAction extends FeatureAction {
26    private final int mAvrAddress;
27
28    // State that waits for <System Audio Mode Status> once send
29    // <Give System Audio Mode Status> to AV Receiver.
30    private static final int STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS = 1;
31
32    SystemAudioAutoInitiationAction(HdmiCecLocalDevice source, int avrAddress) {
33        super(source);
34        mAvrAddress = avrAddress;
35    }
36
37    @Override
38    boolean start() {
39        mState = STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS;
40
41        addTimer(mState, HdmiConfig.TIMEOUT_MS);
42        sendGiveSystemAudioModeStatus();
43        return true;
44    }
45
46    private void sendGiveSystemAudioModeStatus() {
47        sendCommand(HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(getSourceAddress(),
48                mAvrAddress), new SendMessageCallback() {
49            @Override
50            public void onSendCompleted(int error) {
51                if (error != Constants.SEND_RESULT_SUCCESS) {
52                    tv().setSystemAudioMode(false, true);
53                    finish();
54                }
55            }
56        });
57    }
58
59    @Override
60    boolean processCommand(HdmiCecMessage cmd) {
61        if (mState != STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS) {
62            return false;
63        }
64
65        switch (cmd.getOpcode()) {
66            case Constants.MESSAGE_SYSTEM_AUDIO_MODE_STATUS:
67                handleSystemAudioModeStatusMessage();
68                return true;
69            default:
70                return false;
71        }
72    }
73
74    private void handleSystemAudioModeStatusMessage() {
75        // If the last setting is system audio, turn on system audio whatever AVR status is.
76        if (tv().getSystemAudioModeSetting()) {
77            if (canChangeSystemAudio()) {
78                addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, true, null));
79            }
80        } else {
81            // If the last setting is non-system audio, turn off system audio mode
82            // and update system audio status (volume or mute).
83            tv().setSystemAudioMode(false, true);
84            if (canChangeSystemAudio()) {
85                addAndStartAction(new SystemAudioStatusAction(tv(), mAvrAddress, null));
86            }
87        }
88        finish();
89    }
90
91    @Override
92    void handleTimerEvent(int state) {
93        if (mState != state) {
94            return;
95        }
96
97        switch (mState) {
98            case STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS:
99                handleSystemAudioModeStatusTimeout();
100                break;
101        }
102    }
103
104    private void handleSystemAudioModeStatusTimeout() {
105        if (tv().getSystemAudioModeSetting()) {
106            if (canChangeSystemAudio()) {
107                addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, true, null));
108            }
109        } else {
110            tv().setSystemAudioMode(false, true);
111        }
112        finish();
113    }
114
115    private boolean canChangeSystemAudio() {
116        return !(tv().hasAction(SystemAudioActionFromTv.class)
117               || tv().hasAction(SystemAudioActionFromAvr.class));
118    }
119}
120