Break the direct dependency to media-content from the media stats provider 19/67619/2
authorMu-Woong Lee <muwoong.lee@samsung.com>
Wed, 27 Apr 2016 12:04:54 +0000 (21:04 +0900)
committerMu-Woong Lee <muwoong.lee@samsung.com>
Thu, 28 Apr 2016 02:03:41 +0000 (11:03 +0900)
If necessary, the provider dynamically load another so to use the media content API.

Change-Id: Id7f1fab0e956ee7702382328b981860f5fa6c9fc
Signed-off-by: Mu-Woong Lee <muwoong.lee@samsung.com>
packaging/context-provider.spec
src/media-stats/CMakeLists.txt
src/media-stats/MediaContentMonitor.cpp
src/media-stats/MediaContentMonitor.h
src/media-stats/util/CMakeLists.txt [new file with mode: 0644]
src/media-stats/util/MediaInfoUtil.cpp [new file with mode: 0644]

index 01b83db..9d7b30b 100644 (file)
@@ -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
index cf5e6de..19c9ea4 100644 (file)
@@ -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)
index 734b64b..634de43 100644 (file)
  * limitations under the License.
  */
 
+#include <dlfcn.h>
 #include <time.h>
+#include <media-util-noti-common.h>
 #include <Types.h>
 #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<MediaContentMonitor*>(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<get_play_count_t>(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)
index b8709aa..84610b3 100644 (file)
 #define _CONTEXT_STATS_MEDIA_CONTENT_MONITOR_H_
 
 #include <sstream>
-#include <media_content.h>
+#include <DBusSignalWatcher.h>
 #include <DatabaseManager.h>
 
 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<Json>& 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 (file)
index 0000000..bdeffb7
--- /dev/null
@@ -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 (file)
index 0000000..ec0cfba
--- /dev/null
@@ -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 <media_content.h>
+#include <Types.h>
+
+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;
+}