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

Commit 6f031afe authored by Amy's avatar Amy Committed by shubang
Browse files

Add APIs to expose some cec control to other services.

ag/5398143

We exposed Power on/Power off/Device select/Connected device list
query from HdmiControlManager.

Test: local tested
Bug: 117775357
Change-Id: Iee495e7131f44282a60e83ad827faa1431a30389
parent 0063811f
Loading
Loading
Loading
Loading
+68 −0
Original line number Original line Diff line number Diff line
@@ -33,6 +33,8 @@ import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.Log;
import android.util.Log;


import java.util.List;

/**
/**
 * The {@link HdmiControlManager} class is used to send HDMI control messages
 * The {@link HdmiControlManager} class is used to send HDMI control messages
 * to attached CEC devices.
 * to attached CEC devices.
@@ -403,6 +405,72 @@ public final class HdmiControlManager {
        return (HdmiSwitchClient) getClient(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH);
        return (HdmiSwitchClient) getClient(HdmiDeviceInfo.DEVICE_PURE_CEC_SWITCH);
    }
    }


    /**
     * Get a snapshot of the real-time status of the remote devices.
     *
     * @return a list of {@link HdmiDeviceInfo} of the devices connected to the current device.
     *
     * TODO(b/110094868): unhide for Q
     * @hide
     */
    public List<HdmiDeviceInfo> getConnectedDevicesList() {
        try {
            return mService.getDeviceList();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Power off the target device.
     *
     * @param deviceInfo HdmiDeviceInfo of the device to be powered off
     *
     * TODO(b/110094868): unhide for Q
     * @hide
     */
    public void powerOffRemoteDevice(HdmiDeviceInfo deviceInfo) {
        try {
            mService.powerOffRemoteDevice(
                    deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Power on the target device.
     *
     * @param deviceInfo HdmiDeviceInfo of the device to be powered on
     *
     * TODO(b/110094868): unhide for Q
     * @hide
     */
    public void powerOnRemoteDevice(HdmiDeviceInfo deviceInfo) {
        try {
            mService.powerOnRemoteDevice(
                    deviceInfo.getLogicalAddress(), deviceInfo.getDevicePowerStatus());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Ask the target device to be the new Active Source.
     *
     * @param deviceInfo HdmiDeviceInfo of the target device
     *
     * TODO(b/110094868): unhide for Q
     * @hide
     */
    public void askRemoteDeviceToBecomeActiveSource(HdmiDeviceInfo deviceInfo) {
        try {
            mService.askRemoteDeviceToBecomeActiveSource(deviceInfo.getPhysicalAddress());
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
    }

    /**
    /**
     * Controls standby mode of the system. It will also try to turn on/off the connected devices if
     * Controls standby mode of the system. It will also try to turn on/off the connected devices if
     * necessary.
     * necessary.
+3 −0
Original line number Original line Diff line number Diff line
@@ -61,6 +61,9 @@ interface IHdmiControlService {
    void setInputChangeListener(IHdmiInputChangeListener listener);
    void setInputChangeListener(IHdmiInputChangeListener listener);
    List<HdmiDeviceInfo> getInputDevices();
    List<HdmiDeviceInfo> getInputDevices();
    List<HdmiDeviceInfo> getDeviceList();
    List<HdmiDeviceInfo> getDeviceList();
    void powerOffRemoteDevice(int logicalAddress, int powerStatus);
    void powerOnRemoteDevice(int logicalAddress, int powerStatus);
    void askRemoteDeviceToBecomeActiveSource(int physicalAddress);
    void sendVendorCommand(int deviceType, int targetAddress, in byte[] params,
    void sendVendorCommand(int deviceType, int targetAddress, in byte[] params,
            boolean hasVendorId);
            boolean hasVendorId);
    void addVendorCommandListener(IHdmiVendorCommandListener listener, int deviceType);
    void addVendorCommandListener(IHdmiVendorCommandListener listener, int deviceType);
+12 −0
Original line number Original line Diff line number Diff line
@@ -327,6 +327,18 @@ public class HdmiAudioSystemClientTest {
        public int getPhysicalAddress() {
        public int getPhysicalAddress() {
            return 0x0000;
            return 0x0000;
        }
        }

        @Override
        public void powerOffRemoteDevice(int logicalAddress, int powerStatus) {
        }

        @Override
        public void powerOnRemoteDevice(int logicalAddress, int powerStatus) {
        }

        @Override
        public void askRemoteDeviceToBecomeActiveSource(int physicalAddress) {
        }
    }
    }


}
}
+78 −3
Original line number Original line Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_ADD_DEVICE;
import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE;
import static android.hardware.hdmi.HdmiControlManager.DEVICE_EVENT_REMOVE_DEVICE;


import static com.android.internal.os.RoSystemProperties.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH;
import static com.android.internal.os.RoSystemProperties.PROPERTY_HDMI_IS_DEVICE_HDMI_CEC_SWITCH;
import static com.android.server.hdmi.Constants.ADDR_UNREGISTERED;
import static com.android.server.hdmi.Constants.DISABLED;
import static com.android.server.hdmi.Constants.DISABLED;
import static com.android.server.hdmi.Constants.ENABLED;
import static com.android.server.hdmi.Constants.ENABLED;
import static com.android.server.hdmi.Constants.OPTION_MHL_ENABLE;
import static com.android.server.hdmi.Constants.OPTION_MHL_ENABLE;
@@ -1615,12 +1616,63 @@ public class HdmiControlService extends SystemService {
        public List<HdmiDeviceInfo> getDeviceList() {
        public List<HdmiDeviceInfo> getDeviceList() {
            enforceAccessPermission();
            enforceAccessPermission();
            HdmiCecLocalDeviceTv tv = tv();
            HdmiCecLocalDeviceTv tv = tv();
            if (tv != null) {
                synchronized (mLock) {
                    return tv.getSafeCecDevicesLocked();
                }
            } else {
                HdmiCecLocalDeviceAudioSystem audioSystem = audioSystem();
                synchronized (mLock) {
                synchronized (mLock) {
                return (tv == null)
                    return (audioSystem == null)
                        ? Collections.<HdmiDeviceInfo>emptyList()
                        ? Collections.<HdmiDeviceInfo>emptyList()
                        : tv.getSafeCecDevicesLocked();
                        : audioSystem.getSafeCecDevicesLocked();
                }
            }
        }

        @Override
        public void powerOffRemoteDevice(int logicalAddress, int powerStatus) {
            enforceAccessPermission();
            runOnServiceThread(new Runnable() {
                @Override
                public void run() {
                    if (powerStatus == HdmiControlManager.POWER_STATUS_ON
                            || powerStatus == HdmiControlManager.POWER_STATUS_TRANSIENT_TO_ON) {
                        sendCecCommand(HdmiCecMessageBuilder.buildStandby(
                                getRemoteControlSourceAddress(), logicalAddress));
                    } else {
                        Slog.w(TAG, "Device " + logicalAddress + " is already off " + powerStatus);
                    }
                }
            });
        }

        @Override
        public void powerOnRemoteDevice(int logicalAddress, int powerStatus) {
            // TODO(amyjojo): implement the method
        }

        @Override
        // TODO(AMYJOJO): add a result callback
        public void askRemoteDeviceToBecomeActiveSource(int physicalAddress) {
            enforceAccessPermission();
            runOnServiceThread(new Runnable() {
                @Override
                public void run() {
                    HdmiCecMessage setStreamPath = HdmiCecMessageBuilder.buildSetStreamPath(
                            getRemoteControlSourceAddress(), physicalAddress);
                    if (pathToPortId(physicalAddress) != Constants.INVALID_PORT_ID) {
                        if (getSwitchDevice() != null) {
                            getSwitchDevice().handleSetStreamPath(setStreamPath);
                        } else {
                            Slog.e(TAG, "Can't get the correct local device to handle routing.");
                        }
                    } else {
                        sendCecCommand(setStreamPath);
                    }
                    }
                }
                }
            });
        }


        @Override
        @Override
        public void setSystemAudioVolume(final int oldIndex, final int newIndex,
        public void setSystemAudioVolume(final int oldIndex, final int newIndex,
@@ -1917,6 +1969,29 @@ public class HdmiControlService extends SystemService {
        }
        }
    }
    }


    // Get the source address to send out commands to devices connected to the current device
    // when other services interact with HdmiControlService.
    private int getRemoteControlSourceAddress() {
        if (isAudioSystemDevice()) {
            return audioSystem().getDeviceInfo().getLogicalAddress();
        } else if (isPlaybackDevice()) {
            return playback().getDeviceInfo().getLogicalAddress();
        }
        return ADDR_UNREGISTERED;
    }

    // Get the switch device to do CEC routing control
    @Nullable
    private HdmiCecLocalDeviceSource getSwitchDevice() {
        if (isAudioSystemDevice()) {
            return audioSystem();
        }
        if (isPlaybackDevice()) {
            return playback();
        }
        return null;
    }

    @ServiceThreadOnly
    @ServiceThreadOnly
    private void oneTouchPlay(final IHdmiControlCallback callback) {
    private void oneTouchPlay(final IHdmiControlCallback callback) {
        assertRunOnServiceThread();
        assertRunOnServiceThread();