Merge changes from topic "cp pi-tv-dev 6162606"

* changes:
  Add System Audio Mode Status handler to update sam status
  Add setSystemAudioMode handler to update isSystemAudioModeActivated.
  Migrate systemAudioActivated to HdmiControlService
This commit is contained in:
Shubang Lu
2019-02-04 18:47:15 +00:00
committed by Android (Google) Code Review
5 changed files with 116 additions and 25 deletions

View File

@@ -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);

View File

@@ -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();
}
@@ -274,6 +292,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;

View File

@@ -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);

View File

@@ -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();

View File

@@ -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();
}
}