summaryrefslogtreecommitdiffstats
path: root/services/core/java/com/android/server/hdmi
diff options
context:
space:
mode:
authorJinsuk Kim <jinsukkim@google.com>2014-08-18 15:01:53 +0900
committerJinsuk Kim <jinsukkim@google.com>2014-08-19 13:41:51 +0900
commited0864557b3340ab7db00e2dc95b29c4b8bb485d (patch)
tree16e9101f448d1b9ab8597929fa74b1da8233e846 /services/core/java/com/android/server/hdmi
parent03861d072131563561bb5873d35dc346e82bd904 (diff)
downloadframeworks_base-ed0864557b3340ab7db00e2dc95b29c4b8bb485d.zip
frameworks_base-ed0864557b3340ab7db00e2dc95b29c4b8bb485d.tar.gz
frameworks_base-ed0864557b3340ab7db00e2dc95b29c4b8bb485d.tar.bz2
CEC: Invoke events listener upon MHL device state change
With this change, mobile devices state changes are propagated through TIF to UI, hence the input pickers shows the mobile devices as expected. Bug: 16986744 Change-Id: Id633207acf4f814f57d43cc1de5f8cb88ac23ad6
Diffstat (limited to 'services/core/java/com/android/server/hdmi')
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java6
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiControlService.java58
-rw-r--r--services/core/java/com/android/server/hdmi/HdmiUtils.java16
3 files changed, 67 insertions, 13 deletions
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 809fef4..126a56d 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -1007,10 +1007,8 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
/**
* Return external input devices.
*/
- List<HdmiDeviceInfo> getSafeExternalInputs() {
- synchronized (mLock) {
- return mSafeExternalInputs;
- }
+ List<HdmiDeviceInfo> getSafeExternalInputsLocked() {
+ return mSafeExternalInputs;
}
@ServiceThreadOnly
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 14c066e..0b2cf8a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -16,6 +16,8 @@
package com.android.server.hdmi;
+import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE;
+import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE;
import static com.android.server.hdmi.Constants.DISABLED;
import static com.android.server.hdmi.Constants.ENABLED;
import static com.android.server.hdmi.Constants.OPTION_CEC_AUTO_WAKEUP;
@@ -202,6 +204,9 @@ public final class HdmiControlService extends SystemService {
@GuardedBy("mLock")
private boolean mMhlInputChangeEnabled;
+ @GuardedBy("mLock")
+ private List<HdmiDeviceInfo> mMhlDevices;
+
// List of listeners registered by callers that want to get notified of
// system audio mode changes.
private final ArrayList<IHdmiSystemAudioModeChangeListener>
@@ -293,6 +298,7 @@ public final class HdmiControlService extends SystemService {
Slog.i(TAG, "Device does not support MHL-control.");
}
initPortInfo();
+ mMhlDevices = Collections.emptyList();
mMessageValidator = new HdmiCecMessageValidator(this);
publishBinderService(Context.HDMI_CONTROL_SERVICE, new BinderService());
@@ -684,16 +690,16 @@ public final class HdmiControlService extends SystemService {
/**
* Called when a new hotplug event is issued.
*
- * @param portNo hdmi port number where hot plug event issued.
+ * @param portId hdmi port number where hot plug event issued.
* @param connected whether to be plugged in or not
*/
@ServiceThreadOnly
- void onHotplug(int portNo, boolean connected) {
+ void onHotplug(int portId, boolean connected) {
assertRunOnServiceThread();
for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) {
- device.onHotplug(portNo, connected);
+ device.onHotplug(portId, connected);
}
- announceHotplugEvent(portNo, connected);
+ announceHotplugEvent(portId, connected);
}
/**
@@ -794,10 +800,15 @@ public final class HdmiControlService extends SystemService {
HdmiMhlLocalDevice device = mMhlController.removeLocalDevice(portId);
if (device != null) {
device.onDeviceRemoved();
+ // There is no explicit event for device removal unlike capability register event
+ // used for device addition . Hence we remove the device on hotplug event.
+ invokeDeviceEventListeners(device.getInfo(), DEVICE_EVENT_REMOVE_DEVICE);
+ updateSafeMhlInput();
} else {
Slog.w(TAG, "No device to remove:[portId=" + portId);
}
}
+ announceHotplugEvent(portId, connected);
}
@ServiceThreadOnly
@@ -824,18 +835,45 @@ public final class HdmiControlService extends SystemService {
}
@ServiceThreadOnly
- void handleCapabilityRegisterChanged(int portId, int adopterId, int deviceId) {
+ void handleMhlCapabilityRegisterChanged(int portId, int adopterId, int deviceId) {
assertRunOnServiceThread();
HdmiMhlLocalDevice device = mMhlController.getLocalDevice(portId);
- // Hot plug event should be called before capability register change event.
+
+ // Hotplug event should already have been called before capability register change event.
if (device != null) {
device.setCapabilityRegister(adopterId, deviceId);
+ invokeDeviceEventListeners(device.getInfo(), DEVICE_EVENT_ADD_DEVICE);
+ updateSafeMhlInput();
} else {
Slog.w(TAG, "No mhl device exists for capability register change event[portId:"
+ portId + ", adopterId:" + adopterId + ", deviceId:" + deviceId + "]");
}
}
+ @ServiceThreadOnly
+ private void updateSafeMhlInput() {
+ assertRunOnServiceThread();
+ List<HdmiDeviceInfo> inputs = Collections.emptyList();
+ SparseArray<HdmiMhlLocalDevice> devices = mMhlController.getAllLocalDevices();
+ for (int i = 0; i < devices.size(); ++i) {
+ HdmiMhlLocalDevice device = devices.valueAt(i);
+ HdmiDeviceInfo info = device.getInfo();
+ if (info != null) {
+ if (inputs.isEmpty()) {
+ inputs = new ArrayList<>();
+ }
+ inputs.add(device.getInfo());
+ }
+ }
+ synchronized (mLock) {
+ mMhlDevices = inputs;
+ }
+ }
+
+ private List<HdmiDeviceInfo> getMhlDevicesLocked() {
+ return mMhlDevices;
+ }
+
// Record class that monitors the event of the caller of being killed. Used to clean up
// the listener list and record list accordingly.
private final class HotplugEventListenerRecord implements IBinder.DeathRecipient {
@@ -1139,10 +1177,12 @@ public final class HdmiControlService extends SystemService {
// No need to hold the lock for obtaining TV device as the local device instance
// is preserved while the HDMI control is enabled.
HdmiCecLocalDeviceTv tv = tv();
- if (tv == null) {
- return Collections.emptyList();
+ synchronized (mLock) {
+ List<HdmiDeviceInfo> cecDevices = (tv == null)
+ ? Collections.<HdmiDeviceInfo>emptyList()
+ : tv.getSafeExternalInputsLocked();
+ return HdmiUtils.mergeToUnmodifiableList(cecDevices, getMhlDevicesLocked());
}
- return tv.getSafeExternalInputs();
}
@Override
diff --git a/services/core/java/com/android/server/hdmi/HdmiUtils.java b/services/core/java/com/android/server/hdmi/HdmiUtils.java
index 23f19ff..22a519b 100644
--- a/services/core/java/com/android/server/hdmi/HdmiUtils.java
+++ b/services/core/java/com/android/server/hdmi/HdmiUtils.java
@@ -206,6 +206,22 @@ final class HdmiUtils {
return list;
}
+ static <T> List<T> mergeToUnmodifiableList(List<T> a, List<T> b) {
+ if (a.isEmpty() && b.isEmpty()) {
+ return Collections.emptyList();
+ }
+ if (a.isEmpty()) {
+ return Collections.unmodifiableList(b);
+ }
+ if (b.isEmpty()) {
+ return Collections.unmodifiableList(a);
+ }
+ List<T> newList = new ArrayList<>();
+ newList.addAll(a);
+ newList.addAll(b);
+ return Collections.unmodifiableList(newList);
+ }
+
/**
* See if the new path is affecting the active path.
*