Merge "Add SystemAudioAutoInitiationAction and SystemAudioStatusAction"
This commit is contained in:
committed by
Android (Google) Code Review
commit
bce527139a
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -377,6 +377,17 @@ public class HdmiCecMessageBuilder {
|
||||
return buildCommand(src, dest, HdmiCec.MESSAGE_USER_CONTROL_RELEASED);
|
||||
}
|
||||
|
||||
/**
|
||||
* Build <Give System Audio Mode Status> 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. ******/
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 */ }
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user