Loading core/java/android/hardware/hdmi/HdmiDeviceInfo.java +1 −1 Original line number Diff line number Diff line Loading @@ -230,7 +230,7 @@ public class HdmiDeviceInfo implements Parcelable { mDeviceType = DEVICE_RESERVED; mVendorId = 0; mDevicePowerStatus = HdmiControlManager.POWER_STATUS_UNKNOWN; mDisplayName = "MHL"; mDisplayName = "Mobile"; mDeviceId = adopterId; mAdopterId = deviceId; Loading services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +2 −4 Original line number Diff line number Diff line Loading @@ -1007,11 +1007,9 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { /** * Return external input devices. */ List<HdmiDeviceInfo> getSafeExternalInputs() { synchronized (mLock) { List<HdmiDeviceInfo> getSafeExternalInputsLocked() { return mSafeExternalInputs; } } @ServiceThreadOnly private void updateSafeDeviceInfoList() { Loading services/core/java/com/android/server/hdmi/HdmiControlService.java +49 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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> Loading Loading @@ -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()); Loading Loading @@ -683,16 +689,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); } /** Loading Loading @@ -793,10 +799,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 Loading @@ -823,18 +834,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 { Loading Loading @@ -1138,10 +1176,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 Loading services/core/java/com/android/server/hdmi/HdmiUtils.java +16 −0 Original line number Diff line number Diff line Loading @@ -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. * Loading Loading
core/java/android/hardware/hdmi/HdmiDeviceInfo.java +1 −1 Original line number Diff line number Diff line Loading @@ -230,7 +230,7 @@ public class HdmiDeviceInfo implements Parcelable { mDeviceType = DEVICE_RESERVED; mVendorId = 0; mDevicePowerStatus = HdmiControlManager.POWER_STATUS_UNKNOWN; mDisplayName = "MHL"; mDisplayName = "Mobile"; mDeviceId = adopterId; mAdopterId = deviceId; Loading
services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java +2 −4 Original line number Diff line number Diff line Loading @@ -1007,11 +1007,9 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice { /** * Return external input devices. */ List<HdmiDeviceInfo> getSafeExternalInputs() { synchronized (mLock) { List<HdmiDeviceInfo> getSafeExternalInputsLocked() { return mSafeExternalInputs; } } @ServiceThreadOnly private void updateSafeDeviceInfoList() { Loading
services/core/java/com/android/server/hdmi/HdmiControlService.java +49 −9 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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> Loading Loading @@ -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()); Loading Loading @@ -683,16 +689,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); } /** Loading Loading @@ -793,10 +799,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 Loading @@ -823,18 +834,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 { Loading Loading @@ -1138,10 +1176,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 Loading
services/core/java/com/android/server/hdmi/HdmiUtils.java +16 −0 Original line number Diff line number Diff line Loading @@ -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. * Loading