summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/hardware/hdmi/HdmiTvClient.java18
-rw-r--r--core/java/android/hardware/hdmi/IHdmiControlService.aidl1
-rw-r--r--services/core/java/com/android/server/hdmi/ActiveSourceHandler.java5
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java46
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java13
-rw-r--r--services/core/java/com/android/server/hdmi/NewDeviceAction.java8
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)