Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4893c7ef authored by Jinsuk Kim's avatar Jinsuk Kim
Browse files

Report device status event in HdmiControlService

This change allows the event listener (TIF) to get notified
of the CEC logical device status change (addition/removal),
and update the available tv inputs accordingly.

Change-Id: I7f2798ad47212120ecac8093ad281f683a3d125e
parent 5376c00d
Loading
Loading
Loading
Loading
+6 −4
Original line number Diff line number Diff line
@@ -142,6 +142,9 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
    }

    private static void invokeCallback(IHdmiControlCallback callback, int result) {
        if (callback == null) {
            return;
        }
        try {
            callback.onComplete(result);
        } catch (RemoteException e) {
@@ -455,7 +458,7 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
    final void addCecDevice(HdmiCecDeviceInfo info) {
        assertRunOnServiceThread();
        addDeviceInfo(info);

        mService.invokeDeviceEventListeners(info, true);
        // TODO: announce new device detection.
    }

@@ -466,10 +469,9 @@ final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
     */
    final void removeCecDevice(int address) {
        assertRunOnServiceThread();
        removeDeviceInfo(address);
        HdmiCecDeviceInfo info = removeDeviceInfo(address);
        mCecMessageCache.flushMessagesFrom(address);

        // TODO: announce a device removal.
        mService.invokeDeviceEventListeners(info, false);
    }

    /**
+30 −13
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.util.Slog;
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 @@ public final class HdmiControlService extends SystemService {

    // 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 @@ public final class HdmiControlService extends SystemService {
                    }
                    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 @@ public final class HdmiControlService extends SystemService {
    }

    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 @@ public final class HdmiControlService extends SystemService {
        }
    }

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