diff options
author | Jinsuk Kim <jinsukkim@google.com> | 2014-08-18 15:01:53 +0900 |
---|---|---|
committer | Jinsuk Kim <jinsukkim@google.com> | 2014-08-19 13:41:51 +0900 |
commit | ed0864557b3340ab7db00e2dc95b29c4b8bb485d (patch) | |
tree | 16e9101f448d1b9ab8597929fa74b1da8233e846 /services/core/java/com/android/server/hdmi | |
parent | 03861d072131563561bb5873d35dc346e82bd904 (diff) | |
download | frameworks_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')
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. * |