From 673132618c05ba49281208fb5ca9554197af19bf Mon Sep 17 00:00:00 2001 From: Mu-Woong Lee Date: Wed, 27 Apr 2016 21:04:54 +0900 Subject: [PATCH] Break the direct dependency to media-content from the media stats provider If necessary, the provider dynamically load another so to use the media content API. Change-Id: Id7f1fab0e956ee7702382328b981860f5fa6c9fc Signed-off-by: Mu-Woong Lee --- packaging/context-provider.spec | 1 + src/media-stats/CMakeLists.txt | 6 +- src/media-stats/MediaContentMonitor.cpp | 84 ++++++++++++++----------- src/media-stats/MediaContentMonitor.h | 15 +++-- src/media-stats/util/CMakeLists.txt | 19 ++++++ src/media-stats/util/MediaInfoUtil.cpp | 41 ++++++++++++ 6 files changed, 119 insertions(+), 47 deletions(-) create mode 100644 src/media-stats/util/CMakeLists.txt create mode 100644 src/media-stats/util/MediaInfoUtil.cpp diff --git a/packaging/context-provider.spec b/packaging/context-provider.spec index 01b83db..9d7b30b 100644 --- a/packaging/context-provider.spec +++ b/packaging/context-provider.spec @@ -36,6 +36,7 @@ BuildRequires: pkgconfig(tapi) BuildRequires: pkgconfig(capi-telephony) BuildRequires: pkgconfig(capi-messaging-email) BuildRequires: pkgconfig(capi-content-media-content) +BuildRequires: pkgconfig(libmedia-utils) BuildRequires: pkgconfig(capi-location-manager) BuildRequires: pkgconfig(capi-geofence-manager) %endif diff --git a/src/media-stats/CMakeLists.txt b/src/media-stats/CMakeLists.txt index cf5e6de..19c9ea4 100644 --- a/src/media-stats/CMakeLists.txt +++ b/src/media-stats/CMakeLists.txt @@ -1,7 +1,7 @@ SET(target "${target_prefix}-media-stats") SET(DEPS ${DEPS} - capi-content-media-content + libmedia-utils ) FILE(GLOB SRCS *.cpp) @@ -14,6 +14,8 @@ FOREACH(flag ${PKG_MEDIA_STATS_CFLAGS}) ENDFOREACH(flag) ADD_LIBRARY(${target} SHARED ${SRCS}) -TARGET_LINK_LIBRARIES(${target} ${PKG_MEDIA_STATS_LDFLAGS} ${target_shared}) +TARGET_LINK_LIBRARIES(${target} ${PKG_MEDIA_STATS_LDFLAGS} ${target_shared} -ldl) INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}/${target_dir}) + +ADD_SUBDIRECTORY(util) diff --git a/src/media-stats/MediaContentMonitor.cpp b/src/media-stats/MediaContentMonitor.cpp index 734b64b..634de43 100644 --- a/src/media-stats/MediaContentMonitor.cpp +++ b/src/media-stats/MediaContentMonitor.cpp @@ -14,19 +14,27 @@ * limitations under the License. */ +#include #include +#include #include #include "../shared/SystemInfo.h" #include "MediaStatisticsTypes.h" #include "DbHandle.h" #include "MediaContentMonitor.h" +#define SO_PATH "/usr/lib/context-service/libctx-prvd-media-stats-util.so" + #define PLAYCOUNT_RETENTION_PERIOD 259200 /* 1 month in secs */ #define ONE_DAY_IN_SEC 86400 +typedef bool (*get_play_count_t)(int updateItem, int updateType, int mediaType, char *uuid, int *count); + ctx::MediaContentMonitor::MediaContentMonitor() : __started(false), - __lastCleanupTime(0) + __lastCleanupTime(0), + __dbusSignalId(-1), + __dbusWatcher(DBusType::SYSTEM) { __dbManager.createTable(0, MEDIA_TABLE_NAME, MEDIA_TABLE_COLUMNS, NULL, NULL); __dbManager.execute(0, MEDIA_PLAYCOUNT_TABLE_SCHEMA, NULL); @@ -42,50 +50,52 @@ ctx::MediaContentMonitor::~MediaContentMonitor() bool ctx::MediaContentMonitor::__startMonitoring() { - int err; - err = media_content_connect(); - IF_FAIL_RETURN_TAG(err == MEDIA_CONTENT_ERROR_NONE, false, _E, "media_content_connect() failed"); - - err = media_content_set_db_updated_cb(__onMediaContentDbUpdated, this); - if (err != MEDIA_CONTENT_ERROR_NONE) { - media_content_disconnect(); - _E("media_content_set_db_updated_cb() failed"); - return false; - } - + __dbusSignalId = __dbusWatcher.watch(NULL, MS_MEDIA_DBUS_PATH, MS_MEDIA_DBUS_INTERFACE, "ms_db_updated", this); + IF_FAIL_RETURN(__dbusSignalId >= 0, false); return true; } void ctx::MediaContentMonitor::__stopMonitoring() { - media_content_unset_db_updated_cb(); - media_content_disconnect(); + __dbusWatcher.unwatch(__dbusSignalId); } -void ctx::MediaContentMonitor::__onMediaContentDbUpdated( - media_content_error_e error, int pid, - media_content_db_update_item_type_e updateItem, - media_content_db_update_type_e updateType, - media_content_type_e mediaType, - char *uuid, char *path, char *mimeType, void *userData) +void ctx::MediaContentMonitor::onSignal(const char *sender, const char *path, const char *iface, const char *name, GVariant *param) { - IF_FAIL_VOID(error == MEDIA_CONTENT_ERROR_NONE && uuid != NULL); - IF_FAIL_VOID(updateItem == MEDIA_ITEM_FILE && updateType == MEDIA_CONTENT_UPDATE); - IF_FAIL_VOID(mediaType == MEDIA_CONTENT_TYPE_MUSIC || mediaType == MEDIA_CONTENT_TYPE_VIDEO); - - media_info_h media = NULL; - media_info_get_media_from_db(uuid, &media); - IF_FAIL_VOID_TAG(media, _E, "media_info_get_media_from_db() failed"); - - int cnt = -1; - media_info_get_played_count(media, &cnt); - media_info_destroy(media); - IF_FAIL_VOID_TAG(cnt >= 0, _E, "Invalid play count"); - - MediaContentMonitor *instance = static_cast(userData); - instance->__updatePlayCount(uuid, - (mediaType == MEDIA_CONTENT_TYPE_MUSIC) ? MEDIA_TYPE_MUSIC : MEDIA_TYPE_VIDEO, - cnt); + if (g_variant_n_children(param) < 7) + return; + + gint32 item = -1; + gint32 pid = 0; + gint32 updateType = MS_MEDIA_UNKNOWN; + gint32 contentType = -1; + char *updatePath = NULL; + char *uuid = NULL; + char *mimeType = NULL; + + g_variant_get(param, "(iii&s&si&s)", &item, &pid, &updateType, &updatePath, &uuid, &contentType, &mimeType); + + int playCount; + if (__getPlayCount(item, updateType, contentType, uuid, &playCount)) + __updatePlayCount(uuid, (contentType == MS_MEDIA_MUSIC) ? MEDIA_TYPE_MUSIC : MEDIA_TYPE_VIDEO, playCount); +} + +bool ctx::MediaContentMonitor::__getPlayCount(int updateItem, int updateType, int mediaType, char *uuid, int *count) +{ + void *soHandle = dlopen(SO_PATH, RTLD_LAZY | RTLD_GLOBAL); + IF_FAIL_RETURN_TAG(soHandle, false, _E, "%s", dlerror()); + + get_play_count_t getCount = reinterpret_cast(dlsym(soHandle, "getMediaPlayCount")); + if (!getCount) { + _E("%s", dlerror()); + dlclose(soHandle); + return false; + } + + bool ret = getCount(updateItem, updateType, mediaType, uuid, count); + dlclose(soHandle); + + return ret; } void ctx::MediaContentMonitor::__appendCleanupQuery(std::stringstream &query) diff --git a/src/media-stats/MediaContentMonitor.h b/src/media-stats/MediaContentMonitor.h index b8709aa..84610b3 100644 --- a/src/media-stats/MediaContentMonitor.h +++ b/src/media-stats/MediaContentMonitor.h @@ -18,16 +18,18 @@ #define _CONTEXT_STATS_MEDIA_CONTENT_MONITOR_H_ #include -#include +#include #include namespace ctx { - class MediaContentMonitor : public IDatabaseListener { + class MediaContentMonitor : public IDatabaseListener, public IDBusSignalListener { private: bool __started; int __lastCleanupTime; DatabaseManager __dbManager; + int64_t __dbusSignalId; + DBusSignalWatcher __dbusWatcher; bool __startMonitoring(); void __stopMonitoring(); @@ -36,15 +38,12 @@ namespace ctx { void __updatePlayCount(const char *uuid, int type, int count); void __insertLog(int mediaType); + bool __getPlayCount(int updateItem, int updateType, int mediaType, char *uuid, int *count); + void onTableCreated(unsigned int queryId, int error) {} void onInserted(unsigned int queryId, int error, int64_t rowId) {} void onExecuted(unsigned int queryId, int error, std::vector& records); - - static void __onMediaContentDbUpdated(media_content_error_e error, int pid, - media_content_db_update_item_type_e updateItem, - media_content_db_update_type_e updateType, - media_content_type_e mediaType, - char *uuid, char *path, char *mimeType, void *userData); + void onSignal(const char *sender, const char *path, const char *iface, const char *name, GVariant *param); public: MediaContentMonitor(); diff --git a/src/media-stats/util/CMakeLists.txt b/src/media-stats/util/CMakeLists.txt new file mode 100644 index 0000000..bdeffb7 --- /dev/null +++ b/src/media-stats/util/CMakeLists.txt @@ -0,0 +1,19 @@ +SET(target "${target_prefix}-media-stats-util") + +SET(DEPS ${DEPS} + capi-content-media-content +) + +FILE(GLOB SRCS *.cpp) + +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(PKG_MEDIA_STATS_UTIL REQUIRED ${DEPS}) + +FOREACH(flag ${PKG_MEDIA_STATS_UTIL_CFLAGS}) + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag}") +ENDFOREACH(flag) + +ADD_LIBRARY(${target} SHARED ${SRCS}) +TARGET_LINK_LIBRARIES(${target} ${PKG_MEDIA_STATS_UTIL_LDFLAGS} ${target_shared}) + +INSTALL(TARGETS ${target} DESTINATION ${CMAKE_INSTALL_LIBDIR}/${target_dir}) diff --git a/src/media-stats/util/MediaInfoUtil.cpp b/src/media-stats/util/MediaInfoUtil.cpp new file mode 100644 index 0000000..ec0cfba --- /dev/null +++ b/src/media-stats/util/MediaInfoUtil.cpp @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2016 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 +#include + +extern "C" SO_EXPORT bool getMediaPlayCount(int updateItem, int updateType, int mediaType, char *uuid, int *count) +{ + IF_FAIL_RETURN(updateItem == MEDIA_ITEM_FILE && updateType == MEDIA_CONTENT_UPDATE, false); + IF_FAIL_RETURN(mediaType == MEDIA_CONTENT_TYPE_MUSIC || mediaType == MEDIA_CONTENT_TYPE_VIDEO, false); + + int err = media_content_connect(); + IF_FAIL_RETURN_TAG(err == MEDIA_CONTENT_ERROR_NONE, false, _E, "media_content_connect() failed"); + + media_info_h media = NULL; + media_info_get_media_from_db(uuid, &media); + if (!media) { + _E("media_info_get_media_from_db() failed"); + media_content_disconnect(); + return false; + } + + media_info_get_played_count(media, count); + media_info_destroy(media); + media_content_disconnect(); + + return true; +} -- 2.34.1