blob: 18d328d3f971d5500c359ffc5eb10b9782c9b6f2 [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:
54 case Constants.MESSAGE_REPORT_ARC_TERMINATED:
55 audioSystem().setArcStatus(false);
56 finish();
57 return true;
58 case Constants.MESSAGE_REPORT_ARC_INITIATED:
59 mState = STATE_ARC_INITIATED;
Amy25d5bf62018-09-21 16:36:52 -070060 if (audioSystem().getActiveSource().physicalAddress != getSourcePath()
61 && audioSystem().isSystemAudioActivated()) {
62 sendRequestActiveSource();
63 } else {
64 finish();
65 }
Shubang81170da2018-07-12 18:02:52 -070066 return true;
67 }
68 return false;
69 }
70
71 @Override
72 void handleTimerEvent(int state) {
73 if (mState != state) {
74 return;
75 }
76
77 switch (mState) {
78 case STATE_WAITING_FOR_INITIATE_ARC_RESPONSE:
79 handleInitiateArcTimeout();
80 break;
81 }
82 }
83
84 protected void sendInitiateArc() {
85 sendCommand(HdmiCecMessageBuilder.buildInitiateArc(getSourceAddress(), Constants.ADDR_TV),
86 result -> {
87 if (result != SendMessageResult.SUCCESS) {
88 audioSystem().setArcStatus(false);
89 finish();
90 }
91 });
92 }
93
94 private void handleInitiateArcTimeout() {
95 HdmiLogger.debug("handleInitiateArcTimeout");
96 audioSystem().setArcStatus(false);
97 finish();
98 }
99
Amy25d5bf62018-09-21 16:36:52 -0700100 protected void sendRequestActiveSource() {
101 sendCommand(HdmiCecMessageBuilder.buildRequestActiveSource(getSourceAddress()),
102 result -> {
103 if (result != SendMessageResult.SUCCESS) {
104 if (mSendRequestActiveSourceRetryCount < MAX_RETRY_COUNT) {
105 mSendRequestActiveSourceRetryCount++;
106 sendRequestActiveSource();
107 } else {
108 finish();
109 }
110 } else {
111 finish();
112 }
113 });
114 }
Shubang81170da2018-07-12 18:02:52 -0700115}