Loading services/core/java/com/android/server/hdmi/HdmiCecController.java +7 −16 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.hardware.hdmi.HdmiCecDeviceInfo; import android.hardware.hdmi.HdmiCecMessage; import android.os.Handler; import android.os.Looper; import android.os.MessageQueue; import android.util.Slog; import android.util.SparseArray; Loading @@ -29,7 +30,6 @@ import com.android.server.hdmi.HdmiControlService.DevicePollingCallback; import libcore.util.EmptyArray; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** Loading Loading @@ -99,7 +99,7 @@ final class HdmiCecController { */ static HdmiCecController create(HdmiControlService service) { HdmiCecController controller = new HdmiCecController(); long nativePtr = nativeInit(controller); long nativePtr = nativeInit(controller, service.getServiceLooper().getQueue()); if (nativePtr == 0L) { controller = null; return null; Loading Loading @@ -471,8 +471,8 @@ final class HdmiCecController { private void onReceiveCommand(HdmiCecMessage message) { assertRunOnServiceThread(); if (isAcceptableAddress(message.getDestination()) && mService.handleCecCommand(message)) { if (isAcceptableAddress(message.getDestination()) && mService.handleCecCommand(message)) { return; } Loading Loading @@ -517,17 +517,8 @@ final class HdmiCecController { * Called by native when incoming CEC message arrived. */ private void handleIncomingCecCommand(int srcAddress, int dstAddress, byte[] body) { byte opcode = body[0]; byte params[] = Arrays.copyOfRange(body, 1, body.length); final HdmiCecMessage cecMessage = new HdmiCecMessage(srcAddress, dstAddress, opcode, params); // Delegate message to main handler so that it handles in main thread. runOnServiceThread(new Runnable() { @Override public void run() { onReceiveCommand(cecMessage); } }); assertRunOnServiceThread(); onReceiveCommand(HdmiCecMessageBuilder.of(srcAddress, dstAddress, body)); } /** Loading @@ -539,7 +530,7 @@ final class HdmiCecController { mService.onHotplug(0, connected); } private static native long nativeInit(HdmiCecController handler); private static native long nativeInit(HdmiCecController handler, MessageQueue messageQueue); private static native int nativeSendCecCommand(long controllerPtr, int srcAddress, int dstAddress, byte[] body); private static native int nativeAddLogicalAddress(long controllerPtr, int logicalAddress); Loading services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java +15 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.hardware.hdmi.HdmiCec; import android.hardware.hdmi.HdmiCecMessage; import java.io.UnsupportedEncodingException; import java.util.Arrays; /** * A helper class to build {@link HdmiCecMessage} from various cec commands. Loading @@ -38,6 +39,20 @@ public class HdmiCecMessageBuilder { private HdmiCecMessageBuilder() {} /** * Build {@link HdmiCecMessage} from raw data. * * @param src source address of command * @param dest destination address of command * @param body body of message. It includes opcode. * @return newly created {@link HdmiCecMessage} */ static HdmiCecMessage of(int src, int dest, byte[] body) { byte opcode = body[0]; byte params[] = Arrays.copyOfRange(body, 1, body.length); return new HdmiCecMessage(src, dest, opcode, params); } /** * Build <Feature Abort> command. <Feature Abort> consists of * 1 byte original opcode and 1 byte reason fields with basic fields. Loading services/core/jni/com_android_server_hdmi_HdmiCecController.cpp +147 −65 Original line number Diff line number Diff line Loading @@ -21,12 +21,15 @@ #include "JNIHelp.h" #include "ScopedPrimitiveArray.h" #include <string> #include <cstring> #include <android_os_MessageQueue.h> #include <android_runtime/AndroidRuntime.h> #include <android_runtime/Log.h> #include <hardware/hdmi_cec.h> #include <sys/param.h> #include <utils/Looper.h> #include <utils/RefBase.h> namespace android { Loading @@ -37,7 +40,8 @@ static struct { class HdmiCecController { public: HdmiCecController(hdmi_cec_device_t* device, jobject callbacksObj); HdmiCecController(hdmi_cec_device_t* device, jobject callbacksObj, const sp<Looper>& looper); void init(); Loading @@ -54,28 +58,89 @@ public: // Get vendor id used for vendor command. uint32_t getVendorId(); private: // Propagate the message up to Java layer. void propagateCecCommand(const cec_message_t& message); void propagateHotplugEvent(const hotplug_event_t& event); jobject getCallbacksObj() const { return mCallbacksObj; } private: static void onReceived(const hdmi_event_t* event, void* arg); static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName); hdmi_cec_device_t* mDevice; jobject mCallbacksObj; sp<Looper> mLooper; }; HdmiCecController::HdmiCecController(hdmi_cec_device_t* device, jobject callbacksObj) : mDevice(device), mCallbacksObj(callbacksObj) { // RefBase wrapper for hdmi_event_t. As hdmi_event_t coming from HAL // may keep its own lifetime, we need to copy it in order to delegate // it to service thread. class CecEventWrapper : public LightRefBase<CecEventWrapper> { public: CecEventWrapper(const hdmi_event_t& event) { // Copy message. switch (event.type) { case HDMI_EVENT_CEC_MESSAGE: mEvent.cec.initiator = event.cec.initiator; mEvent.cec.destination = event.cec.destination; mEvent.cec.length = event.cec.length; std::memcpy(mEvent.cec.body, event.cec.body, event.cec.length); break; case HDMI_EVENT_HOT_PLUG: mEvent.hotplug.connected = event.hotplug.connected; mEvent.hotplug.port = event.hotplug.port; break; case HDMI_EVENT_TX_STATUS: mEvent.tx_status.status = event.tx_status.status; mEvent.tx_status.opcode = event.tx_status.opcode; break; default: // TODO: add more type whenever new type is introduced. break; } } void HdmiCecController::init() { mDevice->register_event_callback(mDevice, HdmiCecController::onReceived, this); const cec_message_t& cec() const { return mEvent.cec; } const hotplug_event_t& hotplug() const { return mEvent.hotplug; } void HdmiCecController::propagateCecCommand(const cec_message_t& message) { virtual ~CecEventWrapper() {} private: hdmi_event_t mEvent; }; // Handler class to delegate incoming message to service thread. class HdmiCecEventHandler : public MessageHandler { public: HdmiCecEventHandler(HdmiCecController* controller, const sp<CecEventWrapper>& event) : mController(controller), mEventWrapper(event) { } virtual ~HdmiCecEventHandler() {} void handleMessage(const Message& message) { switch (message.what) { case HDMI_EVENT_CEC_MESSAGE: propagateCecCommand(mEventWrapper->cec()); break; case HDMI_EVENT_HOT_PLUG: propagateHotplugEvent(mEventWrapper->hotplug()); break; case HDMI_EVENT_TX_STATUS: // TODO: propagate this to controller. default: // TODO: add more type whenever new type is introduced. break; } } private: // Propagate the message up to Java layer. void propagateCecCommand(const cec_message_t& message) { jint srcAddr = message.initiator; jint dstAddr = message.destination; JNIEnv* env = AndroidRuntime::getJNIEnv(); Loading @@ -83,22 +148,47 @@ void HdmiCecController::propagateCecCommand(const cec_message_t& message) { const jbyte* bodyPtr = reinterpret_cast<const jbyte *>(message.body); env->SetByteArrayRegion(body, 0, message.length, bodyPtr); env->CallVoidMethod(mCallbacksObj, gHdmiCecControllerClassInfo.handleIncomingCecCommand, srcAddr, dstAddr, body); env->CallVoidMethod(mController->getCallbacksObj(), gHdmiCecControllerClassInfo.handleIncomingCecCommand, srcAddr, dstAddr, body); env->DeleteLocalRef(body); checkAndClearExceptionFromCallback(env, __FUNCTION__); } void HdmiCecController::propagateHotplugEvent(const hotplug_event_t& event) { void propagateHotplugEvent(const hotplug_event_t& event) { // Note that this method should be called in service thread. JNIEnv* env = AndroidRuntime::getJNIEnv(); env->CallVoidMethod(mCallbacksObj, env->CallVoidMethod(mController->getCallbacksObj(), gHdmiCecControllerClassInfo.handleHotplug, event.connected); checkAndClearExceptionFromCallback(env, __FUNCTION__); } // static static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { if (env->ExceptionCheck()) { ALOGE("An exception was thrown by callback '%s'.", methodName); LOGE_EX(env); env->ExceptionClear(); } } HdmiCecController* mController; sp<CecEventWrapper> mEventWrapper; }; HdmiCecController::HdmiCecController(hdmi_cec_device_t* device, jobject callbacksObj, const sp<Looper>& looper) : mDevice(device), mCallbacksObj(callbacksObj), mLooper(looper) { } void HdmiCecController::init() { mDevice->register_event_callback(mDevice, HdmiCecController::onReceived, this); } int HdmiCecController::sendMessage(const cec_message_t& message) { // TODO: propagate send_message's return value. return mDevice->send_message(mDevice, &message); Loading Loading @@ -132,15 +222,6 @@ uint32_t HdmiCecController::getVendorId() { return vendorId; } // static void HdmiCecController::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { if (env->ExceptionCheck()) { ALOGE("An exception was thrown by callback '%s'.", methodName); LOGE_EX(env); env->ExceptionClear(); } } // static void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) { Loading @@ -149,17 +230,9 @@ void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) { return; } switch (event->type) { case HDMI_EVENT_CEC_MESSAGE: controller->propagateCecCommand(event->cec); break; case HDMI_EVENT_HOT_PLUG: controller->propagateHotplugEvent(event->hotplug); break; default: ALOGE("Unsupported event type: %d", event->type); break; } sp<CecEventWrapper> spEvent(new CecEventWrapper(*event)); sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(controller, spEvent)); controller->mLooper->sendMessage(handler, event->type); } //------------------------------------------------------------------------------ Loading @@ -167,31 +240,38 @@ void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) { var = env->GetMethodID(clazz, methodName, methodDescriptor); \ LOG_FATAL_IF(! var, "Unable to find method " methodName); static jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj) { // TODO: replace above code with following once // replace old HdmiCecService with HdmiControlService #undef HDMI_CEC_HARDWARE_MODULE_ID #define HDMI_CEC_HARDWARE_MODULE_ID "hdmi_cec_module" #undef HDMI_CEC_HARDWARE_INTERFACE #define HDMI_CEC_HARDWARE_INTERFACE "hdmi_cec_module_hw_if" static jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj, jobject messageQueueObj) { int err; // If use same hardware module id between HdmiCecService and // HdmiControlSservice it may conflict and cause abnormal state of HAL. // TODO: use HDMI_CEC_HARDWARE_MODULE_ID of hdmi_cec.h for module id // once migration to HdmiControlService is done. hw_module_t* module; err = hw_get_module("hdmi_cec_module", err = hw_get_module(HDMI_CEC_HARDWARE_MODULE_ID, const_cast<const hw_module_t **>(&module)); if (err != 0) { ALOGE("Error acquiring hardware module: %d", err); return 0; } hw_device_t* device; // TODO: use HDMI_CEC_HARDWARE_INTERFACE of hdmi_cec.h for interface name // once migration to HdmiControlService is done. err = module->methods->open(module, "hdmi_cec_module_hw_if", &device); err = module->methods->open(module, HDMI_CEC_HARDWARE_INTERFACE, &device); if (err != 0) { ALOGE("Error opening hardware module: %d", err); return 0; } sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); HdmiCecController* controller = new HdmiCecController( reinterpret_cast<hdmi_cec_device*>(device), env->NewGlobalRef(callbacksObj)); env->NewGlobalRef(callbacksObj), messageQueue->getLooper()); controller->init(); GET_METHOD_ID(gHdmiCecControllerClassInfo.handleIncomingCecCommand, clazz, Loading Loading @@ -255,7 +335,8 @@ static jint nativeGetVendorId(JNIEnv* env, jclass clazz, jlong controllerPtr) { static JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ { "nativeInit", "(Lcom/android/server/hdmi/HdmiCecController;)J", { "nativeInit", "(Lcom/android/server/hdmi/HdmiCecController;Landroid/os/MessageQueue;)J", (void *) nativeInit }, { "nativeSendCecCommand", "(JII[B)I", (void *) nativeSendCecCommand }, { "nativeAddLogicalAddress", "(JI)I", (void *) nativeAddLogicalAddress }, Loading @@ -268,7 +349,8 @@ static JNINativeMethod sMethods[] = { #define CLASS_PATH "com/android/server/hdmi/HdmiCecController" int register_android_server_hdmi_HdmiCecController(JNIEnv* env) { int res = jniRegisterNativeMethods(env, CLASS_PATH, sMethods, NELEM(sMethods)); int res = jniRegisterNativeMethods(env, CLASS_PATH, sMethods, NELEM(sMethods)); LOG_FATAL_IF(res < 0, "Unable to register native methods."); return 0; } Loading Loading
services/core/java/com/android/server/hdmi/HdmiCecController.java +7 −16 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.hardware.hdmi.HdmiCecDeviceInfo; import android.hardware.hdmi.HdmiCecMessage; import android.os.Handler; import android.os.Looper; import android.os.MessageQueue; import android.util.Slog; import android.util.SparseArray; Loading @@ -29,7 +30,6 @@ import com.android.server.hdmi.HdmiControlService.DevicePollingCallback; import libcore.util.EmptyArray; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** Loading Loading @@ -99,7 +99,7 @@ final class HdmiCecController { */ static HdmiCecController create(HdmiControlService service) { HdmiCecController controller = new HdmiCecController(); long nativePtr = nativeInit(controller); long nativePtr = nativeInit(controller, service.getServiceLooper().getQueue()); if (nativePtr == 0L) { controller = null; return null; Loading Loading @@ -471,8 +471,8 @@ final class HdmiCecController { private void onReceiveCommand(HdmiCecMessage message) { assertRunOnServiceThread(); if (isAcceptableAddress(message.getDestination()) && mService.handleCecCommand(message)) { if (isAcceptableAddress(message.getDestination()) && mService.handleCecCommand(message)) { return; } Loading Loading @@ -517,17 +517,8 @@ final class HdmiCecController { * Called by native when incoming CEC message arrived. */ private void handleIncomingCecCommand(int srcAddress, int dstAddress, byte[] body) { byte opcode = body[0]; byte params[] = Arrays.copyOfRange(body, 1, body.length); final HdmiCecMessage cecMessage = new HdmiCecMessage(srcAddress, dstAddress, opcode, params); // Delegate message to main handler so that it handles in main thread. runOnServiceThread(new Runnable() { @Override public void run() { onReceiveCommand(cecMessage); } }); assertRunOnServiceThread(); onReceiveCommand(HdmiCecMessageBuilder.of(srcAddress, dstAddress, body)); } /** Loading @@ -539,7 +530,7 @@ final class HdmiCecController { mService.onHotplug(0, connected); } private static native long nativeInit(HdmiCecController handler); private static native long nativeInit(HdmiCecController handler, MessageQueue messageQueue); private static native int nativeSendCecCommand(long controllerPtr, int srcAddress, int dstAddress, byte[] body); private static native int nativeAddLogicalAddress(long controllerPtr, int logicalAddress); Loading
services/core/java/com/android/server/hdmi/HdmiCecMessageBuilder.java +15 −0 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ import android.hardware.hdmi.HdmiCec; import android.hardware.hdmi.HdmiCecMessage; import java.io.UnsupportedEncodingException; import java.util.Arrays; /** * A helper class to build {@link HdmiCecMessage} from various cec commands. Loading @@ -38,6 +39,20 @@ public class HdmiCecMessageBuilder { private HdmiCecMessageBuilder() {} /** * Build {@link HdmiCecMessage} from raw data. * * @param src source address of command * @param dest destination address of command * @param body body of message. It includes opcode. * @return newly created {@link HdmiCecMessage} */ static HdmiCecMessage of(int src, int dest, byte[] body) { byte opcode = body[0]; byte params[] = Arrays.copyOfRange(body, 1, body.length); return new HdmiCecMessage(src, dest, opcode, params); } /** * Build <Feature Abort> command. <Feature Abort> consists of * 1 byte original opcode and 1 byte reason fields with basic fields. Loading
services/core/jni/com_android_server_hdmi_HdmiCecController.cpp +147 −65 Original line number Diff line number Diff line Loading @@ -21,12 +21,15 @@ #include "JNIHelp.h" #include "ScopedPrimitiveArray.h" #include <string> #include <cstring> #include <android_os_MessageQueue.h> #include <android_runtime/AndroidRuntime.h> #include <android_runtime/Log.h> #include <hardware/hdmi_cec.h> #include <sys/param.h> #include <utils/Looper.h> #include <utils/RefBase.h> namespace android { Loading @@ -37,7 +40,8 @@ static struct { class HdmiCecController { public: HdmiCecController(hdmi_cec_device_t* device, jobject callbacksObj); HdmiCecController(hdmi_cec_device_t* device, jobject callbacksObj, const sp<Looper>& looper); void init(); Loading @@ -54,28 +58,89 @@ public: // Get vendor id used for vendor command. uint32_t getVendorId(); private: // Propagate the message up to Java layer. void propagateCecCommand(const cec_message_t& message); void propagateHotplugEvent(const hotplug_event_t& event); jobject getCallbacksObj() const { return mCallbacksObj; } private: static void onReceived(const hdmi_event_t* event, void* arg); static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName); hdmi_cec_device_t* mDevice; jobject mCallbacksObj; sp<Looper> mLooper; }; HdmiCecController::HdmiCecController(hdmi_cec_device_t* device, jobject callbacksObj) : mDevice(device), mCallbacksObj(callbacksObj) { // RefBase wrapper for hdmi_event_t. As hdmi_event_t coming from HAL // may keep its own lifetime, we need to copy it in order to delegate // it to service thread. class CecEventWrapper : public LightRefBase<CecEventWrapper> { public: CecEventWrapper(const hdmi_event_t& event) { // Copy message. switch (event.type) { case HDMI_EVENT_CEC_MESSAGE: mEvent.cec.initiator = event.cec.initiator; mEvent.cec.destination = event.cec.destination; mEvent.cec.length = event.cec.length; std::memcpy(mEvent.cec.body, event.cec.body, event.cec.length); break; case HDMI_EVENT_HOT_PLUG: mEvent.hotplug.connected = event.hotplug.connected; mEvent.hotplug.port = event.hotplug.port; break; case HDMI_EVENT_TX_STATUS: mEvent.tx_status.status = event.tx_status.status; mEvent.tx_status.opcode = event.tx_status.opcode; break; default: // TODO: add more type whenever new type is introduced. break; } } void HdmiCecController::init() { mDevice->register_event_callback(mDevice, HdmiCecController::onReceived, this); const cec_message_t& cec() const { return mEvent.cec; } const hotplug_event_t& hotplug() const { return mEvent.hotplug; } void HdmiCecController::propagateCecCommand(const cec_message_t& message) { virtual ~CecEventWrapper() {} private: hdmi_event_t mEvent; }; // Handler class to delegate incoming message to service thread. class HdmiCecEventHandler : public MessageHandler { public: HdmiCecEventHandler(HdmiCecController* controller, const sp<CecEventWrapper>& event) : mController(controller), mEventWrapper(event) { } virtual ~HdmiCecEventHandler() {} void handleMessage(const Message& message) { switch (message.what) { case HDMI_EVENT_CEC_MESSAGE: propagateCecCommand(mEventWrapper->cec()); break; case HDMI_EVENT_HOT_PLUG: propagateHotplugEvent(mEventWrapper->hotplug()); break; case HDMI_EVENT_TX_STATUS: // TODO: propagate this to controller. default: // TODO: add more type whenever new type is introduced. break; } } private: // Propagate the message up to Java layer. void propagateCecCommand(const cec_message_t& message) { jint srcAddr = message.initiator; jint dstAddr = message.destination; JNIEnv* env = AndroidRuntime::getJNIEnv(); Loading @@ -83,22 +148,47 @@ void HdmiCecController::propagateCecCommand(const cec_message_t& message) { const jbyte* bodyPtr = reinterpret_cast<const jbyte *>(message.body); env->SetByteArrayRegion(body, 0, message.length, bodyPtr); env->CallVoidMethod(mCallbacksObj, gHdmiCecControllerClassInfo.handleIncomingCecCommand, srcAddr, dstAddr, body); env->CallVoidMethod(mController->getCallbacksObj(), gHdmiCecControllerClassInfo.handleIncomingCecCommand, srcAddr, dstAddr, body); env->DeleteLocalRef(body); checkAndClearExceptionFromCallback(env, __FUNCTION__); } void HdmiCecController::propagateHotplugEvent(const hotplug_event_t& event) { void propagateHotplugEvent(const hotplug_event_t& event) { // Note that this method should be called in service thread. JNIEnv* env = AndroidRuntime::getJNIEnv(); env->CallVoidMethod(mCallbacksObj, env->CallVoidMethod(mController->getCallbacksObj(), gHdmiCecControllerClassInfo.handleHotplug, event.connected); checkAndClearExceptionFromCallback(env, __FUNCTION__); } // static static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { if (env->ExceptionCheck()) { ALOGE("An exception was thrown by callback '%s'.", methodName); LOGE_EX(env); env->ExceptionClear(); } } HdmiCecController* mController; sp<CecEventWrapper> mEventWrapper; }; HdmiCecController::HdmiCecController(hdmi_cec_device_t* device, jobject callbacksObj, const sp<Looper>& looper) : mDevice(device), mCallbacksObj(callbacksObj), mLooper(looper) { } void HdmiCecController::init() { mDevice->register_event_callback(mDevice, HdmiCecController::onReceived, this); } int HdmiCecController::sendMessage(const cec_message_t& message) { // TODO: propagate send_message's return value. return mDevice->send_message(mDevice, &message); Loading Loading @@ -132,15 +222,6 @@ uint32_t HdmiCecController::getVendorId() { return vendorId; } // static void HdmiCecController::checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { if (env->ExceptionCheck()) { ALOGE("An exception was thrown by callback '%s'.", methodName); LOGE_EX(env); env->ExceptionClear(); } } // static void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) { Loading @@ -149,17 +230,9 @@ void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) { return; } switch (event->type) { case HDMI_EVENT_CEC_MESSAGE: controller->propagateCecCommand(event->cec); break; case HDMI_EVENT_HOT_PLUG: controller->propagateHotplugEvent(event->hotplug); break; default: ALOGE("Unsupported event type: %d", event->type); break; } sp<CecEventWrapper> spEvent(new CecEventWrapper(*event)); sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(controller, spEvent)); controller->mLooper->sendMessage(handler, event->type); } //------------------------------------------------------------------------------ Loading @@ -167,31 +240,38 @@ void HdmiCecController::onReceived(const hdmi_event_t* event, void* arg) { var = env->GetMethodID(clazz, methodName, methodDescriptor); \ LOG_FATAL_IF(! var, "Unable to find method " methodName); static jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj) { // TODO: replace above code with following once // replace old HdmiCecService with HdmiControlService #undef HDMI_CEC_HARDWARE_MODULE_ID #define HDMI_CEC_HARDWARE_MODULE_ID "hdmi_cec_module" #undef HDMI_CEC_HARDWARE_INTERFACE #define HDMI_CEC_HARDWARE_INTERFACE "hdmi_cec_module_hw_if" static jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj, jobject messageQueueObj) { int err; // If use same hardware module id between HdmiCecService and // HdmiControlSservice it may conflict and cause abnormal state of HAL. // TODO: use HDMI_CEC_HARDWARE_MODULE_ID of hdmi_cec.h for module id // once migration to HdmiControlService is done. hw_module_t* module; err = hw_get_module("hdmi_cec_module", err = hw_get_module(HDMI_CEC_HARDWARE_MODULE_ID, const_cast<const hw_module_t **>(&module)); if (err != 0) { ALOGE("Error acquiring hardware module: %d", err); return 0; } hw_device_t* device; // TODO: use HDMI_CEC_HARDWARE_INTERFACE of hdmi_cec.h for interface name // once migration to HdmiControlService is done. err = module->methods->open(module, "hdmi_cec_module_hw_if", &device); err = module->methods->open(module, HDMI_CEC_HARDWARE_INTERFACE, &device); if (err != 0) { ALOGE("Error opening hardware module: %d", err); return 0; } sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); HdmiCecController* controller = new HdmiCecController( reinterpret_cast<hdmi_cec_device*>(device), env->NewGlobalRef(callbacksObj)); env->NewGlobalRef(callbacksObj), messageQueue->getLooper()); controller->init(); GET_METHOD_ID(gHdmiCecControllerClassInfo.handleIncomingCecCommand, clazz, Loading Loading @@ -255,7 +335,8 @@ static jint nativeGetVendorId(JNIEnv* env, jclass clazz, jlong controllerPtr) { static JNINativeMethod sMethods[] = { /* name, signature, funcPtr */ { "nativeInit", "(Lcom/android/server/hdmi/HdmiCecController;)J", { "nativeInit", "(Lcom/android/server/hdmi/HdmiCecController;Landroid/os/MessageQueue;)J", (void *) nativeInit }, { "nativeSendCecCommand", "(JII[B)I", (void *) nativeSendCecCommand }, { "nativeAddLogicalAddress", "(JI)I", (void *) nativeAddLogicalAddress }, Loading @@ -268,7 +349,8 @@ static JNINativeMethod sMethods[] = { #define CLASS_PATH "com/android/server/hdmi/HdmiCecController" int register_android_server_hdmi_HdmiCecController(JNIEnv* env) { int res = jniRegisterNativeMethods(env, CLASS_PATH, sMethods, NELEM(sMethods)); int res = jniRegisterNativeMethods(env, CLASS_PATH, sMethods, NELEM(sMethods)); LOG_FATAL_IF(res < 0, "Unable to register native methods."); return 0; } Loading