Add APIs to expose some cec control to other services.
ag/5398143 We exposed Power on/Power off/Device select/Connected device list query from HdmiControlManager. Test: local tested Bug: 117775357 Change-Id: Iee495e7131f44282a60e83ad827faa1431a30389
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) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user