blob: f7e871d0b64526867d8a35e8ddcc204f64dea7f3 [file] [log] [blame]
Jungshik Jang187d0172014-06-17 17:48:42 +09001/*
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
Donghyun Chobc6e3722016-11-04 05:25:52 +090019import android.hardware.tv.cec.V1_0.SendMessageResult;
Jungshik Jang187d0172014-06-17 17:48:42 +090020import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
21
22/**
23 * Action to initiate system audio once AVR is detected on Device discovery action.
24 */
Yuncheol Heoc516d652014-07-11 18:23:24 +090025// Seq #27
Jungshik Jangb509c2e2014-08-07 13:45:01 +090026final class SystemAudioAutoInitiationAction extends HdmiCecFeatureAction {
Jungshik Jang187d0172014-06-17 17:48:42 +090027 private final int mAvrAddress;
28
29 // State that waits for <System Audio Mode Status> once send
30 // <Give System Audio Mode Status> to AV Receiver.
31 private static final int STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS = 1;
32
33 SystemAudioAutoInitiationAction(HdmiCecLocalDevice source, int avrAddress) {
34 super(source);
35 mAvrAddress = avrAddress;
36 }
37
38 @Override
39 boolean start() {
40 mState = STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS;
41
Jinsuk Kim5fba96d2014-07-11 11:51:34 +090042 addTimer(mState, HdmiConfig.TIMEOUT_MS);
Jungshik Jang187d0172014-06-17 17:48:42 +090043 sendGiveSystemAudioModeStatus();
44 return true;
45 }
46
47 private void sendGiveSystemAudioModeStatus() {
48 sendCommand(HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(getSourceAddress(),
49 mAvrAddress), new SendMessageCallback() {
50 @Override
51 public void onSendCompleted(int error) {
Donghyun Chobc6e3722016-11-04 05:25:52 +090052 if (error != SendMessageResult.SUCCESS) {
Kyeongkab.Nambbfca332018-09-14 15:23:03 +090053 handleSystemAudioModeStatusTimeout();
Jungshik Jang187d0172014-06-17 17:48:42 +090054 }
55 }
56 });
57 }
58
59 @Override
60 boolean processCommand(HdmiCecMessage cmd) {
Jungshik Jang5352081c2014-09-22 15:14:49 +090061 if (mState != STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS
62 || mAvrAddress != cmd.getSource()) {
Jungshik Jang187d0172014-06-17 17:48:42 +090063 return false;
64 }
65
Jungshik Jang5352081c2014-09-22 15:14:49 +090066 if (cmd.getOpcode() == Constants.MESSAGE_SYSTEM_AUDIO_MODE_STATUS) {
Donghyun Choc21f63a2016-05-10 10:37:47 +090067 handleSystemAudioModeStatusMessage(HdmiUtils.parseCommandParamSystemAudioStatus(cmd));
Jungshik Jang5352081c2014-09-22 15:14:49 +090068 return true;
Jungshik Jang187d0172014-06-17 17:48:42 +090069 }
Jungshik Jang5352081c2014-09-22 15:14:49 +090070 return false;
Jungshik Jang187d0172014-06-17 17:48:42 +090071 }
72
Donghyun Choc1fa9af2016-12-27 18:31:09 +090073 private void handleSystemAudioModeStatusMessage(boolean currentSystemAudioMode) {
Jungshik Jang7fb8e7f2014-11-06 14:03:15 +090074 if (!canChangeSystemAudio()) {
75 HdmiLogger.debug("Cannot change system audio mode in auto initiation action.");
76 finish();
77 return;
Jungshik Jang187d0172014-06-17 17:48:42 +090078 }
Jungshik Jang7fb8e7f2014-11-06 14:03:15 +090079
Donghyun Choc1fa9af2016-12-27 18:31:09 +090080 // If System Audio Control feature is enabled, turn on system audio mode when new AVR is
81 // detected. Otherwise, turn off system audio mode.
82 boolean targetSystemAudioMode = tv().isSystemAudioControlFeatureEnabled();
83 if (currentSystemAudioMode != targetSystemAudioMode) {
84 // Start System Audio Control feature actions only if necessary.
85 addAndStartAction(
86 new SystemAudioActionFromTv(tv(), mAvrAddress, targetSystemAudioMode, null));
Donghyun Choc21f63a2016-05-10 10:37:47 +090087 } else {
Donghyun Choc1fa9af2016-12-27 18:31:09 +090088 // If AVR already has correct system audio mode, update target system audio mode
89 // immediately rather than starting feature action.
90 tv().setSystemAudioMode(targetSystemAudioMode);
Donghyun Choc21f63a2016-05-10 10:37:47 +090091 }
Jungshik Jang187d0172014-06-17 17:48:42 +090092 finish();
93 }
94
95 @Override
96 void handleTimerEvent(int state) {
97 if (mState != state) {
98 return;
99 }
100
101 switch (mState) {
102 case STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS:
103 handleSystemAudioModeStatusTimeout();
104 break;
105 }
106 }
107
108 private void handleSystemAudioModeStatusTimeout() {
Donghyun Choc1fa9af2016-12-27 18:31:09 +0900109 if (!canChangeSystemAudio()) {
110 HdmiLogger.debug("Cannot change system audio mode in auto initiation action.");
111 finish();
112 return;
Jungshik Jang187d0172014-06-17 17:48:42 +0900113 }
Donghyun Choc1fa9af2016-12-27 18:31:09 +0900114 // If we can't get the current system audio mode status, just try to turn on/off system
115 // audio mode according to the system audio control setting.
116 addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress,
117 tv().isSystemAudioControlFeatureEnabled(), null));
Jungshik Jang187d0172014-06-17 17:48:42 +0900118 finish();
119 }
120
121 private boolean canChangeSystemAudio() {
Jungshik Janga858d222014-06-23 17:17:47 +0900122 return !(tv().hasAction(SystemAudioActionFromTv.class)
123 || tv().hasAction(SystemAudioActionFromAvr.class));
Jungshik Jang187d0172014-06-17 17:48:42 +0900124 }
125}