Merge "Report device status event in HdmiControlService"
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 353f603..e61bad9 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -142,6 +142,9 @@
}
private static void invokeCallback(IHdmiControlCallback callback, int result) {
+ if (callback == null) {
+ return;
+ }
try {
callback.onComplete(result);
} catch (RemoteException e) {
@@ -455,7 +458,7 @@
final void addCecDevice(HdmiCecDeviceInfo info) {
assertRunOnServiceThread();
addDeviceInfo(info);
-
+ mService.invokeDeviceEventListeners(info, true);
// TODO: announce new device detection.
}
@@ -466,10 +469,9 @@
*/
final void removeCecDevice(int address) {
assertRunOnServiceThread();
- removeDeviceInfo(address);
+ HdmiCecDeviceInfo info = removeDeviceInfo(address);
mCecMessageCache.flushMessagesFrom(address);
-
- // TODO: announce a device removal.
+ mService.invokeDeviceEventListeners(info, false);
}
/**
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index fddb833..050ba46 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -37,6 +37,7 @@
import android.util.SparseArray;
import android.util.SparseIntArray;
+import com.android.internal.annotations.GuardedBy;
import com.android.server.SystemService;
import com.android.server.hdmi.HdmiCecController.AllocateAddressCallback;
@@ -94,21 +95,25 @@
// List of listeners registered by callers that want to get notified of
// hotplug events.
+ @GuardedBy("mLock")
private final ArrayList<IHdmiHotplugEventListener> mHotplugEventListeners = new ArrayList<>();
// List of records for hotplug event listener to handle the the caller killed in action.
+ @GuardedBy("mLock")
private final ArrayList<HotplugEventListenerRecord> mHotplugEventListenerRecords =
new ArrayList<>();
// List of listeners registered by callers that want to get notified of
// device status events.
+ @GuardedBy("mLock")
private final ArrayList<IHdmiDeviceEventListener> mDeviceEventListeners = new ArrayList<>();
// List of records for device event listener to handle the the caller killed in action.
+ @GuardedBy("mLock")
private final ArrayList<DeviceEventListenerRecord> mDeviceEventListenerRecords =
new ArrayList<>();
- // Handler running on service thread. It's used to run a task in service thread.
+ // Handler used to run a task in service thread.
private final Handler mHandler = new Handler();
@Nullable
@@ -171,8 +176,7 @@
}
finished.append(deviceType, logicalAddress);
- // Once finish address allocation for all devices, notify
- // it to each device.
+ // Address allocation completed for all devices. Notify each device.
if (deviceTypes.size() == finished.size()) {
notifyAddressAllocated(devices);
}
@@ -663,15 +667,28 @@
}
private void addDeviceEventListener(IHdmiDeviceEventListener listener) {
+ DeviceEventListenerRecord record = new DeviceEventListenerRecord(listener);
+ try {
+ listener.asBinder().linkToDeath(record, 0);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Listener already died");
+ return;
+ }
synchronized (mLock) {
- for (DeviceEventListenerRecord record : mDeviceEventListenerRecords) {
- if (record.mListener.asBinder() == listener.asBinder()) {
- listener.asBinder().unlinkToDeath(record, 0);
- mDeviceEventListenerRecords.remove(record);
- break;
+ mDeviceEventListeners.add(listener);
+ mDeviceEventListenerRecords.add(record);
+ }
+ }
+
+ void invokeDeviceEventListeners(HdmiCecDeviceInfo device, boolean activated) {
+ synchronized (mLock) {
+ for (IHdmiDeviceEventListener listener : mDeviceEventListeners) {
+ try {
+ listener.onStatusChanged(device, activated);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to report device event:" + e);
}
}
- mHotplugEventListeners.remove(listener);
}
}
@@ -683,16 +700,16 @@
}
}
- private void announceHotplugEvent(int portNo, boolean connected) {
- HdmiHotplugEvent event = new HdmiHotplugEvent(portNo, connected);
+ private void announceHotplugEvent(int portId, boolean connected) {
+ HdmiHotplugEvent event = new HdmiHotplugEvent(portId, connected);
synchronized (mLock) {
for (IHdmiHotplugEventListener listener : mHotplugEventListeners) {
- invokeHotplugEventListener(listener, event);
+ invokeHotplugEventListenerLocked(listener, event);
}
}
}
- private void invokeHotplugEventListener(IHdmiHotplugEventListener listener,
+ private void invokeHotplugEventListenerLocked(IHdmiHotplugEventListener listener,
HdmiHotplugEvent event) {
try {
listener.onReceived(event);