Merge changes Idebffbec,Ief4435c7,I9f9a5f46,Iee495e71,I949587e1, ...
* changes: Add Power Status query steps in Device Discovery Action. Unmute when turning system audio mode on. Make sure the device route to HOME when OneTouchPlay is triggered. Add APIs to expose some cec control to other services. Fix port id mismatch temporarily. Add dump info of local active port and routing port. Set routing feature enabled to default false and dump its status. Add a thread safe copy of connected device list.
This commit is contained in:
@@ -33,6 +33,8 @@ import android.os.SystemProperties;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The {@link HdmiControlManager} class is used to send HDMI control messages
|
||||
* to attached CEC devices.
|
||||
@@ -403,6 +405,72 @@ public final class HdmiControlManager {
|
||||
return (HdmiSwitchClient) getClient(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a snapshot of the real-time status of the remote devices.
|
||||
*
|
||||
* @return a list of {@link HdmiDeviceInfo} of the devices connected to the current device.
|
||||
*
|
||||
* TODO(b/110094868): unhide for Q
|
||||
* @hide
|
||||
*/
|
||||
public List<HdmiDeviceInfo> getConnectedDevicesList() {
|
||||
try {
|
||||
return mService.getDeviceList();
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Power off the target device.
|
||||
*
|
||||
* @param deviceInfo HdmiDeviceInfo of the device to be powered off
|
||||
*
|
||||
* TODO(b/110094868): unhide for Q
|
||||
* @hide
|
||||
*/
|
||||
public void powerOffRemoteDevice(HdmiDeviceInfo deviceInfo) {
|
||||
try {
|
||||
mService.powerOffRemoteDevice(
|
||||
deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Power on the target device.
|
||||
*
|
||||
* @param deviceInfo HdmiDeviceInfo of the device to be powered on
|
||||
*
|
||||
* TODO(b/110094868): unhide for Q
|
||||
* @hide
|
||||
*/
|
||||
public void powerOnRemoteDevice(HdmiDeviceInfo deviceInfo) {
|
||||
try {
|
||||
mService.powerOnRemoteDevice(
|
||||
deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ask the target device to be the new Active Source.
|
||||
*
|
||||
* @param deviceInfo HdmiDeviceInfo of the target device
|
||||
*
|
||||
* TODO(b/110094868): unhide for Q
|
||||
* @hide
|
||||
*/
|
||||
public void askRemoteDeviceToBecomeActiveSource(HdmiDeviceInfo deviceInfo) {
|
||||
try {
|
||||
mService.askRemoteDeviceToBecomeActiveSource(deviceInfo.getPhysicalAddress());
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls standby mode of the system. It will also try to turn on/off the connected devices if
|
||||
* necessary.
|
||||
|
||||
@@ -61,6 +61,9 @@ interface IHdmiControlService {
|
||||
void setInputChangeListener(IHdmiInputChangeListener listener);
|
||||
List<HdmiDeviceInfo> getInputDevices();
|
||||
List<HdmiDeviceInfo> getDeviceList();
|
||||
void powerOffRemoteDevice(int logicalAddress, int powerStatus);
|
||||
void powerOnRemoteDevice(int logicalAddress, int powerStatus);
|
||||
void askRemoteDeviceToBecomeActiveSource(int physicalAddress);
|
||||
void sendVendorCommand(int deviceType, int targetAddress, in byte[] params,
|
||||
boolean hasVendorId);
|
||||
void addVendorCommandListener(IHdmiVendorCommandListener listener, int deviceType);
|
||||
|
||||
@@ -327,6 +327,18 @@ public class HdmiAudioSystemClientTest {
|
||||
public int getPhysicalAddress() {
|
||||
return 0x0000;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void powerOffRemoteDevice(int logicalAddress, int powerStatus) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void powerOnRemoteDevice(int logicalAddress, int powerStatus) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void askRemoteDeviceToBecomeActiveSource(int physicalAddress) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.server.hdmi;
|
||||
|
||||
import android.hardware.hdmi.HdmiControlManager;
|
||||
import android.hardware.hdmi.HdmiDeviceInfo;
|
||||
import android.util.Slog;
|
||||
|
||||
@@ -51,8 +52,10 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction {
|
||||
private static final int STATE_WAITING_FOR_OSD_NAME = 3;
|
||||
// State in which the action is waiting for gathering vendor id of non-local devices.
|
||||
private static final int STATE_WAITING_FOR_VENDOR_ID = 4;
|
||||
// State in which the action is waiting for devices to be ready
|
||||
// State in which the action is waiting for devices to be ready.
|
||||
private static final int STATE_WAITING_FOR_DEVICES = 5;
|
||||
// State in which the action is waiting for gathering power status of non-local devices.
|
||||
private static final int STATE_WAITING_FOR_POWER = 6;
|
||||
|
||||
/**
|
||||
* Interface used to report result of device discovery.
|
||||
@@ -74,6 +77,7 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction {
|
||||
private int mPhysicalAddress = Constants.INVALID_PHYSICAL_ADDRESS;
|
||||
private int mPortId = Constants.INVALID_PORT_ID;
|
||||
private int mVendorId = Constants.UNKNOWN_VENDOR_ID;
|
||||
private int mPowerStatus = HdmiControlManager.POWER_STATUS_UNKNOWN;
|
||||
private String mDisplayName = "";
|
||||
private int mDeviceType = HdmiDeviceInfo.DEVICE_INACTIVE;
|
||||
|
||||
@@ -83,7 +87,7 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction {
|
||||
|
||||
private HdmiDeviceInfo toHdmiDeviceInfo() {
|
||||
return new HdmiDeviceInfo(mLogicalAddress, mPhysicalAddress, mPortId, mDeviceType,
|
||||
mVendorId, mDisplayName);
|
||||
mVendorId, mDisplayName, mPowerStatus);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -237,6 +241,29 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction {
|
||||
addTimer(mState, HdmiConfig.TIMEOUT_MS);
|
||||
}
|
||||
|
||||
private void startPowerStatusStage() {
|
||||
Slog.v(TAG, "Start [Power Status Stage]:" + mDevices.size());
|
||||
mProcessedDeviceCount = 0;
|
||||
mState = STATE_WAITING_FOR_POWER;
|
||||
|
||||
checkAndProceedStage();
|
||||
}
|
||||
|
||||
private void queryPowerStatus(int address) {
|
||||
if (!verifyValidLogicalAddress(address)) {
|
||||
checkAndProceedStage();
|
||||
return;
|
||||
}
|
||||
|
||||
mActionTimer.clearTimerMessage();
|
||||
|
||||
if (mayProcessMessageIfCached(address, Constants.MESSAGE_REPORT_POWER_STATUS)) {
|
||||
return;
|
||||
}
|
||||
sendCommand(HdmiCecMessageBuilder.buildGiveDevicePowerStatus(getSourceAddress(), address));
|
||||
addTimer(mState, HdmiConfig.TIMEOUT_MS);
|
||||
}
|
||||
|
||||
private boolean mayProcessMessageIfCached(int address, int opcode) {
|
||||
HdmiCecMessage message = getCecMessageCache().getMessage(address, opcode);
|
||||
if (message != null) {
|
||||
@@ -275,6 +302,16 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case STATE_WAITING_FOR_POWER:
|
||||
if (cmd.getOpcode() == Constants.MESSAGE_REPORT_POWER_STATUS) {
|
||||
handleReportPowerStatus(cmd);
|
||||
return true;
|
||||
} else if ((cmd.getOpcode() == Constants.MESSAGE_FEATURE_ABORT)
|
||||
&& ((cmd.getParams()[0] & 0xFF) == Constants.MESSAGE_REPORT_POWER_STATUS)) {
|
||||
handleReportPowerStatus(cmd);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
case STATE_WAITING_FOR_DEVICE_POLLING:
|
||||
// Fall through.
|
||||
default:
|
||||
@@ -359,6 +396,26 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction {
|
||||
checkAndProceedStage();
|
||||
}
|
||||
|
||||
private void handleReportPowerStatus(HdmiCecMessage cmd) {
|
||||
Preconditions.checkState(mProcessedDeviceCount < mDevices.size());
|
||||
|
||||
DeviceInfo current = mDevices.get(mProcessedDeviceCount);
|
||||
if (current.mLogicalAddress != cmd.getSource()) {
|
||||
Slog.w(TAG, "Unmatched address[expected:" + current.mLogicalAddress + ", actual:"
|
||||
+ cmd.getSource());
|
||||
return;
|
||||
}
|
||||
|
||||
if (cmd.getOpcode() != Constants.MESSAGE_FEATURE_ABORT) {
|
||||
byte[] params = cmd.getParams();
|
||||
int powerStatus = params[0] & 0xFF;
|
||||
current.mPowerStatus = powerStatus;
|
||||
}
|
||||
|
||||
increaseProcessedDeviceCount();
|
||||
checkAndProceedStage();
|
||||
}
|
||||
|
||||
private void increaseProcessedDeviceCount() {
|
||||
mProcessedDeviceCount++;
|
||||
mTimeoutRetry = 0;
|
||||
@@ -402,6 +459,9 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction {
|
||||
startVendorIdStage();
|
||||
return;
|
||||
case STATE_WAITING_FOR_VENDOR_ID:
|
||||
startPowerStatusStage();
|
||||
return;
|
||||
case STATE_WAITING_FOR_POWER:
|
||||
wrapUpAndFinish();
|
||||
return;
|
||||
default:
|
||||
@@ -427,6 +487,9 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction {
|
||||
case STATE_WAITING_FOR_VENDOR_ID:
|
||||
queryVendorId(address);
|
||||
return;
|
||||
case STATE_WAITING_FOR_POWER:
|
||||
queryPowerStatus(address);
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -448,7 +511,11 @@ final class DeviceDiscoveryAction extends HdmiCecFeatureAction {
|
||||
}
|
||||
mTimeoutRetry = 0;
|
||||
Slog.v(TAG, "Timeout[State=" + mState + ", Processed=" + mProcessedDeviceCount);
|
||||
removeDevice(mProcessedDeviceCount);
|
||||
if (mState != STATE_WAITING_FOR_POWER) {
|
||||
removeDevice(mProcessedDeviceCount);
|
||||
} else {
|
||||
increaseProcessedDeviceCount();
|
||||
}
|
||||
checkAndProceedStage();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ import com.android.server.hdmi.HdmiAnnotations.ServiceThreadOnly;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -84,6 +85,10 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
// processing.
|
||||
private final HashMap<Integer, String> mTvInputs = new HashMap<>();
|
||||
|
||||
// Copy of mDeviceInfos to guarantee thread-safety.
|
||||
@GuardedBy("mLock")
|
||||
private List<HdmiDeviceInfo> mSafeAllDeviceInfos = Collections.emptyList();
|
||||
|
||||
// Map-like container of all cec devices.
|
||||
// device id is used as key of container.
|
||||
private final SparseArray<HdmiDeviceInfo> mDeviceInfos = new SparseArray<>();
|
||||
@@ -91,16 +96,13 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
protected HdmiCecLocalDeviceAudioSystem(HdmiControlService service) {
|
||||
super(service, HdmiDeviceInfo.DEVICE_AUDIO_SYSTEM);
|
||||
mRoutingControlFeatureEnabled =
|
||||
mService.readBooleanSetting(Global.HDMI_CEC_SWITCH_ENABLED, true);
|
||||
mService.readBooleanSetting(Global.HDMI_CEC_SWITCH_ENABLED, false);
|
||||
mSystemAudioControlFeatureEnabled =
|
||||
mService.readBooleanSetting(Global.HDMI_SYSTEM_AUDIO_CONTROL_ENABLED, true);
|
||||
// TODO(amyjojo): make the map ro property.
|
||||
mTvInputs.put(Constants.CEC_SWITCH_HDMI1,
|
||||
"com.droidlogic.tvinput/.services.Hdmi1InputService/HW5");
|
||||
mTvInputs.put(Constants.CEC_SWITCH_HDMI2,
|
||||
"com.droidlogic.tvinput/.services.Hdmi2InputService/HW6");
|
||||
mTvInputs.put(Constants.CEC_SWITCH_HDMI3,
|
||||
"com.droidlogic.tvinput/.services.Hdmi3InputService/HW7");
|
||||
// TODO(amyjojo): Maintain a portId to TvinputId map.
|
||||
mTvInputs.put(2, "com.droidlogic.tvinput/.services.Hdmi1InputService/HW5");
|
||||
mTvInputs.put(4, "com.droidlogic.tvinput/.services.Hdmi2InputService/HW6");
|
||||
mTvInputs.put(1, "com.droidlogic.tvinput/.services.Hdmi3InputService/HW7");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -174,6 +176,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
removeDeviceInfo(deviceInfo.getId());
|
||||
}
|
||||
mDeviceInfos.append(deviceInfo.getId(), deviceInfo);
|
||||
updateSafeDeviceInfoList();
|
||||
return oldDeviceInfo;
|
||||
}
|
||||
|
||||
@@ -191,6 +194,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
if (deviceInfo != null) {
|
||||
mDeviceInfos.remove(id);
|
||||
}
|
||||
updateSafeDeviceInfoList();
|
||||
return deviceInfo;
|
||||
}
|
||||
|
||||
@@ -207,6 +211,24 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
return mDeviceInfos.get(HdmiDeviceInfo.idForCecDevice(logicalAddress));
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
private void updateSafeDeviceInfoList() {
|
||||
assertRunOnServiceThread();
|
||||
List<HdmiDeviceInfo> copiedDevices = HdmiUtils.sparseArrayToList(mDeviceInfos);
|
||||
synchronized (mLock) {
|
||||
mSafeAllDeviceInfos = copiedDevices;
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
List<HdmiDeviceInfo> getSafeCecDevicesLocked() {
|
||||
ArrayList<HdmiDeviceInfo> infoList = new ArrayList<>();
|
||||
for (HdmiDeviceInfo info : mSafeAllDeviceInfos) {
|
||||
infoList.add(info);
|
||||
}
|
||||
return infoList;
|
||||
}
|
||||
|
||||
private void invokeDeviceEventListener(HdmiDeviceInfo info, int status) {
|
||||
mService.invokeDeviceEventListeners(info, status);
|
||||
}
|
||||
@@ -723,7 +745,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
*/
|
||||
private void setSystemAudioMode(boolean newSystemAudioMode) {
|
||||
int targetPhysicalAddress = getActiveSource().physicalAddress;
|
||||
int port = getLocalPortFromPhysicalAddress(targetPhysicalAddress);
|
||||
int port = mService.pathToPortId(targetPhysicalAddress);
|
||||
if (newSystemAudioMode && port >= 0) {
|
||||
switchToAudioInput();
|
||||
}
|
||||
@@ -731,16 +753,18 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
// PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE is false when device never needs to be muted.
|
||||
boolean currentMuteStatus =
|
||||
mService.getAudioManager().isStreamMute(AudioManager.STREAM_MUSIC);
|
||||
if (SystemProperties.getBoolean(
|
||||
Constants.PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE, true)
|
||||
&& currentMuteStatus == newSystemAudioMode) {
|
||||
mService.getAudioManager()
|
||||
.adjustStreamVolume(
|
||||
AudioManager.STREAM_MUSIC,
|
||||
newSystemAudioMode
|
||||
? AudioManager.ADJUST_UNMUTE
|
||||
: AudioManager.ADJUST_MUTE,
|
||||
0);
|
||||
if (currentMuteStatus == newSystemAudioMode) {
|
||||
if (SystemProperties.getBoolean(
|
||||
Constants.PROPERTY_SYSTEM_AUDIO_MODE_MUTING_ENABLE, true)
|
||||
|| newSystemAudioMode) {
|
||||
mService.getAudioManager()
|
||||
.adjustStreamVolume(
|
||||
AudioManager.STREAM_MUSIC,
|
||||
newSystemAudioMode
|
||||
? AudioManager.ADJUST_UNMUTE
|
||||
: AudioManager.ADJUST_MUTE,
|
||||
0);
|
||||
}
|
||||
}
|
||||
updateAudioManagerForSystemAudio(newSystemAudioMode);
|
||||
synchronized (mLock) {
|
||||
@@ -922,7 +946,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
|
||||
@Override
|
||||
protected void switchInputOnReceivingNewActivePath(int physicalAddress) {
|
||||
int port = getLocalPortFromPhysicalAddress(physicalAddress);
|
||||
int port = mService.pathToPortId(physicalAddress);
|
||||
if (isSystemAudioActivated() && port < 0) {
|
||||
// If system audio mode is on and the new active source is not under the current device,
|
||||
// Will switch to ARC input.
|
||||
@@ -994,7 +1018,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
|
||||
@Override
|
||||
protected void handleRoutingChangeAndInformation(int physicalAddress, HdmiCecMessage message) {
|
||||
int port = getLocalPortFromPhysicalAddress(physicalAddress);
|
||||
int port = mService.pathToPortId(physicalAddress);
|
||||
// Routing change or information sent from switches under the current device can be ignored.
|
||||
if (port > 0) {
|
||||
return;
|
||||
@@ -1063,6 +1087,10 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
@ServiceThreadOnly
|
||||
private void launchDeviceDiscovery() {
|
||||
assertRunOnServiceThread();
|
||||
if (hasAction(DeviceDiscoveryAction.class)) {
|
||||
Slog.i(TAG, "Device Discovery Action is in progress. Restarting.");
|
||||
removeAction(DeviceDiscoveryAction.class);
|
||||
}
|
||||
DeviceDiscoveryAction action = new DeviceDiscoveryAction(this,
|
||||
new DeviceDiscoveryCallback() {
|
||||
@Override
|
||||
@@ -1086,6 +1114,7 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
invokeDeviceEventListener(info, HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE);
|
||||
}
|
||||
mDeviceInfos.clear();
|
||||
updateSafeDeviceInfoList();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1093,10 +1122,13 @@ public class HdmiCecLocalDeviceAudioSystem extends HdmiCecLocalDeviceSource {
|
||||
pw.println("HdmiCecLocalDeviceAudioSystem:");
|
||||
pw.increaseIndent();
|
||||
pw.println("mSystemAudioActivated: " + mSystemAudioActivated);
|
||||
pw.println("isRoutingFeatureEnabled " + isRoutingControlFeatureEnabled());
|
||||
pw.println("mSystemAudioControlFeatureEnabled: " + mSystemAudioControlFeatureEnabled);
|
||||
pw.println("mTvSystemAudioModeSupport: " + mTvSystemAudioModeSupport);
|
||||
pw.println("mArcEstablished: " + mArcEstablished);
|
||||
pw.println("mArcIntentUsed: " + mArcIntentUsed);
|
||||
pw.println("mRoutingPort: " + getRoutingPort());
|
||||
pw.println("mLocalActivePort: " + getLocalActivePort());
|
||||
HdmiUtils.dumpMap(pw, "mTvInputs:", mTvInputs);
|
||||
HdmiUtils.dumpSparseArray(pw, "mDeviceInfos:", mDeviceInfos);
|
||||
pw.decreaseIndent();
|
||||
|
||||
@@ -66,7 +66,7 @@ abstract class HdmiCecLocalDeviceSource extends HdmiCecLocalDevice {
|
||||
@LocalActivePort
|
||||
protected int mLocalActivePort = Constants.CEC_SWITCH_HOME;
|
||||
|
||||
// Whether the Routing Coutrol feature is enabled or not. True by default.
|
||||
// Whether the Routing Coutrol feature is enabled or not. False by default.
|
||||
@GuardedBy("mLock")
|
||||
protected boolean mRoutingControlFeatureEnabled;
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE;
|
||||
import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE;
|
||||
|
||||
import static com.android.internal.os.RoSystemProperties.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH;
|
||||
import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED;
|
||||
import static com.android.server.hdmi.Constants.DISABLED;
|
||||
import static com.android.server.hdmi.Constants.ENABLED;
|
||||
import static com.android.server.hdmi.Constants.OPTION_MHL_ENABLE;
|
||||
@@ -1615,13 +1616,64 @@ public class HdmiControlService extends SystemService {
|
||||
public List<HdmiDeviceInfo> getDeviceList() {
|
||||
enforceAccessPermission();
|
||||
HdmiCecLocalDeviceTv tv = tv();
|
||||
synchronized (mLock) {
|
||||
return (tv == null)
|
||||
if (tv != null) {
|
||||
synchronized (mLock) {
|
||||
return tv.getSafeCecDevicesLocked();
|
||||
}
|
||||
} else {
|
||||
HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem();
|
||||
synchronized (mLock) {
|
||||
return (audioSystem == null)
|
||||
? Collections.<HdmiDeviceInfo>emptyList()
|
||||
: tv.getSafeCecDevicesLocked();
|
||||
: audioSystem.getSafeCecDevicesLocked();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void powerOffRemoteDevice(int logicalAddress, int powerStatus) {
|
||||
enforceAccessPermission();
|
||||
runOnServiceThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (powerStatus == HdmiControlManager.POWER_STATUS_ON
|
||||
|| powerStatus == HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON) {
|
||||
sendCecCommand(HdmiCecMessageBuilder.buildStandby(
|
||||
getRemoteControlSourceAddress(), logicalAddress));
|
||||
} else {
|
||||
Slog.w(TAG, "Device " + logicalAddress + " is already off " + powerStatus);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void powerOnRemoteDevice(int logicalAddress, int powerStatus) {
|
||||
// TODO(amyjojo): implement the method
|
||||
}
|
||||
|
||||
@Override
|
||||
// TODO(AMYJOJO): add a result callback
|
||||
public void askRemoteDeviceToBecomeActiveSource(int physicalAddress) {
|
||||
enforceAccessPermission();
|
||||
runOnServiceThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
HdmiCecMessage setStreamPath = HdmiCecMessageBuilder.buildSetStreamPath(
|
||||
getRemoteControlSourceAddress(), physicalAddress);
|
||||
if (pathToPortId(physicalAddress) != Constants.INVALID_PORT_ID) {
|
||||
if (getSwitchDevice() != null) {
|
||||
getSwitchDevice().handleSetStreamPath(setStreamPath);
|
||||
} else {
|
||||
Slog.e(TAG, "Can't get the correct local device to handle routing.");
|
||||
}
|
||||
} else {
|
||||
sendCecCommand(setStreamPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSystemAudioVolume(final int oldIndex, final int newIndex,
|
||||
final int maxIndex) {
|
||||
@@ -1917,6 +1969,29 @@ public class HdmiControlService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
// Get the source address to send out commands to devices connected to the current device
|
||||
// when other services interact with HdmiControlService.
|
||||
private int getRemoteControlSourceAddress() {
|
||||
if (isAudioSystemDevice()) {
|
||||
return audioSystem().getDeviceInfo().getLogicalAddress();
|
||||
} else if (isPlaybackDevice()) {
|
||||
return playback().getDeviceInfo().getLogicalAddress();
|
||||
}
|
||||
return ADDR_UNREGISTERED;
|
||||
}
|
||||
|
||||
// Get the switch device to do CEC routing control
|
||||
@Nullable
|
||||
private HdmiCecLocalDeviceSource getSwitchDevice() {
|
||||
if (isAudioSystemDevice()) {
|
||||
return audioSystem();
|
||||
}
|
||||
if (isPlaybackDevice()) {
|
||||
return playback();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@ServiceThreadOnly
|
||||
private void oneTouchPlay(final IHdmiControlCallback callback) {
|
||||
assertRunOnServiceThread();
|
||||
|
||||
@@ -92,6 +92,9 @@ final class OneTouchPlayAction extends HdmiCecFeatureAction {
|
||||
if (source.mService.audioSystem() != null) {
|
||||
source = source.mService.audioSystem();
|
||||
}
|
||||
if (source.getLocalActivePort() != Constants.CEC_SWITCH_HOME) {
|
||||
source.switchInputOnReceivingNewActivePath(getSourceAddress());
|
||||
}
|
||||
source.setRoutingPort(Constants.CEC_SWITCH_HOME);
|
||||
source.setLocalActivePort(Constants.CEC_SWITCH_HOME);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user