10792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang/* 20792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang * Copyright (C) 2014 The Android Open Source Project 30792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang * 40792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang * Licensed under the Apache License, Version 2.0 (the "License"); 50792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang * you may not use this file except in compliance with the License. 60792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang * You may obtain a copy of the License at 70792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang * 80792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang * http://www.apache.org/licenses/LICENSE-2.0 90792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang * 100792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang * Unless required by applicable law or agreed to in writing, software 110792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang * distributed under the License is distributed on an "AS IS" BASIS, 120792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang * See the License for the specific language governing permissions and 140792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang * limitations under the License. 150792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang */ 160792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 170792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang#define LOG_TAG "HdmiCecControllerJni" 180792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 190792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang#define LOG_NDEBUG 1 200792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 212279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/JNIHelp.h> 222279b2534272282a5b5152723235da397e49195cSteven Moreland#include <nativehelper/ScopedPrimitiveArray.h> 23e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang 24bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho#include <android/hardware/tv/cec/1.0/IHdmiCec.h> 25bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho#include <android/hardware/tv/cec/1.0/IHdmiCecCallback.h> 26bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho#include <android/hardware/tv/cec/1.0/types.h> 274085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang#include <android_os_MessageQueue.h> 280792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang#include <android_runtime/AndroidRuntime.h> 290792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang#include <android_runtime/Log.h> 30e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang#include <sys/param.h> 31bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho#include <utils/Errors.h> 324085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang#include <utils/Looper.h> 334085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang#include <utils/RefBase.h> 340792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 35bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::tv::cec::V1_0::CecLogicalAddress; 36bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::tv::cec::V1_0::CecMessage; 37bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::tv::cec::V1_0::HdmiPortInfo; 38bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::tv::cec::V1_0::HotplugEvent; 39bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::tv::cec::V1_0::IHdmiCec; 40bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::tv::cec::V1_0::IHdmiCecCallback; 41bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::tv::cec::V1_0::MaxLength; 42bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::tv::cec::V1_0::OptionKey; 43bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::tv::cec::V1_0::Result; 44bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::tv::cec::V1_0::SendMessageResult; 45bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::Return; 46bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::Void; 47bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::hidl_vec; 48bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chousing ::android::hardware::hidl_string; 49bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho 500792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jangnamespace android { 510792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 520792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jangstatic struct { 53e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang jmethodID handleIncomingCecCommand; 54e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang jmethodID handleHotplug; 550792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang} gHdmiCecControllerClassInfo; 560792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 570792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jangclass HdmiCecController { 580792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jangpublic: 59bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho HdmiCecController(sp<IHdmiCec> hdmiCec, jobject callbacksObj, const sp<Looper>& looper); 60bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ~HdmiCecController(); 61e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang 62e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang // Send message to other device. Note that it runs in IO thread. 63bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho int sendMessage(const CecMessage& message); 64a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang // Add a logical address to device. 65bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho int addLogicalAddress(CecLogicalAddress address); 66a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang // Clear all logical address registered to the device. 67a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang void clearLogicaladdress(); 68a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang // Get physical address of device. 69a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang int getPhysicalAddress(); 70a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang // Get CEC version from driver. 71a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang int getVersion(); 72a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang // Get vendor id used for vendor command. 73a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang uint32_t getVendorId(); 740340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim // Get Port information on all the HDMI ports. 750340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim jobjectArray getPortInfos(); 76bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho // Set an option to CEC HAL. 77bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho void setOption(OptionKey key, bool enabled); 78bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho // Informs CEC HAL about the current system language. 79bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho void setLanguage(hidl_string language); 80bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho // Enable audio return channel. 81bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho void enableAudioReturnChannel(int port, bool flag); 82092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang // Whether to hdmi device is connected to the given port. 83092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang bool isConnected(int port); 840792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 854085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang jobject getCallbacksObj() const { 864085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang return mCallbacksObj; 874085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang } 88e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang 894085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jangprivate: 90bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho class HdmiCecCallback : public IHdmiCecCallback { 91bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho public: 92bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho HdmiCecCallback(HdmiCecController* controller) : mController(controller) {}; 93bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<void> onCecMessage(const CecMessage& event) override; 94bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<void> onHotplugEvent(const HotplugEvent& event) override; 95bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho private: 96bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho HdmiCecController* mController; 97bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho }; 98bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho 99a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim static const int INVALID_PHYSICAL_ADDRESS = 0xFFFF; 1000792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 101bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho sp<IHdmiCec> mHdmiCec; 1020792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang jobject mCallbacksObj; 103bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho sp<IHdmiCecCallback> mHdmiCecCallback; 1044085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang sp<Looper> mLooper; 1050792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang}; 1060792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 1074085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang// Handler class to delegate incoming message to service thread. 1084085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jangclass HdmiCecEventHandler : public MessageHandler { 1094085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jangpublic: 110bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho enum EventType { 111bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho CEC_MESSAGE, 112bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho HOT_PLUG 113bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho }; 114bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho 115bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho HdmiCecEventHandler(HdmiCecController* controller, const CecMessage& cecMessage) 116bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho : mController(controller), 117bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho mCecMessage(cecMessage) {} 118bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho 119bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho HdmiCecEventHandler(HdmiCecController* controller, const HotplugEvent& hotplugEvent) 120bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho : mController(controller), 121bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho mHotplugEvent(hotplugEvent) {} 1224085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang 1234085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang virtual ~HdmiCecEventHandler() {} 1244085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang 1254085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang void handleMessage(const Message& message) { 1264085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang switch (message.what) { 127bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho case EventType::CEC_MESSAGE: 128bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho propagateCecCommand(mCecMessage); 1294085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang break; 130bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho case EventType::HOT_PLUG: 131bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho propagateHotplugEvent(mHotplugEvent); 1324085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang break; 1334085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang default: 1344085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang // TODO: add more type whenever new type is introduced. 1354085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang break; 1364085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang } 1374085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang } 138e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang 1394085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jangprivate: 1404085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang // Propagate the message up to Java layer. 141bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho void propagateCecCommand(const CecMessage& message) { 1424085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang JNIEnv* env = AndroidRuntime::getJNIEnv(); 143bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho jint srcAddr = static_cast<jint>(message.initiator); 144bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho jint dstAddr = static_cast<jint>(message.destination); 145bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho jbyteArray body = env->NewByteArray(message.body.size()); 146bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho const jbyte* bodyPtr = reinterpret_cast<const jbyte *>(message.body.data()); 147bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho env->SetByteArrayRegion(body, 0, message.body.size(), bodyPtr); 1484085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang env->CallVoidMethod(mController->getCallbacksObj(), 1494085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang gHdmiCecControllerClassInfo.handleIncomingCecCommand, srcAddr, 1504085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang dstAddr, body); 1514085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang env->DeleteLocalRef(body); 1524085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang 1534085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang checkAndClearExceptionFromCallback(env, __FUNCTION__); 1544085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang } 1554085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang 156bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho void propagateHotplugEvent(const HotplugEvent& event) { 1574085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang // Note that this method should be called in service thread. 1584085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang JNIEnv* env = AndroidRuntime::getJNIEnv(); 159bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho jint port = static_cast<jint>(event.portId); 16042230728b8212738c2351939c5577730f05a58deJungshik Jang jboolean connected = (jboolean) event.connected; 1614085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang env->CallVoidMethod(mController->getCallbacksObj(), 16242230728b8212738c2351939c5577730f05a58deJungshik Jang gHdmiCecControllerClassInfo.handleHotplug, port, connected); 1634085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang 1644085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang checkAndClearExceptionFromCallback(env, __FUNCTION__); 1654085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang } 1664085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang 1674085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang // static 1684085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang static void checkAndClearExceptionFromCallback(JNIEnv* env, const char* methodName) { 1694085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang if (env->ExceptionCheck()) { 1704085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang ALOGE("An exception was thrown by callback '%s'.", methodName); 1714085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang LOGE_EX(env); 1724085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang env->ExceptionClear(); 1734085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang } 1744085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang } 1754085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang 1764085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang HdmiCecController* mController; 177bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho CecMessage mCecMessage; 178bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho HotplugEvent mHotplugEvent; 1794085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang}; 1804085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang 181bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun ChoHdmiCecController::HdmiCecController(sp<IHdmiCec> hdmiCec, 182bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho jobject callbacksObj, const sp<Looper>& looper) 183bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho : mHdmiCec(hdmiCec), 184bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho mCallbacksObj(callbacksObj), 185bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho mLooper(looper) { 186bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho mHdmiCecCallback = new HdmiCecCallback(this); 187bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<void> ret = mHdmiCec->setCallback(mHdmiCecCallback); 188d002a8b07becc7ce1b0978b837bd61f29f8c4d18Steven Moreland if (!ret.isOk()) { 189bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Failed to set a cec callback."); 190bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho } 1914085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang} 1924085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang 193bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun ChoHdmiCecController::~HdmiCecController() { 194bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<void> ret = mHdmiCec->setCallback(nullptr); 195d002a8b07becc7ce1b0978b837bd61f29f8c4d18Steven Moreland if (!ret.isOk()) { 196bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Failed to set a cec callback."); 197bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho } 198e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang} 199e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang 200bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Choint HdmiCecController::sendMessage(const CecMessage& message) { 201e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang // TODO: propagate send_message's return value. 202bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<SendMessageResult> ret = mHdmiCec->sendMessage(message); 203d002a8b07becc7ce1b0978b837bd61f29f8c4d18Steven Moreland if (!ret.isOk()) { 204bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Failed to send CEC message."); 205bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho return static_cast<int>(SendMessageResult::FAIL); 206bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho } 207bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho return static_cast<int>((SendMessageResult) ret); 208e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang} 209e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang 210bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Choint HdmiCecController::addLogicalAddress(CecLogicalAddress address) { 211bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<Result> ret = mHdmiCec->addLogicalAddress(address); 212d002a8b07becc7ce1b0978b837bd61f29f8c4d18Steven Moreland if (!ret.isOk()) { 213bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Failed to add a logical address."); 214bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho return static_cast<int>(Result::FAILURE_UNKNOWN); 215bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho } 216bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho return static_cast<int>((Result) ret); 217a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang} 218a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang 219a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jangvoid HdmiCecController::clearLogicaladdress() { 220bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<void> ret = mHdmiCec->clearLogicalAddress(); 221d002a8b07becc7ce1b0978b837bd61f29f8c4d18Steven Moreland if (!ret.isOk()) { 222bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Failed to clear logical address."); 223bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho } 224a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang} 225a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang 226a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jangint HdmiCecController::getPhysicalAddress() { 227bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Result result; 228a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim uint16_t addr; 229bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<void> ret = mHdmiCec->getPhysicalAddress([&result, &addr](Result res, uint16_t paddr) { 230bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho result = res; 231bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho addr = paddr; 232bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho }); 233d002a8b07becc7ce1b0978b837bd61f29f8c4d18Steven Moreland if (!ret.isOk()) { 234bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Failed to get physical address."); 235bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho return INVALID_PHYSICAL_ADDRESS; 236a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang } 237bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho return result == Result::SUCCESS ? addr : INVALID_PHYSICAL_ADDRESS; 238a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang} 239a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang 240a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jangint HdmiCecController::getVersion() { 241bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<int32_t> ret = mHdmiCec->getCecVersion(); 242d002a8b07becc7ce1b0978b837bd61f29f8c4d18Steven Moreland if (!ret.isOk()) { 243bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Failed to get cec version."); 244bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho } 245bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho return ret; 246a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang} 247a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang 248a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Janguint32_t HdmiCecController::getVendorId() { 249bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<uint32_t> ret = mHdmiCec->getVendorId(); 250d002a8b07becc7ce1b0978b837bd61f29f8c4d18Steven Moreland if (!ret.isOk()) { 251bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Failed to get vendor id."); 252bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho } 253bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho return ret; 254a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang} 255a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang 2560340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk KimjobjectArray HdmiCecController::getPortInfos() { 2570340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim JNIEnv* env = AndroidRuntime::getJNIEnv(); 25863dd3bb3602bc00557680432b08b49a5a15bcdb7Jinsuk Kim jclass hdmiPortInfo = env->FindClass("android/hardware/hdmi/HdmiPortInfo"); 2590340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim if (hdmiPortInfo == NULL) { 2600340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim return NULL; 2610340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim } 2620340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim jmethodID ctor = env->GetMethodID(hdmiPortInfo, "<init>", "(IIIZZZ)V"); 2630340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim if (ctor == NULL) { 2640340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim return NULL; 2650340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim } 266bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho hidl_vec<HdmiPortInfo> ports; 267bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<void> ret = mHdmiCec->getPortInfo([&ports](hidl_vec<HdmiPortInfo> list) { 268bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ports = list; 269bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho }); 270d002a8b07becc7ce1b0978b837bd61f29f8c4d18Steven Moreland if (!ret.isOk()) { 271bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Failed to get port information."); 272bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho return NULL; 273bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho } 274bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho jobjectArray res = env->NewObjectArray(ports.size(), hdmiPortInfo, NULL); 2750340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim 2760340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim // MHL support field will be obtained from MHL HAL. Leave it to false. 2770340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim jboolean mhlSupported = (jboolean) 0; 278bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho for (size_t i = 0; i < ports.size(); ++i) { 279bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho jboolean cecSupported = (jboolean) ports[i].cecSupported; 280bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho jboolean arcSupported = (jboolean) ports[i].arcSupported; 281bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho jobject infoObj = env->NewObject(hdmiPortInfo, ctor, ports[i].portId, ports[i].type, 282bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ports[i].physicalAddress, cecSupported, mhlSupported, arcSupported); 2830340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim env->SetObjectArrayElement(res, i, infoObj); 2840340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim } 2850340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim return res; 2860340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim} 2870340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim 288bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chovoid HdmiCecController::setOption(OptionKey key, bool enabled) { 289bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<void> ret = mHdmiCec->setOption(key, enabled); 290d002a8b07becc7ce1b0978b837bd61f29f8c4d18Steven Moreland if (!ret.isOk()) { 291bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Failed to set option."); 292bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho } 293092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang} 294092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang 295bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chovoid HdmiCecController::setLanguage(hidl_string language) { 296bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<void> ret = mHdmiCec->setLanguage(language); 297d002a8b07becc7ce1b0978b837bd61f29f8c4d18Steven Moreland if (!ret.isOk()) { 298bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Failed to set language."); 299bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho } 300bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho} 301bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho 302bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho// Enable audio return channel. 303bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chovoid HdmiCecController::enableAudioReturnChannel(int port, bool enabled) { 304bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<void> ret = mHdmiCec->enableAudioReturnChannel(port, enabled); 305d002a8b07becc7ce1b0978b837bd61f29f8c4d18Steven Moreland if (!ret.isOk()) { 306bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Failed to enable/disable ARC."); 307bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho } 308092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang} 309092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang 310092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang// Whether to hdmi device is connected to the given port. 311092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jangbool HdmiCecController::isConnected(int port) { 312bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho Return<bool> ret = mHdmiCec->isConnected(port); 313d002a8b07becc7ce1b0978b837bd61f29f8c4d18Steven Moreland if (!ret.isOk()) { 314bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Failed to get connection info."); 315bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho } 316bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho return ret; 317092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang} 318092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang 319bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun ChoReturn<void> HdmiCecController::HdmiCecCallback::onCecMessage(const CecMessage& message) { 320bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(mController, message)); 321bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho mController->mLooper->sendMessage(handler, HdmiCecEventHandler::EventType::CEC_MESSAGE); 322bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho return Void(); 323bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho} 3240792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 325bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun ChoReturn<void> HdmiCecController::HdmiCecCallback::onHotplugEvent(const HotplugEvent& event) { 326bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho sp<HdmiCecEventHandler> handler(new HdmiCecEventHandler(mController, event)); 327bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho mController->mLooper->sendMessage(handler, HdmiCecEventHandler::EventType::HOT_PLUG); 328bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho return Void(); 3290792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang} 3300792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 3310792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang//------------------------------------------------------------------------------ 332e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang#define GET_METHOD_ID(var, clazz, methodName, methodDescriptor) \ 333e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang var = env->GetMethodID(clazz, methodName, methodDescriptor); \ 3346c89616c388d2e5cac5f7d0c1682e48fa6ea7d31Chih-Hung Hsieh LOG_FATAL_IF(! (var), "Unable to find method " methodName); 335e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang 3364085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jangstatic jlong nativeInit(JNIEnv* env, jclass clazz, jobject callbacksObj, 3374085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang jobject messageQueueObj) { 338bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho // TODO(b/31632518) 3397e6627eade85a1861ad5ca55200301cd7799e4e1Chris Phoenix sp<IHdmiCec> hdmiCec = IHdmiCec::getService(); 340bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho if (hdmiCec == nullptr) { 341bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho ALOGE("Couldn't get tv.cec service."); 342e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang return 0; 343e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang } 3444085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang sp<MessageQueue> messageQueue = 3454085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang android_os_MessageQueue_getMessageQueue(env, messageQueueObj); 3464085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang 3470792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang HdmiCecController* controller = new HdmiCecController( 348bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho hdmiCec, 3494085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang env->NewGlobalRef(callbacksObj), 3504085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang messageQueue->getLooper()); 351e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang 352e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang GET_METHOD_ID(gHdmiCecControllerClassInfo.handleIncomingCecCommand, clazz, 353e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang "handleIncomingCecCommand", "(II[B)V"); 354e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang GET_METHOD_ID(gHdmiCecControllerClassInfo.handleHotplug, clazz, 35542230728b8212738c2351939c5577730f05a58deJungshik Jang "handleHotplug", "(IZ)V"); 3560792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 3570792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang return reinterpret_cast<jlong>(controller); 3580792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang} 3590792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 360e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jangstatic jint nativeSendCecCommand(JNIEnv* env, jclass clazz, jlong controllerPtr, 361e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang jint srcAddr, jint dstAddr, jbyteArray body) { 362bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho CecMessage message; 363bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho message.initiator = static_cast<CecLogicalAddress>(srcAddr); 364bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho message.destination = static_cast<CecLogicalAddress>(dstAddr); 365e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang 366e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang jsize len = env->GetArrayLength(body); 367e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang ScopedByteArrayRO bodyPtr(env, body); 368bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho size_t bodyLength = MIN(static_cast<size_t>(len), 369bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho static_cast<size_t>(MaxLength::MESSAGE_BODY)); 370bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho message.body.resize(bodyLength); 371bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho for (size_t i = 0; i < bodyLength; ++i) { 372bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho message.body[i] = static_cast<uint8_t>(bodyPtr[i]); 373bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho } 374e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang 375e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang HdmiCecController* controller = 376e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang reinterpret_cast<HdmiCecController*>(controllerPtr); 377e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang return controller->sendMessage(message); 378e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang} 379e9c77c88ea34a66f83a94f960547275c0ff6bd07Jungshik Jang 380a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimstatic jint nativeAddLogicalAddress(JNIEnv* env, jclass clazz, jlong controllerPtr, 381a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim jint logicalAddress) { 382a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); 383bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho return controller->addLogicalAddress(static_cast<CecLogicalAddress>(logicalAddress)); 384a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang} 385a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang 386a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimstatic void nativeClearLogicalAddress(JNIEnv* env, jclass clazz, jlong controllerPtr) { 387a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); 388a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang controller->clearLogicaladdress(); 389a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang} 390a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang 391a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimstatic jint nativeGetPhysicalAddress(JNIEnv* env, jclass clazz, jlong controllerPtr) { 392a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); 393a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang return controller->getPhysicalAddress(); 394a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang} 395a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang 396a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimstatic jint nativeGetVersion(JNIEnv* env, jclass clazz, jlong controllerPtr) { 397a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); 398a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang return controller->getVersion(); 399a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang} 400a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang 401a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jangstatic jint nativeGetVendorId(JNIEnv* env, jclass clazz, jlong controllerPtr) { 402a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); 403a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang return controller->getVendorId(); 404a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang} 405a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang 4060340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kimstatic jobjectArray nativeGetPortInfos(JNIEnv* env, jclass clazz, jlong controllerPtr) { 4070340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); 4080340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim return controller->getPortInfos(); 4090340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim} 4100340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim 411a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kimstatic void nativeSetOption(JNIEnv* env, jclass clazz, jlong controllerPtr, jint flag, jint value) { 412a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); 413bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho controller->setOption(static_cast<OptionKey>(flag), value > 0 ? true : false); 414bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho} 415bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho 416bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chostatic void nativeSetLanguage(JNIEnv* env, jclass clazz, jlong controllerPtr, jstring language) { 417bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); 418bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho const char *languageStr = env->GetStringUTFChars(language, NULL); 419bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho controller->setLanguage(languageStr); 420bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho env->ReleaseStringUTFChars(language, languageStr); 421092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang} 422092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang 423bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Chostatic void nativeEnableAudioReturnChannel(JNIEnv* env, jclass clazz, jlong controllerPtr, 4241481a4282818939436f590d8c88aea2d19166b8eJinsuk Kim jint port, jboolean enabled) { 425a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); 426bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho controller->enableAudioReturnChannel(port, enabled == JNI_TRUE); 427092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang} 428092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang 429092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jangstatic jboolean nativeIsConnected(JNIEnv* env, jclass clazz, jlong controllerPtr, jint port) { 430a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim HdmiCecController* controller = reinterpret_cast<HdmiCecController*>(controllerPtr); 431092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang return controller->isConnected(port) ? JNI_TRUE : JNI_FALSE ; 432092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang} 433092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang 43476f6a86de25e1bf74717e047e55fd44b089673f3Daniel Micaystatic const JNINativeMethod sMethods[] = { 4350792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang /* name, signature, funcPtr */ 4364085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang { "nativeInit", 4374085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang "(Lcom/android/server/hdmi/HdmiCecController;Landroid/os/MessageQueue;)J", 4384085d0ef62554c7e139b82bca0f97161bb159f8cJungshik Jang (void *) nativeInit }, 439a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang { "nativeSendCecCommand", "(JII[B)I", (void *) nativeSendCecCommand }, 440a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang { "nativeAddLogicalAddress", "(JI)I", (void *) nativeAddLogicalAddress }, 441a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang { "nativeClearLogicalAddress", "(J)V", (void *) nativeClearLogicalAddress }, 442a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang { "nativeGetPhysicalAddress", "(J)I", (void *) nativeGetPhysicalAddress }, 443a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang { "nativeGetVersion", "(J)I", (void *) nativeGetVersion }, 444a9095ba488ea18aeafaf9c3a8258bf9f459bda71Jungshik Jang { "nativeGetVendorId", "(J)I", (void *) nativeGetVendorId }, 4450340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim { "nativeGetPortInfos", 44663dd3bb3602bc00557680432b08b49a5a15bcdb7Jinsuk Kim "(J)[Landroid/hardware/hdmi/HdmiPortInfo;", 4470340bbc89f8162f9c2a298c98b03bfcdd1bc6e87Jinsuk Kim (void *) nativeGetPortInfos }, 448bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho { "nativeSetOption", "(JIZ)V", (void *) nativeSetOption }, 449bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho { "nativeSetLanguage", "(JLjava/lang/String;)V", (void *) nativeSetLanguage }, 450bc6e372b25d7d62efecefba09304c5a66218c91aDonghyun Cho { "nativeEnableAudioReturnChannel", "(JIZ)V", (void *) nativeEnableAudioReturnChannel }, 451092b445ef898e3c1e5b2918b554480940f0f5a28Jungshik Jang { "nativeIsConnected", "(JI)Z", (void *) nativeIsConnected }, 4520792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang}; 4530792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 4540792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang#define CLASS_PATH "com/android/server/hdmi/HdmiCecController" 4550792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 4560792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jangint register_android_server_hdmi_HdmiCecController(JNIEnv* env) { 457a6ce7708d6124224399241503fadcafe0c4684d4Jinsuk Kim int res = jniRegisterNativeMethods(env, CLASS_PATH, sMethods, NELEM(sMethods)); 4580792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang LOG_FATAL_IF(res < 0, "Unable to register native methods."); 4594048a4bcb1ea709ddb83a4fde3ff5c53e642f7d0Bernhard Rosenkränzer (void)res; // Don't scream about unused variable in the LOG_NDEBUG case 4600792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang return 0; 4610792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang} 4620792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang 4630792d37385e60aa8d73f8df174d0a32f4f618bc4Jungshik Jang} /* namespace android */ 464