blob: 13f0f4ae4a92543354404da9106bff0fe1f51d50 [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
Jungshik Jangea67c182014-06-19 22:19:20 +090019import android.annotation.Nullable;
Jinsuk Kimc0c20d02014-07-04 14:34:31 +090020import android.hardware.hdmi.HdmiControlManager;
Jungshik Jangea67c182014-06-19 22:19:20 +090021import android.hardware.hdmi.IHdmiControlCallback;
Donghyun Chobc6e3722016-11-04 05:25:52 +090022import android.hardware.tv.cec.V1_0.SendMessageResult;
Jungshik Jangea67c182014-06-19 22:19:20 +090023import android.os.RemoteException;
Jungshik Jang187d0172014-06-17 17:48:42 +090024import android.util.Slog;
Jungshik Jang187d0172014-06-17 17:48:42 +090025import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
26
27/**
28 * Action to update audio status (volume or mute) of audio amplifier
29 */
Jungshik Jangb509c2e2014-08-07 13:45:01 +090030final class SystemAudioStatusAction extends HdmiCecFeatureAction {
Jungshik Jang187d0172014-06-17 17:48:42 +090031 private static final String TAG = "SystemAudioStatusAction";
32
33 // State that waits for <ReportAudioStatus>.
34 private static final int STATE_WAIT_FOR_REPORT_AUDIO_STATUS = 1;
35
36 private final int mAvrAddress;
Jungshik Jangea67c182014-06-19 22:19:20 +090037 @Nullable private final IHdmiControlCallback mCallback;
Jungshik Jang187d0172014-06-17 17:48:42 +090038
Jungshik Jangea67c182014-06-19 22:19:20 +090039 SystemAudioStatusAction(HdmiCecLocalDevice source, int avrAddress,
40 IHdmiControlCallback callback) {
Jungshik Jang187d0172014-06-17 17:48:42 +090041 super(source);
42 mAvrAddress = avrAddress;
Jungshik Jangea67c182014-06-19 22:19:20 +090043 mCallback = callback;
Jungshik Jang187d0172014-06-17 17:48:42 +090044 }
45
46 @Override
47 boolean start() {
48 mState = STATE_WAIT_FOR_REPORT_AUDIO_STATUS;
Jinsuk Kim5fba96d2014-07-11 11:51:34 +090049 addTimer(mState, HdmiConfig.TIMEOUT_MS);
Jungshik Jang187d0172014-06-17 17:48:42 +090050 sendGiveAudioStatus();
51 return true;
52 }
53
54 private void sendGiveAudioStatus() {
55 sendCommand(HdmiCecMessageBuilder.buildGiveAudioStatus(getSourceAddress(), mAvrAddress),
56 new SendMessageCallback() {
57 @Override
58 public void onSendCompleted(int error) {
Donghyun Chobc6e3722016-11-04 05:25:52 +090059 if (error != SendMessageResult.SUCCESS) {
Jungshik Jang187d0172014-06-17 17:48:42 +090060 handleSendGiveAudioStatusFailure();
61 }
62 }
63 });
64 }
65
66 private void handleSendGiveAudioStatusFailure() {
Shubanga3f59502018-06-05 16:32:53 -070067 // Inform to all application that the audio status (volume, mute) of
Jungshik Jang187d0172014-06-17 17:48:42 +090068 // the audio amplifier is unknown.
Jinsuk Kimc0c20d02014-07-04 14:34:31 +090069 tv().setAudioStatus(false, Constants.UNKNOWN_VOLUME);
Jungshik Jang187d0172014-06-17 17:48:42 +090070
Jinsuk Kim0ab37792015-10-17 06:53:52 +090071 sendUserControlPressedAndReleased(mAvrAddress,
72 HdmiCecKeycode.getMuteKey(!tv().isSystemAudioActivated()));
Jungshik Jangea67c182014-06-19 22:19:20 +090073
74 // Still return SUCCESS to callback.
Jinsuk Kimc0c20d02014-07-04 14:34:31 +090075 finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
Jungshik Jang187d0172014-06-17 17:48:42 +090076 }
77
Jungshik Jang187d0172014-06-17 17:48:42 +090078 @Override
79 boolean processCommand(HdmiCecMessage cmd) {
Jungshik Jang5352081c2014-09-22 15:14:49 +090080 if (mState != STATE_WAIT_FOR_REPORT_AUDIO_STATUS || mAvrAddress != cmd.getSource()) {
Jungshik Jang187d0172014-06-17 17:48:42 +090081 return false;
82 }
83
84 switch (cmd.getOpcode()) {
Jinsuk Kimc0c20d02014-07-04 14:34:31 +090085 case Constants.MESSAGE_REPORT_AUDIO_STATUS:
Jungshik Jang187d0172014-06-17 17:48:42 +090086 handleReportAudioStatus(cmd);
87 return true;
88 }
89
90 return false;
91 }
92
93 private void handleReportAudioStatus(HdmiCecMessage cmd) {
94 byte[] params = cmd.getParams();
Shuichi.Noguchifbb50bc2017-12-06 11:12:33 +090095 boolean mute = HdmiUtils.isAudioStatusMute(cmd);
96 int volume = HdmiUtils.getAudioStatusVolume(cmd);
Yuncheol Heo75a77e72014-07-09 18:27:53 +090097 tv().setAudioStatus(mute, volume);
Jungshik Jang187d0172014-06-17 17:48:42 +090098
Jungshik Jang377dcbd2014-07-15 15:49:02 +090099 if (!(tv().isSystemAudioActivated() ^ mute)) {
Yuncheol Heo75a77e72014-07-09 18:27:53 +0900100 // Toggle AVR's mute status to match with the system audio status.
101 sendUserControlPressedAndReleased(mAvrAddress, HdmiCecKeycode.CEC_KEYCODE_MUTE);
Jungshik Jang187d0172014-06-17 17:48:42 +0900102 }
Yuncheol Heo75a77e72014-07-09 18:27:53 +0900103 finishWithCallback(HdmiControlManager.RESULT_SUCCESS);
Jungshik Jang187d0172014-06-17 17:48:42 +0900104 }
105
Jungshik Jangea67c182014-06-19 22:19:20 +0900106 private void finishWithCallback(int returnCode) {
107 if (mCallback != null) {
108 try {
109 mCallback.onComplete(returnCode);
110 } catch (RemoteException e) {
111 Slog.e(TAG, "Failed to invoke callback.", e);
112 }
113 }
114 finish();
115 }
116
Jungshik Jang187d0172014-06-17 17:48:42 +0900117 @Override
118 void handleTimerEvent(int state) {
119 if (mState != state) {
120 return;
121 }
122
123 handleSendGiveAudioStatusFailure();
124 }
125}