summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java18
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java49
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java17
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java17
-rw-r--r--services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java40
5 files changed, 116 insertions, 25 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
index 1ba0c52ce875..3f90dfec52ba 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceAudioSystem.java
@@ -68,11 +68,6 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
private static final String TAG = "HdmiCecLocalDeviceAudioSystem";
- // Whether System audio mode is activated or not.
- // This becomes true only when all system audio sequences are finished.
- @GuardedBy("mLock")
- private boolean mSystemAudioActivated;
-
// Whether the System Audio Control feature is enabled or not. True by default.
@GuardedBy("mLock")
private boolean mSystemAudioControlFeatureEnabled;
@@ -271,7 +266,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
synchronized (mLock) {
mService.writeStringSystemProperty(
Constants.PROPERTY_LAST_SYSTEM_AUDIO_CONTROL,
- mSystemAudioActivated ? "true" : "false");
+ isSystemAudioActivated() ? "true" : "false");
}
terminateSystemAudioMode();
}
@@ -814,7 +809,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
}
HdmiLogger.debug(
"System Audio Mode change[old:%b new:%b]",
- mSystemAudioActivated, newSystemAudioMode);
+ isSystemAudioActivated(), newSystemAudioMode);
// Wake up device if System Audio Control is turned on
if (newSystemAudioMode) {
mService.wakeUp();
@@ -854,8 +849,8 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
}
updateAudioManagerForSystemAudio(newSystemAudioMode);
synchronized (mLock) {
- if (mSystemAudioActivated != newSystemAudioMode) {
- mSystemAudioActivated = newSystemAudioMode;
+ if (isSystemAudioActivated() != newSystemAudioMode) {
+ mService.setSystemAudioActivated(newSystemAudioMode);
mService.announceSystemAudioModeChange(newSystemAudioMode);
}
}
@@ -946,9 +941,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
}
protected boolean isSystemAudioActivated() {
- synchronized (mLock) {
- return mSystemAudioActivated;
- }
+ return mService.isSystemAudioActivated();
}
protected void terminateSystemAudioMode() {
@@ -1215,7 +1208,6 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
protected void dump(IndentingPrintWriter pw) {
pw.println("HdmiCecLocalDeviceAudioSystem:");
pw.increaseIndent();
- pw.println("mSystemAudioActivated: " + mSystemAudioActivated);
pw.println("isRoutingFeatureEnabled " + isRoutingControlFeatureEnabled());
pw.println("mSystemAudioControlFeatureEnabled: " + mSystemAudioControlFeatureEnabled);
pw.println("mTvSystemAudioModeSupport: " + mTvSystemAudioModeSupport);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
index e7c4bf7443ee..20933db803b9 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevicePlayback.java
@@ -19,6 +19,7 @@ package com.android.server.hdmi;
import android.hardware.hdmi.HdmiControlManager;
import android.hardware.hdmi.HdmiDeviceInfo;
import android.hardware.hdmi.IHdmiControlCallback;
+import android.hardware.tv.cec.V1_0.SendMessageResult;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.os.SystemProperties;
@@ -30,6 +31,7 @@ import com.android.internal.app.LocalePicker;
import com.android.internal.app.LocalePicker.LocaleInfo;
import com.android.internal.util.IndentingPrintWriter;
import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
+import com.android.server.hdmi.HdmiControlService.SendMessageCallback;
import java.io.UnsupportedEncodingException;
import java.util.List;
@@ -85,6 +87,22 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
mAddress, mService.getPhysicalAddress(), mDeviceType));
mService.sendCecCommand(HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
mAddress, mService.getVendorId()));
+ if (mService.audioSystem() == null) {
+ // If current device is not a functional audio system device,
+ // send message to potential audio system device in the system to get the system
+ // audio mode status. If no response, set to false.
+ mService.sendCecCommand(HdmiCecMessageBuilder.buildGiveSystemAudioModeStatus(
+ mAddress, Constants.ADDR_AUDIO_SYSTEM), new SendMessageCallback() {
+ @Override
+ public void onSendCompleted(int error) {
+ if (error != SendMessageResult.SUCCESS) {
+ HdmiLogger.debug(
+ "AVR did not respond to <Give System Audio Mode Status>");
+ mService.setSystemAudioActivated(false);
+ }
+ }
+ });
+ }
startQueuedActions();
}
@@ -275,6 +293,37 @@ public class HdmiCecLocalDevicePlayback extends HdmiCecLocalDeviceSource {
}
@Override
+ protected boolean handleSetSystemAudioMode(HdmiCecMessage message) {
+ // System Audio Mode only turns on/off when Audio System broadcasts on/off message.
+ // For device with type 4 and 5, it can set system audio mode on/off
+ // when there is another audio system device connected into the system first.
+ if (message.getDestination() != Constants.ADDR_BROADCAST
+ || message.getSource() != Constants.ADDR_AUDIO_SYSTEM
+ || mService.audioSystem() != null) {
+ return true;
+ }
+ boolean setSystemAudioModeOn = HdmiUtils.parseCommandParamSystemAudioStatus(message);
+ if (mService.isSystemAudioActivated() != setSystemAudioModeOn) {
+ mService.setSystemAudioActivated(setSystemAudioModeOn);
+ }
+ return true;
+ }
+
+ @Override
+ protected boolean handleSystemAudioModeStatus(HdmiCecMessage message) {
+ // Only directly addressed System Audio Mode Status message can change internal
+ // system audio mode status.
+ if (message.getDestination() == mAddress
+ && message.getSource() == Constants.ADDR_AUDIO_SYSTEM) {
+ boolean setSystemAudioModeOn = HdmiUtils.parseCommandParamSystemAudioStatus(message);
+ if (mService.isSystemAudioActivated() != setSystemAudioModeOn) {
+ mService.setSystemAudioActivated(setSystemAudioModeOn);
+ }
+ }
+ return true;
+ }
+
+ @Override
protected int findKeyReceiverAddress() {
return Constants.ADDR_TV;
}
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index a8c435086e8e..8a7051f0e736 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -77,11 +77,6 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
// True by default for all the ARC-enabled ports.
private final SparseBooleanArray mArcFeatureEnabled = new SparseBooleanArray();
- // Whether System audio mode is activated or not.
- // This becomes true only when all system audio sequences are finished.
- @GuardedBy("mLock")
- private boolean mSystemAudioActivated = false;
-
// Whether the System Audio Control feature is enabled or not. True by default.
@GuardedBy("mLock")
private boolean mSystemAudioControlFeatureEnabled;
@@ -829,11 +824,12 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
+ "because the System Audio Control feature is disabled.");
return;
}
- HdmiLogger.debug("System Audio Mode change[old:%b new:%b]", mSystemAudioActivated, on);
+ HdmiLogger.debug("System Audio Mode change[old:%b new:%b]",
+ mService.isSystemAudioActivated(), on);
updateAudioManagerForSystemAudio(on);
synchronized (mLock) {
- if (mSystemAudioActivated != on) {
- mSystemAudioActivated = on;
+ if (mService.isSystemAudioActivated() != on) {
+ mService.setSystemAudioActivated(on);
mService.announceSystemAudioModeChange(on);
}
startArcAction(on);
@@ -849,9 +845,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
if (!hasSystemAudioDevice()) {
return false;
}
- synchronized (mLock) {
- return mSystemAudioActivated;
- }
+ return mService.isSystemAudioActivated();
}
@ServiceThreadOnly
@@ -1904,7 +1898,6 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
super.dump(pw);
pw.println("mArcEstablished: " + mArcEstablished);
pw.println("mArcFeatureEnabled: " + mArcFeatureEnabled);
- pw.println("mSystemAudioActivated: " + mSystemAudioActivated);
pw.println("mSystemAudioMute: " + mSystemAudioMute);
pw.println("mSystemAudioControlFeatureEnabled: " + mSystemAudioControlFeatureEnabled);
pw.println("mAutoDeviceOff: " + mAutoDeviceOff);
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index eb29c93b1ced..7376ed2b0679 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -147,6 +147,10 @@ public class HdmiControlService extends SystemService {
@GuardedBy("mLock")
protected final ActiveSource mActiveSource = new ActiveSource();
+ // Whether System Audio Mode is activated or not.
+ @GuardedBy("mLock")
+ private boolean mSystemAudioActivated = false;
+
private static final boolean isHdmiCecNeverClaimPlaybackLogicAddr =
SystemProperties.getBoolean(
Constants.PROPERTY_HDMI_CEC_NEVER_CLAIM_PLAYBACK_LOGICAL_ADDRESS, false);
@@ -2032,6 +2036,7 @@ public class HdmiControlService extends SystemService {
pw.increaseIndent();
pw.println("mHdmiControlEnabled: " + mHdmiControlEnabled);
pw.println("mMhlInputChangeEnabled: " + mMhlInputChangeEnabled);
+ pw.println("mSystemAudioActivated: " + isSystemAudioActivated());
pw.decreaseIndent();
pw.println("mMhlController: ");
@@ -2658,6 +2663,18 @@ public class HdmiControlService extends SystemService {
}
}
+ boolean isSystemAudioActivated() {
+ synchronized (mLock) {
+ return mSystemAudioActivated;
+ }
+ }
+
+ void setSystemAudioActivated(boolean on) {
+ synchronized (mLock) {
+ mSystemAudioActivated = on;
+ }
+ }
+
@ServiceThreadOnly
void setCecOption(int key, boolean value) {
assertRunOnServiceThread();
diff --git a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
index feae4eed7eb1..b8799c3f16f7 100644
--- a/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
+++ b/services/tests/servicestests/src/com/android/server/hdmi/HdmiCecLocalDevicePlaybackTest.java
@@ -60,6 +60,11 @@ public class HdmiCecLocalDevicePlaybackTest {
boolean isControlEnabled() {
return true;
}
+
+ @Override
+ void writeStringSystemProperty(String key, String value) {
+ // do nothing
+ }
};
mMyLooper = mTestLooper.getLooper();
@@ -92,4 +97,39 @@ public class HdmiCecLocalDevicePlaybackTest {
// TODO(amyjojo): Move set and get LocalActivePath to Control Service.
assertThat(mHdmiCecLocalDevicePlayback.getLocalActivePath()).isEqualTo(1);
}
+
+ @Test
+ public void handleSetSystemAudioModeOn_audioSystemBroadcast() {
+ mHdmiControlService.setSystemAudioActivated(false);
+ assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildSetSystemAudioMode(
+ Constants.ADDR_AUDIO_SYSTEM, Constants.ADDR_BROADCAST, true);
+ assertThat(mHdmiCecLocalDevicePlayback.handleSetSystemAudioMode(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
+ }
+
+ @Test
+ public void handleSetSystemAudioModeOff_audioSystemToPlayback() {
+ mHdmiCecLocalDevicePlayback.mService.setSystemAudioActivated(true);
+ assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
+ // This direct message to Playback device is invalid.
+ // Test should ignore it and still keep the system audio mode on.
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildSetSystemAudioMode(
+ Constants.ADDR_AUDIO_SYSTEM, mHdmiCecLocalDevicePlayback.mAddress, false);
+ assertThat(mHdmiCecLocalDevicePlayback.handleSetSystemAudioMode(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
+ }
+
+ @Test
+ public void handleSystemAudioModeStatusOn_DirectltToLocalDeviceFromAudioSystem() {
+ mHdmiControlService.setSystemAudioActivated(false);
+ assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isFalse();
+ HdmiCecMessage message =
+ HdmiCecMessageBuilder.buildReportSystemAudioMode(
+ Constants.ADDR_AUDIO_SYSTEM, mHdmiCecLocalDevicePlayback.mAddress, true);
+ assertThat(mHdmiCecLocalDevicePlayback.handleSystemAudioModeStatus(message)).isTrue();
+ assertThat(mHdmiCecLocalDevicePlayback.mService.isSystemAudioActivated()).isTrue();
+ }
}