am 53130b88: Merge "CEC: Invoke events listener upon MHL device state change" into lmp-dev

* commit '53130b886f8baf2e7e75fdae8f71d90cc2b51929':
  CEC: Invoke events listener upon MHL device state change
This commit is contained in:
Jinsuk Kim
2014-08-19 06:07:54 +00:00
committed by Android Git Automerger
4 changed files with 68 additions and 14 deletions

View File

@@ -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;

View File

@@ -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

View File

@@ -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());
@@ -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);
}
/**
@@ -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
@@ -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 {
@@ -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

View File

@@ -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.
*