SystemAudioAutoInitiationAction.java revision 187d01765b935d07936f74343b4f4af590c239a1
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 android.hardware.hdmi.HdmiCec;
20import android.hardware.hdmi.HdmiCecMessage;
21
22import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
23
24/**
25 * Action to initiate system audio once AVR is detected on Device discovery action.
26 */
27final class SystemAudioAutoInitiationAction extends FeatureAction {
28    private final int mAvrAddress;
29
30    // State that waits for <System Audio Mode Status> once send
31    // <Give System Audio Mode Status> to AV Receiver.
32    private static final int STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS = 1;
33
34    SystemAudioAutoInitiationAction(HdmiCecLocalDevice source, int avrAddress) {
35        super(source);
36        mAvrAddress = avrAddress;
37    }
38
39    @Override
40    boolean start() {
41        mState = STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS;
42
43        addTimer(mState, TIMEOUT_MS);
44        sendGiveSystemAudioModeStatus();
45        return true;
46    }
47
48    private void sendGiveSystemAudioModeStatus() {
49        sendCommand(HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(getSourceAddress(),
50                mAvrAddress), new SendMessageCallback() {
51            @Override
52            public void onSendCompleted(int error) {
53                if (error != HdmiConstants.SEND_RESULT_SUCCESS) {
54                    tv().setSystemAudioMode(false);
55                    finish();
56                }
57            }
58        });
59    }
60
61    @Override
62    boolean processCommand(HdmiCecMessage cmd) {
63        if (mState != STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS) {
64            return false;
65        }
66
67        switch (cmd.getOpcode()) {
68            case HdmiCec.MESSAGE_SYSTEM_AUDIO_MODE_STATUS:
69                handleSystemAudioModeStatusMessage();
70                return true;
71            default:
72                return false;
73        }
74    }
75
76    private void handleSystemAudioModeStatusMessage() {
77        // If the last setting is system audio, turn on system audio whatever AVR status is.
78        if (tv().getSystemAudioMode()) {
79            if (canChangeSystemAudio()) {
80                addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, true));
81            }
82        } else {
83            // If the last setting is non-system audio, turn off system audio mode
84            // and update system audio status (volume or mute).
85            tv().setSystemAudioMode(false);
86            if (canChangeSystemAudio()) {
87                addAndStartAction(new SystemAudioStatusAction(tv(), mAvrAddress));
88            }
89        }
90        finish();
91    }
92
93    @Override
94    void handleTimerEvent(int state) {
95        if (mState != state) {
96            return;
97        }
98
99        switch (mState) {
100            case STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS:
101                handleSystemAudioModeStatusTimeout();
102                break;
103        }
104    }
105
106    private void handleSystemAudioModeStatusTimeout() {
107        if (tv().getSystemAudioMode()) {
108            if (canChangeSystemAudio()) {
109                addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, true));
110            }
111        } else {
112            tv().setSystemAudioMode(false);
113        }
114        finish();
115    }
116
117    private boolean canChangeSystemAudio() {
118        return tv().canChangeSystemAudio();
119    }
120}
121