summaryrefslogtreecommitdiffstats
path: root/services/core
diff options
context:
space:
mode:
authorJungshik Jang <jayjang@google.com>2014-06-18 02:38:11 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2014-06-17 22:26:08 +0000
commitbce527139a9fe80a8195a4fc787759ff27da8d27 (patch)
treeb31815e022a63aeff48d089564641688721a0b58 /services/core
parent128be2a919d2915a1a677cddb3a2e93617dc4d0b (diff)
parent187d01765b935d07936f74343b4f4af590c239a1 (diff)
downloadframeworks_base-bce527139a9fe80a8195a4fc787759ff27da8d27.zip
frameworks_base-bce527139a9fe80a8195a4fc787759ff27da8d27.tar.gz
frameworks_base-bce527139a9fe80a8195a4fc787759ff27da8d27.tar.bz2
Merge "Add SystemAudioAutoInitiationAction and SystemAudioStatusAction"
Diffstat (limited to 'services/core')
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java17
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java11
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiConstants.java2
-rw-r--r--services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java120
-rw-r--r--services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java123
5 files changed, 273 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 92ddd3d..18a3bbf 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -52,6 +52,8 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
HdmiCecLocalDeviceTv(HdmiControlService service) {
super(service, HdmiCec.DEVICE_TV);
+
+ // TODO: load system audio mode and set it to mSystemAudioMode.
}
@Override
@@ -174,6 +176,15 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
}
addAndStartAction(new HotplugDetectionAction(HdmiCecLocalDeviceTv.this));
+
+ // If there is AVR, initiate System Audio Auto initiation action,
+ // which turns on and off system audio according to last system
+ // audio setting.
+ HdmiCecDeviceInfo avrInfo = getAvrDeviceInfo();
+ if (avrInfo != null) {
+ addAndStartAction(new SystemAudioAutoInitiationAction(
+ HdmiCecLocalDeviceTv.this, avrInfo.getLogicalAddress()));
+ }
}
});
addAndStartAction(action);
@@ -456,4 +467,10 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
hotplugActions.get(0).pollAllDevicesNow();
}
}
+
+ boolean canChangeSystemAudio() {
+ // TODO: implement this.
+ // return true if no system audio control sequence is running.
+ return false;
+ }
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
index 8dbfd85..361a063 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java
@@ -377,6 +377,17 @@ public class HdmiCecMessageBuilder {
return buildCommand(src, dest, HdmiCec.MESSAGE_USER_CONTROL_RELEASED);
}
+ /**
+ * Build &lt;Give System Audio Mode Status&gt; command.
+ *
+ * @param src source address of command
+ * @param dest destination address of command
+ * @return newly created {@link HdmiCecMessage}
+ */
+ static HdmiCecMessage buildGiveSystemAudioModeStatus(int src, int dest) {
+ return buildCommand(src, dest, HdmiCec.MESSAGE_GIVE_SYSTEM_AUDIO_MODE_STATUS);
+ }
+
/***** Please ADD new buildXXX() methods above. ******/
/**
diff --git a/services/core/java/com/android/server/hdmi/HdmiConstants.java b/services/core/java/com/android/server/hdmi/HdmiConstants.java
index 9c60e55..5294506 100644
--- a/services/core/java/com/android/server/hdmi/HdmiConstants.java
+++ b/services/core/java/com/android/server/hdmi/HdmiConstants.java
@@ -95,5 +95,7 @@ final class HdmiConstants {
static final int POLL_ITERATION_IN_ORDER = 0x10000;
static final int POLL_ITERATION_REVERSE_ORDER = 0x20000;
+ static final int UNKNOWN_VOLUME = -1;
+
private HdmiConstants() { /* cannot be instantiated */ }
}
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
new file mode 100644
index 0000000..e4d82ef
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/SystemAudioAutoInitiationAction.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.hardware.hdmi.HdmiCec;
+import android.hardware.hdmi.HdmiCecMessage;
+
+import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
+
+/**
+ * Action to initiate system audio once AVR is detected on Device discovery action.
+ */
+final class SystemAudioAutoInitiationAction extends FeatureAction {
+ private final int mAvrAddress;
+
+ // State that waits for <System Audio Mode Status> once send
+ // <Give System Audio Mode Status> to AV Receiver.
+ private static final int STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS = 1;
+
+ SystemAudioAutoInitiationAction(HdmiCecLocalDevice source, int avrAddress) {
+ super(source);
+ mAvrAddress = avrAddress;
+ }
+
+ @Override
+ boolean start() {
+ mState = STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS;
+
+ addTimer(mState, TIMEOUT_MS);
+ sendGiveSystemAudioModeStatus();
+ return true;
+ }
+
+ private void sendGiveSystemAudioModeStatus() {
+ sendCommand(HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(getSourceAddress(),
+ mAvrAddress), new SendMessageCallback() {
+ @Override
+ public void onSendCompleted(int error) {
+ if (error != HdmiConstants.SEND_RESULT_SUCCESS) {
+ tv().setSystemAudioMode(false);
+ finish();
+ }
+ }
+ });
+ }
+
+ @Override
+ boolean processCommand(HdmiCecMessage cmd) {
+ if (mState != STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS) {
+ return false;
+ }
+
+ switch (cmd.getOpcode()) {
+ case HdmiCec.MESSAGE_SYSTEM_AUDIO_MODE_STATUS:
+ handleSystemAudioModeStatusMessage();
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ private void handleSystemAudioModeStatusMessage() {
+ // If the last setting is system audio, turn on system audio whatever AVR status is.
+ if (tv().getSystemAudioMode()) {
+ if (canChangeSystemAudio()) {
+ addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, true));
+ }
+ } else {
+ // If the last setting is non-system audio, turn off system audio mode
+ // and update system audio status (volume or mute).
+ tv().setSystemAudioMode(false);
+ if (canChangeSystemAudio()) {
+ addAndStartAction(new SystemAudioStatusAction(tv(), mAvrAddress));
+ }
+ }
+ finish();
+ }
+
+ @Override
+ void handleTimerEvent(int state) {
+ if (mState != state) {
+ return;
+ }
+
+ switch (mState) {
+ case STATE_WAITING_FOR_SYSTEM_AUDIO_MODE_STATUS:
+ handleSystemAudioModeStatusTimeout();
+ break;
+ }
+ }
+
+ private void handleSystemAudioModeStatusTimeout() {
+ if (tv().getSystemAudioMode()) {
+ if (canChangeSystemAudio()) {
+ addAndStartAction(new SystemAudioActionFromTv(tv(), mAvrAddress, true));
+ }
+ } else {
+ tv().setSystemAudioMode(false);
+ }
+ finish();
+ }
+
+ private boolean canChangeSystemAudio() {
+ return tv().canChangeSystemAudio();
+ }
+}
diff --git a/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java b/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java
new file mode 100644
index 0000000..75e4fef
--- /dev/null
+++ b/services/core/java/com/android/server/hdmi/SystemAudioStatusAction.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.hdmi;
+
+import android.hardware.hdmi.HdmiCec;
+import android.hardware.hdmi.HdmiCecMessage;
+import android.util.Slog;
+
+import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
+
+/**
+ * Action to update audio status (volume or mute) of audio amplifier
+ */
+// TODO: refactor SystemAudioMode so that it uses this class instead of internal state.
+final class SystemAudioStatusAction extends FeatureAction {
+ private static final String TAG = "SystemAudioStatusAction";
+
+ // State that waits for <ReportAudioStatus>.
+ private static final int STATE_WAIT_FOR_REPORT_AUDIO_STATUS = 1;
+
+ private final int mAvrAddress;
+
+ SystemAudioStatusAction(HdmiCecLocalDevice source, int avrAddress) {
+ super(source);
+ mAvrAddress = avrAddress;
+ }
+
+ @Override
+ boolean start() {
+ mState = STATE_WAIT_FOR_REPORT_AUDIO_STATUS;
+ addTimer(mState, TIMEOUT_MS);
+ sendGiveAudioStatus();
+ return true;
+ }
+
+ private void sendGiveAudioStatus() {
+ sendCommand(HdmiCecMessageBuilder.buildGiveAudioStatus(getSourceAddress(), mAvrAddress),
+ new SendMessageCallback() {
+ @Override
+ public void onSendCompleted(int error) {
+ if (error != HdmiConstants.SEND_RESULT_SUCCESS) {
+ handleSendGiveAudioStatusFailure();
+ }
+ }
+ });
+ }
+
+ private void handleSendGiveAudioStatusFailure() {
+ // Inform to all application that the audio status (volumn, mute) of
+ // the audio amplifier is unknown.
+ tv().setAudioStatus(false, HdmiConstants.UNKNOWN_VOLUME);
+
+ int uiCommand = tv().getSystemAudioMode()
+ ? HdmiConstants.UI_COMMAND_RESTORE_VOLUME_FUNCTION // SystemAudioMode: ON
+ : HdmiConstants.UI_COMMAND_MUTE_FUNCTION; // SystemAudioMode: OFF
+ sendUserControlPressedAndReleased(uiCommand);
+ finish();
+ }
+
+ private void sendUserControlPressedAndReleased(int uiCommand) {
+ sendCommand(HdmiCecMessageBuilder.buildUserControlPressed(
+ getSourceAddress(), mAvrAddress, uiCommand));
+ sendCommand(HdmiCecMessageBuilder.buildUserControlReleased(
+ getSourceAddress(), mAvrAddress));
+ }
+
+ @Override
+ boolean processCommand(HdmiCecMessage cmd) {
+ if (mState != STATE_WAIT_FOR_REPORT_AUDIO_STATUS) {
+ return false;
+ }
+
+ switch (cmd.getOpcode()) {
+ case HdmiCec.MESSAGE_REPORT_AUDIO_STATUS:
+ handleReportAudioStatus(cmd);
+ return true;
+ }
+
+ return false;
+ }
+
+ private void handleReportAudioStatus(HdmiCecMessage cmd) {
+ byte[] params = cmd.getParams();
+ if (params.length > 0) {
+ boolean mute = (params[0] & 0x80) == 0x80;
+ int volume = params[0] & 0x7F;
+ tv().setAudioStatus(mute, volume);
+
+ if ((tv().getSystemAudioMode() && mute) || (!tv().getSystemAudioMode() && !mute)) {
+ // Toggle AVR's mute status to match with the system audio status.
+ sendUserControlPressedAndReleased(HdmiConstants.UI_COMMAND_MUTE);
+ }
+ finish();
+ } else {
+ Slog.e(TAG, "Invalid <Report Audio Status> message:" + cmd);
+ handleSendGiveAudioStatusFailure();
+ return;
+ }
+ }
+
+ @Override
+ void handleTimerEvent(int state) {
+ if (mState != state) {
+ return;
+ }
+
+ handleSendGiveAudioStatusFailure();
+ }
+}