# Source Lists
FILE(GLOB SRCS src/shared/*.cpp)
FILE(GLOB SRCS ${SRCS} src/app/*.cpp)
-FILE(GLOB SRCS ${SRCS} src/media/*.cpp)
# Dependencies
SET(provider_deps "context-common capi-system-runtime-info pkgmgr pkgmgr-info capi-appfw-package-manager")
# Dependencies regarding profiles
IF("${PROFILE}" STREQUAL "mobile")
ADD_DEFINITIONS("-D_MOBILE_")
+ FILE(GLOB SRCS ${SRCS} src/media/*.cpp)
FILE(GLOB SRCS ${SRCS} src/social/*.cpp)
- SET(provider_deps "${provider_deps} contacts-service2")
+ SET(provider_deps "${provider_deps} contacts-service2 capi-content-media-content")
ELSE("${PROFILE}" STREQUAL "mobile")
+ FILE(GLOB SRCS ${SRCS} src/media_dummy/*.cpp)
FILE(GLOB SRCS ${SRCS} src/social_dummy/*.cpp)
ENDIF("${PROFILE}" STREQUAL "mobile")
ADD_DEFINITIONS("-D_EMULATOR_")
ENDIF("${ARCH}" STREQUAL "arm")
+IF("${ACTIVE_WINDOW_HOOK}" STREQUAL "on")
+ ADD_DEFINITIONS("-D_USE_ACTIVE_WINDOW_HOOKING_")
+ SET(provider_deps "${provider_deps} ecore ecore-x")
+ SET(SRCS ${SRCS} src/app/app_use_monitor/active_window_monitor.cpp)
+ELSE("${ACTIVE_WINDOW_HOOK}" STREQUAL "on")
+ SET(SRCS ${SRCS} src/app/app_use_monitor/launch_monitor.cpp)
+ENDIF("${ACTIVE_WINDOW_HOOK}" STREQUAL "on")
+
# Common Options
INCLUDE(FindPkgConfig)
INCLUDE_DIRECTORIES(
Name: statistics-context-provider
Summary: Statistics Context Provider
-Version: 0.4.2
+Version: 0.4.3
Release: 1
Group: System/Libraries
License: Apache-2.0
Source0: %{name}-%{version}.tar.gz
+# Using the active window hooking for app monitoring, via ecore-x
+%define ACTIVE_WINDOW_HOOK on
+
BuildRequires: cmake
BuildRequires: pkgconfig(context-common)
%if "%{?tizen_profile_name}" == "mobile"
BuildRequires: pkgconfig(contacts-service2)
+BuildRequires: pkgconfig(capi-content-media-content)
+%endif
+
+%if "%{ACTIVE_WINDOW_HOOK}" == "on"
+BuildRequires: pkgconfig(ecore)
+BuildRequires: pkgconfig(ecore-x)
%endif
%ifarch %{arm}
export CXXFLAGS+=" -DTIZEN_ENGINEER_MODE"
export FFLAGS+=" -DTIZEN_ENGINEER_MODE"
-cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DARCH=%{ARCH} -DMAJORVER=${MAJORVER} -DFULLVER=%{version} -DPROFILE=%{?tizen_profile_name} -DBINTYPE=%{BINTYPE}
+cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} -DARCH=%{ARCH} -DMAJORVER=${MAJORVER} -DFULLVER=%{version} -DPROFILE=%{?tizen_profile_name} \
+ -DBINTYPE=%{BINTYPE} -DACTIVE_WINDOW_HOOK=%{ACTIVE_WINDOW_HOOK}
make %{?jobs:-j%jobs}
%install
#include "db_init.h"
#include "install_monitor.h"
-#include "launch_monitor.h"
+
+#ifdef _USE_ACTIVE_WINDOW_HOOKING_
+#include "app_use_monitor/active_window_monitor.h"
+#else
+#include "app_use_monitor/launch_monitor.h"
+#endif
static ctx::app_install_monitor *install_mon = NULL;
-static ctx::app_launch_monitor *launch_mon = NULL;
+static ctx::app_use_monitor *launch_mon = NULL;
EXTAPI ctx::app_statistics_provider::app_statistics_provider()
{
IF_FAIL_RETURN_TAG(initializer, false, _E, "Memory allocation failed");
install_mon = new(std::nothrow) ctx::app_install_monitor();
- launch_mon = new(std::nothrow) ctx::app_launch_monitor();
+ launch_mon = new(std::nothrow) ctx::app_use_monitor();
IF_FAIL_CATCH_TAG(install_mon && launch_mon, _E, "Memory allocation failed");
context_manager::register_provider(APP_SUBJ_FREQUENTLY_USED, this);
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <sys/types.h>
+#include <time.h>
+#include <sstream>
+#include <Ecore_X.h>
+#include <app_manager.h>
+
+#include <db_mgr.h>
+#include <json.h>
+#include <types_internal.h>
+#include <system_info.h>
+#include "../app_stats_types.h"
+#include "active_window_monitor.h"
+
+/* Active window changes frequently.
+ * We thus consider the apps being foregrounded at least 3 secs */
+#define MIN_VALID_USE_TIME 2
+
+static Ecore_Event_Handler *window_property_event_handler;
+
+ctx::app_use_monitor::app_use_monitor()
+ : last_timestamp(0)
+ , last_pid(-1)
+{
+ start_logging();
+}
+
+ctx::app_use_monitor::~app_use_monitor()
+{
+ stop_logging();
+}
+
+bool ctx::app_use_monitor::start_logging()
+{
+ /* This ecore_x based approach does not work with virtualization features */
+ if(window_property_event_handler == NULL) {
+ ecore_x_init(NULL);
+ ecore_x_event_mask_set(ecore_x_window_root_first_get(), ECORE_X_EVENT_MASK_WINDOW_PROPERTY);
+ window_property_event_handler = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_PROPERTY, on_window_property_changed, this);
+ IF_FAIL_RETURN_TAG(window_property_event_handler, false, _E, "ecore_event_handler_add() failed");
+ _D("Active window monitoring started");
+ }
+
+ return true;
+}
+
+void ctx::app_use_monitor::stop_logging()
+{
+ if (window_property_event_handler) {
+ ecore_event_handler_del(window_property_event_handler);
+ window_property_event_handler = NULL;
+ _D("Active window monitoring stopped");
+ }
+}
+
+Eina_Bool ctx::app_use_monitor::on_window_property_changed(void* data, int type, void* event)
+{
+ IF_FAIL_RETURN_TAG(data && event, ECORE_CALLBACK_PASS_ON, _W, "Invalid window event");
+
+ Ecore_X_Event_Window_Property *property = static_cast<Ecore_X_Event_Window_Property*>(event);
+ Ecore_X_Atom atom = ecore_x_atom_get("_NET_ACTIVE_WINDOW");
+
+ IF_FAIL_RETURN(property->atom == atom, ECORE_CALLBACK_PASS_ON);
+
+ int pid = 0;
+ Ecore_X_Window win = 0;
+
+ ecore_x_window_prop_window_get(property->win, atom, &win, 1);
+ ecore_x_netwm_pid_get(win, &pid);
+
+ IF_FAIL_RETURN_TAG(pid > 0, ECORE_CALLBACK_PASS_ON, _W, "Invalid pid");
+
+ app_use_monitor *instance = static_cast<app_use_monitor*>(data);
+ instance->on_active_window_changed(pid);
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+void ctx::app_use_monitor::on_active_window_changed(int pid)
+{
+ IF_FAIL_VOID(last_pid != pid);
+ _D("Active window changed: PID-%d", pid);
+
+ int timestamp = static_cast<int>(time(NULL));
+ int duration = timestamp - last_timestamp;
+
+ if (!last_app_id.empty() > 0 && duration >= MIN_VALID_USE_TIME)
+ verify_used_app(last_app_id.c_str(), duration);
+
+ last_timestamp = timestamp;
+ last_pid = pid;
+
+ char *app_id = NULL;
+ app_manager_get_app_id(pid, &app_id);
+ last_app_id = (app_id ? app_id : "");
+ g_free(app_id);
+ _D("Current Active App: %s", last_app_id.c_str());
+}
+
+void ctx::app_use_monitor::verify_used_app(const char *app_id, int duration)
+{
+ app_info_h app_info = NULL;
+ int err = app_manager_get_app_info(app_id, &app_info);
+ IF_FAIL_VOID_TAG(err == APP_MANAGER_ERROR_NONE && app_info, _E, "app_manager_get_app_info() failed");
+
+ bool nodisp = false;
+ err = app_info_is_nodisplay(app_info, &nodisp);
+ IF_FAIL_CATCH_TAG(err == APP_MANAGER_ERROR_NONE, _E, "app_info_is_nodisplay() failed");
+ IF_FAIL_CATCH(!nodisp);
+
+ insert_log(app_id, duration);
+
+CATCH:
+ if (app_info)
+ app_info_destroy(app_info);
+}
+
+void ctx::app_use_monitor::insert_log(const char *app_id, int duration)
+{
+ int audiojack;
+ int system_volume;
+ int media_volume;
+ std::string bssid;
+
+ std::stringstream cols;
+ std::stringstream vals;
+
+ /* App ID */
+ cols << STATS_APP_ID << ",";
+ vals << "'" << app_id << "',";
+
+ /* Audio Jack */
+ if (ctx::system_info::get_audio_jack_state(&audiojack)) {
+ cols << STATS_AUDIO_JACK << ",";
+ vals << audiojack << ",";
+ }
+
+ /* Volume */
+ if (ctx::system_info::get_volume(&system_volume, &media_volume)) {
+ cols << STATS_SYSTEM_VOLUME << "," << STATS_MEDIA_VOLUME << ",";
+ vals << system_volume << "," << media_volume << ",";
+ }
+
+ /* BSSID */
+ if (ctx::system_info::get_wifi_bssid(bssid)) {
+ cols << STATS_BSSID << ",";
+ vals << "'" << bssid << "',";
+ }
+
+ /* Time */
+ cols << STATS_UNIV_TIME << ",";
+ vals << "(strftime('%s', 'now')) - " << duration << ",";
+
+ cols << STATS_LOCAL_TIME << ",";
+ vals << "(strftime('%s', 'now', 'localtime')) - " << duration << ",";
+
+ /* Duration */
+ cols << STATS_DURATION;
+ vals << duration;
+
+ std::stringstream query;
+ query << "INSERT INTO " << APP_TABLE_USAGE_LOG << " ("
+ << cols.str() << ") VALUES (" << vals.str() << ")";
+
+ db_manager::execute(0, query.str().c_str(), NULL);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 __CONTEXT_APP_USE_MONITOR_H__
+#define __CONTEXT_APP_USE_MONITOR_H__
+
+#include <string>
+#include <Ecore.h>
+
+namespace ctx {
+
+ class app_use_monitor {
+ private:
+ int last_timestamp;
+ int last_pid;
+ std::string last_app_id;
+
+ bool start_logging(void);
+ void stop_logging(void);
+
+ void verify_used_app(const char *app_id, int duration);
+ void insert_log(const char *app_id, int duration);
+
+ void on_active_window_changed(int pid);
+ static Eina_Bool on_window_property_changed(void* data, int type, void* event);
+
+ public:
+ app_use_monitor();
+ ~app_use_monitor();
+ }; /* class app_use_monitor */
+
+} /* namespace ctx */
+
+#endif /* __CONTEXT_APP_USE_MONITOR_H__ */
#include <zone_util.h>
#include <system_info.h>
-#include "app_stats_types.h"
+#include "../app_stats_types.h"
#include "launch_monitor.h"
-ctx::app_launch_monitor::app_launch_monitor()
+ctx::app_use_monitor::app_use_monitor()
{
start_logging();
}
-ctx::app_launch_monitor::~app_launch_monitor()
+ctx::app_use_monitor::~app_use_monitor()
{
stop_logging();
}
-bool ctx::app_launch_monitor::start_logging()
+bool ctx::app_use_monitor::start_logging()
{
scope_zone_joiner sz(zone_util::default_zone());
return true;
}
-void ctx::app_launch_monitor::stop_logging()
+void ctx::app_use_monitor::stop_logging()
{
scope_zone_joiner sz(zone_util::default_zone());
app_manager_unset_app_context_event_cb();
}
-void ctx::app_launch_monitor::app_context_event_cb(app_context_h app_context, app_context_event_e event, void *user_data)
+void ctx::app_use_monitor::app_context_event_cb(app_context_h app_context, app_context_event_e event, void *user_data)
{
scope_zone_joiner sz(zone_util::default_zone());
int err = app_context_get_app_id(app_context, &app_id);
IF_FAIL_VOID_TAG(err == APP_MANAGER_ERROR_NONE, _E, "app_context_get_app_id() failed");
- app_launch_monitor *monitor = static_cast<app_launch_monitor*>(user_data);
+ app_use_monitor *monitor = static_cast<app_use_monitor*>(user_data);
if (event == APP_CONTEXT_EVENT_LAUNCHED) {
monitor->log_launch_event(app_id);
g_free(app_id);
}
-void ctx::app_launch_monitor::log_launch_event(const char* app_id)
+void ctx::app_use_monitor::log_launch_event(const char* app_id)
{
int audiojack;
int system_volume;
db_manager::insert(0, APP_TABLE_USAGE_LOG, data, NULL);
}
-void ctx::app_launch_monitor::log_terminate_event(const char* app_id)
+void ctx::app_use_monitor::log_terminate_event(const char* app_id)
{
std::stringstream query;
query <<
* limitations under the License.
*/
-#ifndef __CONTEXT_APP_LAUNCH_MONITOR_H__
-#define __CONTEXT_APP_LAUNCH_MONITOR_H__
+#ifndef __CONTEXT_APP_USE_MONITOR_H__
+#define __CONTEXT_APP_USE_MONITOR_H__
#include <app_manager.h>
#include <db_listener_iface.h>
namespace ctx {
- class app_launch_monitor : public db_listener_iface {
+ class app_use_monitor : public db_listener_iface {
private:
bool start_logging(void);
void stop_logging(void);
static void app_context_event_cb(app_context_h app_context, app_context_event_e event, void *user_data);
public:
- app_launch_monitor();
- ~app_launch_monitor();
- }; /* class app_launch_monitor */
+ app_use_monitor();
+ ~app_use_monitor();
+ }; /* class app_use_monitor */
} /* namespace ctx */
-#endif /* __CONTEXT_APP_LAUNCH_MONITOR_H__ */
+#endif /* __CONTEXT_APP_USE_MONITOR_H__ */
ctx::media_db_handle::media_db_handle(const char* zone)
: stats_db_handle_base(zone)
{
- create_table();
}
ctx::media_db_handle::~media_db_handle()
{
}
-void ctx::media_db_handle::create_table()
-{
- static bool done = false;
- IF_FAIL_VOID(!done);
-
- db_manager::create_table(generate_qid(), MEDIA_TABLE_NAME, MEDIA_TABLE_COLUMNS, NULL, NULL);
-
- done = true;
-}
-
int ctx::media_db_handle::read(const char* subject, ctx::json filter)
{
//TODO: filter validation (in the API side?)
return ERR_NONE;
}
-int ctx::media_db_handle::write(const char* subject, ctx::json data)
-{
- std::string app_id;
- int media_type = -1;
- int action_type = -1;
-
- data.get(NULL, COMMON_ATTR_CLIENT_APP_ID, &app_id);
- IF_FAIL_RETURN_TAG(!app_id.empty(), ERR_OPERATION_FAILED, _E, "No AppId");
-
- if (STR_EQ(subject, MEDIA_SUBJ_START_MUSIC)) {
- media_type = MEDIA_TYPE_MUSIC;
- action_type = MEDIA_ACTION_START;
-
- } else if (STR_EQ(subject, MEDIA_SUBJ_STOP_MUSIC)) {
- media_type = MEDIA_TYPE_MUSIC;
- action_type = MEDIA_ACTION_STOP;
-
- } else if (STR_EQ(subject, MEDIA_SUBJ_START_VIDEO)) {
- media_type = MEDIA_TYPE_VIDEO;
- action_type = MEDIA_ACTION_START;
-
- } else if (STR_EQ(subject, MEDIA_SUBJ_STOP_VIDEO)) {
- media_type = MEDIA_TYPE_VIDEO;
- action_type = MEDIA_ACTION_STOP;
-
- } else {
- return ERR_NOT_SUPPORTED;
- }
-
- IF_FAIL_RETURN(insert_log(app_id, media_type, action_type), ERR_OPERATION_FAILED);
- return ERR_NONE;
-}
-
std::string ctx::media_db_handle::create_where_clause(int media_type, ctx::json filter)
{
std::stringstream where_clause;
- where_clause << MEDIA_TYPE " = " << media_type << " AND ";
- where_clause << MEDIA_ACTION " = " << MEDIA_ACTION_START << " AND ";
+ where_clause << CX_MEDIA_TYPE " = " << media_type << " AND ";
where_clause << stats_db_handle_base::create_where_clause(filter);
return where_clause.str();
return query.str();
}
-
-bool ctx::media_db_handle::insert_log(std::string app_id, int media_type, int action_type)
-{
- int system_volume = -1, media_volume = -1, audiojack = -1;
-
- json data;
- data.set(NULL, STATS_APP_ID, app_id);
- data.set(NULL, MEDIA_TYPE, media_type);
- data.set(NULL, MEDIA_ACTION, action_type);
-
- if (ctx::system_info::get_audio_jack_state(&audiojack))
- data.set(NULL, STATS_AUDIO_JACK, audiojack);
-
- if (ctx::system_info::get_volume(&system_volume, &media_volume)) {
- data.set(NULL, STATS_SYSTEM_VOLUME, system_volume);
- data.set(NULL, STATS_MEDIA_VOLUME, media_volume);
- }
-
- return db_manager::insert(generate_qid(), MEDIA_TABLE_NAME, data, this);
-}
~media_db_handle();
int read(const char* subject, ctx::json filter);
- int write(const char* subject, ctx::json data);
private:
- void create_table();;
- bool insert_log(std::string app_id, int media_type, int action_type);
-
std::string create_where_clause(int media_type, ctx::json filter);
std::string create_sql_peak_time(int media_type, ctx::json filter);
std::string create_sql_common_setting(int media_type, ctx::json filter);
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <sstream>
+#include <types_internal.h>
+#include <db_mgr.h>
+#include <system_info.h>
+#include "media_stats_types.h"
+#include "db_handle.h"
+#include "media_content_monitor.h"
+
+ctx::media_content_monitor::media_content_monitor()
+ : started(false)
+{
+ db_manager::create_table(0, MEDIA_TABLE_NAME, MEDIA_TABLE_COLUMNS, NULL, NULL);
+ db_manager::execute(0, MEDIA_PLAYCOUNT_TABLE_SCHEMA, NULL);
+
+ started = start_monitoring();
+}
+
+ctx::media_content_monitor::~media_content_monitor()
+{
+ if (started)
+ stop_monitoring();
+}
+
+bool ctx::media_content_monitor::start_monitoring()
+{
+ 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(on_media_content_db_updated, this);
+ if (err != MEDIA_CONTENT_ERROR_NONE) {
+ media_content_disconnect();
+ _E("media_content_set_db_updated_cb() failed");
+ return false;
+ }
+
+ return true;
+}
+
+void ctx::media_content_monitor::stop_monitoring()
+{
+ media_content_unset_db_updated_cb();
+ media_content_disconnect();
+}
+
+void ctx::media_content_monitor::on_media_content_db_updated(
+ media_content_error_e error, int pid,
+ media_content_db_update_item_type_e update_item,
+ media_content_db_update_type_e update_type,
+ media_content_type_e media_type,
+ char *uuid, char *path, char *mime_type, void *user_data)
+{
+ IF_FAIL_VOID(error == MEDIA_CONTENT_ERROR_NONE && uuid != NULL);
+ IF_FAIL_VOID(update_item == MEDIA_ITEM_FILE && update_type == MEDIA_CONTENT_UPDATE);
+ IF_FAIL_VOID(media_type == MEDIA_CONTENT_TYPE_MUSIC || media_type == 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");
+
+ media_content_monitor *instance = static_cast<media_content_monitor*>(user_data);
+ instance->update_play_count(uuid,
+ (media_type == MEDIA_CONTENT_TYPE_MUSIC) ? MEDIA_TYPE_MUSIC : MEDIA_TYPE_VIDEO,
+ cnt);
+}
+
+void ctx::media_content_monitor::update_play_count(const char *uuid, int type, int count)
+{
+ std::stringstream query;
+ query << "INSERT OR IGNORE INTO Log_MediaPlayCount" \
+ " (UUID, MediaType) VALUES ('" << uuid << "'," << type <<");" \
+ "UPDATE Log_MediaPlayCount SET Diff = " << count << " - Count," \
+ " Count = " << count << " WHERE UUID = '" << uuid << "';" \
+ "SELECT MediaType FROM Log_MediaPlayCount" \
+ " WHERE UUID = '" << uuid << "' AND Diff > 0;";
+
+ db_manager::execute(0, query.str().c_str(), this);
+}
+
+void ctx::media_content_monitor::on_query_result_received(unsigned int query_id, int error, std::vector<json>& records)
+{
+ IF_FAIL_VOID(!records.empty());
+
+ int media_type = 0;
+ records[0].get(NULL, CX_MEDIA_TYPE, &media_type);
+
+ insert_log(media_type);
+}
+
+void ctx::media_content_monitor::insert_log(int media_type)
+{
+ int system_volume = -1, media_volume = -1, audiojack = -1;
+
+ json data;
+ data.set(NULL, CX_MEDIA_TYPE, media_type);
+
+ if (ctx::system_info::get_audio_jack_state(&audiojack))
+ data.set(NULL, STATS_AUDIO_JACK, audiojack);
+
+ if (ctx::system_info::get_volume(&system_volume, &media_volume)) {
+ data.set(NULL, STATS_SYSTEM_VOLUME, system_volume);
+ data.set(NULL, STATS_MEDIA_VOLUME, media_volume);
+ }
+
+ db_manager::insert(0, MEDIA_TABLE_NAME, data, NULL);
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 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 __CONTEXT_MEDIA_CONTENT_MONITOR_H__
+#define __CONTEXT_MEDIA_CONTENT_MONITOR_H__
+
+#include <media_content.h>
+#include <db_listener_iface.h>
+
+namespace ctx {
+
+ class media_content_monitor : public db_listener_iface {
+ private:
+ bool started;
+ bool start_monitoring();
+ void stop_monitoring();
+
+ void update_play_count(const char *uuid, int type, int count);
+ void insert_log(int media_type);
+
+ void on_creation_result_received(unsigned int query_id, int error) {}
+ void on_insertion_result_received(unsigned int query_id, int error, int64_t row_id) {}
+ void on_query_result_received(unsigned int query_id, int error, std::vector<json>& records);
+
+ static void on_media_content_db_updated(media_content_error_e error, int pid,
+ media_content_db_update_item_type_e update_item,
+ media_content_db_update_type_e update_type,
+ media_content_type_e media_type,
+ char *uuid, char *path, char *mime_type, void *user_data);
+
+ public:
+ media_content_monitor();
+ ~media_content_monitor();
+ };
+
+} /* namespace ctx */
+
+#endif
#include <media_statistics_provider.h>
#include "media_stats_types.h"
#include "db_handle.h"
+#include "media_content_monitor.h"
+
+static ctx::media_content_monitor *content_mon = NULL;
EXTAPI ctx::media_statistics_provider::media_statistics_provider()
{
EXTAPI ctx::media_statistics_provider::~media_statistics_provider()
{
+ delete content_mon;
+ content_mon = NULL;
}
bool ctx::media_statistics_provider::init()
{
- context_manager::register_provider(MEDIA_SUBJ_START_MUSIC, this);
- context_manager::register_provider(MEDIA_SUBJ_STOP_MUSIC, this);
- context_manager::register_provider(MEDIA_SUBJ_START_VIDEO, this);
- context_manager::register_provider(MEDIA_SUBJ_STOP_VIDEO, this);
+ content_mon = new(std::nothrow) ctx::media_content_monitor();
+ IF_FAIL_RETURN_TAG(content_mon, false, _E, "Memory allocation failed");
+
context_manager::register_provider(MEDIA_SUBJ_PEAK_TIME_FOR_MUSIC, this);
context_manager::register_provider(MEDIA_SUBJ_PEAK_TIME_FOR_VIDEO, this);
context_manager::register_provider(MEDIA_SUBJ_COMMON_SETTING_FOR_MUSIC, this);
int ctx::media_statistics_provider::write(const char* subject, ctx::json data, ctx::json* request_result, const char* zone)
{
- if (!STR_EQ(zone, zone_util::default_zone())) {
- _D("Not supported in the current zone '%s'", zone);
- return ERR_NOT_SUPPORTED;
- }
-
- media_db_handle *handle = new(std::nothrow) media_db_handle(zone);
- IF_FAIL_RETURN_TAG(handle, ERR_OPERATION_FAILED, _E, "Memory allocation failed");
-
- int err = handle->write(subject, data);
- if (err != ERR_NONE) {
- delete handle;
- return err;
- }
-
- return ERR_NONE;
+ return ERR_NOT_SUPPORTED;
}
#define __CONTEXT_MEDIA_STATS_TYPES_H__
#include <common_types.h>
-
-#define MEDIA_SUBJ_START_MUSIC "music/event/start"
-#define MEDIA_SUBJ_STOP_MUSIC "music/event/stop"
-#define MEDIA_SUBJ_START_VIDEO "video/event/start"
-#define MEDIA_SUBJ_STOP_VIDEO "video/event/stop"
-
#define MEDIA_SUBJ_PEAK_TIME_FOR_MUSIC "music/history/peak_time"
#define MEDIA_SUBJ_PEAK_TIME_FOR_VIDEO "video/history/peak_time"
#define MEDIA_SUBJ_COMMON_SETTING_FOR_MUSIC "music/history/common_setting"
#define MEDIA_TABLE_NAME "Log_MediaPlayback"
#define MEDIA_TABLE_COLUMNS \
- "AppId TEXT NOT NULL, MediaType INTEGER NOT NULL, Action INTEGER NOT NULL, " \
+ "MediaType INTEGER NOT NULL, " \
"SystemVolume INTEGER, MediaVolume INTEGER, AudioJack INTEGER, " \
"UTC TIMESTAMP DEFAULT (strftime('%s', 'now')), " \
"LocalTime TIMESTAMP DEFAULT (strftime('%s', 'now', 'localtime'))"
-#define MEDIA_TYPE "MediaType"
-#define MEDIA_ACTION "Action"
+#define MEDIA_PLAYCOUNT_TABLE_SCHEMA \
+ "CREATE TABLE IF NOT EXISTS Log_MediaPlayCount" \
+ " (UUID TEXT NOT NULL PRIMARY KEY, MediaType INTEGER NOT NULL," \
+ " Count INTEGER DEFAULT 0, Diff INTEGER DEFAULT 0)"
+
+#define CX_MEDIA_TYPE "MediaType"
enum media_type_e {
MEDIA_TYPE_MUSIC = 1,
MEDIA_TYPE_VIDEO,
};
-enum media_action_e {
- MEDIA_ACTION_START = 1,
- MEDIA_ACTION_STOP,
-};
-
#endif
--- /dev/null
+/*
+ * Copyright (c) 2015 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 <types_internal.h>
+#include <json.h>
+#include <media_statistics_provider.h>
+
+EXTAPI ctx::media_statistics_provider::media_statistics_provider()
+{
+}
+
+EXTAPI ctx::media_statistics_provider::~media_statistics_provider()
+{
+}
+
+bool ctx::media_statistics_provider::init()
+{
+ return true;
+}
+
+bool ctx::media_statistics_provider::is_supported(const char* subject, const char* zone)
+{
+ return false;
+}
+
+int ctx::media_statistics_provider::subscribe(const char* subject, ctx::json option, ctx::json* request_result, const char* zone)
+{
+ return ERR_NOT_SUPPORTED;
+}
+
+int ctx::media_statistics_provider::unsubscribe(const char* subject, ctx::json option, const char* zone)
+{
+ return ERR_NOT_SUPPORTED;
+}
+
+int ctx::media_statistics_provider::read(const char* subject, ctx::json option, ctx::json* request_result, const char* zone)
+{
+ return ERR_NOT_SUPPORTED;
+}
+
+int ctx::media_statistics_provider::write(const char* subject, ctx::json data, ctx::json* request_result, const char* zone)
+{
+ return ERR_NOT_SUPPORTED;
+}