blob: 137833cc955114af8d54eb4b4e183d471c7312bf [file] [log] [blame]
Shubang81170da2018-07-12 18:02:52 -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 initiated by AVR devices.
22 */
23public class ArcInitiationActionFromAvr extends HdmiCecFeatureAction {
Shubang81170da2018-07-12 18:02:52 -070024 // State in which waits for ARC response.
25 private static final int STATE_WAITING_FOR_INITIATE_ARC_RESPONSE = 1;
26 private static final int STATE_ARC_INITIATED = 2;
27
28 // the required maximum response time specified in CEC 9.2
29 private static final int TIMEOUT_MS = 1000;
Amy25d5bf62018-09-21 16:36:52 -070030 private static final int MAX_RETRY_COUNT = 5;
31
32 private int mSendRequestActiveSourceRetryCount = 0;
Shubang81170da2018-07-12 18:02:52 -070033
34 ArcInitiationActionFromAvr(HdmiCecLocalDevice source) {
35 super(source);
36 }
37
38 @Override
39 boolean start() {
40 audioSystem().setArcStatus(true);
41 mState = STATE_WAITING_FOR_INITIATE_ARC_RESPONSE;
42 addTimer(mState, TIMEOUT_MS);
43 sendInitiateArc();
44 return true;
45 }
46
47 @Override
48 boolean processCommand(HdmiCecMessage cmd) {
49 if (mState != STATE_WAITING_FOR_INITIATE_ARC_RESPONSE) {
50 return false;
51 }
52 switch (cmd.getOpcode()) {
53 case Constants.MESSAGE_FEATURE_ABORT:
Amyf4b66f62018-11-09 09:52:50 -080054 if ((cmd.getParams()[0] & 0xFF) == Constants.MESSAGE_INITIATE_ARC) {
55 audioSystem().setArcStatus(false);
56 finish();
57 return true;
58 } else {
59 return false;
60 }
Shubang81170da2018-07-12 18:02:52 -070061 case Constants.MESSAGE_REPORT_ARC_TERMINATED:
62 audioSystem().setArcStatus(false);
63 finish();
64 return true;
65 case Constants.MESSAGE_REPORT_ARC_INITIATED:
66 mState = STATE_ARC_INITIATED;
Amy25d5bf62018-09-21 16:36:52 -070067 if (audioSystem().getActiveSource().physicalAddress != getSourcePath()
68 && audioSystem().isSystemAudioActivated()) {
69 sendRequestActiveSource();
70 } else {
71 finish();
72 }
Shubang81170da2018-07-12 18:02:52 -070073 return true;
74 }
75 return false;
76 }
77
78 @Override
79 void handleTimerEvent(int state) {
80 if (mState != state) {
81 return;
82 }
83
84 switch (mState) {
85 case STATE_WAITING_FOR_INITIATE_ARC_RESPONSE:
86 handleInitiateArcTimeout();
87 break;
88 }
89 }
90
91 protected void sendInitiateArc() {
92 sendCommand(HdmiCecMessageBuilder.buildInitiateArc(getSourceAddress(), Constants.ADDR_TV),
93 result -> {
94 if (result != SendMessageResult.SUCCESS) {
95 audioSystem().setArcStatus(false);
96 finish();
97 }
98 });
99 }
100
101 private void handleInitiateArcTimeout() {
102 HdmiLogger.debug("handleInitiateArcTimeout");
103 audioSystem().setArcStatus(false);
104 finish();
105 }
106
Amy25d5bf62018-09-21 16:36:52 -0700107 protected void sendRequestActiveSource() {
108 sendCommand(HdmiCecMessageBuilder.buildRequestActiveSource(getSourceAddress()),
109 result -> {
110 if (result != SendMessageResult.SUCCESS) {
111 if (mSendRequestActiveSourceRetryCount < MAX_RETRY_COUNT) {
112 mSendRequestActiveSourceRetryCount++;
113 sendRequestActiveSource();
114 } else {
115 finish();
116 }
117 } else {
118 finish();
119 }
120 });
121 }
Shubang81170da2018-07-12 18:02:52 -0700122}