From: Lukasz Foniok Date: Wed, 17 Dec 2014 17:02:25 +0000 (+0100) Subject: [TV][Channel] tune implementation X-Git-Tag: submit/tizen_tv/20150603.064601~1^2~513 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=692fbe4e6b4cf36f9b626ae570897cc98b0b03c7;p=platform%2Fcore%2Fapi%2Fwebapi-plugins.git [TV][Channel] tune implementation [Verification] tizen.tvchannel.tune( {major:someChannleNo }, function(){} ) should work. Change-Id: If845fe810847af11941fceb354584a7fdeca56b6 Signed-off-by: Lukasz Foniok --- diff --git a/src/tvchannel/tune_option.cc b/src/tvchannel/tune_option.cc new file mode 100644 index 00000000..0de5250f --- /dev/null +++ b/src/tvchannel/tune_option.cc @@ -0,0 +1,171 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#include "tvchannel/tune_option.h" +#include +#include + +namespace extension { +namespace tvchannel { + +TuneOption::TuneOption() { + initialize(); +} + +void TuneOption::initialize() { + m_ptc = 0; + m_major = 0; + m_minor = 0; + m_sourceID = 0; + m_programNumber = 0; + m_transportStreamID = 0; + m_originalNetworkID = 0; + m_ptc_is_set = false; + m_major_is_set = false; + m_minor_is_set = false; + m_sourceID_is_set = false; + m_programNumber_is_set = false; + m_transportStreamID_is_set = false; + m_originalNetworkID_is_set = false; +} + +TuneOption::~TuneOption() { +} + +TuneOption::TuneOption(picojson::object const& _tuneDict) { + LOGD("Enter"); + initialize(); + picojson::object tuneDict = _tuneDict; + if (tuneDict.find("major") != tuneDict.end()) { + setMajor(static_cast(tuneDict["major"].get())); + } + if (tuneDict.find("minor") != tuneDict.end()) { + setMinor(static_cast(tuneDict["minor"].get())); + } + if (tuneDict.find("sourceID") != tuneDict.end()) { + setSourceID(static_cast(tuneDict["sourceID"].get())); + } + if (tuneDict.find("programNumber") != tuneDict.end()) { + setProgramNumber( + static_cast(tuneDict["programNumber"].get())); + } + if (tuneDict.find("transportStreamID") != tuneDict.end()) { + setTransportStreamID( + static_cast(tuneDict["transportStreamID"].get())); + } + if (tuneDict.find("ptc") != tuneDict.end()) { + setPtc(static_cast(tuneDict["ptc"].get())); + } + if (tuneDict.find("originalNetworkID") != tuneDict.end()) { + setOriginalNetworkID( + static_cast(tuneDict["originalNetworkID"].get())); + } +} + +int64_t TuneOption::getPtc() const { + return m_ptc; +} + +bool TuneOption::isPtcSet() const { + return m_ptc_is_set; +} + +void TuneOption::setPtc(int64_t ptc) { + m_ptc = ptc; + m_ptc_is_set = true; +} + +int64_t TuneOption::getMajor() const { + return m_major; +} + +bool TuneOption::isMajorSet() const { + return m_major_is_set; +} + +void TuneOption::setMajor(int64_t major) { + m_major = major; + m_major_is_set = true; +} + +int64_t TuneOption::getMinor() const { + return m_minor; +} + +bool TuneOption::isMinorSet() const { + return m_minor_is_set; +} + +void TuneOption::setMinor(int64_t minor) { + m_minor = minor; + m_minor_is_set = true; +} + +int64_t TuneOption::getSourceID() const { + return m_sourceID; +} + +bool TuneOption::isSourceIDSet() const { + return m_sourceID_is_set; +} + +void TuneOption::setSourceID(int64_t sourceID) { + m_sourceID = sourceID; + m_sourceID_is_set = true; +} + +int64_t TuneOption::getProgramNumber() const { + return m_programNumber; +} + +bool TuneOption::isProgramNumberSet() const { + return m_programNumber_is_set; +} + +void TuneOption::setProgramNumber(int64_t programNumber) { + m_programNumber = programNumber; + m_programNumber_is_set = true; +} + +int64_t TuneOption::getTransportStreamID() const { + return m_transportStreamID; +} + +bool TuneOption::isTransportStreamIDSet() const { + return m_transportStreamID_is_set; +} + +void TuneOption::setTransportStreamID(int64_t transportStreamID) { + m_transportStreamID = transportStreamID; + m_transportStreamID_is_set = true; +} + +int64_t TuneOption::getOriginalNetworkID() const { + return m_originalNetworkID; +} + +bool TuneOption::isOriginalNetworkIDSet() const { + return m_originalNetworkID_is_set; +} + +void TuneOption::setOriginalNetworkID(int64_t originalNetworkID) { + m_originalNetworkID = originalNetworkID; + m_originalNetworkID_is_set = true; +} + +} // namespace tvchannel +} // namespace extension diff --git a/src/tvchannel/tune_option.h b/src/tvchannel/tune_option.h new file mode 100644 index 00000000..6d2ea45c --- /dev/null +++ b/src/tvchannel/tune_option.h @@ -0,0 +1,86 @@ +// +// Tizen Web Device API +// Copyright (c) 2012 Samsung Electronics Co., Ltd. +// +// Licensed under the Apache License, Version 2.0 (the License); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +#ifndef SRC_TVCHANNEL_TUNE_OPTION_H_ +#define SRC_TVCHANNEL_TUNE_OPTION_H_ + +#include +#include "common/picojson.h" +#include "tvchannel/types.h" + +namespace extension { +namespace tvchannel { + +class TuneOption { + public: + TuneOption(); + virtual ~TuneOption(); + + explicit TuneOption(picojson::object const& _tuneDict); + + int64_t getPtc() const; + bool isPtcSet() const; + void setPtc(int64_t ptc); + + int64_t getMajor() const; + bool isMajorSet() const; + void setMajor(int64_t major); + + int64_t getMinor() const; + bool isMinorSet() const; + void setMinor(int64_t minor); + + int64_t getSourceID() const; + bool isSourceIDSet() const; + void setSourceID(int64_t sourceID); + + int64_t getProgramNumber() const; + bool isProgramNumberSet() const; + void setProgramNumber(int64_t programNumber); + + int64_t getTransportStreamID() const; + bool isTransportStreamIDSet() const; + void setTransportStreamID(int64_t transportStreamID); + + int64_t getOriginalNetworkID() const; + bool isOriginalNetworkIDSet() const; + void setOriginalNetworkID(int64_t originalNetworkID); + + private: + int64_t m_ptc; + int64_t m_major; + int64_t m_minor; + int64_t m_sourceID; + int64_t m_programNumber; + int64_t m_transportStreamID; + int64_t m_originalNetworkID; + bool m_ptc_is_set; + bool m_major_is_set; + bool m_minor_is_set; + bool m_sourceID_is_set; + bool m_programNumber_is_set; + bool m_transportStreamID_is_set; + bool m_originalNetworkID_is_set; + void initialize(); +}; + +typedef std::shared_ptr TuneOptionPtr; + +} // namespace tvchannel +} // namespace extension + +#endif // SRC_TVCHANNEL_TUNE_OPTION_H_ diff --git a/src/tvchannel/tvchannel.gyp b/src/tvchannel/tvchannel.gyp index f0c2f758..fe641bc5 100644 --- a/src/tvchannel/tvchannel.gyp +++ b/src/tvchannel/tvchannel.gyp @@ -41,7 +41,9 @@ 'tvchannel_manager.h', 'tvchannel_manager.cc', 'types.h', - 'types.cc' + 'types.cc', + 'tune_option.h', + 'tune_option.cc' ], }, ], diff --git a/src/tvchannel/tvchannel_instance.cc b/src/tvchannel/tvchannel_instance.cc index 9c06d2d4..bff3953c 100644 --- a/src/tvchannel/tvchannel_instance.cc +++ b/src/tvchannel/tvchannel_instance.cc @@ -9,31 +9,89 @@ #include "common/picojson.h" #include "tvchannel/channel_info.h" #include "tvchannel/program_info.h" +#include "tvchannel/types.h" +#include "common/task-queue.h" namespace extension { namespace tvchannel { TVChannelInstance::TVChannelInstance() { - LOGE("Entered"); + LOGD("Entered"); RegisterSyncHandler("TVChannelManager_getCurrentChannel", std::bind(&TVChannelInstance::getCurrentChannel, this, - std::placeholders::_1, - std::placeholders::_2)); + std::placeholders::_1, std::placeholders::_2)); RegisterSyncHandler("TVChannelManager_getCurrentProgram", std::bind(&TVChannelInstance::getCurrentProgram, this, - std::placeholders::_1, + std::placeholders::_1, std::placeholders::_2)); + RegisterHandler("TVChannelManager_tune", + std::bind(&TVChannelInstance::tune, this, std::placeholders::_1, std::placeholders::_2)); - TVChannelManager::getInstance()->registerListener(this); + + m_pSubscriber = TVChannelManager::getInstance()->createSubscriber(this); + TVChannelManager::getInstance()->registerListener(m_pSubscriber); } TVChannelInstance::~TVChannelInstance() { - LOGE("Entered"); + LOGD("Entered"); +} + +void TVChannelInstance::tune(picojson::value const& args, + picojson::object& out) { + LOGD("Enter"); + picojson::object tuneOption = + args.get("tuneOption").get(); + double callbackId = args.get("callbackId").get(); + std::string windowType; + if (args.contains("windowType")) { + windowType = args.get("windowType").get(); + } else { + windowType = "MAIN"; + } + + LOGD("CallbackID %f", callbackId); + std::shared_ptr pTuneData( + new TVChannelManager::TuneData(TuneOption(tuneOption), + stringToWindowType(windowType), callbackId)); + + std::function const&)> task = std::bind( + &TVChannelInstance::tuneTask, this, std::placeholders::_1); + std::function const&)> taskAfter = std::bind( + &TVChannelInstance::tuneTaskAfter, this, std::placeholders::_1); + + common::TaskQueue::GetInstance().Queue(task, + taskAfter, pTuneData); + + picojson::value v; + ReportSuccess(v, out); +} + +void TVChannelInstance::tuneTaskAfter( + std::shared_ptr const& _tuneData) { + LOGD("Enter"); + if (_tuneData->pError) { + picojson::value event = picojson::value(picojson::object()); + picojson::object& obj = event.get(); + obj.insert(std::make_pair("callbackId", picojson::value( + _tuneData->callbackId))); + obj.insert(std::make_pair("error", _tuneData->pError->ToJSON())); + PostMessage(event.serialize().c_str()); + } +} + +void TVChannelInstance::tuneTask( + std::shared_ptr const& _tuneData) { + LOGD("Enter"); + TVChannelManager::getInstance()->tune(_tuneData); } void TVChannelInstance::getCurrentChannel(picojson::value const& args, picojson::object& out) { - std::unique_ptr< ChannelInfo > pChannel = TVChannelManager::getInstance()->getCurrentChannel( - args.get("windowType").get()); + + std::unique_ptr pChannel = + TVChannelManager::getInstance()->getCurrentChannel( + stringToWindowType(args.get("windowType").get())); picojson::value v = channelInfoToJson(pChannel); ReportSuccess(v, out); @@ -79,15 +137,10 @@ picojson::value TVChannelInstance::channelInfoToJson( return picojson::value(channel); } - -void TVChannelInstance::getCurrentProgram(const picojson::value& args, - picojson::object& out) { - std::unique_ptr pInfo(TVChannelManager::getInstance() - ->getCurrentProgram(args.get("windowType").get())); +picojson::value TVChannelInstance::programInfoToJson( + const std::unique_ptr& pInfo) { picojson::value::object program; - program.insert( - std::make_pair("title", - picojson::value(pInfo->getTitle()))); + program.insert(std::make_pair("title", picojson::value(pInfo->getTitle()))); program.insert( std::make_pair("startTime", picojson::value(static_cast(pInfo->getStartTimeMs())))); @@ -98,25 +151,71 @@ void TVChannelInstance::getCurrentProgram(const picojson::value& args, std::make_pair("detailedDescription", picojson::value(pInfo->getDetailedDescription()))); program.insert( - std::make_pair("language", - picojson::value(pInfo->getLanguage()))); + std::make_pair("language", picojson::value(pInfo->getLanguage()))); program.insert( - std::make_pair("rating", - picojson::value(pInfo->getRating()))); + std::make_pair("rating", picojson::value(pInfo->getRating()))); picojson::value result(program); - ReportSuccess(result, out); + return result; +} + +void TVChannelInstance::getCurrentProgram(const picojson::value& args, + picojson::object& out) { + std::unique_ptr pInfo( + TVChannelManager::getInstance()->getCurrentProgram( + stringToWindowType(args.get("windowType").get()))); + ReportSuccess(programInfoToJson(pInfo), out); } -void TVChannelInstance::onChannelChange() { +void TVChannelInstance::onChannelChange(double callbackId) { LOGD("Enter"); try { + WindowType windowType = stringToWindowType("MAIN"); + picojson::value::object dict; - std::unique_ptr pChannel = TVChannelManager::getInstance() - ->getCurrentChannel("MAIN"); + std::unique_ptr pChannel = + TVChannelManager::getInstance()->getCurrentChannel(windowType); dict["listenerId"] = picojson::value("ChannelChanged"); dict["channel"] = channelInfoToJson(pChannel); dict["windowType"] = picojson::value("MAIN"); + dict["success"] = picojson::value(true); + picojson::value resultListener(dict); + PostMessage(resultListener.serialize().c_str()); + if (callbackId !=- 1) { + dict.erase("listenerId"); + dict["callbackId"] = picojson::value(callbackId); + picojson::value resultCallback(dict); + PostMessage(resultCallback.serialize().c_str()); + } + } catch (common::PlatformException& e) { + LOGW("Failed to post message: %s", e.message().c_str()); + } catch (...) { + LOGW("Failed to post message, unknown error"); + } +} + +void TVChannelInstance::onEPGReceived(double callbackId) { + try { + picojson::value::object dict; + dict["listenerId"] = picojson::value("ProgramInfoReceived"); + dict["windowType"] = picojson::value("MAIN"); + std::unique_ptr pInfo( + TVChannelManager::getInstance()->getCurrentProgram(MAIN)); + dict["program"] = programInfoToJson(pInfo); + picojson::value result(dict); + PostMessage(result.serialize().c_str()); + } catch (common::PlatformException& e) { + LOGW("Failed to post message: %s", e.message().c_str()); + } catch (...) { + LOGW("Failed to post message, unknown error"); + } +} +void TVChannelInstance::onNoSignal(double callbackId) { + try { + picojson::value::object dict; + dict["windowType"] = picojson::value("MAIN"); + dict["callbackId"] = picojson::value(callbackId); + dict["nosignal"] = picojson::value(true); picojson::value result(dict); PostMessage(result.serialize().c_str()); } catch (common::PlatformException& e) { @@ -126,5 +225,5 @@ void TVChannelInstance::onChannelChange() { } } -} // namespace tvchannel -} // namespace extension +} // namespace tvchannel +} // namespace extension diff --git a/src/tvchannel/tvchannel_instance.h b/src/tvchannel/tvchannel_instance.h index cd852ef8..24fcecbc 100644 --- a/src/tvchannel/tvchannel_instance.h +++ b/src/tvchannel/tvchannel_instance.h @@ -10,8 +10,8 @@ #include "common/extension.h" #include "common/picojson.h" -#include "tvchannel/tvchannel_manager.h" #include "tvchannel/tvchannel_extension.h" +#include "tvchannel/tvchannel_manager.h" namespace extension { namespace tvchannel { @@ -26,9 +26,20 @@ class TVChannelInstance: private: void getCurrentChannel(const picojson::value& args, picojson::object& out); void getCurrentProgram(const picojson::value& args, picojson::object& out); - virtual void onChannelChange(); + virtual void onChannelChange(double callbackId); + virtual void onEPGReceived(double callbackId); + virtual void onNoSignal(double callbackId); picojson::value channelInfoToJson( const std::unique_ptr &pChannel); + picojson::value programInfoToJson( + const std::unique_ptr &pProgram); + void tune(picojson::value const& args, + picojson::object& out); + void tuneTask(std::shared_ptr const& _tuneData); + void tuneTaskAfter( + std::shared_ptr const& _pTuneData); + + ISignalSubscriber* m_pSubscriber; }; } // namespace tvchannel diff --git a/src/tvchannel/tvchannel_manager.cc b/src/tvchannel/tvchannel_manager.cc index 57b15eda..14a2f2bb 100644 --- a/src/tvchannel/tvchannel_manager.cc +++ b/src/tvchannel/tvchannel_manager.cc @@ -4,6 +4,8 @@ #include "tvchannel/tvchannel_manager.h" #include +#include +#include #include "tvchannel/channel_info.h" #include "tvchannel/program_info.h" #include "common/logger.h" @@ -12,63 +14,195 @@ namespace extension { namespace tvchannel { -using common::UnknownException; - TVChannelManager* TVChannelManager::getInstance() { static TVChannelManager manager; return &manager; } -std::unique_ptr TVChannelManager::getCurrentChannel( - std::string const& _windowType) { - LOGE("Entered %s", _windowType.c_str()); +TVChannelManager::TVChannelManager() : + m_listener(NULL) { + LOGD("Enter"); + int ret = TVServiceAPI::CreateService(&m_pService); + if (TV_SERVICE_API_SUCCESS != ret) { + LOGE("Failed to create tvs-api service: %d", ret); + throw common::UnknownException("Failed to create tvs-api service"); + } +} - TCServiceData serviceData; - TCCriteriaHelper criteria; - criteria.Fetch(SERVICE_ID); - criteria.Fetch(MAJOR); - criteria.Fetch(MINOR); - criteria.Fetch(PROGRAM_NUMBER); - criteria.Fetch(CHANNEL_NUMBER); - criteria.Fetch(CHANNEL_TYPE); - criteria.Fetch(SERVICE_NAME); - criteria.Fetch(SOURCE_ID); - criteria.Fetch(TRANSPORT_STREAM_ID); - criteria.Fetch(ORIGINAL_NETWORK_ID); - criteria.Fetch(LCN); +IService* TVChannelManager::getService() { + return m_pService; +} - // Navigation +void TVChannelManager::tune(std::shared_ptr const& _pTuneData) { + LOGD("Enter"); + try { + std::unique_lock lock(tuneMutex); + + WindowType windowType = _pTuneData->windowType; + TuneOption tuneOption = _pTuneData->tuneOption; + + TCServiceId currentServiceId = + getCurrentChannel(windowType)->getServiceID(); + + TSTvMode tvMode = getTvMode( + getNavigation(getProfile(windowType), SCREENID)); + + ENavigationMode naviMode = NAVIGATION_MODE_ALL; + std::unique_ptr < TCCriteriaHelper > pCriteria = getBasicCriteria( + tvMode, naviMode); + pCriteria->Fetch(SERVICE_ID); + pCriteria->Fetch(CHANNEL_TYPE); + pCriteria->Fetch(CHANNEL_NUMBER); + + if (tuneOption.isMajorSet()) { + LOGD("MAJOR: %d", tuneOption.getMajor()); + pCriteria->Where(MAJOR, static_cast(tuneOption.getMajor())); + } + if (tuneOption.isMinorSet()) { + LOGD("MINOR: %d", tuneOption.getMinor()); + pCriteria->Where(MINOR, static_cast(tuneOption.getMinor())); + } + if (tuneOption.isPtcSet()) { + LOGD("PTC: %d", tuneOption.getPtc()); + pCriteria->Where(CHANNEL_NUMBER, + static_cast(tuneOption.getPtc())); + } + if (tuneOption.isOriginalNetworkIDSet()) { + LOGD("ORIGINAL_NETWORK_ID: %d", tuneOption.getOriginalNetworkID()); + pCriteria->Where(ORIGINAL_NETWORK_ID, + static_cast(tuneOption.getOriginalNetworkID())); + } + if (tuneOption.isProgramNumberSet()) { + LOGD("PROGRAM_NUMBER: %d", tuneOption.getProgramNumber()); + pCriteria->Where(PROGRAM_NUMBER, + static_cast(tuneOption.getProgramNumber())); + } + if (tuneOption.isSourceIDSet()) { + LOGD("SOURCE_ID: %d", tuneOption.getSourceID()); + pCriteria->Where(SOURCE_ID, + static_cast(tuneOption.getSourceID())); + } + if (tuneOption.isTransportStreamIDSet()) { + LOGD("TRANSPORT_STREAM_ID: %d", tuneOption.getTransportStreamID()); + pCriteria->Where(TRANSPORT_STREAM_ID, + static_cast(tuneOption.getTransportStreamID())); + } + + TCServiceData foundService; + int ret = getService()->FindService(*pCriteria, foundService); + if (TV_SERVICE_API_METHOD_SUCCESS != ret) { + LOGE("Failed to find channel: %d", ret); + throw common::NotFoundException("Failed to find channel"); + } + + TCServiceId serviceId = foundService.Get < TCServiceId > (SERVICE_ID); + u_int16_t channelNumber = foundService.Get < u_int16_t + > (CHANNEL_NUMBER); + EChannelType channelType = foundService.Get < EChannelType + > (CHANNEL_TYPE); + + ret = getNavigation(getProfile(windowType), 0)->SetService(serviceId); + if (TV_SERVICE_API_METHOD_SUCCESS != ret) { + LOGE("Failed to set selected channel: %d", ret); + throw new common::UnknownException( + "Failed to set selected channel"); + } + _pTuneData->serviceId = serviceId; + m_callbackTuneMap[serviceId] = _pTuneData->callbackId; + } catch (common::PlatformException const& _error) { + _pTuneData->pError.reset( + new common::PlatformException(_error.name(), _error.message())); + LOGE("Some exception caught"); + } +} + +IServiceNavigation* TVChannelManager::getNavigation(EProfile profileId, + u_int16_t screenId) { + LOGD("Enter"); IServiceNavigation* navigation; - int ret = TVServiceAPI::CreateServiceNavigation( - getProfile(stringToWindowType(_windowType)), 0, &navigation); + int ret = TVServiceAPI::CreateServiceNavigation(profileId, screenId, + &navigation); if (TV_SERVICE_API_SUCCESS != ret) { - LoggerE("Failed to create service navigation: %d", ret); + LOGE("Failed to create service navigation: %d", ret); throw common::UnknownException("Failed to create service navigation"); } + return navigation; +} - struct TSTvMode tvMode; - ret = navigation->GetTvMode(tvMode); +TSTvMode TVChannelManager::getTvMode(IServiceNavigation* pNavigation) { + LOGD("Enter"); + TSTvMode tvMode; + int ret = pNavigation->GetTvMode(tvMode); if (TV_SERVICE_API_METHOD_SUCCESS != ret) { - LoggerE("Failed to get current tv mode: %d", ret); + LOGE("Failed to get current tv mode: %d", ret); throw common::UnknownException("Failed to get current tv mode"); } - LOGE("tvMode : antenna - %d, service - %d", tvMode.antennaMode, - tvMode.serviceMode); + LOGD("tvMode : antenna - %d, service - %d", tvMode.antennaMode, + tvMode.serviceMode); + return tvMode; +} - ret = navigation->GetCurrentServiceInfo(tvMode, criteria, serviceData); +std::unique_ptr TVChannelManager::getBasicCriteria( + TSTvMode tvMode, ENavigationMode naviMode) { + LOGD("Enter"); + std::unique_ptr < TCCriteriaHelper > pCriteria(new TCCriteriaHelper()); + bool found = TCNavigationModeHelper::GetNavigationCriteria(tvMode, naviMode, + *pCriteria); + if (!found) { + LOGE("Failed to create navigation criteria"); + throw common::UnknownException("Failed to create navigation criteria"); + } + return pCriteria; +} + +TCServiceData TVChannelManager::getCurrentServiceInfo( + IServiceNavigation* _pNavigation, TSTvMode _mode, + std::unique_ptr const& _pCriteria) { + LOGD("Enter"); + TCServiceData serviceData; + int ret = _pNavigation->GetCurrentServiceInfo(_mode, *_pCriteria, + serviceData); if (TV_SERVICE_API_METHOD_SUCCESS != ret) { LOGE("Failed to get current service info: %d", ret); throw common::UnknownException("Failed to get current service info"); } - LoggerE("Current channel id: %llu", - serviceData.Get < TCServiceId > (SERVICE_ID)); - std::unique_ptr pChannel( new ChannelInfo() ); + return serviceData; +} + +std::unique_ptr TVChannelManager::getCurrentChannel( + WindowType _windowType) { + LOGD("Entered %d", _windowType); + + std::unique_ptr < TCCriteriaHelper > pCriteria(new TCCriteriaHelper()); + pCriteria->Fetch(SERVICE_ID); + pCriteria->Fetch(MAJOR); + pCriteria->Fetch(MINOR); + pCriteria->Fetch(PROGRAM_NUMBER); + pCriteria->Fetch(CHANNEL_NUMBER); + pCriteria->Fetch(CHANNEL_TYPE); + pCriteria->Fetch(SERVICE_NAME); + pCriteria->Fetch(SOURCE_ID); + pCriteria->Fetch(TRANSPORT_STREAM_ID); + pCriteria->Fetch(ORIGINAL_NETWORK_ID); + pCriteria->Fetch(LCN); + + // Navigation + IServiceNavigation* navigation = getNavigation(getProfile(_windowType), + SCREENID); + + TSTvMode tvMode = getTvMode(navigation); + + TCServiceData serviceData = getCurrentServiceInfo(navigation, tvMode, + pCriteria); + LOGD("Current channel id: %llu", + serviceData.Get < TCServiceId > (SERVICE_ID)); + std::unique_ptr pChannel(new ChannelInfo()); pChannel->fromApiData(serviceData); return pChannel; } EProfile TVChannelManager::getProfile(WindowType windowType) { - LOGE("Enter"); + LOGD("Enter"); switch (windowType) { case MAIN: return PROFILE_TYPE_MAIN; @@ -80,43 +214,26 @@ EProfile TVChannelManager::getProfile(WindowType windowType) { } } -TCServiceId TVChannelManager::getCurrentChannelId( - const std::string& _windowType) { - TCServiceData serviceData; - TCCriteriaHelper criteria; - criteria.Fetch(SERVICE_ID); +TCServiceId TVChannelManager::getCurrentChannelId(WindowType _windowType) { + LOGD("Enter"); // Navigation - IServiceNavigation* navigation; - int ret = TVServiceAPI::CreateServiceNavigation( - getProfile(stringToWindowType(_windowType)), 0, &navigation); - if (TV_SERVICE_API_SUCCESS != ret) { - LOGE("Failed to create service navigation: %d", ret); - throw UnknownException("Failed to create service navigation"); - } - - struct TSTvMode tvMode; - ret = navigation->GetTvMode(tvMode); - if (TV_SERVICE_API_METHOD_SUCCESS != ret) { - LOGE("Failed to get current tv mode: %d", ret); - throw UnknownException("Failed to get current tv mode"); - } - - ret = navigation->GetCurrentServiceInfo(tvMode, criteria, serviceData); - if (TV_SERVICE_API_METHOD_SUCCESS != ret) { - LOGE("Failed to get current service info: %d", ret); - throw UnknownException("Failed to get current service info"); - } - return serviceData.Get(SERVICE_ID); + IServiceNavigation* navigation = getNavigation(getProfile(_windowType), + SCREENID); + TSTvMode tvMode = getTvMode(navigation); + std::unique_ptr < TCCriteriaHelper > pCriteria(new TCCriteriaHelper()); + pCriteria->Fetch(SERVICE_ID); + TCServiceData serviceData = getCurrentServiceInfo(navigation, tvMode, + pCriteria); + return serviceData.Get < TCServiceId > (SERVICE_ID); } -ProgramInfo* TVChannelManager::getCurrentProgram( - const std::string& _windowType) { - +ProgramInfo* TVChannelManager::getCurrentProgram(WindowType _windowType) { + LOGD("Enter"); IServiceGuide* guide; int ret = TVServiceAPI::CreateServiceGuide(&guide); if (TV_SERVICE_API_SUCCESS != ret) { LOGE("Failed to create service guide: %d", ret); - throw UnknownException("Failed to create service guide"); + throw common::UnknownException("Failed to create service guide"); } TCProgramData programData; @@ -124,47 +241,80 @@ ProgramInfo* TVChannelManager::getCurrentProgram( programData); if (TV_SERVICE_API_METHOD_SUCCESS != ret) { LOGE("Failed to get current program: %d", ret); - throw UnknownException("Failed to get current program"); + throw common::UnknownException("Failed to get current program"); } ProgramInfo* program = new ProgramInfo(); program->fromApiData(programData); return program; } -void TVChannelManager::registerListener(EventListener* listener) { +ISignalSubscriber* TVChannelManager::createSubscriber( + EventListener* pListener) { LOGD("Enter"); - m_listener = listener; - ISignalSubscriber* subscriber; - int ret = TVServiceAPI::CreateSignalSubscriber(signalListener, &subscriber); + m_listener = pListener; + ISignalSubscriber* pSubscriber; + int ret = TVServiceAPI::CreateSignalSubscriber(signalListener, + &pSubscriber); if (TV_SERVICE_API_SUCCESS != ret) { LOGW("Failed to create tvs-api SignalSubscriber"); - return; } - ret = subscriber->Subscribe(SIGNAL_TUNE_SUCCESS); + return pSubscriber; +} + +void TVChannelManager::registerListener(ISignalSubscriber* pSubscriber) { + LOGD("Enter"); + pSubscriber->Unsubscribe(SIGNAL_TUNE_SUCCESS); + int ret = pSubscriber->Subscribe(SIGNAL_TUNE_SUCCESS); if (TV_SERVICE_API_METHOD_SUCCESS != ret) { LOGW("Failed to add listener: SIGNAL_TUNE_SUCCESS"); } + pSubscriber->Unsubscribe(SIGNAL_TUNER_LOCK_FAIL); + ret = pSubscriber->Subscribe(SIGNAL_TUNER_LOCK_FAIL); + if (TV_SERVICE_API_METHOD_SUCCESS != ret) { + LOGW("Failed to add listener: SIGNAL_TUNER_LOCK_FAIL"); + } + pSubscriber->Unsubscribe(SIGNAL_EPG_COMPLETED); + ret = pSubscriber->Subscribe(SIGNAL_EPG_COMPLETED); + if (TV_SERVICE_API_METHOD_SUCCESS != ret) { + LOGW("Failed to add listener: SIGNAL_EPG_COMPLETED"); + } } -int TVChannelManager::signalListener(ESignalType type, - TSSignalData data, void*) { +int TVChannelManager::signalListener(ESignalType type, EProfile _profile, + u_int16_t _screenID, TSSignalData data, void*) { LOGD("Enter: %d", type); if (!getInstance()->m_listener) { LOGE("Listener is empty, ignoring message"); return 0; } + + TCServiceId pChannelId = + getInstance()->getCurrentChannelId(stringToWindowType("MAIN")); + double callbackID = -1; + auto it = getInstance()->m_callbackTuneMap.find(pChannelId); + if (it != getInstance()->m_callbackTuneMap.end()) { + callbackID = it->second; + } + LOGD("CallbackID %f", callbackID); + switch (type) { - case SIGNAL_TUNE_SUCCESS: - getInstance()->m_listener->onChannelChange(); - break; - default: - LOGW("Unrecognized event type"); + case SIGNAL_TUNE_SUCCESS: + getInstance()->m_listener->onChannelChange(callbackID); + break; + case SIGNAL_TUNER_LOCK_FAIL: + getInstance()->m_listener->onNoSignal(callbackID); + break; + case SIGNAL_EPG_COMPLETED: + getInstance()->m_listener->onEPGReceived(callbackID); + break; + default: + LOGW("Unrecognized event type"); } return 0; } void TVChannelManager::ucs2utf8(char *out, size_t out_len, char *in, - size_t in_len) { + size_t in_len) { iconv_t cd; size_t r; diff --git a/src/tvchannel/tvchannel_manager.h b/src/tvchannel/tvchannel_manager.h index e1796960..e7b2f40e 100644 --- a/src/tvchannel/tvchannel_manager.h +++ b/src/tvchannel/tvchannel_manager.h @@ -7,8 +7,17 @@ #include #include +#include +#include #include +#include +#include #include "tvchannel/types.h" +#include "tvchannel/tune_option.h" + +namespace common { +class PlatformException; +} namespace extension { namespace tvchannel { @@ -26,29 +35,64 @@ static const int TV_SERVICE_API_METHOD_FAILURE = -1; class EventListener { public: - virtual void onChannelChange() = 0; + virtual void onChannelChange(double callbackId) = 0; + virtual void onEPGReceived(double callbackId) = 0; + virtual void onNoSignal(double callbackId) = 0; + virtual ~EventListener() { + } }; class TVChannelManager { public: + struct TuneData { + TuneData(TuneOption _tuneOption, WindowType _windowType, + double _callbackId) : + tuneOption(_tuneOption), windowType(_windowType), + callbackId(_callbackId) { + } + TuneOption tuneOption; + WindowType windowType; + double callbackId; + u_int64_t serviceId; + std::shared_ptr pError; + }; + static TVChannelManager* getInstance(); - std::unique_ptr getCurrentChannel(std::string const& _windowType); - ProgramInfo* getCurrentProgram(std::string const& _windowType); static void ucs2utf8(char *out, size_t out_len, char *in, size_t in_len); - void registerListener(EventListener* listener); + void registerListener(ISignalSubscriber* pSubscriber); + ISignalSubscriber* createSubscriber(EventListener* pListener); + std::unique_ptr getCurrentChannel(WindowType _windowType); + ProgramInfo* getCurrentProgram(WindowType _windowType); + + void tune(std::shared_ptr const& _pTuneData); + + EProfile getProfile(WindowType windowType); + IServiceNavigation* getNavigation(EProfile profileId, u_int16_t screenId); + TSTvMode getTvMode(IServiceNavigation* _pNavigation); + std::unique_ptr getBasicCriteria(TSTvMode tvMode, + ENavigationMode naviMode); + TCServiceData getCurrentServiceInfo(IServiceNavigation* _pNavigation, + TSTvMode _mode, std::unique_ptr const& _pCriteria); + + IService* getService(); + private: EventListener* m_listener; // Not copyable, assignable, movable - TVChannelManager(): - m_listener(NULL) { - } + TVChannelManager(); TVChannelManager(TVChannelManager const&) = delete; void operator=(TVChannelManager const&) = delete; TVChannelManager(TVChannelManager &&) = delete; - EProfile getProfile(WindowType windowType); - TCServiceId getCurrentChannelId(std::string const& _windowType); - static int signalListener(ESignalType type, TSSignalData data, void*); + TCServiceId getCurrentChannelId(WindowType _windowType); + static int signalListener(ESignalType type, EProfile _profile, + u_int16_t _screenID, TSSignalData data, void*); + IService* m_pService; + + static const int SCREENID = 0; + + std::mutex tuneMutex; + std::map m_callbackTuneMap; }; } // namespace tvchannel