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

Commit 8809f1e5 authored by Jinsuk Kim's avatar Jinsuk Kim Committed by Android (Google) Code Review
Browse files

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

parents fc6b01f4 ed086455
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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;
+2 −4
Original line number Diff line number Diff line
@@ -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() {
+49 −9
Original line number Diff line number Diff line
@@ -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
+16 −0
Original line number Diff line number Diff line
@@ -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.
     *