1119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kimpackage android.hardware.hdmi;
2119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim
36ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kimimport android.annotation.NonNull;
4119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kimimport android.annotation.SystemApi;
5119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kimimport android.hardware.hdmi.HdmiControlManager.VendorCommandListener;
6119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kimimport android.os.RemoteException;
7119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kimimport android.util.Log;
8119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim
9119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim/**
10119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim * Parent for classes of various HDMI-CEC device type used to access
115487ab07c77558efa524cfc9b40cbe6fe90fc50eYuncheol Heo * the HDMI control system service. Contains methods and data used in common.
12119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim *
13119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim * @hide
14119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim */
15fa68c30bbd91c63cf1cf29822b9d0ea9b0bb5b86Ying Wang@SystemApi
16119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kimpublic abstract class HdmiClient {
17119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim    private static final String TAG = "HdmiClient";
18119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim
192b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo    /* package */ final IHdmiControlService mService;
20119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim
212b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo    private IHdmiVendorCommandListener mIHdmiVendorCommandListener;
22119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim
232b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo    /* package */ abstract int getDeviceType();
242b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo
252b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo    /* package */ HdmiClient(IHdmiControlService service) {
26119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim        mService = service;
27119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim    }
28119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim
29c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim    /**
306ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim     * Returns the active source information.
316ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim     *
3261f4fbd2e8436a1ecd478c2a1f516d064a24d43bJungshik Jang     * @return {@link HdmiDeviceInfo} object that describes the active source
336ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim     *         or active routing path
346ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim     */
3561f4fbd2e8436a1ecd478c2a1f516d064a24d43bJungshik Jang    public HdmiDeviceInfo getActiveSource() {
366ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim        try {
376ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim            return mService.getActiveSource();
386ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim        } catch (RemoteException e) {
396ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim            Log.e(TAG, "getActiveSource threw exception ", e);
406ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim        }
416ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim        return null;
426ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim    }
436ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim
446ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim    /**
452b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo     * Sends a key event to other logical device.
46c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     *
47c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     * @param keyCode key code to send. Defined in {@link android.view.KeyEvent}.
48c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     * @param isPressed true if this is key press event
49c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     */
50c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim    public void sendKeyEvent(int keyCode, boolean isPressed) {
51c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim        try {
52c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim            mService.sendKeyEvent(getDeviceType(), keyCode, isPressed);
53c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim        } catch (RemoteException e) {
54f424932cfb1b16b01a37500d09e295912700a51dJungshik Jang            Log.e(TAG, "sendKeyEvent threw exception ", e);
55c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim        }
56c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim    }
57c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim
58c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim    /**
592b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo     * Sends vendor-specific command.
60c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     *
61c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     * @param targetAddress address of the target device
62c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     * @param params vendor-specific parameter. For <Vendor Command With ID> do not
63c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     *               include the first 3 bytes (vendor ID).
64c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     * @param hasVendorId {@code true} if the command type will be <Vendor Command With ID>.
65c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     *                    {@code false} if the command will be <Vendor Command>
66c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     */
67119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim    public void sendVendorCommand(int targetAddress, byte[] params, boolean hasVendorId) {
68119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim        try {
69119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim            mService.sendVendorCommand(getDeviceType(), targetAddress, params, hasVendorId);
70119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim        } catch (RemoteException e) {
71119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim            Log.e(TAG, "failed to send vendor command: ", e);
72119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim        }
73119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim    }
74119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim
75c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim    /**
762b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo     * Sets a listener used to receive incoming vendor-specific command.
77c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     *
78c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     * @param listener listener object
79c068bb5a0468bf605b0398e6f0ea5721917de4eeJinsuk Kim     */
802b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo    public void setVendorCommandListener(@NonNull VendorCommandListener listener) {
816ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim        if (listener == null) {
826ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim            throw new IllegalArgumentException("listener cannot be null");
836ffb03816f7410c001072a25c3e4161a2da4f501Jinsuk Kim        }
842b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo        if (mIHdmiVendorCommandListener != null) {
852b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo            throw new IllegalStateException("listener was already set");
862b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo        }
87119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim        try {
882b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo            IHdmiVendorCommandListener wrappedListener = getListenerWrapper(listener);
892b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo            mService.addVendorCommandListener(wrappedListener, getDeviceType());
902b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo            mIHdmiVendorCommandListener = wrappedListener;
91119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim        } catch (RemoteException e) {
922b0da5c4c84305f1d391dc78b85e244c9fd92456Yuncheol Heo            Log.e(TAG, "failed to set vendor command listener: ", e);
93119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim        }
94119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim    }
95119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim
96119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim    private static IHdmiVendorCommandListener getListenerWrapper(
97119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim            final VendorCommandListener listener) {
98119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim        return new IHdmiVendorCommandListener.Stub() {
99119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim            @Override
1000608b9328b1c2f804ffb2d4165c34383d34bde2aYuncheol Heo            public void onReceived(int srcAddress, int destAddress, byte[] params,
1010608b9328b1c2f804ffb2d4165c34383d34bde2aYuncheol Heo                    boolean hasVendorId) {
1020608b9328b1c2f804ffb2d4165c34383d34bde2aYuncheol Heo                listener.onReceived(srcAddress, destAddress, params, hasVendorId);
1030608b9328b1c2f804ffb2d4165c34383d34bde2aYuncheol Heo            }
1040608b9328b1c2f804ffb2d4165c34383d34bde2aYuncheol Heo            @Override
1050608b9328b1c2f804ffb2d4165c34383d34bde2aYuncheol Heo            public void onControlStateChanged(boolean enabled, int reason) {
1060608b9328b1c2f804ffb2d4165c34383d34bde2aYuncheol Heo                listener.onControlStateChanged(enabled, reason);
107119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim            }
108119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim        };
109119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim    }
110119160a68195bcb2f5bdf4a269807e01228eca97Jinsuk Kim}
111