diff options
| author | Jinsuk Kim <jinsukkim@google.com> | 2014-10-20 10:00:04 +0900 |
|---|---|---|
| committer | Jinsuk Kim <jinsukkim@google.com> | 2014-10-20 11:32:47 +0900 |
| commit | bdf27fbf746bee11430c4db2ea6dfd026bae77fe (patch) | |
| tree | 1ec49e6871736b476e80e23252c3ec68cb7212f9 | |
| parent | 512c2330c652c56996bf3ef63ddad242752cebcd (diff) | |
CEC: add getDeviceList()
Returns the list of all the connected CEC device information. This is
different from getInputDevices() which returns devices of source type only.
For this, turned the local device address list to unmodifiable so that it can
be used by any threads.
Now respects the device type info passed through <Report Physical Address>
rather than always defaulting to the one from HdmiUtil.getTypeFromAddress().
This ensures future compatibility when a device of reserved logical address
comes with a specific type.
Bug: 18046603
Change-Id: I5f7d5e31706efba1ad5dcf4bcfd4ffc918d1d940
6 files changed, 73 insertions, 18 deletions
diff --git a/core/java/android/hardware/hdmi/HdmiTvClient.java b/core/java/android/hardware/hdmi/HdmiTvClient.java index 9d92fd9c7fbd..683d04b3ef5d 100644 --- a/core/java/android/hardware/hdmi/HdmiTvClient.java +++ b/core/java/android/hardware/hdmi/HdmiTvClient.java @@ -22,6 +22,9 @@ import android.hardware.hdmi.HdmiTimerRecordSources.TimerRecordSource; import android.os.RemoteException; import android.util.Log; +import java.util.Collections; +import java.util.List; + import libcore.util.EmptyArray; /** @@ -150,6 +153,21 @@ public final class HdmiTvClient extends HdmiClient { } /** + * Returns all the CEC devices connected to TV. + * + * @return list of {@link HdmiDeviceInfo} for connected CEC devices. + * Empty list is returned if there is none. + */ + public List<HdmiDeviceInfo> getDeviceList() { + try { + return mService.getDeviceList(); + } catch (RemoteException e) { + Log.e("TAG", "Failed to call getDeviceList():", e); + return Collections.<HdmiDeviceInfo>emptyList(); + } + } + + /** * Set system audio volume * * @param oldIndex current volume index diff --git a/core/java/android/hardware/hdmi/IHdmiControlService.aidl b/core/java/android/hardware/hdmi/IHdmiControlService.aidl index 4866a9a9b6e2..c1e924e59735 100644 --- a/core/java/android/hardware/hdmi/IHdmiControlService.aidl +++ b/core/java/android/hardware/hdmi/IHdmiControlService.aidl @@ -59,6 +59,7 @@ interface IHdmiControlService { void setSystemAudioMute(boolean mute); void setInputChangeListener(IHdmiInputChangeListener listener); List<HdmiDeviceInfo> getInputDevices(); + List<HdmiDeviceInfo> getDeviceList(); void sendVendorCommand(int deviceType, int targetAddress, in byte[] params, boolean hasVendorId); void addVendorCommandListener(IHdmiVendorCommandListener listener, int deviceType); diff --git a/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java b/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java index cb921125230f..9593a9cb8e8a 100644 --- a/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java +++ b/services/core/java/com/android/server/hdmi/ActiveSourceHandler.java @@ -57,8 +57,9 @@ final class ActiveSourceHandler { * Handles the incoming active source command. * * @param newActive new active source information + * @param deviceType device type of the new active source */ - void process(ActiveSource newActive) { + void process(ActiveSource newActive, int deviceType) { // Seq #17 HdmiCecLocalDeviceTv tv = mSource; ActiveSource activeSource = tv.getActiveSource(); @@ -68,7 +69,7 @@ final class ActiveSourceHandler { } HdmiDeviceInfo device = mService.getDeviceInfo(newActive.logicalAddress); if (device == null) { - tv.startNewDeviceAction(newActive); + tv.startNewDeviceAction(newActive, deviceType); } if (!tv.isProhibitMode()) { diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java index 1a5678b62961..6bae761c7478 100644 --- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java @@ -110,6 +110,9 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { // If true, TV wakes itself up when receiving <Text/Image View On>. private boolean mAutoWakeup; + // List of the logical address of local CEC devices. Unmodifiable, thread-safe. + private List<Integer> mLocalDeviceAddresses; + private final HdmiCecStandbyModeHandler mStandbyHandler; // If true, do not do routing control/send active source for internal source. @@ -141,10 +144,22 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { mSkipRoutingControl = (reason == HdmiControlService.INITIATED_BY_WAKE_UP_MESSAGE); launchRoutingControl(reason != HdmiControlService.INITIATED_BY_ENABLE_CEC && reason != HdmiControlService.INITIATED_BY_BOOT_UP); + mLocalDeviceAddresses = initLocalDeviceAddresses(); launchDeviceDiscovery(); startQueuedActions(); } + + @ServiceThreadOnly + private List<Integer> initLocalDeviceAddresses() { + assertRunOnServiceThread(); + List<Integer> addresses = new ArrayList<>(); + for (HdmiCecLocalDevice device : mService.getAllLocalDevices()) { + addresses.add(device.getDeviceInfo().getLogicalAddress()); + } + return Collections.unmodifiableList(addresses); + } + @Override @ServiceThreadOnly protected int getPreferredAddress() { @@ -390,11 +405,12 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { assertRunOnServiceThread(); int logicalAddress = message.getSource(); int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams()); - if (getCecDeviceInfo(logicalAddress) == null) { + HdmiDeviceInfo info = getCecDeviceInfo(logicalAddress); + if (info == null) { handleNewDeviceAtTheTailOfActivePath(physicalAddress); } else { ActiveSource activeSource = ActiveSource.of(logicalAddress, physicalAddress); - ActiveSourceHandler.create(this, null).process(activeSource); + ActiveSourceHandler.create(this, null).process(activeSource, info.getDeviceType()); } return true; } @@ -484,7 +500,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { if (!isInDeviceList(address, path)) { handleNewDeviceAtTheTailOfActivePath(path); } - startNewDeviceAction(ActiveSource.of(address, path)); + startNewDeviceAction(ActiveSource.of(address, path), type); return true; } @@ -520,7 +536,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { return false; } - void startNewDeviceAction(ActiveSource activeSource) { + void startNewDeviceAction(ActiveSource activeSource, int deviceType) { for (NewDeviceAction action : getActions(NewDeviceAction.class)) { // If there is new device action which has the same logical address and path // ignore new request. @@ -536,7 +552,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { } addAndStartAction(new NewDeviceAction(this, activeSource.logicalAddress, - activeSource.physicalAddress)); + activeSource.physicalAddress, deviceType)); } private void handleNewDeviceAtTheTailOfActivePath(int path) { @@ -1195,15 +1211,8 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { } } - @ServiceThreadOnly private boolean isLocalDeviceAddress(int address) { - assertRunOnServiceThread(); - for (HdmiCecLocalDevice device : mService.getAllLocalDevices()) { - if (device.isAddressOf(address)) { - return true; - } - } - return false; + return mLocalDeviceAddresses.contains(address); } @ServiceThreadOnly @@ -1253,6 +1262,17 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { } } + List<HdmiDeviceInfo> getSafeCecDevicesLocked() { + ArrayList<HdmiDeviceInfo> infoList = new ArrayList<>(); + for (HdmiDeviceInfo info : mSafeAllDeviceInfos) { + if (isLocalDeviceAddress(info.getLogicalAddress())) { + continue; + } + infoList.add(info); + } + return infoList; + } + /** * Called when a device is newly added or a new device is detected or * existing device is updated. diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java index 22b71470f2cc..d58d787eca17 100644 --- a/services/core/java/com/android/server/hdmi/HdmiControlService.java +++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java @@ -1232,6 +1232,19 @@ public final class HdmiControlService extends SystemService { } } + // Returns all the CEC devices on the bus including system audio, switch, + // even those of reserved type. + @Override + public List<HdmiDeviceInfo> getDeviceList() { + enforceAccessPermission(); + HdmiCecLocalDeviceTv tv = tv(); + synchronized (mLock) { + return (tv == null) + ? Collections.<HdmiDeviceInfo>emptyList() + : tv.getSafeCecDevicesLocked(); + } + } + @Override public void setSystemAudioVolume(final int oldIndex, final int newIndex, final int maxIndex) { diff --git a/services/core/java/com/android/server/hdmi/NewDeviceAction.java b/services/core/java/com/android/server/hdmi/NewDeviceAction.java index 207408515c91..998889bc270d 100644 --- a/services/core/java/com/android/server/hdmi/NewDeviceAction.java +++ b/services/core/java/com/android/server/hdmi/NewDeviceAction.java @@ -47,6 +47,7 @@ final class NewDeviceAction extends HdmiCecFeatureAction { private final int mDeviceLogicalAddress; private final int mDevicePhysicalAddress; + private final int mDeviceType; private int mVendorId; private String mDisplayName; @@ -57,12 +58,14 @@ final class NewDeviceAction extends HdmiCecFeatureAction { * @param source {@link HdmiCecLocalDevice} instance * @param deviceLogicalAddress logical address of the device in interest * @param devicePhysicalAddress physical address of the device in interest + * @param deviceType type of the device */ NewDeviceAction(HdmiCecLocalDevice source, int deviceLogicalAddress, - int devicePhysicalAddress) { + int devicePhysicalAddress, int deviceType) { super(source); mDeviceLogicalAddress = deviceLogicalAddress; mDevicePhysicalAddress = devicePhysicalAddress; + mDeviceType = deviceType; mVendorId = Constants.UNKNOWN_VENDOR_ID; } @@ -155,8 +158,7 @@ final class NewDeviceAction extends HdmiCecFeatureAction { HdmiDeviceInfo deviceInfo = new HdmiDeviceInfo( mDeviceLogicalAddress, mDevicePhysicalAddress, tv().getPortId(mDevicePhysicalAddress), - HdmiUtils.getTypeFromAddress(mDeviceLogicalAddress), - mVendorId, mDisplayName); + mDeviceType, mVendorId, mDisplayName); tv().addCecDevice(deviceInfo); if (HdmiUtils.getTypeFromAddress(mDeviceLogicalAddress) |
