From 13e0691078668f10e07909a126f7354a169566c8 Mon Sep 17 00:00:00 2001 From: Dongwon Kang Date: Wed, 19 Oct 2016 16:12:51 -0700 Subject: [PATCH] tv.input: Updating tv input hal client with hidl. Test: end-to-end test with sw hal implementation. Bug: 32096101 Change-Id: I673b6c8b2cb1f20ae6fce7d201d2a01fca446042 --- services/core/jni/Android.mk | 2 + .../core/jni/com_android_server_tv_TvInputHal.cpp | 274 ++++++++++----------- 2 files changed, 129 insertions(+), 147 deletions(-) diff --git a/services/core/jni/Android.mk b/services/core/jni/Android.mk index 121067a9f229..2c46413b3263 100644 --- a/services/core/jni/Android.mk +++ b/services/core/jni/Android.mk @@ -71,3 +71,5 @@ LOCAL_SHARED_LIBRARIES += \ android.hardware.vibrator@1.0 \ android.hardware.light@2.0 \ android.hardware.vr@1.0 \ + android.hardware.audio.common@2.0 \ + android.hardware.tv.input@1.0 \ diff --git a/services/core/jni/com_android_server_tv_TvInputHal.cpp b/services/core/jni/com_android_server_tv_TvInputHal.cpp index e34a8e8a8cf8..179fba073e75 100644 --- a/services/core/jni/com_android_server_tv_TvInputHal.cpp +++ b/services/core/jni/com_android_server_tv_TvInputHal.cpp @@ -24,6 +24,9 @@ #include "JNIHelp.h" #include "jni.h" +#include +#include +#include #include #include #include @@ -32,6 +35,20 @@ #include #include +using ::android::hardware::audio::common::V2_0::AudioDevice; +using ::android::hardware::tv::input::V1_0::ITvInput; +using ::android::hardware::tv::input::V1_0::ITvInputCallback; +using ::android::hardware::tv::input::V1_0::Result; +using ::android::hardware::tv::input::V1_0::TvInputDeviceInfo; +using ::android::hardware::tv::input::V1_0::TvInputEvent; +using ::android::hardware::tv::input::V1_0::TvInputEventType; +using ::android::hardware::tv::input::V1_0::TvInputType; +using ::android::hardware::tv::input::V1_0::TvStreamConfig; +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::hidl_vec; +using ::android::hardware::hidl_string; + namespace android { static struct { @@ -239,9 +256,9 @@ public: int addOrUpdateStream(int deviceId, int streamId, const sp& surface); int removeStream(int deviceId, int streamId); - const tv_stream_config_t* getStreamConfigs(int deviceId, int* numConfigs); + const hidl_vec getStreamConfigs(int deviceId); - void onDeviceAvailable(const tv_input_device_info_t& info); + void onDeviceAvailable(const TvInputDeviceInfo& info); void onDeviceUnavailable(int deviceId); void onStreamConfigurationsChanged(int deviceId); void onCaptured(int deviceId, int streamId, uint32_t seq, bool succeeded); @@ -263,73 +280,60 @@ private: class NotifyHandler : public MessageHandler { public: - NotifyHandler(JTvInputHal* hal, const tv_input_event_t* event); - ~NotifyHandler(); + NotifyHandler(JTvInputHal* hal, const TvInputEvent& event); virtual void handleMessage(const Message& message); private: - tv_input_event_t mEvent; + TvInputEvent mEvent; JTvInputHal* mHal; }; - JTvInputHal(JNIEnv* env, jobject thiz, tv_input_device_t* dev, const sp& looper); - - static void notify( - tv_input_device_t* dev, tv_input_event_t* event, void* data); + class TvInputCallback : public ITvInputCallback { + public: + TvInputCallback(JTvInputHal* hal); + Return notify(const TvInputEvent& event) override; + private: + JTvInputHal* mHal; + }; - static void cloneTvInputEvent( - tv_input_event_t* dstEvent, const tv_input_event_t* srcEvent); + JTvInputHal(JNIEnv* env, jobject thiz, sp tvInput, const sp& looper); Mutex mLock; jweak mThiz; - tv_input_device_t* mDevice; - tv_input_callback_ops_t mCallback; sp mLooper; KeyedVector > mConnections; + + sp mTvInput; + sp mTvInputCallback; }; -JTvInputHal::JTvInputHal(JNIEnv* env, jobject thiz, tv_input_device_t* device, +JTvInputHal::JTvInputHal(JNIEnv* env, jobject thiz, sp tvInput, const sp& looper) { mThiz = env->NewWeakGlobalRef(thiz); - mDevice = device; - mCallback.notify = &JTvInputHal::notify; + mTvInput = tvInput; mLooper = looper; - - mDevice->initialize(mDevice, &mCallback, this); + mTvInputCallback = new TvInputCallback(this); + mTvInput->setCallback(mTvInputCallback); } JTvInputHal::~JTvInputHal() { - mDevice->common.close((hw_device_t*)mDevice); - + mTvInput->setCallback(nullptr); JNIEnv* env = AndroidRuntime::getJNIEnv(); env->DeleteWeakGlobalRef(mThiz); mThiz = NULL; } JTvInputHal* JTvInputHal::createInstance(JNIEnv* env, jobject thiz, const sp& looper) { - tv_input_module_t* module = NULL; - status_t err = hw_get_module(TV_INPUT_HARDWARE_MODULE_ID, - (hw_module_t const**)&module); - if (err) { - ALOGE("Couldn't load %s module (%s)", - TV_INPUT_HARDWARE_MODULE_ID, strerror(-err)); - return 0; - } - - tv_input_device_t* device = NULL; - err = module->common.methods->open( - (hw_module_t*)module, - TV_INPUT_DEFAULT_DEVICE, - (hw_device_t**)&device); - if (err) { - ALOGE("Couldn't open %s device (%s)", - TV_INPUT_DEFAULT_DEVICE, strerror(-err)); - return 0; - } - - return new JTvInputHal(env, thiz, device, looper); + // TODO(b/31632518) + sp tvInput = ITvInput::getService("tv.input"); + if (tvInput == nullptr) { + ALOGE("Couldn't get tv.input service."); + return nullptr; + } + + return new JTvInputHal(env, thiz, tvInput, looper); } int JTvInputHal::addOrUpdateStream(int deviceId, int streamId, const sp& surface) { @@ -353,16 +357,22 @@ int JTvInputHal::addOrUpdateStream(int deviceId, int streamId, const sp } if (connection.mSourceHandle == NULL && connection.mThread == NULL) { // Need to configure stream - int numConfigs = 0; - const tv_stream_config_t* configs = NULL; - if (mDevice->get_stream_configurations( - mDevice, deviceId, &numConfigs, &configs) != 0) { - ALOGE("Couldn't get stream configs"); + Result result = Result::UNKNOWN; + hidl_vec list; + mTvInput->getStreamConfigurations(deviceId, + [&result, &list](Result res, hidl_vec configs) { + result = res; + if (res == Result::OK) { + list = configs; + } + }); + if (result != Result::OK) { + ALOGE("Couldn't get stream configs for device id:%d result:%d", deviceId, result); return UNKNOWN_ERROR; } int configIndex = -1; - for (int i = 0; i < numConfigs; ++i) { - if (configs[i].stream_id == streamId) { + for (size_t i = 0; i < list.size(); ++i) { + if (list[i].streamId == streamId) { configIndex = i; break; } @@ -371,34 +381,27 @@ int JTvInputHal::addOrUpdateStream(int deviceId, int streamId, const sp ALOGE("Cannot find a config with given stream ID: %d", streamId); return BAD_VALUE; } - connection.mStreamType = configs[configIndex].type; - - tv_stream_t stream; - stream.stream_id = configs[configIndex].stream_id; - if (connection.mStreamType == TV_STREAM_TYPE_BUFFER_PRODUCER) { - stream.buffer_producer.width = configs[configIndex].max_video_width; - stream.buffer_producer.height = configs[configIndex].max_video_height; - } - if (mDevice->open_stream(mDevice, deviceId, &stream) != 0) { - ALOGE("Couldn't add stream"); + connection.mStreamType = TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE; + + result = Result::UNKNOWN; + const native_handle_t* sidebandStream; + mTvInput->openStream(deviceId, streamId, + [&result, &sidebandStream](Result res, const native_handle_t* handle) { + result = res; + if (res == Result::OK) { + sidebandStream = handle; + } + }); + if (result != Result::OK) { + ALOGE("Couldn't open stream. device id:%d stream id:%d result:%d", deviceId, streamId, + result); return UNKNOWN_ERROR; } - if (connection.mStreamType == TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE) { - connection.mSourceHandle = NativeHandle::create( - stream.sideband_stream_source_handle, false); - } else if (connection.mStreamType == TV_STREAM_TYPE_BUFFER_PRODUCER) { - if (connection.mThread != NULL) { - connection.mThread->shutdown(); - } - connection.mThread = new BufferProducerThread(mDevice, deviceId, &stream); - connection.mThread->run("BufferProducerThread"); - } + connection.mSourceHandle = NativeHandle::create((native_handle_t*)sidebandStream, false); } connection.mSurface = surface; - if (connection.mStreamType == TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE) { + if (connection.mSurface != nullptr) { connection.mSurface->setSidebandStream(connection.mSourceHandle); - } else if (connection.mStreamType == TV_STREAM_TYPE_BUFFER_PRODUCER) { - connection.mThread->setSurface(surface); } return NO_ERROR; } @@ -421,8 +424,8 @@ int JTvInputHal::removeStream(int deviceId, int streamId) { connection.mThread->shutdown(); connection.mThread.clear(); } - if (mDevice->close_stream(mDevice, deviceId, streamId) != 0) { - ALOGE("Couldn't remove stream"); + if (mTvInput->closeStream(deviceId, streamId) != Result::OK) { + ALOGE("Couldn't close stream. device id:%d stream id:%d", deviceId, streamId); return BAD_VALUE; } if (connection.mSourceHandle != NULL) { @@ -431,41 +434,26 @@ int JTvInputHal::removeStream(int deviceId, int streamId) { return NO_ERROR; } -const tv_stream_config_t* JTvInputHal::getStreamConfigs(int deviceId, int* numConfigs) { - const tv_stream_config_t* configs = NULL; - if (mDevice->get_stream_configurations( - mDevice, deviceId, numConfigs, &configs) != 0) { - ALOGE("Couldn't get stream configs"); - return NULL; - } - return configs; -} - -// static -void JTvInputHal::notify( - tv_input_device_t* dev, tv_input_event_t* event, void* data) { - JTvInputHal* thiz = (JTvInputHal*)data; - thiz->mLooper->sendMessage(new NotifyHandler(thiz, event), event->type); -} - -// static -void JTvInputHal::cloneTvInputEvent( - tv_input_event_t* dstEvent, const tv_input_event_t* srcEvent) { - memcpy(dstEvent, srcEvent, sizeof(tv_input_event_t)); - if ((srcEvent->type == TV_INPUT_EVENT_DEVICE_AVAILABLE || - srcEvent->type == TV_INPUT_EVENT_DEVICE_UNAVAILABLE || - srcEvent->type == TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED) && - srcEvent->device_info.audio_address != NULL){ - char* audio_address = new char[strlen(srcEvent->device_info.audio_address) + 1]; - strcpy(audio_address, srcEvent->device_info.audio_address); - dstEvent->device_info.audio_address = audio_address; - } +const hidl_vec JTvInputHal::getStreamConfigs(int deviceId) { + Result result = Result::UNKNOWN; + hidl_vec list; + mTvInput->getStreamConfigurations(deviceId, + [&result, &list](Result res, hidl_vec configs) { + result = res; + if (res == Result::OK) { + list = configs; + } + }); + if (result != Result::OK) { + ALOGE("Couldn't get stream configs for device id:%d result:%d", deviceId, result); + } + return list; } -void JTvInputHal::onDeviceAvailable(const tv_input_device_info_t& info) { +void JTvInputHal::onDeviceAvailable(const TvInputDeviceInfo& info) { { Mutex::Autolock autoLock(&mLock); - mConnections.add(info.device_id, KeyedVector()); + mConnections.add(info.deviceId, KeyedVector()); } JNIEnv* env = AndroidRuntime::getJNIEnv(); @@ -473,17 +461,20 @@ void JTvInputHal::onDeviceAvailable(const tv_input_device_info_t& info) { gTvInputHardwareInfoBuilderClassInfo.clazz, gTvInputHardwareInfoBuilderClassInfo.constructor); env->CallObjectMethod( - builder, gTvInputHardwareInfoBuilderClassInfo.deviceId, info.device_id); + builder, gTvInputHardwareInfoBuilderClassInfo.deviceId, info.deviceId); env->CallObjectMethod( builder, gTvInputHardwareInfoBuilderClassInfo.type, info.type); - if (info.type == TV_INPUT_TYPE_HDMI) { + if (info.type == TvInputType::HDMI) { env->CallObjectMethod( - builder, gTvInputHardwareInfoBuilderClassInfo.hdmiPortId, info.hdmi.port_id); + builder, gTvInputHardwareInfoBuilderClassInfo.hdmiPortId, info.portId); } env->CallObjectMethod( - builder, gTvInputHardwareInfoBuilderClassInfo.audioType, info.audio_type); - if (info.audio_type != AUDIO_DEVICE_NONE) { - jstring audioAddress = env->NewStringUTF(info.audio_address); + builder, gTvInputHardwareInfoBuilderClassInfo.audioType, info.audioType); + if (info.audioType != AudioDevice::NONE) { + uint8_t buffer[info.audioAddress.size() + 1]; + memcpy(buffer, info.audioAddress.data(), info.audioAddress.size()); + buffer[info.audioAddress.size()] = '\0'; + jstring audioAddress = env->NewStringUTF(reinterpret_cast(buffer)); env->CallObjectMethod( builder, gTvInputHardwareInfoBuilderClassInfo.audioAddress, audioAddress); env->DeleteLocalRef(audioAddress); @@ -556,48 +547,37 @@ void JTvInputHal::onCaptured(int deviceId, int streamId, uint32_t seq, bool succ } } -JTvInputHal::NotifyHandler::NotifyHandler(JTvInputHal* hal, const tv_input_event_t* event) { +JTvInputHal::NotifyHandler::NotifyHandler(JTvInputHal* hal, const TvInputEvent& event) { mHal = hal; - cloneTvInputEvent(&mEvent, event); -} - -JTvInputHal::NotifyHandler::~NotifyHandler() { - if ((mEvent.type == TV_INPUT_EVENT_DEVICE_AVAILABLE || - mEvent.type == TV_INPUT_EVENT_DEVICE_UNAVAILABLE || - mEvent.type == TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED) && - mEvent.device_info.audio_address != NULL) { - delete mEvent.device_info.audio_address; - } + mEvent = event; } void JTvInputHal::NotifyHandler::handleMessage(const Message& message) { switch (mEvent.type) { - case TV_INPUT_EVENT_DEVICE_AVAILABLE: { - mHal->onDeviceAvailable(mEvent.device_info); - } break; - case TV_INPUT_EVENT_DEVICE_UNAVAILABLE: { - mHal->onDeviceUnavailable(mEvent.device_info.device_id); + case TvInputEventType::DEVICE_AVAILABLE: { + mHal->onDeviceAvailable(mEvent.deviceInfo); } break; - case TV_INPUT_EVENT_STREAM_CONFIGURATIONS_CHANGED: { - mHal->onStreamConfigurationsChanged(mEvent.device_info.device_id); + case TvInputEventType::DEVICE_UNAVAILABLE: { + mHal->onDeviceUnavailable(mEvent.deviceInfo.deviceId); } break; - case TV_INPUT_EVENT_CAPTURE_SUCCEEDED: { - mHal->onCaptured(mEvent.capture_result.device_id, - mEvent.capture_result.stream_id, - mEvent.capture_result.seq, - true /* succeeded */); - } break; - case TV_INPUT_EVENT_CAPTURE_FAILED: { - mHal->onCaptured(mEvent.capture_result.device_id, - mEvent.capture_result.stream_id, - mEvent.capture_result.seq, - false /* succeeded */); + case TvInputEventType::STREAM_CONFIGURATIONS_CHANGED: { + mHal->onStreamConfigurationsChanged(mEvent.deviceInfo.deviceId); } break; default: ALOGE("Unrecognizable event"); } } +JTvInputHal::TvInputCallback::TvInputCallback(JTvInputHal* hal) { + mHal = hal; +} + +Return JTvInputHal::TvInputCallback::notify(const TvInputEvent& event) { + // TODO(b/32200867): Ensure the event type values are in sync with the framework code. + mHal->mLooper->sendMessage(new NotifyHandler(mHal, event), static_cast(event.type)); + return Void(); +} + //////////////////////////////////////////////////////////////////////////////// static jlong nativeOpen(JNIEnv* env, jobject thiz, jobject messageQueueObj) { @@ -628,22 +608,22 @@ static int nativeRemoveStream(JNIEnv* env, jclass clazz, static jobjectArray nativeGetStreamConfigs(JNIEnv* env, jclass clazz, jlong ptr, jint deviceId, jint generation) { JTvInputHal* tvInputHal = (JTvInputHal*)ptr; - int numConfigs = 0; - const tv_stream_config_t* configs = tvInputHal->getStreamConfigs(deviceId, &numConfigs); + const hidl_vec configs = tvInputHal->getStreamConfigs(deviceId); - jobjectArray result = env->NewObjectArray(numConfigs, gTvStreamConfigClassInfo.clazz, NULL); - for (int i = 0; i < numConfigs; ++i) { + jobjectArray result = env->NewObjectArray(configs.size(), gTvStreamConfigClassInfo.clazz, NULL); + for (size_t i = 0; i < configs.size(); ++i) { jobject builder = env->NewObject( gTvStreamConfigBuilderClassInfo.clazz, gTvStreamConfigBuilderClassInfo.constructor); env->CallObjectMethod( - builder, gTvStreamConfigBuilderClassInfo.streamId, configs[i].stream_id); + builder, gTvStreamConfigBuilderClassInfo.streamId, configs[i].streamId); env->CallObjectMethod( - builder, gTvStreamConfigBuilderClassInfo.type, configs[i].type); + builder, gTvStreamConfigBuilderClassInfo.type, + TV_STREAM_TYPE_INDEPENDENT_VIDEO_SOURCE); env->CallObjectMethod( - builder, gTvStreamConfigBuilderClassInfo.maxWidth, configs[i].max_video_width); + builder, gTvStreamConfigBuilderClassInfo.maxWidth, configs[i].maxVideoWidth); env->CallObjectMethod( - builder, gTvStreamConfigBuilderClassInfo.maxHeight, configs[i].max_video_height); + builder, gTvStreamConfigBuilderClassInfo.maxHeight, configs[i].maxVideoHeight); env->CallObjectMethod( builder, gTvStreamConfigBuilderClassInfo.generation, generation); -- 2.11.0