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

Commit 38a70170 authored by Shubang Lu's avatar Shubang Lu Committed by Android (Google) Code Review
Browse files

Merge "Add sendVolumeKeyEvent API to handle forwarding volume key separately."

parents a0d18b60 bd8b4fa1
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -55,6 +55,26 @@ public abstract class HdmiClient {
        }
    }

    /**
     * Sends a volume key event to the primary audio receiver in the system. This method should only
     * be called when the volume key is not handled by the local device. HDMI framework handles the
     * logic of finding the address of the receiver.
     *
     * @param keyCode key code to send. Defined in {@link android.view.KeyEvent}.
     * @param isPressed true if this is key press event
     *
     * @hide
     * TODO(b/110094868): unhide for Q
     */
    public void sendVolumeKeyEvent(int keyCode, boolean isPressed) {
        try {
            mService.sendVolumeKeyEvent(getDeviceType(), keyCode, isPressed);
        } catch (RemoteException e) {
            Log.e(TAG, "sendVolumeKeyEvent threw exception ", e);
            throw e.rethrowFromSystemServer();
        }
    }

    /**
     * Sends vendor-specific command.
     *
+1 −0
Original line number Diff line number Diff line
@@ -47,6 +47,7 @@ interface IHdmiControlService {
    void deviceSelect(int deviceId, IHdmiControlCallback callback);
    void portSelect(int portId, IHdmiControlCallback callback);
    void sendKeyEvent(int deviceType, int keyCode, boolean isPressed);
    void sendVolumeKeyEvent(int deviceType, int keyCode, boolean isPressed);
    List<HdmiPortInfo> getPortInfo();
    boolean canChangeSystemAudioMode();
    boolean getSystemAudioMode();
+5 −0
Original line number Diff line number Diff line
@@ -180,6 +180,11 @@ public class HdmiAudioSystemClientTest {
        public void sendKeyEvent(final int deviceType, final int keyCode, final boolean isPressed) {
        }

        @Override
        public void sendVolumeKeyEvent(
            final int deviceType, final int keyCode, final boolean isPressed) {
        }

        @Override
        public void oneTouchPlay(final IHdmiControlCallback callback) {
        }
+14 −0
Original line number Diff line number Diff line
@@ -449,6 +449,20 @@ final class HdmiCecKeycode {
        return HdmiCecKeycode.androidKeyToCecKey(androidKeycode) != null;
    }

    /**
     * Returns {@code true} if given Android keycode is volume control related,
     * otherwise {@code false}.
     */
    static boolean isVolumeKeycode(int androidKeycode) {
        int cecKeyCode = HdmiCecKeycode.androidKeyToCecKey(androidKeycode)[0];
        return isSupportedKeycode(androidKeycode)
            && (cecKeyCode == CEC_KEYCODE_VOLUME_UP
                || cecKeyCode == CEC_KEYCODE_VOLUME_DOWN
                || cecKeyCode == CEC_KEYCODE_MUTE
                || cecKeyCode == CEC_KEYCODE_MUTE_FUNCTION
                || cecKeyCode == CEC_KEYCODE_RESTORE_VOLUME_FUNCTION);
    }

    /**
     * Returns CEC keycode to control audio mute status.
     *
+45 −0
Original line number Diff line number Diff line
@@ -1015,6 +1015,40 @@ abstract class HdmiCecLocalDevice {
        }
    }

    /**
     * Send a volume key event to other CEC device. The logical address of target device will be
     * given by {@link #findAudioReceiverAddress()}.
     *
     * @param keyCode key code defined in {@link android.view.KeyEvent}
     * @param isPressed {@code true} for key down event
     * @see #findAudioReceiverAddress()
     */
    @ServiceThreadOnly
    protected void sendVolumeKeyEvent(int keyCode, boolean isPressed) {
        assertRunOnServiceThread();
        if (!HdmiCecKeycode.isVolumeKeycode(keyCode)) {
            Slog.w(TAG, "Not a volume key: " + keyCode);
            return;
        }
        List<SendKeyAction> action = getActions(SendKeyAction.class);
        int logicalAddress = findAudioReceiverAddress();
        if (logicalAddress == Constants.ADDR_INVALID || logicalAddress == mAddress) {
            // Don't send key event to invalid device or itself.
            Slog.w(
                TAG,
                "Discard volume key event: "
                    + keyCode
                    + ", pressed:"
                    + isPressed
                    + ", receiverAddr="
                    + logicalAddress);
        } else if (!action.isEmpty()) {
            action.get(0).processKeyEvent(keyCode, isPressed);
        } else if (isPressed) {
            addAndStartAction(new SendKeyAction(this, logicalAddress, keyCode));
        }
    }

    /**
     * Returns the logical address of the device which will receive key events via {@link
     * #sendKeyEvent}.
@@ -1026,6 +1060,17 @@ abstract class HdmiCecLocalDevice {
        return Constants.ADDR_INVALID;
    }

    /**
     * Returns the logical address of the audio receiver device which will receive volume key events
     * via {@link#sendVolumeKeyEvent}.
     *
     * @see #sendVolumeKeyEvent(int, boolean)
     */
    protected int findAudioReceiverAddress() {
        Slog.w(TAG, "findAudioReceiverAddress is not implemented");
        return Constants.ADDR_INVALID;
    }

    @ServiceThreadOnly
    void invokeCallback(IHdmiControlCallback callback, int result) {
        assertRunOnServiceThread();
Loading