1187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang/*
2187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang * Copyright (C) 2014 The Android Open Source Project
3187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang *
4187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang * Licensed under the Apache License, Version 2.0 (the "License");
5187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang * you may not use this file except in compliance with the License.
6187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang * You may obtain a copy of the License at
7187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang *
8187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang *      http://www.apache.org/licenses/LICENSE-2.0
9187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang *
10187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang * Unless required by applicable law or agreed to in writing, software
11187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang * distributed under the License is distributed on an "AS IS" BASIS,
12187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang * See the License for the specific language governing permissions and
14187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang * limitations under the License.
15187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang */
16187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
17187d01765b935d07936f74343b4f4af590c239a1Jungshik Jangpackage com.android.server.hdmi;
18187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
19187d01765b935d07936f74343b4f4af590c239a1Jungshik Jangimport com.android.server.hdmi.HdmiControlService.SendMessageCallback;
20187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
21187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang/**
22187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang * Action to initiate system audio once AVR is detected on Device discovery action.
23187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang */
24c516d65fd96cdc39f9935ddb80d26ee6499a77bfYuncheol Heo// Seq #27
25b509c2ecd99619248b7a07fb0fa978bb27f25cc3Jungshik Jangfinal class SystemAudioAutoInitiationAction extends HdmiCecFeatureAction {
26187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    private final int mAvrAddress;
27187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
28187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    // State that waits for <System Audio Mode Status> once send
29187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    // <Give System Audio Mode Status> to AV Receiver.
30187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    private static final int STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS = 1;
31187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
32187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    SystemAudioAutoInitiationAction(HdmiCecLocalDevice source, int avrAddress) {
33187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        super(source);
34187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        mAvrAddress = avrAddress;
35187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    }
36187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
37187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    @Override
38187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    boolean start() {
39187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        mState = STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS;
40187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
415fba96df30b6b50b3cb9fe1d783320b1cc3bd6eaJinsuk Kim        addTimer(mState, HdmiConfig.TIMEOUT_MS);
42187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        sendGiveSystemAudioModeStatus();
43187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        return true;
44187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    }
45187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
46187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    private void sendGiveSystemAudioModeStatus() {
47187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        sendCommand(HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(getSourceAddress(),
48187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang                mAvrAddress), new SendMessageCallback() {
49187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang            @Override
50187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang            public void onSendCompleted(int error) {
51c0c20d0522d7756d80f011e7a54bf3b51c78df41Jinsuk Kim                if (error != Constants.SEND_RESULT_SUCCESS) {
527ecfbaed6e902aea151bc1919cf7771bbd868fc4Jinsuk Kim                    tv().setSystemAudioMode(false, true);
53187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang                    finish();
54187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang                }
55187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang            }
56187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        });
57187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    }
58187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
59187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    @Override
60187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    boolean processCommand(HdmiCecMessage cmd) {
615352081c662299b618335bf3024058fa04ef2dfdJungshik Jang        if (mState != STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS
625352081c662299b618335bf3024058fa04ef2dfdJungshik Jang                || mAvrAddress != cmd.getSource()) {
63187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang            return false;
64187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        }
65187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
665352081c662299b618335bf3024058fa04ef2dfdJungshik Jang        if (cmd.getOpcode() == Constants.MESSAGE_SYSTEM_AUDIO_MODE_STATUS) {
675352081c662299b618335bf3024058fa04ef2dfdJungshik Jang            handleSystemAudioModeStatusMessage();
685352081c662299b618335bf3024058fa04ef2dfdJungshik Jang            return true;
69187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        }
705352081c662299b618335bf3024058fa04ef2dfdJungshik Jang        return false;
71187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    }
72187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
73187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    private void handleSystemAudioModeStatusMessage() {
747fb8e7f4ff524f9131a387efc2649aa78e4ae376Jungshik Jang        if (!canChangeSystemAudio()) {
757fb8e7f4ff524f9131a387efc2649aa78e4ae376Jungshik Jang            HdmiLogger.debug("Cannot change system audio mode in auto initiation action.");
767fb8e7f4ff524f9131a387efc2649aa78e4ae376Jungshik Jang            finish();
777fb8e7f4ff524f9131a387efc2649aa78e4ae376Jungshik Jang            return;
78187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        }
797fb8e7f4ff524f9131a387efc2649aa78e4ae376Jungshik Jang
807fb8e7f4ff524f9131a387efc2649aa78e4ae376Jungshik Jang        boolean systemAudioModeSetting = tv().getSystemAudioModeSetting();
817fb8e7f4ff524f9131a387efc2649aa78e4ae376Jungshik Jang        // Update AVR's system audio mode regardless of AVR's status.
827fb8e7f4ff524f9131a387efc2649aa78e4ae376Jungshik Jang        addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, systemAudioModeSetting,
837fb8e7f4ff524f9131a387efc2649aa78e4ae376Jungshik Jang                null));
84187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        finish();
85187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    }
86187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
87187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    @Override
88187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    void handleTimerEvent(int state) {
89187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        if (mState != state) {
90187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang            return;
91187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        }
92187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
93187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        switch (mState) {
94187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang            case STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS:
95187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang                handleSystemAudioModeStatusTimeout();
96187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang                break;
97187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        }
98187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    }
99187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
100187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    private void handleSystemAudioModeStatusTimeout() {
101377dcbd53af4529c352d453424539b069909fce4Jungshik Jang        if (tv().getSystemAudioModeSetting()) {
102187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang            if (canChangeSystemAudio()) {
1037f0a1c54a837da7ebbb6f7eb56f44894e0df22c2Jungshik Jang                addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, true, null));
104187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang            }
105187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        } else {
1067ecfbaed6e902aea151bc1919cf7771bbd868fc4Jinsuk Kim            tv().setSystemAudioMode(false, true);
107187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        }
108187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang        finish();
109187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    }
110187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang
111187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    private boolean canChangeSystemAudio() {
112a858d221ff86c497e745222ea15bab141e337636Jungshik Jang        return !(tv().hasAction(SystemAudioActionFromTv.class)
113a858d221ff86c497e745222ea15bab141e337636Jungshik Jang               || tv().hasAction(SystemAudioActionFromAvr.class));
114187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang    }
115187d01765b935d07936f74343b4f4af590c239a1Jungshik Jang}
116