Support "Mute" and "Restore Volume" CEC commands
Adds support for <User Control Pressed> ["Mute Function"] and ["Restore Volume Function"] on all HDMI devices. These commands are currently ignored because they are not mapped to an Android keycode. Support for these commands is required for HDMI CEC 2.0. Bug: 191230341 Test: Manual; atest HdmiCecLocalDeviceTest Change-Id: I5146e9e99595a9a124e0ce2176f5e70a29923a49
This commit is contained in:
@@ -23,6 +23,7 @@ import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
import android.hardware.hdmi.IHdmiControlCallback;
|
||||
import android.hardware.input.InputManager;
|
||||
import android.hardware.tv.cec.V1_0.SendMessageResult;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.os.Message;
|
||||
@@ -685,11 +686,29 @@ abstract class HdmiCecLocalDevice {
|
||||
Message.obtain(mHandler, MSG_USER_CONTROL_RELEASE_TIMEOUT),
|
||||
FOLLOWER_SAFETY_TIMEOUT);
|
||||
return Constants.HANDLED;
|
||||
} else if (params.length > 0) {
|
||||
// Handle CEC UI commands that are not mapped to an Android keycode
|
||||
return handleUnmappedCecKeycode(params[0]);
|
||||
}
|
||||
|
||||
return Constants.ABORT_INVALID_OPERAND;
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
@Constants.HandleMessageResult
|
||||
protected int handleUnmappedCecKeycode(int cecKeycode) {
|
||||
if (cecKeycode == HdmiCecKeycode.CEC_KEYCODE_MUTE_FUNCTION) {
|
||||
mService.getAudioManager().adjustStreamVolume(AudioManager.STREAM_MUSIC,
|
||||
AudioManager.ADJUST_MUTE, AudioManager.FLAG_SHOW_UI);
|
||||
return Constants.HANDLED;
|
||||
} else if (cecKeycode == HdmiCecKeycode.CEC_KEYCODE_RESTORE_VOLUME_FUNCTION) {
|
||||
mService.getAudioManager().adjustStreamVolume(AudioManager.STREAM_MUSIC,
|
||||
AudioManager.ADJUST_UNMUTE, AudioManager.FLAG_SHOW_UI);
|
||||
return Constants.HANDLED;
|
||||
}
|
||||
return Constants.ABORT_INVALID_OPERAND;
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
@Constants.HandleMessageResult
|
||||
protected int handleUserControlReleased() {
|
||||
|
||||
@@ -32,9 +32,15 @@ import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertFalse;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
import android.content.Context;
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.HdmiPortInfo;
|
||||
import android.media.AudioManager;
|
||||
import android.os.test.TestLooper;
|
||||
import android.platform.test.annotations.Presubmit;
|
||||
|
||||
@@ -45,6 +51,8 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.JUnit4;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -123,8 +131,12 @@ public class HdmiCecLocalDeviceTest {
|
||||
private boolean isControlEnabled;
|
||||
private int mPowerStatus;
|
||||
|
||||
@Mock
|
||||
private AudioManager mAudioManager;
|
||||
|
||||
@Before
|
||||
public void SetUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
Context context = InstrumentationRegistry.getTargetContext();
|
||||
|
||||
@@ -161,6 +173,11 @@ public class HdmiCecLocalDeviceTest {
|
||||
void wakeUp() {
|
||||
mWakeupMessageReceived = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
AudioManager getAudioManager() {
|
||||
return mAudioManager;
|
||||
}
|
||||
};
|
||||
mHdmiControlService.setIoLooper(mTestLooper.getLooper());
|
||||
mHdmiControlService.setHdmiCecConfig(new FakeHdmiCecConfig(context));
|
||||
@@ -418,6 +435,28 @@ public class HdmiCecLocalDeviceTest {
|
||||
assertThat(mStandbyMessageReceived).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleUserControlPressed_muteFunction() {
|
||||
@Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
|
||||
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
|
||||
HdmiCecKeycode.CEC_KEYCODE_MUTE_FUNCTION));
|
||||
|
||||
assertEquals(result, Constants.HANDLED);
|
||||
verify(mAudioManager, times(1))
|
||||
.adjustStreamVolume(anyInt(), eq(AudioManager.ADJUST_MUTE), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleUserControlPressed_restoreVolumeFunction() {
|
||||
@Constants.HandleMessageResult int result = mHdmiLocalDevice.handleUserControlPressed(
|
||||
HdmiCecMessageBuilder.buildUserControlPressed(ADDR_TV, ADDR_PLAYBACK_1,
|
||||
HdmiCecKeycode.CEC_KEYCODE_RESTORE_VOLUME_FUNCTION));
|
||||
|
||||
assertEquals(result, Constants.HANDLED);
|
||||
verify(mAudioManager, times(1))
|
||||
.adjustStreamVolume(anyInt(), eq(AudioManager.ADJUST_UNMUTE), anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleVendorCommand_notHandled() {
|
||||
HdmiCecMessage vendorCommand = HdmiCecMessageBuilder.buildVendorCommand(ADDR_TV,
|
||||
|
||||
Reference in New Issue
Block a user