blob: dedf2e28a573167619e647fe783404b0cb3df8cd [file] [log] [blame]
Amy21674272018-07-24 16:28:34 -07001/*
2 * Copyright (C) 2018 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 */
16package com.android.server.hdmi;
17
18import android.hardware.tv.cec.V1_0.SendMessageResult;
19
20/**
21 * Feature action that handles Audio Return Channel terminated by AVR devices.
22 */
23public class ArcTerminationActionFromAvr extends HdmiCecFeatureAction {
24
25 // State in which waits for ARC response.
26 private static final int STATE_WAITING_FOR_INITIATE_ARC_RESPONSE = 1;
27 private static final int STATE_ARC_TERMINATED = 2;
28
29 // the required maximum response time specified in CEC 9.2
30 private static final int TIMEOUT_MS = 1000;
31
32 ArcTerminationActionFromAvr(HdmiCecLocalDevice source) {
33 super(source);
34 }
35
36 @Override
37 boolean start() {
38 mState = STATE_WAITING_FOR_INITIATE_ARC_RESPONSE;
39 addTimer(mState, TIMEOUT_MS);
40 sendTerminateArc();
41 return true;
42 }
43
44 @Override
45 boolean processCommand(HdmiCecMessage cmd) {
46 if (mState != STATE_WAITING_FOR_INITIATE_ARC_RESPONSE) {
47 return false;
48 }
49 switch (cmd.getOpcode()) {
50 case Constants.MESSAGE_REPORT_ARC_TERMINATED:
51 mState = STATE_ARC_TERMINATED;
52 audioSystem().setArcStatus(false);
Amy03afe482018-09-18 16:57:45 -070053 if (audioSystem().getLocalActivePort() == Constants.CEC_SWITCH_ARC) {
54 audioSystem().routeToInputFromPortId(audioSystem().getRoutingPort());
55 }
Amy21674272018-07-24 16:28:34 -070056 finish();
57 return true;
58 }
59 return false;
60 }
61
62 @Override
63 void handleTimerEvent(int state) {
64 if (mState != state) {
65 return;
66 }
67
68 switch (mState) {
69 case STATE_WAITING_FOR_INITIATE_ARC_RESPONSE:
70 handleTerminateArcTimeout();
71 break;
72 }
73 }
74
75 protected void sendTerminateArc() {
76 sendCommand(HdmiCecMessageBuilder.buildTerminateArc(getSourceAddress(), Constants.ADDR_TV),
77 result -> {
78 if (result != SendMessageResult.SUCCESS) {
Amy1aca8a72019-04-01 11:31:58 -070079 // If the physical connection is already off or TV does not handle
80 // Terminate ARC, turn off ARC internally.
81 if (result == SendMessageResult.NACK) {
82 audioSystem().setArcStatus(false);
83 }
Amy21674272018-07-24 16:28:34 -070084 HdmiLogger.debug("Terminate ARC was not successfully sent.");
85 finish();
86 }
87 });
88 }
89
90 private void handleTerminateArcTimeout() {
91 HdmiLogger.debug("handleTerminateArcTimeout");
92 finish();
93 }
94}