blob: bffa854b79e56765b9ddd0ee7a2782c15a6d8249 [file] [log] [blame]
Jungshik Jang67ea5212014-05-15 14:05:24 +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
Jungshik Jang61f4fbd2014-08-06 19:21:12 +090019import android.hardware.hdmi.HdmiDeviceInfo;
Jungshik Jang67ea5212014-05-15 14:05:24 +090020import android.util.Slog;
21
22/**
23 * Feature action that handles enabling/disabling of ARC transmission channel.
24 * Once TV gets <Initiate ARC>, TV sends <Report ARC Initiated> to AV Receiver.
25 * If it fails or it gets <Terminate ARC>, TV just disables ARC.
26 */
Jungshik Jangb509c2e2014-08-07 13:45:01 +090027final class SetArcTransmissionStateAction extends HdmiCecFeatureAction {
Jungshik Jang67ea5212014-05-15 14:05:24 +090028 private static final String TAG = "SetArcTransmissionStateAction";
29
30 // State in which the action sent <Rerpot Arc Initiated> and
31 // is waiting for time out. If it receives <Feature Abort> within timeout
32 // ARC should be disabled.
33 private static final int STATE_WAITING_TIMEOUT = 1;
34
35 private final boolean mEnabled;
36 private final int mAvrAddress;
37
38 /**
39 * @Constructor
40 *
Jungshik Jang79c58a42014-06-16 16:45:36 +090041 * @param source {@link HdmiCecLocalDevice} instance
Jungshik Jang67ea5212014-05-15 14:05:24 +090042 * @param enabled whether to enable ARC Transmission channel
43 */
Jungshik Jang79c58a42014-06-16 16:45:36 +090044 SetArcTransmissionStateAction(HdmiCecLocalDevice source, int avrAddress,
Jungshik Jang67ea5212014-05-15 14:05:24 +090045 boolean enabled) {
Jungshik Jang79c58a42014-06-16 16:45:36 +090046 super(source);
Jungshik Jang61f4fbd2014-08-06 19:21:12 +090047 HdmiUtils.verifyAddressType(getSourceAddress(), HdmiDeviceInfo.DEVICE_TV);
48 HdmiUtils.verifyAddressType(avrAddress, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
Jungshik Jang67ea5212014-05-15 14:05:24 +090049 mAvrAddress = avrAddress;
50 mEnabled = enabled;
51 }
52
Jungshik Jang67ea5212014-05-15 14:05:24 +090053 @Override
54 boolean start() {
55 if (mEnabled) {
Jungshik Jang2e8f1b62014-09-03 08:28:02 +090056 // Enable ARC status immediately after sending <Report Arc Initiated>.
57 // If AVR responds with <Feature Abort>, disable ARC status again.
58 // This is different from spec that says that turns ARC status to
59 // "Enabled" if <Report ARC Initiated> is acknowledged and no
60 // <Feature Abort> is received.
61 // But implemented this way to save the time having to wait for
62 // <Feature Abort>.
63 setArcStatus(true);
64 // If succeeds to send <Report ARC Initiated>, wait general timeout
65 // to check whether there is no <Feature Abort> for <Report ARC Initiated>.
66 mState = STATE_WAITING_TIMEOUT;
67 addTimer(mState, HdmiConfig.TIMEOUT_MS);
Jungshik Jangd643f762014-05-22 19:28:09 +090068 sendReportArcInitiated();
Jungshik Jang67ea5212014-05-15 14:05:24 +090069 } else {
70 setArcStatus(false);
71 finish();
72 }
73 return true;
74 }
75
Jungshik Jangd643f762014-05-22 19:28:09 +090076 private void sendReportArcInitiated() {
77 HdmiCecMessage command =
Jungshik Jang79c58a42014-06-16 16:45:36 +090078 HdmiCecMessageBuilder.buildReportArcInitiated(getSourceAddress(), mAvrAddress);
Jungshik Jangd643f762014-05-22 19:28:09 +090079 sendCommand(command, new HdmiControlService.SendMessageCallback() {
80 @Override
81 public void onSendCompleted(int error) {
Jungshik Jang2e8f1b62014-09-03 08:28:02 +090082 if (error != Constants.SEND_RESULT_SUCCESS) {
Jungshik Jangd643f762014-05-22 19:28:09 +090083 // If fails to send <Report ARC Initiated>, disable ARC and
84 // send <Report ARC Terminated> directly.
Jungshik Jangd643f762014-05-22 19:28:09 +090085 setArcStatus(false);
Jungshik Jang2e8f1b62014-09-03 08:28:02 +090086 HdmiLogger.debug("Failed to send <Report Arc Initiated>.");
Jungshik Jangd643f762014-05-22 19:28:09 +090087 finish();
88 }
89 }
90 });
91 }
92
Jungshik Jang67ea5212014-05-15 14:05:24 +090093 private void setArcStatus(boolean enabled) {
Jungshik Jang79c58a42014-06-16 16:45:36 +090094 boolean wasEnabled = tv().setArcStatus(enabled);
Jungshik Jangc94ac5c2014-08-27 13:48:37 +090095 Slog.i(TAG, "Change arc status [old:" + wasEnabled + ", new:" + enabled + "]");
Jungshik Jang67ea5212014-05-15 14:05:24 +090096
97 // If enabled before and set to "disabled" and send <Report Arc Terminated> to
98 // av reciever.
99 if (!enabled && wasEnabled) {
Jungshik Jang79c58a42014-06-16 16:45:36 +0900100 sendCommand(HdmiCecMessageBuilder.buildReportArcTerminated(getSourceAddress(),
101 mAvrAddress));
Jungshik Jang67ea5212014-05-15 14:05:24 +0900102 }
103 }
104
105 @Override
106 boolean processCommand(HdmiCecMessage cmd) {
107 if (mState != STATE_WAITING_TIMEOUT) {
108 return false;
109 }
110
111 int opcode = cmd.getOpcode();
Jinsuk Kimc0c20d02014-07-04 14:34:31 +0900112 if (opcode == Constants.MESSAGE_FEATURE_ABORT) {
Jungshik Jang339227d2014-08-25 15:37:20 +0900113 int originalOpcode = cmd.getParams()[0] & 0xFF;
114 if (originalOpcode == Constants.MESSAGE_REPORT_ARC_INITIATED) {
Jungshik Jang2e8f1b62014-09-03 08:28:02 +0900115 HdmiLogger.debug("Feature aborted for <Report Arc Initiated>");
Jungshik Jang339227d2014-08-25 15:37:20 +0900116 setArcStatus(false);
117 finish();
118 return true;
119 }
Jungshik Jang67ea5212014-05-15 14:05:24 +0900120 }
Jungshik Jang339227d2014-08-25 15:37:20 +0900121 return false;
Jungshik Jang67ea5212014-05-15 14:05:24 +0900122 }
123
124 @Override
125 void handleTimerEvent(int state) {
126 if (mState != state || mState != STATE_WAITING_TIMEOUT) {
127 return;
128 }
129 // Expire timeout for <Feature Abort>.
130 finish();
131 }
132}