Merge "Move message handling logic to local device instead of service."
diff --git a/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
index 6f42c8b..d36fc2c 100644
--- a/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
+++ b/services/core/java/com/android/server/hdmi/DeviceDiscoveryAction.java
@@ -259,7 +259,7 @@
 
         byte params[] = cmd.getParams();
         if (params.length == 3) {
-            current.mPhysicalAddress = ((params[0] & 0xFF) << 8) | (params[1] & 0xFF);
+            current.mPhysicalAddress = HdmiUtils.twoBytesToInt(params);
             current.mDeviceType = params[2] & 0xFF;
 
             increaseProcessedDeviceCount();
@@ -307,9 +307,7 @@
 
         byte[] params = cmd.getParams();
         if (params.length == 3) {
-            int vendorId = ((params[0] & 0xFF) << 16)
-                    | ((params[1] & 0xFF) << 8)
-                    | (params[2] & 0xFF);
+            int vendorId = HdmiUtils.threeBytesToInt(params);
             current.mVendorId = vendorId;
         } else {
             Slog.w(TAG, "Invalid vendor id: " + cmd.toString());
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecController.java b/services/core/java/com/android/server/hdmi/HdmiCecController.java
index 5c420d7..f869424 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecController.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecController.java
@@ -387,6 +387,41 @@
     }
 
     /**
+     * Pass a option to CEC HAL.
+     *
+     * @param flag a key of option. For more details, look at
+     *        {@link HdmiConstants#FLAG_HDMI_OPTION_WAKEUP} to
+     *        {@link HdmiConstants#FLAG_HDMI_OPTION_SYSTEM_CEC_CONTROL}
+     * @param value a value of option. Actual value varies flag. For more
+     *        details, look at description of flags
+     */
+    void setOption(int flag, int value) {
+        assertRunOnServiceThread();
+        nativeSetOption(mNativePtr, flag, value);
+    }
+
+    /**
+     * Configure ARC circuit in the hardware logic to start or stop the feature.
+     *
+     * @param enabled whether to enable/disable ARC
+     */
+    void setAudioReturnChannel(boolean enabled) {
+        assertRunOnServiceThread();
+        nativeSetAudioReturnChannel(mNativePtr, enabled);
+    }
+
+    /**
+     * Return the connection status of the specified port
+     *
+     * @param port port number to check connection status
+     * @return true if connected; otherwise, return false
+     */
+    boolean isConnected(int port) {
+        assertRunOnServiceThread();
+        return nativeIsConnected(mNativePtr, port);
+    }
+
+    /**
      * Poll all remote devices. It sends &lt;Polling Message&gt; to all remote
      * devices.
      *
@@ -606,4 +641,8 @@
     private static native int nativeGetPhysicalAddress(long controllerPtr);
     private static native int nativeGetVersion(long controllerPtr);
     private static native int nativeGetVendorId(long controllerPtr);
+    private static native void nativeSetOption(long controllerPtr, int flag, int value);
+    private static native void nativeSetAudioReturnChannel(long controllerPtr, boolean flag);
+    private static native boolean nativeIsConnected(long controllerPtr, int port);
+
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
index 23454ad..6697a53 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDevice.java
@@ -18,12 +18,15 @@
 
 import android.hardware.hdmi.HdmiCec;
 import android.hardware.hdmi.HdmiCecDeviceInfo;
+import android.hardware.hdmi.HdmiCecMessage;
+import android.util.Slog;
 
 /**
  * Class that models a logical CEC device hosted in this system. Handles initialization,
  * CEC commands that call for actions customized per device type.
  */
 abstract class HdmiCecLocalDevice {
+    private static final String TAG = "HdmiCecLocalDevice";
 
     protected final HdmiControlService mService;
     protected final int mDeviceType;
@@ -59,6 +62,83 @@
      */
     protected abstract void onAddressAllocated(int logicalAddress);
 
+    /**
+     * Dispatch incoming message.
+     *
+     * @param message incoming message
+     * @return true if consumed a message; otherwise, return false.
+     */
+    final boolean dispatchMessage(HdmiCecMessage message) {
+        int dest = message.getDestination();
+        if (dest != mAddress && dest != HdmiCec.ADDR_BROADCAST) {
+            return false;
+        }
+        return onMessage(message);
+    }
+
+    protected boolean onMessage(HdmiCecMessage message) {
+        switch (message.getOpcode()) {
+            case HdmiCec.MESSAGE_GET_MENU_LANGUAGE:
+                return handleGetMenuLanguage(message);
+            case HdmiCec.MESSAGE_GIVE_PHYSICAL_ADDRESS:
+                return handleGivePhysicalAddress();
+            case HdmiCec.MESSAGE_GIVE_OSD_NAME:
+                return handleGiveOsdName(message);
+            case HdmiCec.MESSAGE_GIVE_DEVICE_VENDOR_ID:
+                return handleGiveDeviceVendorId();
+            case HdmiCec.MESSAGE_GET_CEC_VERSION:
+                return handleGetCecVersion(message);
+            default:
+                return false;
+        }
+    }
+
+    protected boolean handleGivePhysicalAddress() {
+        int physicalAddress = mService.getPhysicalAddress();
+        HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
+                mAddress, physicalAddress, mDeviceType);
+        mService.sendCecCommand(cecMessage);
+        return true;
+    }
+
+    protected boolean handleGiveDeviceVendorId() {
+        int vendorId = mService.getVendorId();
+        HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
+                mAddress, vendorId);
+        mService.sendCecCommand(cecMessage);
+        return true;
+    }
+
+    protected boolean handleGetCecVersion(HdmiCecMessage message) {
+        int version = mService.getCecVersion();
+        HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildCecVersion(message.getDestination(),
+                message.getSource(), version);
+        mService.sendCecCommand(cecMessage);
+        return true;
+    }
+
+    protected boolean handleGetMenuLanguage(HdmiCecMessage message) {
+        Slog.w(TAG, "Only TV can handle <Get Menu Language>:" + message.toString());
+        mService.sendCecCommand(
+                HdmiCecMessageBuilder.buildFeatureAbortCommand(mAddress,
+                        message.getSource(), HdmiCec.MESSAGE_GET_MENU_LANGUAGE,
+                        HdmiConstants.ABORT_UNRECOGNIZED_MODE));
+        return true;
+    }
+
+    protected boolean handleGiveOsdName(HdmiCecMessage message) {
+        // Note that since this method is called after logical address allocation is done,
+        // mDeviceInfo should not be null.
+        HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildSetOsdNameCommand(
+                mAddress, message.getSource(), mDeviceInfo.getDisplayName());
+        if (cecMessage != null) {
+            mService.sendCecCommand(cecMessage);
+        } else {
+            Slog.w(TAG, "Failed to build <Get Osd Name>:" + mDeviceInfo.getDisplayName());
+        }
+        return true;
+    }
+
     final void handleAddressAllocated(int logicalAddress) {
         mAddress = mPreferredAddress = logicalAddress;
         onAddressAllocated(logicalAddress);
diff --git a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
index 72d7f2d..8bd81ea 100644
--- a/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
+++ b/services/core/java/com/android/server/hdmi/HdmiCecLocalDeviceTv.java
@@ -17,11 +17,16 @@
 package com.android.server.hdmi;
 
 import android.hardware.hdmi.HdmiCec;
+import android.hardware.hdmi.HdmiCecMessage;
+import android.util.Slog;
+
+import java.util.Locale;
 
 /**
  * Represent a logical device of type TV residing in Android system.
  */
 final class HdmiCecLocalDeviceTv extends HdmiCecLocalDevice {
+    private static final String TAG = "HdmiCecLocalDeviceTv";
 
     HdmiCecLocalDeviceTv(HdmiControlService service) {
         super(service, HdmiCec.DEVICE_TV);
@@ -39,4 +44,42 @@
         mService.launchDeviceDiscovery(mAddress);
         // TODO: Start routing control action, device discovery action.
     }
+
+    @Override
+    protected boolean onMessage(HdmiCecMessage message) {
+        switch (message.getOpcode()) {
+            case HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS:
+                return handleReportPhysicalAddress(message);
+            default:
+                return super.onMessage(message);
+        }
+    }
+
+    @Override
+    protected boolean handleGetMenuLanguage(HdmiCecMessage message) {
+        HdmiCecMessage command = HdmiCecMessageBuilder.buildSetMenuLanguageCommand(
+                mAddress, Locale.getDefault().getISO3Language());
+        // TODO: figure out how to handle failed to get language code.
+        if (command != null) {
+            mService.sendCecCommand(command);
+        } else {
+            Slog.w(TAG, "Failed to respond to <Get Menu Language>: " + message.toString());
+        }
+        return true;
+    }
+
+    private boolean handleReportPhysicalAddress(HdmiCecMessage message) {
+        // Ignore if [Device Discovery Action] is going on.
+        if (mService.hasAction(DeviceDiscoveryAction.class)) {
+            Slog.i(TAG, "Ignore unrecognizable <Report Physical Address> "
+                    + "because Device Discovery Action is on-going:" + message);
+            return true;
+        }
+
+        int physicalAddress = HdmiUtils.twoBytesToInt(message.getParams());
+        mService.addAndStartAction(new NewDeviceAction(mService,
+                mAddress, message.getSource(), physicalAddress));
+
+        return true;
+    }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiConstants.java b/services/core/java/com/android/server/hdmi/HdmiConstants.java
index a83d1ed..54b5dcb 100644
--- a/services/core/java/com/android/server/hdmi/HdmiConstants.java
+++ b/services/core/java/com/android/server/hdmi/HdmiConstants.java
@@ -43,5 +43,31 @@
     static final int UI_COMMAND_MUTE_FUNCTION = 0x65;
     static final int UI_COMMAND_RESTORE_VOLUME_FUNCTION = 0x66;
 
+    // Flags used for setOption to CEC HAL.
+    /**
+     * When set to false, HAL does not wake up the system upon receiving
+     * <Image View On> or <Text View On>. Used when user changes the TV
+     * settings to disable the auto TV on functionality.
+     * True by default.
+     */
+    static final int FLAG_HDMI_OPTION_WAKEUP = 1;
+    /**
+     * When set to false, all the CEC commands are discarded. Used when
+     * user changes the TV settings to disable CEC functionality.
+     * True by default.
+     */
+    static final int FLAG_HDMI_OPTION_ENABLE_CEC = 2;
+    /**
+     * Setting this flag to false means Android system will stop handling
+     * CEC service and yield the control over to the microprocessor that is
+     * powered on through the standby mode. When set to true, the system
+     * will gain the control over, hence telling the microprocessor to stop
+     * handling the cec commands. This is called when system goes
+     * in and out of standby mode to notify the microprocessor that it should
+     * start/stop handling CEC commands on behalf of the system.
+     * False by default.
+     */
+    static final int FLAG_HDMI_OPTION_SYSTEM_CEC_CONTROL = 3;
+
     private HdmiConstants() { /* cannot be instantiated */ }
 }
diff --git a/services/core/java/com/android/server/hdmi/HdmiControlService.java b/services/core/java/com/android/server/hdmi/HdmiControlService.java
index 58bd5f1..3e0f07a 100644
--- a/services/core/java/com/android/server/hdmi/HdmiControlService.java
+++ b/services/core/java/com/android/server/hdmi/HdmiControlService.java
@@ -239,6 +239,13 @@
     }
 
     /**
+     * Returns version of CEC.
+     */
+    int getCecVersion() {
+        return mCecController.getVersion();
+    }
+
+    /**
      * Returns a list of {@link HdmiCecDeviceInfo}.
      *
      * @param includeLocalDevice whether to include local devices
@@ -277,7 +284,7 @@
     }
 
     // See if we have an action of a given type in progress.
-    private <T extends FeatureAction> boolean hasAction(final Class<T> clazz) {
+    <T extends FeatureAction> boolean hasAction(final Class<T> clazz) {
         for (FeatureAction action : mActions) {
             if (action.getClass().equals(clazz)) {
                 return true;
@@ -335,10 +342,13 @@
      * @return {@code true} if ARC was in "Enabled" status
      */
     boolean setArcStatus(boolean enabled) {
+        assertRunOnServiceThread();
         synchronized (mLock) {
             boolean oldStatus = mArcStatusEnabled;
             // 1. Enable/disable ARC circuit.
-            // TODO: call set_audio_return_channel of hal interface.
+            mCecController.setAudioReturnChannel(enabled);
+
+            // TODO: notify arc mode change to AudioManager.
 
             // 2. Update arc status;
             mArcStatusEnabled = enabled;
@@ -366,31 +376,14 @@
 
         // Commands that queries system information replies directly instead
         // of creating FeatureAction because they are state-less.
+        // TODO: move the leftover message to local device.
         switch (message.getOpcode()) {
-            case HdmiCec.MESSAGE_GET_MENU_LANGUAGE:
-                handleGetMenuLanguage(message);
-                return true;
-            case HdmiCec.MESSAGE_GIVE_OSD_NAME:
-                handleGiveOsdName(message);
-                return true;
-            case HdmiCec.MESSAGE_GIVE_PHYSICAL_ADDRESS:
-                handleGivePhysicalAddress(message);
-                return true;
-            case HdmiCec.MESSAGE_GIVE_DEVICE_VENDOR_ID:
-                handleGiveDeviceVendorId(message);
-                return true;
-            case HdmiCec.MESSAGE_GET_CEC_VERSION:
-                handleGetCecVersion(message);
-                return true;
             case HdmiCec.MESSAGE_INITIATE_ARC:
                 handleInitiateArc(message);
                 return true;
             case HdmiCec.MESSAGE_TERMINATE_ARC:
                 handleTerminateArc(message);
                 return true;
-            case HdmiCec.MESSAGE_REPORT_PHYSICAL_ADDRESS:
-                handleReportPhysicalAddress(message);
-                return true;
             case HdmiCec.MESSAGE_SET_SYSTEM_AUDIO_MODE:
                 handleSetSystemAudioMode(message);
                 return true;
@@ -398,8 +391,22 @@
                 handleSystemAudioModeStatus(message);
                 return true;
             default:
-                return dispatchMessageToAction(message);
+                if (dispatchMessageToAction(message)) {
+                    return true;
+                }
+                break;
         }
+
+        return dispatchMessageToLocalDevice(message);
+    }
+
+    private boolean dispatchMessageToLocalDevice(HdmiCecMessage message) {
+        for (HdmiCecLocalDevice device : mCecController.getLocalDeviceList()) {
+            if (device.dispatchMessage(message)) {
+                return true;
+            }
+        }
+        return false;
     }
 
     /**
@@ -446,9 +453,8 @@
     void launchDeviceDiscovery(final int sourceAddress) {
         // At first, clear all existing device infos.
         mCecController.clearDeviceInfoList();
-        mCecMessageCache.flushAll();
+        // TODO: flush cec message cache when CEC is turned off.
 
-        // TODO: check whether TV is one of local devices.
         DeviceDiscoveryAction action = new DeviceDiscoveryAction(this, sourceAddress,
                 new DeviceDiscoveryCallback() {
                     @Override
@@ -476,22 +482,6 @@
                 getPhysicalAddress(), deviceType, getVendorId(), displayName);
     }
 
-    private void handleReportPhysicalAddress(HdmiCecMessage message) {
-        // At first, try to consume it.
-        if (dispatchMessageToAction(message)) {
-            return;
-        }
-
-        // Ignore if [Device Discovery Action] is going on.
-        if (hasAction(DeviceDiscoveryAction.class)) {
-            Slog.i(TAG, "Ignore unrecognizable <Report Physical Address> "
-                    + "because Device Discovery Action is on-going:" + message);
-            return;
-        }
-
-        // TODO: start new device action.
-    }
-
     private void handleInitiateArc(HdmiCecMessage message){
         // In case where <Initiate Arc> is started by <Request ARC Initiation>
         // need to clean up RequestArcInitiationAction.
@@ -512,64 +502,6 @@
         addAndStartAction(action);
     }
 
-    private void handleGetCecVersion(HdmiCecMessage message) {
-        int version = mCecController.getVersion();
-        HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildCecVersion(message.getDestination(),
-                message.getSource(),
-                version);
-        sendCecCommand(cecMessage);
-    }
-
-    private void handleGiveDeviceVendorId(HdmiCecMessage message) {
-        int vendorId = mCecController.getVendorId();
-        HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildDeviceVendorIdCommand(
-                message.getDestination(), vendorId);
-        sendCecCommand(cecMessage);
-    }
-
-    private void handleGivePhysicalAddress(HdmiCecMessage message) {
-        int physicalAddress = mCecController.getPhysicalAddress();
-        int deviceType = HdmiCec.getTypeFromAddress(message.getDestination());
-        HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildReportPhysicalAddressCommand(
-                message.getDestination(), physicalAddress, deviceType);
-        sendCecCommand(cecMessage);
-    }
-
-    private void handleGiveOsdName(HdmiCecMessage message) {
-        // TODO: read device name from settings or property.
-        String name = HdmiCec.getDefaultDeviceName(message.getDestination());
-        HdmiCecMessage cecMessage = HdmiCecMessageBuilder.buildSetOsdNameCommand(
-                message.getDestination(), message.getSource(), name);
-        if (cecMessage != null) {
-            sendCecCommand(cecMessage);
-        } else {
-            Slog.w(TAG, "Failed to build <Get Osd Name>:" + name);
-        }
-    }
-
-    private void handleGetMenuLanguage(HdmiCecMessage message) {
-        // Only 0 (TV), 14 (specific use) can answer.
-        if (message.getDestination() != HdmiCec.ADDR_TV
-                && message.getDestination() != HdmiCec.ADDR_SPECIFIC_USE) {
-            Slog.w(TAG, "Only TV can handle <Get Menu Language>:" + message.toString());
-            sendCecCommand(
-                    HdmiCecMessageBuilder.buildFeatureAbortCommand(message.getDestination(),
-                            message.getSource(), HdmiCec.MESSAGE_GET_MENU_LANGUAGE,
-                            HdmiConstants.ABORT_UNRECOGNIZED_MODE));
-            return;
-        }
-
-        HdmiCecMessage command = HdmiCecMessageBuilder.buildSetMenuLanguageCommand(
-                message.getDestination(),
-                Locale.getDefault().getISO3Language());
-        // TODO: figure out how to handle failed to get language code.
-        if (command != null) {
-            sendCecCommand(command);
-        } else {
-            Slog.w(TAG, "Failed to respond to <Get Menu Language>: " + message.toString());
-        }
-    }
-
     private boolean dispatchMessageToAction(HdmiCecMessage message) {
         for (FeatureAction action : mActions) {
             if (action.processCommand(message)) {
diff --git a/services/core/java/com/android/server/hdmi/HdmiUtils.java b/services/core/java/com/android/server/hdmi/HdmiUtils.java
index ef128ed1..ca09fe6 100644
--- a/services/core/java/com/android/server/hdmi/HdmiUtils.java
+++ b/services/core/java/com/android/server/hdmi/HdmiUtils.java
@@ -71,4 +71,24 @@
         return cmd.getParams().length > 0
                 && cmd.getParams()[0] == HdmiConstants.SYSTEM_AUDIO_STATUS_ON;
     }
+
+    /**
+     * Assemble two bytes into single integer value.
+     *
+     * @param data to be assembled
+     * @return assembled value
+     */
+    static int twoBytesToInt(byte[] data) {
+        return ((data[0] & 0xFF) << 8) | (data[1] & 0xFF);
+    }
+
+    /**
+     * Assemble three bytes into single integer value.
+     *
+     * @param data to be assembled
+     * @return assembled value
+     */
+    static int threeBytesToInt(byte[] data) {
+        return ((data[0] & 0xFF) << 16) | ((data[1] & 0xFF) << 8) | (data[2] & 0xFF);
+    }
 }
diff --git a/services/core/java/com/android/server/hdmi/NewDeviceAction.java b/services/core/java/com/android/server/hdmi/NewDeviceAction.java
index 088c40b..c284d10 100644
--- a/services/core/java/com/android/server/hdmi/NewDeviceAction.java
+++ b/services/core/java/com/android/server/hdmi/NewDeviceAction.java
@@ -114,8 +114,7 @@
         } else if (mState == STATE_WAITING_FOR_DEVICE_VENDOR_ID) {
             if (opcode == HdmiCec.MESSAGE_DEVICE_VENDOR_ID) {
                 if (params.length == 3) {
-                    mVendorId = ((params[0] & 0xFF) << 16) + ((params[1] & 0xFF) << 8)
-                        + (params[2] & 0xFF);
+                    mVendorId = HdmiUtils.threeBytesToInt(params);
                 } else {
                     Slog.e(TAG, "Failed to get device vendor ID: ");
                 }
diff --git a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp b/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp
index a734026..cbc853d 100644
--- a/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp
+++ b/services/core/jni/com_android_server_hdmi_HdmiCecController.cpp
@@ -57,6 +57,12 @@
     int getVersion();
     // Get vendor id used for vendor command.
     uint32_t getVendorId();
+    // Set a flag and its value.
+    void setOption(int flag, int value);
+    // Set audio return channel status.
+    void setAudioReturnChannel(bool flag);
+    // Whether to hdmi device is connected to the given port.
+    bool isConnected(int port);
 
     jobject getCallbacksObj() const {
         return mCallbacksObj;
@@ -222,6 +228,20 @@
     return vendorId;
 }
 
+void HdmiCecController::setOption(int flag, int value) {
+    mDevice->set_option(mDevice, flag, value);
+}
+
+// Set audio return channel status.
+void HdmiCecController::setAudioReturnChannel(bool enabled) {
+    mDevice->set_audio_return_channel(mDevice, enabled ? 1 : 0);
+}
+
+// Whether to hdmi device is connected to the given port.
+bool HdmiCecController::isConnected(int port) {
+    return mDevice->is_connected(mDevice, port) == HDMI_CONNECTED;
+}
+
 
 // static
 void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) {
@@ -326,6 +346,26 @@
     return controller->getVendorId();
 }
 
+static void nativeSetOption(JNIEnv* env, jclass clazz, jlong controllerPtr, jint flag,
+        jint value) {
+    HdmiCecController* controller =
+            reinterpret_cast<HdmiCecController*>(controllerPtr);
+    controller->setOption(flag, value);
+}
+
+static void nativeSetAudioReturnChannel(JNIEnv* env, jclass clazz, jlong controllerPtr,
+        jboolean enabled) {
+    HdmiCecController* controller =
+            reinterpret_cast<HdmiCecController*>(controllerPtr);
+    controller->setAudioReturnChannel(enabled == JNI_TRUE);
+}
+
+static jboolean nativeIsConnected(JNIEnv* env, jclass clazz, jlong controllerPtr, jint port) {
+    HdmiCecController* controller =
+                reinterpret_cast<HdmiCecController*>(controllerPtr);
+    return controller->isConnected(port) ? JNI_TRUE : JNI_FALSE ;
+}
+
 static JNINativeMethod sMethods[] = {
     /* name, signature, funcPtr */
     { "nativeInit",
@@ -337,6 +377,9 @@
     { "nativeGetPhysicalAddress", "(J)I", (void *) nativeGetPhysicalAddress },
     { "nativeGetVersion", "(J)I", (void *) nativeGetVersion },
     { "nativeGetVendorId", "(J)I", (void *) nativeGetVendorId },
+    { "nativeSetOption", "(JII)V", (void *) nativeSetOption },
+    { "nativeSetAudioReturnChannel", "(JZ)V", (void *) nativeSetAudioReturnChannel },
+    { "nativeIsConnected", "(JI)Z", (void *) nativeIsConnected },
 };
 
 #define CLASS_PATH "com/android/server/hdmi/HdmiCecController"